@iobroker/adapter-react-v5 7.7.2 → 7.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/Components/CustomModal.js +4 -2
- package/build/Components/CustomModal.js.map +1 -1
- package/build/Components/FileBrowser.d.ts +1 -1
- package/build/Components/FileBrowser.js +12 -5
- package/build/Components/FileBrowser.js.map +1 -1
- package/build/Components/FileViewer.js +1 -1
- package/build/Components/FileViewer.js.map +1 -1
- package/build/Components/ObjectBrowser.d.ts +7 -5
- package/build/Components/ObjectBrowser.js +107 -44
- package/build/Components/ObjectBrowser.js.map +1 -1
- package/build/Components/Utils.d.ts +7 -6
- package/build/Components/Utils.js +67 -62
- package/build/Components/Utils.js.map +1 -1
- package/build/Dialogs/SelectFile.d.ts +2 -0
- package/build/Dialogs/SelectFile.js +2 -3
- package/build/Dialogs/SelectFile.js.map +1 -1
- package/build/Dialogs/SelectID.d.ts +7 -6
- package/build/Dialogs/SelectID.js +3 -3
- package/build/Dialogs/SelectID.js.map +1 -1
- package/build/LegacyConnection.d.ts +14 -1
- package/build/LegacyConnection.js +26 -2
- package/build/LegacyConnection.js.map +1 -1
- package/build/i18n/de.json +8 -0
- package/build/i18n/en.json +8 -0
- package/build/i18n/es.json +8 -0
- package/build/i18n/fr.json +8 -0
- package/build/i18n/it.json +3 -0
- package/build/i18n/nl.json +3 -0
- package/build/i18n/pl.json +6 -3
- package/build/i18n/pt.json +3 -0
- package/build/i18n/ru.json +3 -0
- package/build/i18n/uk.json +3 -0
- package/build/i18n/zh-cn.json +3 -0
- package/build/types.d.ts +2 -0
- package/i18n/de.json +8 -0
- package/i18n/en.json +8 -0
- package/i18n/es.json +8 -0
- package/i18n/fr.json +8 -0
- package/i18n/it.json +3 -0
- package/i18n/nl.json +3 -0
- package/i18n/pl.json +6 -3
- package/i18n/pt.json +3 -0
- package/i18n/ru.json +3 -0
- package/i18n/uk.json +3 -0
- package/i18n/zh-cn.json +3 -0
- package/package.json +8 -8
- package/craco-module-federation.js +0 -62
|
@@ -35,7 +35,7 @@ const styles = {
|
|
|
35
35
|
export const EXTENSIONS = {
|
|
36
36
|
images: ['png', 'jpg', 'svg', 'jpeg', 'bmp', 'gif', 'apng', 'avif', 'webp', 'ico'],
|
|
37
37
|
code: ['js', 'json', 'json5', 'md'],
|
|
38
|
-
txt: ['log', 'txt', 'html', 'css', 'xml', 'ics'],
|
|
38
|
+
txt: ['log', 'txt', 'html', 'css', 'xml', 'ics', 'csv'],
|
|
39
39
|
audio: ['mp3', 'wav', 'ogg', 'acc'],
|
|
40
40
|
video: ['mp4', 'mov', 'avi'],
|
|
41
41
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileViewer.js","sourceRoot":"./src/","sources":["Components/FileViewer.tsx"],"names":[],"mappings":"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","sourcesContent":["// File viewer in adapter-react does not support write\n// import { Buffer } from 'buffer';\nimport React, { Component, type JSX } from 'react';\n\nimport { TextField, Button, Dialog, DialogActions, DialogContent, DialogTitle, IconButton } from '@mui/material';\n\n// Icons\nimport {\n Close as CloseIcon,\n Save as SaveIcon,\n Brightness6 as Brightness5Icon,\n ContentCopy as CopyIcon,\n} from '@mui/icons-material';\n\nimport type { Connection } from '@iobroker/socket-client';\n\nimport { IconNoIcon } from '../icons/IconNoIcon';\nimport { withWidth } from './withWidth';\nimport { Utils } from './Utils';\nimport type { ThemeType, Translate } from '../types';\nimport { Icon } from './Icon';\n\nconst styles: Record<string, React.CSSProperties> = {\n dialog: {\n height: '100%',\n },\n paper: {\n height: 'calc(100% - 64px)',\n },\n content: {\n textAlign: 'center',\n },\n textarea: {\n width: '100%',\n height: '100%',\n },\n img: {\n width: 'auto',\n height: 'calc(100% - 5px)',\n objectFit: 'contain',\n },\n dialogTitle: {\n justifyContent: 'space-between',\n display: 'flex',\n },\n};\n\nexport const EXTENSIONS = {\n images: ['png', 'jpg', 'svg', 'jpeg', 'bmp', 'gif', 'apng', 'avif', 'webp', 'ico'],\n code: ['js', 'json', 'json5', 'md'],\n txt: ['log', 'txt', 'html', 'css', 'xml', 'ics'],\n audio: ['mp3', 'wav', 'ogg', 'acc'],\n video: ['mp4', 'mov', 'avi'],\n};\n\nfunction bufferToBase64(buffer: Buffer, isFull?: boolean): string {\n let binary = '';\n const bytes = new Uint8Array((buffer as unknown as { data: number[]; type: 'Buffer' })?.data || buffer);\n const len = bytes.byteLength;\n for (let i = 0; i < len && (isFull || i < 50); i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return window.btoa(binary);\n}\n\nexport interface FileViewerProps {\n /** Translation function */\n t: Translate;\n /** Callback when the viewer is closed. */\n onClose: () => void;\n /** The URL (file path) to the file to be displayed. */\n href: string;\n formatEditFile?: string;\n socket: Connection;\n setStateBackgroundImage: () => void;\n themeType: ThemeType;\n getStyleBackgroundImage: () => React.CSSProperties | null;\n /** Flag is the js-controller support subscribe on file */\n supportSubscribes?: boolean;\n}\n\nexport interface FileViewerState {\n text: string | null;\n code: string | null;\n ext: string | null;\n editing: boolean;\n editingValue: string | null;\n copyPossible: boolean;\n forceUpdate: number;\n changed: boolean;\n imgError: boolean;\n}\n\nexport class FileViewerClass extends Component<FileViewerProps, FileViewerState> {\n private timeout: ReturnType<typeof setTimeout> | null = null;\n\n constructor(props: FileViewerProps) {\n super(props);\n const ext = Utils.getFileExtension(props.href);\n\n this.state = {\n text: null,\n code: null,\n ext,\n // File viewer in adapter-react does not support write\n editing: /* !!this.props.formatEditFile || */ false,\n editingValue: null,\n copyPossible: !!ext && (EXTENSIONS.code.includes(ext) || EXTENSIONS.txt.includes(ext)),\n forceUpdate: Date.now(),\n changed: false,\n imgError: false,\n };\n }\n\n readFile(): void {\n if (this.props.href) {\n const parts = this.props.href.split('/');\n parts.splice(0, 2);\n const adapter = parts[0];\n const name = parts.splice(1).join('/');\n\n this.props.socket\n .readFile(adapter, name)\n .then((data: { file: string | Buffer; mimeType: string }) => {\n let fileData: string | Buffer = '';\n if (data.file !== undefined) {\n fileData = (data as { file: string; mimeType: string }).file;\n }\n\n const newState: Partial<FileViewerState> = {\n copyPossible: this.state.copyPossible,\n ext: this.state.ext,\n };\n // try to detect valid extension\n if ((fileData as unknown as { data: Buffer; type: string }).type === 'Buffer') {\n if (name.toLowerCase().endsWith('.json5')) {\n newState.ext = 'json5';\n newState.copyPossible = true;\n try {\n fileData = atob(bufferToBase64(fileData as unknown as Buffer, true));\n } catch {\n console.error('Cannot convert base64 to string');\n fileData = '';\n }\n } else {\n const ext = Utils.detectMimeType(bufferToBase64(fileData as unknown as Buffer));\n if (ext) {\n newState.ext = ext;\n newState.copyPossible = EXTENSIONS.code.includes(ext) || EXTENSIONS.txt.includes(ext);\n }\n }\n }\n\n if (newState.copyPossible) {\n if (newState.ext && EXTENSIONS.txt.includes(newState.ext)) {\n newState.text = fileData;\n newState.editingValue = fileData;\n } else if (newState.ext && EXTENSIONS.code.includes(newState.ext)) {\n newState.code = fileData;\n newState.editingValue = fileData;\n }\n }\n\n this.setState(newState as FileViewerState);\n })\n .catch(e => window.alert(`Cannot read file: ${e}`));\n }\n }\n\n componentDidMount(): void {\n this.readFile();\n\n const parts = this.props.href.split('/');\n parts.splice(0, 2);\n const adapter = parts[0];\n const name = parts.splice(1).join('/');\n\n if (this.props.supportSubscribes) {\n this.props.socket\n .subscribeFiles(adapter, name, this.onFileChanged)\n .catch(e => window.alert(`Cannot subscribe on file: ${e}`));\n }\n }\n\n componentWillUnmount(): void {\n if (this.timeout) {\n clearTimeout(this.timeout);\n this.timeout = null;\n }\n const parts = this.props.href.split('/');\n parts.splice(0, 2);\n const adapter = parts[0];\n const name = parts.splice(1).join('/');\n if (this.props.supportSubscribes) {\n this.props.socket\n .subscribeFiles(adapter, name, this.onFileChanged)\n .catch(e => window.alert(`Cannot subscribe on file: ${e}`));\n }\n }\n\n onFileChanged = (_id: string, _fileName: string, size: number | null): void => {\n if (!this.state.changed) {\n if (this.timeout) {\n clearTimeout(this.timeout);\n }\n this.timeout = setTimeout(() => {\n this.timeout = null;\n if (size === null) {\n window.alert('Show file was deleted!');\n } else if (this.state.text !== null || this.state.code !== null) {\n this.readFile();\n } else {\n this.setState({ forceUpdate: Date.now() });\n }\n }, 300);\n }\n };\n\n getEditorOrViewer(): JSX.Element {\n return (\n <TextField\n variant=\"standard\"\n style={styles.textarea}\n multiline\n value={this.state.editingValue || this.state.code || this.state.text}\n // onChange={newValue => this.setState({ editingValue: newValue, changed: true })}\n slotProps={{\n htmlInput: {\n readOnly: !this.state.editing,\n },\n }}\n />\n );\n }\n\n getContent(): React.JSX.Element | null {\n if (this.state.ext && EXTENSIONS.images.includes(this.state.ext)) {\n if (this.state.imgError) {\n return <IconNoIcon style={{ ...styles.img, ...this.props.getStyleBackgroundImage() }} />;\n }\n return (\n <Icon\n onError={e => {\n (e.target as HTMLImageElement).onerror = null;\n this.setState({ imgError: true });\n }}\n style={{ ...styles.img, ...this.props.getStyleBackgroundImage() }}\n src={`${this.props.href}?ts=${this.state.forceUpdate}`}\n alt={this.props.href}\n />\n );\n }\n if (this.state.ext && EXTENSIONS.audio.includes(this.state.ext)) {\n return (\n <div\n style={{\n width: '100%',\n height: '100%',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n }}\n >\n <audio\n style={{ width: '100%' }}\n src={this.props.href}\n controls\n ></audio>\n </div>\n );\n }\n if (this.state.ext && EXTENSIONS.video.includes(this.state.ext)) {\n return (\n <div\n style={{\n width: '100%',\n height: '100%',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n }}\n >\n <video\n style={{ width: '100%', height: '100%' }}\n controls\n >\n <source\n src={this.props.href}\n type={`video/${this.state.ext}}`}\n />\n </video>\n </div>\n );\n }\n if (this.state.code !== null || this.state.text !== null || this.state.editing) {\n // File viewer in adapter-react does not support write\n // return <Editor\n // mode={this.getEditFile(this.props.formatEditFile)}\n // themeType={this.props.themeType}\n // value={this.state.editingValue || this.state.code || this.state.text}\n // onChange={this.state.editing ? newValue => this.setState({ editingValue: newValue, changed: true }) : undefined}\n // />;\n return this.getEditorOrViewer();\n }\n return null;\n }\n\n // eslint-disable-next-line class-methods-use-this\n onSave(): void {\n // Do nothing as the file viewer in adapter-react does not support writing\n }\n\n render(): JSX.Element {\n return (\n <Dialog\n sx={{\n '&.MuiDialog-scrollPaper': styles.dialog,\n '& .MuiDialog-paper': styles.paper,\n }}\n scroll=\"paper\"\n open={!!this.props.href}\n onClose={() => this.props.onClose()}\n fullWidth\n maxWidth=\"xl\"\n aria-labelledby=\"ar_dialog_file_view_title\"\n >\n <div style={styles.dialogTitle}>\n <DialogTitle id=\"ar_dialog_file_view_title\">{`${this.props.t(this.state.editing ? 'Edit' : 'View')}: ${this.props.href}`}</DialogTitle>\n {this.state.ext && EXTENSIONS.images.includes(this.state.ext) && (\n <div>\n <IconButton\n size=\"large\"\n color=\"inherit\"\n onClick={this.props.setStateBackgroundImage}\n >\n <Brightness5Icon />\n </IconButton>\n </div>\n )}\n </div>\n <DialogContent style={styles.content}>{this.getContent()}</DialogContent>\n <DialogActions>\n {this.state.copyPossible ? (\n <Button\n color=\"grey\"\n onClick={e => {\n e.stopPropagation();\n e.preventDefault();\n Utils.copyToClipboard(this.state.text || this.state.code || '');\n }}\n startIcon={<CopyIcon />}\n >\n {this.props.t('Copy content')}\n </Button>\n ) : null}\n {this.state.editing ? (\n <Button\n color=\"grey\"\n disabled={\n this.state.editingValue === this.state.code ||\n this.state.editingValue === this.state.text\n }\n variant=\"contained\"\n onClick={() => this.onSave()}\n startIcon={<SaveIcon />}\n >\n {this.props.t('Save')}\n </Button>\n ) : null}\n <Button\n variant=\"contained\"\n onClick={() => this.props.onClose()}\n color=\"primary\"\n startIcon={<CloseIcon />}\n >\n {this.props.t('Close')}\n </Button>\n </DialogActions>\n </Dialog>\n );\n }\n}\nexport const FileViewer = withWidth()(FileViewerClass);\n"]}
|
|
1
|
+
{"version":3,"file":"FileViewer.js","sourceRoot":"./src/","sources":["Components/FileViewer.tsx"],"names":[],"mappings":"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","sourcesContent":["// File viewer in adapter-react does not support write\n// import { Buffer } from 'buffer';\nimport React, { Component, type JSX } from 'react';\n\nimport { TextField, Button, Dialog, DialogActions, DialogContent, DialogTitle, IconButton } from '@mui/material';\n\n// Icons\nimport {\n Close as CloseIcon,\n Save as SaveIcon,\n Brightness6 as Brightness5Icon,\n ContentCopy as CopyIcon,\n} from '@mui/icons-material';\n\nimport type { Connection } from '@iobroker/socket-client';\n\nimport { IconNoIcon } from '../icons/IconNoIcon';\nimport { withWidth } from './withWidth';\nimport { Utils } from './Utils';\nimport type { ThemeType, Translate } from '../types';\nimport { Icon } from './Icon';\n\nconst styles: Record<string, React.CSSProperties> = {\n dialog: {\n height: '100%',\n },\n paper: {\n height: 'calc(100% - 64px)',\n },\n content: {\n textAlign: 'center',\n },\n textarea: {\n width: '100%',\n height: '100%',\n },\n img: {\n width: 'auto',\n height: 'calc(100% - 5px)',\n objectFit: 'contain',\n },\n dialogTitle: {\n justifyContent: 'space-between',\n display: 'flex',\n },\n};\n\nexport const EXTENSIONS = {\n images: ['png', 'jpg', 'svg', 'jpeg', 'bmp', 'gif', 'apng', 'avif', 'webp', 'ico'],\n code: ['js', 'json', 'json5', 'md'],\n txt: ['log', 'txt', 'html', 'css', 'xml', 'ics', 'csv'],\n audio: ['mp3', 'wav', 'ogg', 'acc'],\n video: ['mp4', 'mov', 'avi'],\n};\n\nfunction bufferToBase64(buffer: Buffer, isFull?: boolean): string {\n let binary = '';\n const bytes = new Uint8Array((buffer as unknown as { data: number[]; type: 'Buffer' })?.data || buffer);\n const len = bytes.byteLength;\n for (let i = 0; i < len && (isFull || i < 50); i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return window.btoa(binary);\n}\n\nexport interface FileViewerProps {\n /** Translation function */\n t: Translate;\n /** Callback when the viewer is closed. */\n onClose: () => void;\n /** The URL (file path) to the file to be displayed. */\n href: string;\n formatEditFile?: string;\n socket: Connection;\n setStateBackgroundImage: () => void;\n themeType: ThemeType;\n getStyleBackgroundImage: () => React.CSSProperties | null;\n /** Flag is the js-controller support subscribe on file */\n supportSubscribes?: boolean;\n}\n\nexport interface FileViewerState {\n text: string | null;\n code: string | null;\n ext: string | null;\n editing: boolean;\n editingValue: string | null;\n copyPossible: boolean;\n forceUpdate: number;\n changed: boolean;\n imgError: boolean;\n}\n\nexport class FileViewerClass extends Component<FileViewerProps, FileViewerState> {\n private timeout: ReturnType<typeof setTimeout> | null = null;\n\n constructor(props: FileViewerProps) {\n super(props);\n const ext = Utils.getFileExtension(props.href);\n\n this.state = {\n text: null,\n code: null,\n ext,\n // File viewer in adapter-react does not support write\n editing: /* !!this.props.formatEditFile || */ false,\n editingValue: null,\n copyPossible: !!ext && (EXTENSIONS.code.includes(ext) || EXTENSIONS.txt.includes(ext)),\n forceUpdate: Date.now(),\n changed: false,\n imgError: false,\n };\n }\n\n readFile(): void {\n if (this.props.href) {\n const parts = this.props.href.split('/');\n parts.splice(0, 2);\n const adapter = parts[0];\n const name = parts.splice(1).join('/');\n\n this.props.socket\n .readFile(adapter, name)\n .then((data: { file: string | Buffer; mimeType: string }) => {\n let fileData: string | Buffer = '';\n if (data.file !== undefined) {\n fileData = (data as { file: string; mimeType: string }).file;\n }\n\n const newState: Partial<FileViewerState> = {\n copyPossible: this.state.copyPossible,\n ext: this.state.ext,\n };\n // try to detect valid extension\n if ((fileData as unknown as { data: Buffer; type: string }).type === 'Buffer') {\n if (name.toLowerCase().endsWith('.json5')) {\n newState.ext = 'json5';\n newState.copyPossible = true;\n try {\n fileData = atob(bufferToBase64(fileData as unknown as Buffer, true));\n } catch {\n console.error('Cannot convert base64 to string');\n fileData = '';\n }\n } else {\n const ext = Utils.detectMimeType(bufferToBase64(fileData as unknown as Buffer));\n if (ext) {\n newState.ext = ext;\n newState.copyPossible = EXTENSIONS.code.includes(ext) || EXTENSIONS.txt.includes(ext);\n }\n }\n }\n\n if (newState.copyPossible) {\n if (newState.ext && EXTENSIONS.txt.includes(newState.ext)) {\n newState.text = fileData;\n newState.editingValue = fileData;\n } else if (newState.ext && EXTENSIONS.code.includes(newState.ext)) {\n newState.code = fileData;\n newState.editingValue = fileData;\n }\n }\n\n this.setState(newState as FileViewerState);\n })\n .catch(e => window.alert(`Cannot read file: ${e}`));\n }\n }\n\n componentDidMount(): void {\n this.readFile();\n\n const parts = this.props.href.split('/');\n parts.splice(0, 2);\n const adapter = parts[0];\n const name = parts.splice(1).join('/');\n\n if (this.props.supportSubscribes) {\n this.props.socket\n .subscribeFiles(adapter, name, this.onFileChanged)\n .catch(e => window.alert(`Cannot subscribe on file: ${e}`));\n }\n }\n\n componentWillUnmount(): void {\n if (this.timeout) {\n clearTimeout(this.timeout);\n this.timeout = null;\n }\n const parts = this.props.href.split('/');\n parts.splice(0, 2);\n const adapter = parts[0];\n const name = parts.splice(1).join('/');\n if (this.props.supportSubscribes) {\n this.props.socket\n .subscribeFiles(adapter, name, this.onFileChanged)\n .catch(e => window.alert(`Cannot subscribe on file: ${e}`));\n }\n }\n\n onFileChanged = (_id: string, _fileName: string, size: number | null): void => {\n if (!this.state.changed) {\n if (this.timeout) {\n clearTimeout(this.timeout);\n }\n this.timeout = setTimeout(() => {\n this.timeout = null;\n if (size === null) {\n window.alert('Show file was deleted!');\n } else if (this.state.text !== null || this.state.code !== null) {\n this.readFile();\n } else {\n this.setState({ forceUpdate: Date.now() });\n }\n }, 300);\n }\n };\n\n getEditorOrViewer(): JSX.Element {\n return (\n <TextField\n variant=\"standard\"\n style={styles.textarea}\n multiline\n value={this.state.editingValue || this.state.code || this.state.text}\n // onChange={newValue => this.setState({ editingValue: newValue, changed: true })}\n slotProps={{\n htmlInput: {\n readOnly: !this.state.editing,\n },\n }}\n />\n );\n }\n\n getContent(): React.JSX.Element | null {\n if (this.state.ext && EXTENSIONS.images.includes(this.state.ext)) {\n if (this.state.imgError) {\n return <IconNoIcon style={{ ...styles.img, ...this.props.getStyleBackgroundImage() }} />;\n }\n return (\n <Icon\n onError={e => {\n (e.target as HTMLImageElement).onerror = null;\n this.setState({ imgError: true });\n }}\n style={{ ...styles.img, ...this.props.getStyleBackgroundImage() }}\n src={`${this.props.href}?ts=${this.state.forceUpdate}`}\n alt={this.props.href}\n />\n );\n }\n if (this.state.ext && EXTENSIONS.audio.includes(this.state.ext)) {\n return (\n <div\n style={{\n width: '100%',\n height: '100%',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n }}\n >\n <audio\n style={{ width: '100%' }}\n src={this.props.href}\n controls\n ></audio>\n </div>\n );\n }\n if (this.state.ext && EXTENSIONS.video.includes(this.state.ext)) {\n return (\n <div\n style={{\n width: '100%',\n height: '100%',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n }}\n >\n <video\n style={{ width: '100%', height: '100%' }}\n controls\n >\n <source\n src={this.props.href}\n type={`video/${this.state.ext}}`}\n />\n </video>\n </div>\n );\n }\n if (this.state.code !== null || this.state.text !== null || this.state.editing) {\n // File viewer in adapter-react does not support write\n // return <Editor\n // mode={this.getEditFile(this.props.formatEditFile)}\n // themeType={this.props.themeType}\n // value={this.state.editingValue || this.state.code || this.state.text}\n // onChange={this.state.editing ? newValue => this.setState({ editingValue: newValue, changed: true }) : undefined}\n // />;\n return this.getEditorOrViewer();\n }\n return null;\n }\n\n // eslint-disable-next-line class-methods-use-this\n onSave(): void {\n // Do nothing as the file viewer in adapter-react does not support writing\n }\n\n render(): JSX.Element {\n return (\n <Dialog\n sx={{\n '&.MuiDialog-scrollPaper': styles.dialog,\n '& .MuiDialog-paper': styles.paper,\n }}\n scroll=\"paper\"\n open={!!this.props.href}\n onClose={() => this.props.onClose()}\n fullWidth\n maxWidth=\"xl\"\n aria-labelledby=\"ar_dialog_file_view_title\"\n >\n <div style={styles.dialogTitle}>\n <DialogTitle id=\"ar_dialog_file_view_title\">{`${this.props.t(this.state.editing ? 'Edit' : 'View')}: ${this.props.href}`}</DialogTitle>\n {this.state.ext && EXTENSIONS.images.includes(this.state.ext) && (\n <div>\n <IconButton\n size=\"large\"\n color=\"inherit\"\n onClick={this.props.setStateBackgroundImage}\n >\n <Brightness5Icon />\n </IconButton>\n </div>\n )}\n </div>\n <DialogContent style={styles.content}>{this.getContent()}</DialogContent>\n <DialogActions>\n {this.state.copyPossible ? (\n <Button\n color=\"grey\"\n onClick={e => {\n e.stopPropagation();\n e.preventDefault();\n Utils.copyToClipboard(this.state.text || this.state.code || '');\n }}\n startIcon={<CopyIcon />}\n >\n {this.props.t('Copy content')}\n </Button>\n ) : null}\n {this.state.editing ? (\n <Button\n color=\"grey\"\n disabled={\n this.state.editingValue === this.state.code ||\n this.state.editingValue === this.state.text\n }\n variant=\"contained\"\n onClick={() => this.onSave()}\n startIcon={<SaveIcon />}\n >\n {this.props.t('Save')}\n </Button>\n ) : null}\n <Button\n variant=\"contained\"\n onClick={() => this.props.onClose()}\n color=\"primary\"\n startIcon={<CloseIcon />}\n >\n {this.props.t('Close')}\n </Button>\n </DialogActions>\n </Dialog>\n );\n }\n}\nexport const FileViewer = withWidth()(FileViewerClass);\n"]}
|
|
@@ -113,11 +113,11 @@ export declare const ITEM_IMAGES: Record<string, JSX.Element>;
|
|
|
113
113
|
export interface ObjectBrowserFilter {
|
|
114
114
|
id?: string;
|
|
115
115
|
name?: string;
|
|
116
|
-
room?: string;
|
|
117
|
-
func?: string;
|
|
118
|
-
role?: string;
|
|
119
|
-
type?: string;
|
|
120
|
-
custom?: string;
|
|
116
|
+
room?: string[];
|
|
117
|
+
func?: string[];
|
|
118
|
+
role?: string[];
|
|
119
|
+
type?: string[];
|
|
120
|
+
custom?: string[];
|
|
121
121
|
expertMode?: boolean;
|
|
122
122
|
}
|
|
123
123
|
interface AdapterColumn {
|
|
@@ -271,6 +271,8 @@ export interface ObjectBrowserProps {
|
|
|
271
271
|
levelPadding?: number;
|
|
272
272
|
/** Allow selection of non-objects (virtual branches) */
|
|
273
273
|
allowNonObjects?: boolean;
|
|
274
|
+
/** Called when all objects are loaded */
|
|
275
|
+
onAllLoaded?: () => void;
|
|
274
276
|
objectCustomDialog?: React.FC<ObjectCustomDialogProps>;
|
|
275
277
|
objectMoveRenameDialog?: React.FC<ObjectMoveRenameDialogProps>;
|
|
276
278
|
objectAddBoolean?: boolean;
|
|
@@ -970,24 +970,30 @@ function applyFilter(item, filters, lang, objects, context, counter, customFilte
|
|
|
970
970
|
context.name = name;
|
|
971
971
|
}
|
|
972
972
|
}
|
|
973
|
-
if (filters.type) {
|
|
974
|
-
context.type = filters.type.toLowerCase();
|
|
973
|
+
if (filters.type?.length) {
|
|
974
|
+
context.type = filters.type.map(f => f.toLowerCase());
|
|
975
975
|
}
|
|
976
|
-
if (filters.custom) {
|
|
977
|
-
context.custom = filters.custom.toLowerCase();
|
|
976
|
+
if (filters.custom?.length) {
|
|
977
|
+
context.custom = filters.custom.map(c => c.toLowerCase());
|
|
978
978
|
}
|
|
979
|
-
if (filters.role) {
|
|
980
|
-
context.role = filters.role.toLowerCase();
|
|
979
|
+
if (filters.role?.length) {
|
|
980
|
+
context.role = filters.role.map(r => r.toLowerCase());
|
|
981
981
|
}
|
|
982
|
-
if (filters.room) {
|
|
983
|
-
context.room =
|
|
982
|
+
if (filters.room?.length) {
|
|
983
|
+
context.room = [];
|
|
984
|
+
filters.room.forEach(room => {
|
|
985
|
+
context.room = context.room.concat(objects[room]?.common?.members || []);
|
|
986
|
+
});
|
|
984
987
|
}
|
|
985
|
-
if (filters.func) {
|
|
986
|
-
context.func =
|
|
988
|
+
if (filters.func?.length) {
|
|
989
|
+
context.func = [];
|
|
990
|
+
filters.func.forEach(func => {
|
|
991
|
+
context.func = context.func.concat(objects[func]?.common?.members || []);
|
|
992
|
+
});
|
|
987
993
|
}
|
|
988
994
|
}
|
|
989
995
|
const data = item.data;
|
|
990
|
-
if (data
|
|
996
|
+
if (data?.id) {
|
|
991
997
|
const common = data.obj?.common;
|
|
992
998
|
if (customFilter) {
|
|
993
999
|
if (customFilter.type) {
|
|
@@ -1100,33 +1106,28 @@ function applyFilter(item, filters, lang, objects, context, counter, customFilte
|
|
|
1100
1106
|
filteredOut = !context.nameRx.test(data.fName);
|
|
1101
1107
|
}
|
|
1102
1108
|
}
|
|
1103
|
-
if (!filteredOut && filters.role && common) {
|
|
1104
|
-
|
|
1105
|
-
filteredOut = !(typeof common.role === 'string' && common.role.startsWith(context.role));
|
|
1106
|
-
}
|
|
1107
|
-
else {
|
|
1108
|
-
filteredOut = true;
|
|
1109
|
-
}
|
|
1109
|
+
if (!filteredOut && filters.role?.length && common) {
|
|
1110
|
+
filteredOut = !(typeof common.role === 'string' && context.role.find(role => common.role.startsWith(role)));
|
|
1110
1111
|
}
|
|
1111
|
-
if (!filteredOut && context.room) {
|
|
1112
|
+
if (!filteredOut && context.room?.length) {
|
|
1112
1113
|
filteredOut = !context.room.find(id => id === data.id || data.id.startsWith(`${id}.`));
|
|
1113
1114
|
}
|
|
1114
|
-
if (!filteredOut && context.func) {
|
|
1115
|
+
if (!filteredOut && context.func?.length) {
|
|
1115
1116
|
filteredOut = !context.func.find(id => id === data.id || data.id.startsWith(`${id}.`));
|
|
1116
1117
|
}
|
|
1117
|
-
if (!filteredOut && context.type) {
|
|
1118
|
-
filteredOut = !(data.obj &&
|
|
1118
|
+
if (!filteredOut && context.type?.length) {
|
|
1119
|
+
filteredOut = !(data.obj?.type && context.type.includes(data.obj.type));
|
|
1119
1120
|
}
|
|
1120
1121
|
if (!filteredOut && selectedTypes) {
|
|
1121
|
-
filteredOut = !(data.obj
|
|
1122
|
+
filteredOut = !(data.obj?.type && selectedTypes.includes(data.obj.type));
|
|
1122
1123
|
}
|
|
1123
|
-
if (!filteredOut && context.custom) {
|
|
1124
|
+
if (!filteredOut && context.custom?.length) {
|
|
1124
1125
|
if (common) {
|
|
1125
|
-
if (context.custom
|
|
1126
|
+
if (context.custom.includes('_')) {
|
|
1126
1127
|
filteredOut = !!common.custom;
|
|
1127
1128
|
}
|
|
1128
|
-
else {
|
|
1129
|
-
filteredOut = !common.custom
|
|
1129
|
+
else if (common.custom) {
|
|
1130
|
+
filteredOut = !context.custom.find(custom => common.custom[custom]);
|
|
1130
1131
|
}
|
|
1131
1132
|
}
|
|
1132
1133
|
else {
|
|
@@ -1614,6 +1615,24 @@ function formatValue(options) {
|
|
|
1614
1615
|
v = v ? new Date(v).toString() : v;
|
|
1615
1616
|
}
|
|
1616
1617
|
}
|
|
1618
|
+
else if (isCommon?.role && typeof isCommon.role === 'string' && isCommon.role.match(/^value\.duration/)) {
|
|
1619
|
+
// Format duration values in HH:mm:ss format
|
|
1620
|
+
if (typeof v === 'number' && v >= 0) {
|
|
1621
|
+
const hours = Math.floor(v / 3600);
|
|
1622
|
+
const minutes = Math.floor((v % 3600) / 60);
|
|
1623
|
+
const seconds = Math.floor(v % 60);
|
|
1624
|
+
v = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
|
|
1625
|
+
}
|
|
1626
|
+
else if (typeof v === 'string' && Utils.isStringInteger(v)) {
|
|
1627
|
+
const numValue = parseInt(v, 10);
|
|
1628
|
+
if (numValue >= 0) {
|
|
1629
|
+
const hours = Math.floor(numValue / 3600);
|
|
1630
|
+
const minutes = Math.floor((numValue % 3600) / 60);
|
|
1631
|
+
const seconds = Math.floor(numValue % 60);
|
|
1632
|
+
v = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
|
|
1633
|
+
}
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1617
1636
|
else {
|
|
1618
1637
|
if (type === 'number') {
|
|
1619
1638
|
if (!Number.isInteger(v)) {
|
|
@@ -1841,11 +1860,11 @@ let objectsAlreadyLoaded = false;
|
|
|
1841
1860
|
const DEFAULT_FILTER = {
|
|
1842
1861
|
id: '',
|
|
1843
1862
|
name: '',
|
|
1844
|
-
room:
|
|
1845
|
-
func:
|
|
1846
|
-
role:
|
|
1847
|
-
type:
|
|
1848
|
-
custom:
|
|
1863
|
+
room: [],
|
|
1864
|
+
func: [],
|
|
1865
|
+
role: [],
|
|
1866
|
+
type: [],
|
|
1867
|
+
custom: [],
|
|
1849
1868
|
expertMode: false,
|
|
1850
1869
|
};
|
|
1851
1870
|
export class ObjectBrowserClass extends Component {
|
|
@@ -1956,6 +1975,22 @@ export class ObjectBrowserClass extends Component {
|
|
|
1956
1975
|
else {
|
|
1957
1976
|
filter = { ...DEFAULT_FILTER };
|
|
1958
1977
|
}
|
|
1978
|
+
// Migrate old filters to new one
|
|
1979
|
+
if (typeof filter.room === 'string') {
|
|
1980
|
+
filter.room = [filter.room];
|
|
1981
|
+
}
|
|
1982
|
+
if (typeof filter.func === 'string') {
|
|
1983
|
+
filter.func = [filter.func];
|
|
1984
|
+
}
|
|
1985
|
+
if (typeof filter.role === 'string') {
|
|
1986
|
+
filter.role = [filter.role];
|
|
1987
|
+
}
|
|
1988
|
+
if (typeof filter.type === 'string') {
|
|
1989
|
+
filter.type = [filter.type];
|
|
1990
|
+
}
|
|
1991
|
+
if (typeof filter.custom === 'string') {
|
|
1992
|
+
filter.custom = [filter.custom];
|
|
1993
|
+
}
|
|
1959
1994
|
filter.expertMode =
|
|
1960
1995
|
props.expertMode !== undefined
|
|
1961
1996
|
? props.expertMode
|
|
@@ -2158,8 +2193,8 @@ export class ObjectBrowserClass extends Component {
|
|
|
2158
2193
|
await new Promise(resolve => {
|
|
2159
2194
|
this.setState({ updating: true }, () => resolve());
|
|
2160
2195
|
});
|
|
2161
|
-
const objects = (
|
|
2162
|
-
? await
|
|
2196
|
+
const objects = (props.objectsWorker
|
|
2197
|
+
? await props.objectsWorker.getObjects(update)
|
|
2163
2198
|
: await props.socket.getObjects(update, true)) || {};
|
|
2164
2199
|
if (props.types && Connection.isWeb()) {
|
|
2165
2200
|
for (let i = 0; i < props.types.length; i++) {
|
|
@@ -2264,10 +2299,10 @@ export class ObjectBrowserClass extends Component {
|
|
|
2264
2299
|
const columnsForAdmin = await this.getAdditionalColumns();
|
|
2265
2300
|
this.calculateColumnsVisibility(null, null, columnsForAdmin);
|
|
2266
2301
|
const { info, root } = buildTree(this.objects, {
|
|
2267
|
-
imagePrefix:
|
|
2268
|
-
root:
|
|
2269
|
-
lang:
|
|
2270
|
-
themeType:
|
|
2302
|
+
imagePrefix: props.imagePrefix,
|
|
2303
|
+
root: props.root,
|
|
2304
|
+
lang: props.lang,
|
|
2305
|
+
themeType: props.themeType,
|
|
2271
2306
|
});
|
|
2272
2307
|
this.root = root;
|
|
2273
2308
|
this.info = info;
|
|
@@ -2276,7 +2311,7 @@ export class ObjectBrowserClass extends Component {
|
|
|
2276
2311
|
this.lastAppliedFilter = null;
|
|
2277
2312
|
// If the selected ID is not visible, reset filter
|
|
2278
2313
|
if (node &&
|
|
2279
|
-
!applyFilter(node, this.state.filter,
|
|
2314
|
+
!applyFilter(node, this.state.filter, props.lang, this.objects, undefined, undefined, props.customFilter, props.types)) {
|
|
2280
2315
|
// reset filter
|
|
2281
2316
|
this.setState({ filter: { ...DEFAULT_FILTER }, columnsForAdmin }, () => {
|
|
2282
2317
|
this.setState({ loaded: true, updating: false }, () => this.expandAllSelected(() => this.onAfterSelect()));
|
|
@@ -2346,6 +2381,13 @@ export class ObjectBrowserClass extends Component {
|
|
|
2346
2381
|
else if (this.state.selected.length === 1 && this.props.allowNonObjects) {
|
|
2347
2382
|
this.props.onSelect?.(this.state.selected, null, isDouble);
|
|
2348
2383
|
}
|
|
2384
|
+
else {
|
|
2385
|
+
// we have more than one state
|
|
2386
|
+
// Check if all IDs are objects
|
|
2387
|
+
if (!this.props.allowNonObjects || !this.state.selected.find(id => !this.objects[id])) {
|
|
2388
|
+
this.props.onSelect?.(this.state.selected, null, isDouble);
|
|
2389
|
+
}
|
|
2390
|
+
}
|
|
2349
2391
|
}
|
|
2350
2392
|
else {
|
|
2351
2393
|
this.localStorage.removeItem(`${this.props.dialogName || 'App'}.objectSelected`);
|
|
@@ -2404,6 +2446,12 @@ export class ObjectBrowserClass extends Component {
|
|
|
2404
2446
|
window.addEventListener('contextmenu', this.onContextMenu, true);
|
|
2405
2447
|
window.addEventListener('keydown', this.onKeyPress, true);
|
|
2406
2448
|
window.addEventListener('keyup', this.onKeyPress, true);
|
|
2449
|
+
// Inform dialog that all objects are loaded
|
|
2450
|
+
if (this.props.onAllLoaded) {
|
|
2451
|
+
setTimeout(() => {
|
|
2452
|
+
this.props.onAllLoaded?.();
|
|
2453
|
+
}, 100);
|
|
2454
|
+
}
|
|
2407
2455
|
}
|
|
2408
2456
|
onKeyPress = (event) => {
|
|
2409
2457
|
if (event.type === 'keydown' && event.ctrlKey && !this.cltrPressed) {
|
|
@@ -2987,12 +3035,27 @@ export class ObjectBrowserClass extends Component {
|
|
|
2987
3035
|
onFilter(name, value) {
|
|
2988
3036
|
this.filterTimer = null;
|
|
2989
3037
|
const filter = { ...this.state.filter };
|
|
2990
|
-
Object.keys(this.filterRefs).forEach(_name => {
|
|
3038
|
+
Object.keys(this.filterRefs).forEach((_name) => {
|
|
2991
3039
|
if (this.filterRefs[_name]?.current) {
|
|
2992
3040
|
const filterRef = this.filterRefs[_name].current;
|
|
2993
3041
|
for (let i = 0; i < filterRef.children.length; i++) {
|
|
2994
3042
|
if (filterRef.children[i].tagName === 'INPUT') {
|
|
2995
|
-
|
|
3043
|
+
if (_name === 'role' ||
|
|
3044
|
+
_name === 'type' ||
|
|
3045
|
+
_name === 'func' ||
|
|
3046
|
+
_name === 'custom' ||
|
|
3047
|
+
_name === 'room') {
|
|
3048
|
+
const value = filterRef.children[i].value;
|
|
3049
|
+
if (value) {
|
|
3050
|
+
filter[_name] = value.split(',');
|
|
3051
|
+
}
|
|
3052
|
+
else {
|
|
3053
|
+
filter[_name] = undefined;
|
|
3054
|
+
}
|
|
3055
|
+
}
|
|
3056
|
+
else {
|
|
3057
|
+
filter[_name] = filterRef.children[i].value;
|
|
3058
|
+
}
|
|
2996
3059
|
break;
|
|
2997
3060
|
}
|
|
2998
3061
|
}
|
|
@@ -3058,12 +3121,12 @@ export class ObjectBrowserClass extends Component {
|
|
|
3058
3121
|
getFilterSelect(name, values) {
|
|
3059
3122
|
const hasIcons = !!values?.find(item => item.icon);
|
|
3060
3123
|
return (React.createElement("div", { style: { position: 'relative' } },
|
|
3061
|
-
React.createElement(Select, { variant: "standard", key: `${name}_${this.state.filterKey}`, ref: this.filterRefs[name], sx: styles.headerCellInput, className: "no-underline", onChange: () => {
|
|
3124
|
+
React.createElement(Select, { variant: "standard", key: `${name}_${this.state.filterKey}`, ref: this.filterRefs[name], sx: styles.headerCellInput, className: "no-underline", multiple: true, onChange: () => {
|
|
3062
3125
|
if (this.filterTimer) {
|
|
3063
3126
|
clearTimeout(this.filterTimer);
|
|
3064
3127
|
}
|
|
3065
3128
|
this.filterTimer = setTimeout(() => this.onFilter(), 400);
|
|
3066
|
-
}, defaultValue: this.state.filter[name] ||
|
|
3129
|
+
}, defaultValue: this.state.filter[name] || [], inputProps: { name, id: name }, displayEmpty: true },
|
|
3067
3130
|
React.createElement(MenuItem, { key: "empty", value: "" },
|
|
3068
3131
|
React.createElement("span", { style: styles.selectNone }, name === 'custom' ? this.texts.showAll : this.texts[`filter_${name}`])),
|
|
3069
3132
|
values?.map(item => {
|
|
@@ -3086,7 +3149,7 @@ export class ObjectBrowserClass extends Component {
|
|
|
3086
3149
|
this.filterRefs[name]?.current?.childNodes[1]?.value ? (React.createElement(Box, { component: "div", sx: styles.selectClearButton },
|
|
3087
3150
|
React.createElement(IconButton, { size: "small", onClick: () => {
|
|
3088
3151
|
const newFilter = { ...this.state.filter };
|
|
3089
|
-
newFilter[name]
|
|
3152
|
+
delete newFilter[name];
|
|
3090
3153
|
(this.filterRefs[name].current?.childNodes[1]).value = '';
|
|
3091
3154
|
this.localStorage.setItem(`${this.props.dialogName || 'App'}.objectFilter`, JSON.stringify(newFilter));
|
|
3092
3155
|
this.setState({ filter: newFilter, filterKey: this.state.filterKey + 1 }, () => this.props.onFilterChanged && this.props.onFilterChanged(newFilter));
|