diff --git a/packages/iobroker.vis-2/src/package.json b/packages/iobroker.vis-2/src/package.json index 1fb3553a..ca8227b1 100644 --- a/packages/iobroker.vis-2/src/package.json +++ b/packages/iobroker.vis-2/src/package.json @@ -7,7 +7,7 @@ "scripts": { "start": "craco start", "types": "tsc ./src/Vis/visRxWidget.tsx --declaration --emitDeclarationOnly --outDir ../../types-vis-2", - "lint": "eslint --fix --ext .js,.jsx src", + "lint": "eslint -c eslint.config.mjs --debug", "build": "craco build", "check-ts": "tsc --noEmit --checkJS false" }, diff --git a/packages/iobroker.vis-2/src/src/Attributes/View.tsx b/packages/iobroker.vis-2/src/src/Attributes/View.tsx index a29e0e75..6fa36ef7 100644 --- a/packages/iobroker.vis-2/src/src/Attributes/View.tsx +++ b/packages/iobroker.vis-2/src/src/Attributes/View.tsx @@ -172,7 +172,16 @@ const ViewAttributes = (props: ViewProps): React.JSX.Element | null => { const fields = useMemo( () => (view ? getFields(resolutionSelect, view, props.selectedView, props.editMode, props.changeProject) : []), - [resolutionSelect, view?.settings?.sizex, view?.settings?.sizey, props.selectedView, props.editMode], + // eslint-disable-next-line react-hooks/exhaustive-deps + [ + view, + resolutionSelect, + view?.settings?.sizex, + view?.settings?.sizey, + props.selectedView, + props.editMode, + props.changeProject, + ], ); const [accordionOpen, setAccordionOpen] = useState>({}); @@ -214,7 +223,8 @@ const ViewAttributes = (props: ViewProps): React.JSX.Element | null => { window.localStorage.setItem('attributesView', JSON.stringify(newAccordionOpen)); setAccordionOpen(newAccordionOpen); } - }, [props.triggerAllOpened, props.triggerAllClosed]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [props.triggerAllOpened, props.triggerAllClosed, fields]); if (!project?.[props.selectedView]) { return null; diff --git a/packages/iobroker.vis-2/src/src/Attributes/Widget/TextDialog.tsx b/packages/iobroker.vis-2/src/src/Attributes/Widget/TextDialog.tsx index 39594341..e9c21319 100644 --- a/packages/iobroker.vis-2/src/src/Attributes/Widget/TextDialog.tsx +++ b/packages/iobroker.vis-2/src/src/Attributes/Widget/TextDialog.tsx @@ -20,7 +20,6 @@ const TextDialog = (props: TextDialogProps): React.JSX.Element => { props.onChange(value)} onClose={props.onClose} diff --git a/packages/iobroker.vis-2/src/src/Attributes/Widget/WidgetField.tsx b/packages/iobroker.vis-2/src/src/Attributes/Widget/WidgetField.tsx index 0d25ba14..a3a00cb2 100644 --- a/packages/iobroker.vis-2/src/src/Attributes/Widget/WidgetField.tsx +++ b/packages/iobroker.vis-2/src/src/Attributes/Widget/WidgetField.tsx @@ -502,6 +502,7 @@ const WidgetField = (props: WidgetFieldProps): string | React.JSX.Element | Reac }); } } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [propValue]); let value: string | number | boolean | null = cachedValue; @@ -565,7 +566,7 @@ const WidgetField = (props: WidgetFieldProps): string | React.JSX.Element | Reac // take the first child in div customLegacyComponent.init.call(refCustom.current.children[0] || refCustom.current, field.name, propValue); } - }, []); + }); if (askForUsage) { const usages = findWidgetUsages(store.getState().visProject, props.selectedView, askForUsage.wid); diff --git a/packages/iobroker.vis-2/src/src/Attributes/Widget/index.tsx b/packages/iobroker.vis-2/src/src/Attributes/Widget/index.tsx index fea1d05e..f56b8ba1 100644 --- a/packages/iobroker.vis-2/src/src/Attributes/Widget/index.tsx +++ b/packages/iobroker.vis-2/src/src/Attributes/Widget/index.tsx @@ -2064,7 +2064,6 @@ class Widget extends Component { this.setState({ clearGroup: null })} - open={!0} action={() => this.onGroupDelete(this.state.clearGroup)} actionTitle="Clear" > diff --git a/packages/iobroker.vis-2/src/src/Attributes/index.tsx b/packages/iobroker.vis-2/src/src/Attributes/index.tsx index 9a8b61f9..def3baa5 100644 --- a/packages/iobroker.vis-2/src/src/Attributes/index.tsx +++ b/packages/iobroker.vis-2/src/src/Attributes/index.tsx @@ -74,6 +74,7 @@ const Attributes = (props: AttributesProps): React.JSX.Element => { if (prevSelectedWidgets && !prevSelectedWidgets.length && props.selectedWidgets.length) { setSelected('Widget'); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [props.selectedWidgets]); if (!props.openedViews.length) { diff --git a/packages/iobroker.vis-2/src/src/Components/CreateFirstProjectDialog.tsx b/packages/iobroker.vis-2/src/src/Components/CreateFirstProjectDialog.tsx index b93b82a0..1c6168c1 100644 --- a/packages/iobroker.vis-2/src/src/Components/CreateFirstProjectDialog.tsx +++ b/packages/iobroker.vis-2/src/src/Components/CreateFirstProjectDialog.tsx @@ -2,19 +2,13 @@ import React from 'react'; import IODialog from './IODialog'; interface CreateFirstProjectDialogProps { - open: boolean; onClose: () => void; addProject: (name: string) => void; } -const CreateFirstProjectDialog = (props: CreateFirstProjectDialogProps): React.JSX.Element | null => { - if (props.open) { - return null; - } - +const CreateFirstProjectDialog = (props: CreateFirstProjectDialogProps): React.JSX.Element => { return ( props.addProject('Demo project')} diff --git a/packages/iobroker.vis-2/src/src/Components/IODialog.tsx b/packages/iobroker.vis-2/src/src/Components/IODialog.tsx index f5c840bf..43391c45 100644 --- a/packages/iobroker.vis-2/src/src/Components/IODialog.tsx +++ b/packages/iobroker.vis-2/src/src/Components/IODialog.tsx @@ -19,7 +19,6 @@ interface IODialogProps { dialogActions?: any; keyboardDisabled?: boolean; onClose: () => void; - open: boolean; title: string; fullScreen?: boolean; maxWidth?: Breakpoint; @@ -27,61 +26,60 @@ interface IODialogProps { noTranslation?: boolean; } -const IODialog = (props: IODialogProps): React.JSX.Element => - props.open ? ( - - {props.noTranslation ? props.title : I18n.t(props.title)} - { - if (props.action) { - if (!props.actionDisabled && !props.keyboardDisabled) { - if (e.key === 'Enter') { - props.action(); - if (!props.actionNoClose) { - props.onClose(); - } - } - } - } - }} - > - {props.children} - - - {props.dialogActions || null} - {props.actionTitle ? ( - - ) : null} + } + } + } + }} + > + {props.children} + + + {props.dialogActions || null} + {props.actionTitle ? ( - - - ) : null; + ) : null} + + + +); export default IODialog; diff --git a/packages/iobroker.vis-2/src/src/Components/UploadFile.tsx b/packages/iobroker.vis-2/src/src/Components/UploadFile.tsx index c789e99d..beaf0976 100644 --- a/packages/iobroker.vis-2/src/src/Components/UploadFile.tsx +++ b/packages/iobroker.vis-2/src/src/Components/UploadFile.tsx @@ -47,11 +47,13 @@ const UploadFile = (props: UploadFileProps): React.JSX.Element => { ) => { if (acceptedFiles?.length) { setWorking(true); - error && setError(''); + if (error) { + setError(''); + } const reader = new FileReader(); setFileName(acceptedFiles[0].name); - reader.onload = async (evt: ProgressEvent): Promise => { + reader.onload = (evt: ProgressEvent): void => { setWorking(false); setFileData(evt.target.result); props.onUpload(acceptedFiles[0].name, evt.target.result); @@ -68,11 +70,17 @@ const UploadFile = (props: UploadFileProps): React.JSX.Element => { } else { setError(`Error: ${err.message}`); } - setTimeout(() => error && setError(''), 3000); + // hide error after 3 seconds + setTimeout(() => { + if (error) { + setError(''); + } + }, 3000); }); } }, - [], + // eslint-disable-next-line react-hooks/exhaustive-deps + [error], ); const { getRootProps, getInputProps, isDragActive } = useDropzone({ diff --git a/packages/iobroker.vis-2/src/src/Editor.tsx b/packages/iobroker.vis-2/src/src/Editor.tsx index 81196208..18051e0e 100644 --- a/packages/iobroker.vis-2/src/src/Editor.tsx +++ b/packages/iobroker.vis-2/src/src/Editor.tsx @@ -2127,10 +2127,9 @@ class Editor extends Runtime { ); } - renderCreateFirstProjectDialog(): React.JSX.Element { + renderCreateFirstProjectDialog(): React.JSX.Element | null { return this.state.createFirstProjectDialog ? ( this.setState({ createFirstProjectDialog: false })} addProject={this.addProject} /> diff --git a/packages/iobroker.vis-2/src/src/Palette/Widget.tsx b/packages/iobroker.vis-2/src/src/Palette/Widget.tsx index ddfaa48a..9175e4cf 100644 --- a/packages/iobroker.vis-2/src/src/Palette/Widget.tsx +++ b/packages/iobroker.vis-2/src/src/Palette/Widget.tsx @@ -261,6 +261,7 @@ const Widget = (props: WidgetProps): React.JSX.Element => { useEffect(() => { preview(getEmptyImage(), { captureDraggingState: true }); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [props.widgetType]); if (typeof props.widgetType.customPalette === 'function') { diff --git a/packages/iobroker.vis-2/src/src/Toolbar/ProjectsManager/ImportProjectDialog.tsx b/packages/iobroker.vis-2/src/src/Toolbar/ProjectsManager/ImportProjectDialog.tsx index 4a476fe3..f57e410a 100644 --- a/packages/iobroker.vis-2/src/src/Toolbar/ProjectsManager/ImportProjectDialog.tsx +++ b/packages/iobroker.vis-2/src/src/Toolbar/ProjectsManager/ImportProjectDialog.tsx @@ -130,7 +130,6 @@ const ImportProjectDialog: React.FC = props => { return ( props.onClose()} actionNoClose action={importProject} diff --git a/packages/iobroker.vis-2/src/src/Toolbar/ProjectsManager/PermissionsDialog.tsx b/packages/iobroker.vis-2/src/src/Toolbar/ProjectsManager/PermissionsDialog.tsx index 8c33d4e6..dc386688 100644 --- a/packages/iobroker.vis-2/src/src/Toolbar/ProjectsManager/PermissionsDialog.tsx +++ b/packages/iobroker.vis-2/src/src/Toolbar/ProjectsManager/PermissionsDialog.tsx @@ -380,7 +380,6 @@ export default class PermissionsDialog extends React.Component this.props.onClose()} actionNoClose action={() => this.onSave()} diff --git a/packages/iobroker.vis-2/src/src/Toolbar/ProjectsManager/ProjectDialog.tsx b/packages/iobroker.vis-2/src/src/Toolbar/ProjectsManager/ProjectDialog.tsx index a679ca61..490a5b1b 100644 --- a/packages/iobroker.vis-2/src/src/Toolbar/ProjectsManager/ProjectDialog.tsx +++ b/packages/iobroker.vis-2/src/src/Toolbar/ProjectsManager/ProjectDialog.tsx @@ -14,7 +14,7 @@ interface ProjectDialogProps { dialogProject: string; dialogName: string; projects: string[]; - setDialog: (dialog: null | 'delete' | 'rename' | 'add') => void; + closeDialog: () => void; setDialogProject: (project: null | string) => void; setDialogName: (name: string) => void; addProject: (name: string) => void; @@ -22,7 +22,7 @@ interface ProjectDialogProps { renameProject: (project: string, name: string) => void; } -const ProjectDialog: React.FC = props => { +const ProjectDialog: React.FC = (props: ProjectDialogProps): React.JSX.Element | null => { const inputField = useFocus(props.dialog && props.dialog !== 'delete', props.dialog === 'add'); if (!props.dialog) { @@ -76,9 +76,8 @@ const ProjectDialog: React.FC = props => { title={dialogTitles[props.dialog]} actionTitle={dialogButtons[props.dialog]} noTranslation - open={!!props.dialog} onClose={() => { - props.setDialog(null); + props.closeDialog(); props.setDialogProject(null); }} ActionIcon={DialogIcon || null} diff --git a/packages/iobroker.vis-2/src/src/Toolbar/ProjectsManager/index.tsx b/packages/iobroker.vis-2/src/src/Toolbar/ProjectsManager/index.tsx index 757ec432..2a7b3324 100644 --- a/packages/iobroker.vis-2/src/src/Toolbar/ProjectsManager/index.tsx +++ b/packages/iobroker.vis-2/src/src/Toolbar/ProjectsManager/index.tsx @@ -194,7 +194,6 @@ const ProjectsManage: React.FC = props => { return props.open ? ( = props => { dialog={dialog} dialogProject={dialogProject} dialogName={dialogName} - setDialog={setDialog} + closeDialog={() => setDialog(null)} setDialogProject={setDialogProject} setDialogName={setDialogName} addProject={props.addProject} diff --git a/packages/iobroker.vis-2/src/src/Toolbar/Settings.tsx b/packages/iobroker.vis-2/src/src/Toolbar/Settings.tsx index e98ecf87..f5b6a4c2 100644 --- a/packages/iobroker.vis-2/src/src/Toolbar/Settings.tsx +++ b/packages/iobroker.vis-2/src/src/Toolbar/Settings.tsx @@ -86,7 +86,7 @@ const Settings: React.FC = props => { const [settings, setSettings] = useState({} as ProjectSettings); const [instance, setInstance] = useState(''); - /* eslint no-underscore-dangle: 0 */ + useEffect(() => { const _settings = { ...store.getState().visProject.___settings }; if (_settings.reloadOnEdit === undefined) { @@ -105,6 +105,7 @@ const Settings: React.FC = props => { }); setSettings(_settings); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const fields: SettingsField[] = [ @@ -247,7 +248,6 @@ const Settings: React.FC = props => { return ( { dialogCallback={dialogCallback} noTranslation dialogParentId={dialogParentId} - setDialog={setDialog} + closeDialog={() => setDialog(null)} setDialogView={setDialogView} setDialogName={setDialogName} setDialogParentId={setDialogParentId} diff --git a/packages/iobroker.vis-2/src/src/Toolbar/ViewsManager/ExportDialog.tsx b/packages/iobroker.vis-2/src/src/Toolbar/ViewsManager/ExportDialog.tsx index 9f8658e2..70ecde40 100644 --- a/packages/iobroker.vis-2/src/src/Toolbar/ViewsManager/ExportDialog.tsx +++ b/packages/iobroker.vis-2/src/src/Toolbar/ViewsManager/ExportDialog.tsx @@ -9,14 +9,12 @@ import { store } from '../../Store'; interface ExportDialogProps { onClose: () => void; - open: boolean; themeType: ThemeType; view: string; } const ExportDialog: React.FC = props => ( = props => { ); + const visProject = store.getState().visProject; + const [{ canDrop }, drop] = useDrop< { name: string; @@ -96,13 +98,14 @@ const Folder: React.FC = props => { drop: () => ({ folder: props.folder }), canDrop: (item, monitor) => { if (monitor.getItemType() === 'view') { - return store.getState().visProject[item.name].parentId !== props.folder.id; + return visProject[item.name].parentId !== props.folder.id; } if (monitor.getItemType() === 'folder') { let currentFolder = props.folder; if (currentFolder.id === item.folder.parentId) { return false; } + const folders = visProject.___settings.folders; // eslint-disable-next-line no-constant-condition while (true) { if (currentFolder.id === item.folder.id) { @@ -111,11 +114,8 @@ const Folder: React.FC = props => { if (!currentFolder.parentId) { return true; } - currentFolder = store - .getState() - .visProject.___settings.folders.find( - foundFolder => foundFolder.id === currentFolder.parentId, - ); + const parentId = currentFolder.parentId; + currentFolder = folders.find(foundFolder => foundFolder.id === parentId); } } return false; @@ -125,7 +125,7 @@ const Folder: React.FC = props => { canDrop: monitor.canDrop(), }), }), - [store.getState().visProject], + [visProject], ); const [{ isDraggingThisItem }, dragRef, preview] = useDrag( @@ -146,15 +146,17 @@ const Folder: React.FC = props => { handlerId: monitor.getHandlerId(), }), }, - [store.getState().visProject], + [visProject], ); useEffect(() => { preview(getEmptyImage(), { captureDraggingState: true }); - }, [store.getState().visProject]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [visProject]); useEffect(() => { props.setIsDragging(isDraggingThisItem ? props.folder.id : ''); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [isDraggingThisItem]); console.log(`${props.folder.name} ${props.isDragging} ${canDrop}`); @@ -291,7 +293,7 @@ const Folder: React.FC = props => { .visProject.___settings.folders.find( foundFolder => foundFolder.parentId === props.folder.id, ) || - Object.values(store.getState().visProject).find( + Object.values(visProject).find( foundView => foundView.parentId === props.folder.id, ) ) diff --git a/packages/iobroker.vis-2/src/src/Toolbar/ViewsManager/FolderDialog.tsx b/packages/iobroker.vis-2/src/src/Toolbar/ViewsManager/FolderDialog.tsx index b18a8178..8c105e50 100644 --- a/packages/iobroker.vis-2/src/src/Toolbar/ViewsManager/FolderDialog.tsx +++ b/packages/iobroker.vis-2/src/src/Toolbar/ViewsManager/FolderDialog.tsx @@ -21,12 +21,12 @@ interface FolderDialogProps { dialogFolder: string; dialogName: string; dialogParentId: string; - setDialog: (dialog: 'add' | 'rename' | 'delete' | null) => void; + closeDialog: () => void; setDialogFolder: (folder: string | null) => void; setDialogName: (name: string) => void; } -const FolderDialog: React.FC = props => { +const FolderDialog: React.FC = (props: FolderDialogProps): React.JSX.Element | null => { const inputField = useFocus(props.dialog && props.dialog !== 'delete', props.dialog === 'add'); if (!props.dialog) { @@ -103,9 +103,8 @@ const FolderDialog: React.FC = props => { title={dialogTitles[props.dialog]} noTranslation actionTitle={dialogButtons[props.dialog]} - open={!!props.dialog} onClose={() => { - props.setDialog(null); + props.closeDialog(); props.setDialogFolder(null); }} ActionIcon={DialogIcon || null} diff --git a/packages/iobroker.vis-2/src/src/Toolbar/ViewsManager/ImportDialog.tsx b/packages/iobroker.vis-2/src/src/Toolbar/ViewsManager/ImportDialog.tsx index 55bfdbbd..1a48217d 100644 --- a/packages/iobroker.vis-2/src/src/Toolbar/ViewsManager/ImportDialog.tsx +++ b/packages/iobroker.vis-2/src/src/Toolbar/ViewsManager/ImportDialog.tsx @@ -12,49 +12,42 @@ import { store } from '../../Store'; interface ImportDialogProps { importViewAction: (view: string, data: string) => void; onClose: () => void; - open: boolean; view: string; themeType: ThemeType; } const ImportDialog: React.FC = props => { - const [data, setData] = useState(''); - const [view, setView] = useState(''); - const [errors, setErrors] = useState([]); - - const inputField = useFocus(props.open, true, true); + const visProject = store.getState().visProject; - useEffect(() => { - setErrors([]); - setView(props.view); - setData( - store.getState().visProject[props.view] - ? JSON.stringify(store.getState().visProject[props.view], null, 2) - : `{ + const [data, setData] = useState( + visProject[props.view] + ? JSON.stringify(visProject[props.view], null, 2) + : `{ "settings": { "style": {} }, "widgets": {}, "activeWidgets": {} }`, - ); - }, [props.open]); + ); + const [view, setView] = useState(props.view); + const [errors, setErrors] = useState([]); + + const inputField = useFocus(true, true, true); const editor = useRef(null); useEffect(() => { - if (editor.current) { - editor.current.editor.getSession().on('changeAnnotation', () => { - if (editor.current) { - setErrors(editor.current.editor.getSession().getAnnotations()); - } - }); - } + editor.current?.editor.getSession().on('changeAnnotation', () => { + if (editor.current) { + setErrors(editor.current.editor.getSession().getAnnotations()); + } + }); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [editor.current]); return ( = props => { useEffect(() => { props.setIsOverRoot(isOver && canDrop); - }, [isOver]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [isOver, canDrop]); return props.isDragging && canDrop ? (
diff --git a/packages/iobroker.vis-2/src/src/Toolbar/ViewsManager/View.tsx b/packages/iobroker.vis-2/src/src/Toolbar/ViewsManager/View.tsx index 77d7b5bb..87cf44e7 100644 --- a/packages/iobroker.vis-2/src/src/Toolbar/ViewsManager/View.tsx +++ b/packages/iobroker.vis-2/src/src/Toolbar/ViewsManager/View.tsx @@ -86,6 +86,8 @@ const View = (props: ViewProps): React.JSX.Element => { ); + const visProject = store.getState().visProject; + const [{ isDraggingThisItem }, dragRef, preview] = useDrag( { type: 'view', @@ -104,15 +106,17 @@ const View = (props: ViewProps): React.JSX.Element => { handlerId: monitor.getHandlerId(), }), }, - [store.getState().visProject], + [visProject], ); useEffect(() => { preview(getEmptyImage(), { captureDraggingState: true }); - }, [store.getState().visProject]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [visProject]); useEffect(() => { props.setIsDragging(isDraggingThisItem ? props.name : ''); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [isDraggingThisItem]); const selectView = (): void => { diff --git a/packages/iobroker.vis-2/src/src/Toolbar/ViewsManager/ViewDialog.tsx b/packages/iobroker.vis-2/src/src/Toolbar/ViewsManager/ViewDialog.tsx index 4bfe2cc2..b3cc1e35 100644 --- a/packages/iobroker.vis-2/src/src/Toolbar/ViewsManager/ViewDialog.tsx +++ b/packages/iobroker.vis-2/src/src/Toolbar/ViewsManager/ViewDialog.tsx @@ -20,7 +20,7 @@ interface ViewDialogProps { dialogView: string; dialogCallback?: { cb: (dialogName: string) => void }; selectedView: string; - setDialog: (closeAction: null) => void; + closeDialog: () => void; setDialogName: (dialogName: string) => void; setDialogView: (action: null) => void; dialogParentId?: string; @@ -37,7 +37,7 @@ const ViewDialog = (props: ViewDialogProps): React.JSX.Element => { delete project[view]; await props.changeView(Object.keys(project).filter(foundView => !foundView.startsWith('__'))[0]); await props.changeProject(project); - props.setDialog(null); // close dialog + props.closeDialog(); // close dialog }; const addView = async (): Promise => { @@ -53,7 +53,7 @@ const ViewDialog = (props: ViewDialogProps): React.JSX.Element => { } as View; await props.changeProject(project); await props.changeView(props.dialogName.trim()); - props.setDialog(null); // close dialog + props.closeDialog(); // close dialog props.dialogCallback?.cb(props.dialogName.trim()); }; @@ -108,7 +108,7 @@ const ViewDialog = (props: ViewDialogProps): React.JSX.Element => { await props.changeProject(project); await props.changeView(newViewName); - props.setDialog(null); + props.closeDialog(); props.dialogCallback?.cb(newViewName); }; @@ -134,7 +134,7 @@ const ViewDialog = (props: ViewDialogProps): React.JSX.Element => { await props.changeProject(project); await props.changeView(props.dialogName); - props.setDialog(null); + props.closeDialog(); props.dialogCallback?.cb(props.dialogName); }; @@ -190,9 +190,8 @@ const ViewDialog = (props: ViewDialogProps): React.JSX.Element => { title={dialogTitles[props.dialog]} noTranslation={props.noTranslation} actionTitle={dialogButtons[props.dialog]} - open={!!props.dialog} onClose={() => { - props.setDialog(null); + props.closeDialog(); props.setDialogView(null); props.setDialogParentId(null); }} diff --git a/packages/iobroker.vis-2/src/src/Toolbar/ViewsManager/index.tsx b/packages/iobroker.vis-2/src/src/Toolbar/ViewsManager/index.tsx index fc2d5ae4..8c6b9c4c 100644 --- a/packages/iobroker.vis-2/src/src/Toolbar/ViewsManager/index.tsx +++ b/packages/iobroker.vis-2/src/src/Toolbar/ViewsManager/index.tsx @@ -214,7 +214,6 @@ const ViewsManager: React.FC = props => { return ( = props => {
- + {folderDialog ? ( + setFolderDialog(null)} + setDialogFolder={setFolderDialogId} + setDialogName={setFolderDialogName} + changeProject={props.changeProject} + /> + ) : null} {importDialog !== false ? ( setImportDialog(false)} view={importDialog || ''} importViewAction={importViewAction} @@ -358,7 +358,6 @@ const ViewsManager: React.FC = props => { ) : null} {exportDialog !== false ? ( setExportDialog(false)} view={exportDialog || ''} themeType={props.themeType} diff --git a/packages/iobroker.vis-2/src/src/Toolbar/WidgetExportDialog.tsx b/packages/iobroker.vis-2/src/src/Toolbar/WidgetExportDialog.tsx index 01f8b01e..2e3a5cdc 100644 --- a/packages/iobroker.vis-2/src/src/Toolbar/WidgetExportDialog.tsx +++ b/packages/iobroker.vis-2/src/src/Toolbar/WidgetExportDialog.tsx @@ -35,9 +35,10 @@ const WidgetExportDialog: React.FC = props => { if (widget.data?.members) { const members: string[] = []; - widget.data.members.forEach(member => { + for (let m = 0; m < widget.data.members.length; m++) { + const member = widget.data.members[m]; if (groupWidgets.includes(member)) { - return; + continue; } const memberWidget = deepClone(props.widgets[member]); memberWidget._id = `i${wIdx.toString().padStart(6, '0')}`; @@ -47,7 +48,7 @@ const WidgetExportDialog: React.FC = props => { memberWidget.grouped = true; widgets.push(memberWidget); groupWidgets.push(member); - }); + } widget.data.members = members as AnyWidgetId[]; } @@ -66,7 +67,6 @@ const WidgetExportDialog: React.FC = props => { return ( = props => { const [filters, setFilters] = useState<{ key: AnyWidgetId; count: number }[]>([]); - const [filterWidgets, setFilterWidgets] = useState( - store.getState().visProject[props.selectedView].filterWidgets || [], - ); - const [filterInvert, setFilterInvert] = useState( - store.getState().visProject[props.selectedView].filterInvert || false, - ); + + const visProject = store.getState().visProject; + + const [filterWidgets, setFilterWidgets] = useState(visProject[props.selectedView].filterWidgets || []); + const [filterInvert, setFilterInvert] = useState(visProject[props.selectedView].filterInvert || false); useEffect(() => { // Collect all filters of all widgets const _filters: { key: AnyWidgetId; count: number }[] = []; - const widgets = store.getState().visProject[props.selectedView].widgets; + const widgets = visProject[props.selectedView].widgets; Object.values(widgets).forEach(widget => { if (widget.data && widget.data.filterkey) { widget.data.filterkey.split(',').forEach(filter => { @@ -53,7 +52,7 @@ const WidgetFilterDialog: React.FC = props => { } }); setFilters(_filters); - }, [store.getState().visProject, props.selectedView]); + }, [visProject, props.selectedView]); return ( = props => { - {store.getState().visProject[props.selectedView].filterWidgets?.length ? ( + {visProject[props.selectedView].filterWidgets?.length ? (