@iobroker/json-config 9.0.24 → 9.1.1

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/README.md CHANGED
@@ -1503,6 +1503,7 @@ In the Settings of the Web developer tools, you can create your own devices with
1503
1503
  | `notOs` | Do not show this element on these operating systems of the host, on which the instance runs: `"win32"` or `["linux", "darwin"]` |
1504
1504
  | `docker` | Show this element only if the ioBroker runs (`true`) or does not run (`false`) in a docker container |
1505
1505
  | `disabled` | JS function that could use `native.attribute` for calculation |
1506
+ | `dependsOnStates` | ioBroker states, on which this element depends: `{"running": ".info.browsing"}`. See [Show or disable elements depending on ioBroker states](#show-or-disable-elements-depending-on-iobroker-states) |
1506
1507
  | `help` | help text (multi-language) |
1507
1508
  | `helpLink` | href to help (could be used only together with `help`) |
1508
1509
  | `style` | CSS style in ReactJS notation: `radiusBorder` and not `radius-border`. |
@@ -1558,6 +1559,42 @@ the text patterns of `label`, `help` and so on:
1558
1559
  }
1559
1560
  ```
1560
1561
 
1562
+ ### Show or disable elements depending on ioBroker states
1563
+
1564
+ With `dependsOnStates`, an element can react on the values of ioBroker states. The states are subscribed,
1565
+ so the element is updated immediately if a state changes - no reload of the configuration dialog is required.
1566
+
1567
+ ```json5
1568
+ {
1569
+ "startBrowse": {
1570
+ "type": "sendTo",
1571
+ "command": "browse",
1572
+ "label": "${_states.running?.val ? 'Stop browse' : 'Start browse'}",
1573
+ "dependsOnStates": { "running": ".info.browsing" },
1574
+ "disabled": "!!_states.running?.val"
1575
+ }
1576
+ }
1577
+ ```
1578
+
1579
+ - `dependsOnStates` is written as `{"<alias>": "<state ID>"}`. The values are available in **all** JS functions
1580
+ (`hidden`, `disabled`, `validator`, `defaultFunc`, `onChange.calculateFunc`, `confirm.condition`) and in the
1581
+ text patterns of `label`, `help`, `tooltip` and so on as `_states.<alias>`.
1582
+ - `_states.<alias>` contains the **whole state object**, so `_states.running?.val`, `_states.running?.ts`,
1583
+ `_states.running?.ack` can be used. It is `null` if the state does not exist, so always use `?.`.
1584
+ - A state ID that starts with a dot addresses the own instance: `.info.browsing` => `myAdapter.0.info.browsing`.
1585
+ Every other ID is used as it is, so the states of other adapters can be monitored too.
1586
+ - The ID may contain `${data.xxx}` patterns, e.g. `"device": "${data.deviceInstance}.info.connection"`.
1587
+ It will be resolved anew if the configuration changes. Wildcards (`*`) are **not** allowed.
1588
+ - If one of the states changes, `hidden`, `disabled`, `label`, `help`, `validator` and `defaultFunc` of this
1589
+ element will be calculated anew. Every state is subscribed only once, independent of how many elements
1590
+ (or table lines) use it.
1591
+ - The short form `"dependsOnStates": ["admin.0.info.connection"]` uses the ID itself as an alias:
1592
+ `_states['admin.0.info.connection']`.
1593
+ - The attribute may be used on every element, also on `panel`, `tabs` and table columns.
1594
+
1595
+ **Note:** old admin versions do not know `_states` and would throw an error by the evaluation of such a
1596
+ function, so the element would stay visible and enabled.
1597
+
1561
1598
  **Note:** old admin versions do not know `_os` and would evaluate `"hidden": "_os !== 'linux'"` to `true`
1562
1599
  and so hide the element everywhere. Because of that, `os`/`notOs` should be preferred, as they are simply
1563
1600
  ignored by old admin versions (the element will be shown). If a JS function must be used, write it
@@ -1708,6 +1745,7 @@ const func = new Function(
1708
1745
  '_os', // Operating system of the host, where the instance runs: 'win32', 'linux', 'darwin', ...
1709
1746
  '_arch', // Architecture of the host, where the instance runs: 'x64', 'arm64', ...
1710
1747
  '_host', // Information about the host: {id, os, osType, arch, release, nodeVersion, controllerVersion, docker, dockerVersion}
1748
+ '_states', // Values of the states from `dependsOnStates`: {<alias>: <state object or null>}
1711
1749
  myValidator.includes('return') ? myValidator : 'return ' + myValidator); // e.g. "_alive === true"
1712
1750
 
1713
1751
  const isValid = func(data, systemConfig.common, instanceAlive, adapter.common, this.props.socket);
@@ -1728,6 +1766,7 @@ The following variables are available in JS function in adapter settings:
1728
1766
  - `_os` - operating system of the host, on which the instance runs (`process.platform`), e.g. `linux`, `win32`, `darwin`. Empty string if unknown
1729
1767
  - `_arch` - architecture of the host, on which the instance runs, e.g. `x64`, `arm64`
1730
1768
  - `_host` - information about the host: `{id, os, osType, arch, release, nodeVersion, controllerVersion, docker, dockerVersion}`. `docker` is `undefined` if the docker state was not requested or the host did not answer
1769
+ - `_states` - values of the states from [`dependsOnStates`](#show-or-disable-elements-depending-on-iobroker-states): `{<alias>: <state object>}`. `null` if the state does not exist
1731
1770
 
1732
1771
  ### Custom settings dialog
1733
1772
 
@@ -1748,6 +1787,7 @@ const func = new Function(
1748
1787
  "_os",
1749
1788
  "_arch",
1750
1789
  "_host",
1790
+ "_states",
1751
1791
  myValidator.includes("return") ? myValidator : "return " + myValidator
1752
1792
  ); // e.g. "_alive === true"
1753
1793
 
@@ -1774,6 +1814,7 @@ The following variables are available in JS function in custom settings:
1774
1814
  - `_os` - operating system of the host, on which the instance runs (`process.platform`), e.g. `linux`, `win32`, `darwin`. Empty string if unknown
1775
1815
  - `_arch` - architecture of the host, on which the instance runs, e.g. `x64`, `arm64`
1776
1816
  - `_host` - information about the host: `{id, os, osType, arch, release, nodeVersion, controllerVersion, docker, dockerVersion}`. `docker` is `undefined` if the docker state was not requested or the host did not answer
1817
+ - `_states` - values of the states from [`dependsOnStates`](#show-or-disable-elements-depending-on-iobroker-states): `{<alias>: <state object>}`. `null` if the state does not exist
1777
1818
 
1778
1819
  ```json5
1779
1820
  {
@@ -1907,8 +1948,12 @@ The schema is used here: https://github.com/SchemaStore/schemastore/blob/6da29cd
1907
1948
  ### **WORK IN PROGRESS**
1908
1949
  -->
1909
1950
  ## Changelog
1910
- ### 9.0.24 (2026-08-30)
1951
+ ### 9.1.1 (2026-08-31)
1952
+ - (@GermanBluefox) Do not show export import on narrow devices
1953
+
1954
+ ### 9.1.0 (2026-08-31)
1911
1955
  - (@GermanBluefox) Added progress bar to the state component
1956
+ - (@GermanBluefox) Added the possibility to show or hide elements depending on the states: `dependsOnStates` and the JS variable `_states`
1912
1957
 
1913
1958
  ### 9.0.23 (2026-08-27)
1914
1959
  - (@krobipd) Corrected: the object browser stayed empty after closing the object customization dialog if any object was changed while the dialog was open (ioBroker/ioBroker.admin#3391)
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import JSON5 from 'json5';
3
3
  import MD5 from 'crypto-js/md5';
4
- import { Fab, Tooltip, LinearProgress } from '@mui/material';
4
+ import { Box, Fab, Tooltip, LinearProgress } from '@mui/material';
5
5
  import { Publish as PublishIcon } from '@mui/icons-material';
6
6
  import { I18n, Router, SaveCloseButtons, Theme, DialogConfirm, Utils, } from '@iobroker/gui-components';
7
7
  import ConfigGeneric from './JsonConfigComponent/ConfigGeneric';
@@ -214,7 +214,11 @@ class JsonConfig extends Router {
214
214
  }
215
215
  };
216
216
  getExportImportButtons() {
217
- return (React.createElement("div", { style: styles.exportImportButtons },
217
+ return (React.createElement(Box, { sx: {
218
+ ...styles.exportImportButtons,
219
+ // On xs displays the buttons would hide the tabs, so do not show them there
220
+ display: { xs: 'none', sm: 'block' },
221
+ } },
218
222
  React.createElement(Tooltip, { title: this.props.t('jc_Import settings from JSON file'), slotProps: { popper: { sx: styles.tooltip } } },
219
223
  React.createElement(Fab, { size: "small", sx: { '&.MuiFab-root': styles.button }, onClick: () => {
220
224
  const input = document.createElement('input');
@@ -1 +1 @@
1
- {"version":3,"file":"JsonConfig.js","sourceRoot":"src/","sources":["JsonConfig.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\nimport JSON5 from 'json5';\nimport MD5 from 'crypto-js/md5';\n\nimport { Fab, Tooltip, LinearProgress } from '@mui/material';\nimport { Publish as PublishIcon } from '@mui/icons-material';\n\nimport {\n I18n,\n Router,\n SaveCloseButtons,\n Theme,\n DialogConfirm,\n type AdminConnection,\n type IobTheme,\n type ThemeName,\n type ThemeType,\n Utils,\n} from '@iobroker/gui-components';\n\nimport type { ConfigItemAny, ConfigItemPanel, ConfigItemTabs } from './types';\nimport ConfigGeneric, {\n type ConfigGenericProps,\n type DeviceManagerPropsProps,\n} from './JsonConfigComponent/ConfigGeneric';\nimport JsonConfigComponent from './JsonConfigComponent';\n\nconst styles: Record<string, React.CSSProperties> = {\n root: {\n width: '100%',\n height: '100%',\n overflow: 'hidden',\n position: 'relative',\n },\n scroll: {\n height: 'calc(100% - 48px)',\n overflowY: 'auto',\n },\n exportImportButtons: {\n position: 'absolute',\n top: 5,\n right: 0,\n zIndex: 3,\n },\n button: {\n marginRight: '5px',\n },\n tooltip: {\n pointerEvents: 'none',\n },\n};\n\n/**\n * Decrypt the password/value with given key\n *\n * @param key - Secret key\n * @param value - value to decrypt\n */\nfunction decryptLegacy(key: string, value: string): string {\n let result = '';\n for (let i = 0; i < value.length; i++) {\n result += String.fromCharCode(key[i % key.length].charCodeAt(0) ^ value.charCodeAt(i));\n }\n return result;\n}\n\n/**\n * Encrypt the password/value with given key\n *\n * @param key - Secret key\n * @param value - value to encrypt\n */\nfunction encryptLegacy(key: string, value: string): string {\n let result = '';\n for (let i = 0; i < value.length; i++) {\n result += String.fromCharCode(key[i % key.length].charCodeAt(0) ^ value.charCodeAt(i));\n }\n return result;\n}\n\n/**\n * Decrypt the password/value with the given key\n * Usage:\n * ```js\n * function load(settings, onChange) {\n * if (settings.password) {\n * settings.password = decrypt(systemSecret, settings.password);\n * // same as\n * settings.password = decrypt(settings.password);\n * }\n * // ...\n * }\n * ```\n *\n * @param key - Secret key\n * @param value - value to decrypt\n */\nfunction decrypt(key: string, value: string): string {\n if (typeof value !== 'string') {\n return value;\n }\n\n // if not encrypted as aes-192 or key not a valid 48-digit hex -> fallback\n if (!value.startsWith('$/aes-192-cbc:') || !/^[0-9a-f]{48}$/.test(key)) {\n return decryptLegacy(key, value);\n }\n\n // algorithm:iv:encryptedValue\n const textParts = value.split(':', 3);\n\n const _key = window.CryptoJS.enc.Hex.parse(key);\n const iv = window.CryptoJS.enc.Hex.parse(textParts[1]);\n\n const cipherParams = window.CryptoJS.lib.CipherParams.create({\n ciphertext: window.CryptoJS.enc.Hex.parse(textParts[2]),\n });\n\n const decryptedBinary = window.CryptoJS.AES.decrypt(cipherParams, _key, { iv });\n\n return window.CryptoJS.enc.Utf8.stringify(decryptedBinary);\n}\n\n/**\n * Encrypt the password/value with given key\n * Usage:\n * ```\n * function save(callback) {\n * ...\n * if (obj.password) {\n * obj.password = encrypt(systemSecret, obj.password);\n * // same as\n * obj.password = decrypt(obj.password);\n * }\n * ...\n * }\n * ```\n *\n * @param key - Secret key\n * @param value - value to encrypt\n * @param _iv - optional initial vector for tests\n */\nfunction encrypt(key: string, value: string, _iv?: string): string {\n if (typeof value !== 'string') {\n return value;\n }\n\n if (!/^[0-9a-f]{48}$/.test(key)) {\n // key length is not matching for AES-192-CBC, or key is no valid hex - fallback to old encryption\n return encryptLegacy(key, value);\n }\n\n let iv;\n if (_iv) {\n iv = window.CryptoJS.enc.Hex.parse(_iv);\n } else {\n iv = window.CryptoJS.lib.WordArray.random(128 / 8);\n }\n\n const _key = window.CryptoJS.enc.Hex.parse(key);\n const encrypted = window.CryptoJS.AES.encrypt(value, _key, { iv }).ciphertext;\n\n return `$/aes-192-cbc:${window.CryptoJS.enc.Hex.stringify(iv)}:${encrypted}`;\n}\n\nfunction loadScript(\n src: string,\n id: string,\n): ((this: GlobalEventHandlers, ev: Event) => any) | null | undefined | Promise<void> {\n if (!id || !document.getElementById(id)) {\n return new Promise(resolve => {\n const script = document.createElement('script');\n script.setAttribute('id', id);\n script.onload = resolve as unknown as (this: GlobalEventHandlers, ev: Event) => any;\n script.src = src;\n document.getElementsByTagName('head')[0].appendChild(script);\n });\n }\n return document.getElementById(id)?.onload;\n}\n\ninterface BufferObject {\n type: 'Buffer';\n data: Buffer;\n}\n\ninterface JsonConfigProps {\n adapterName: string;\n instance: number;\n isFloatComma: boolean;\n dateFormat: string;\n secret?: string;\n socket: AdminConnection;\n theme: IobTheme;\n themeName: ThemeName;\n themeType: ThemeType;\n expertMode?: boolean;\n /** Translate method */\n t: typeof I18n.t;\n configStored: (notChanged: boolean) => void;\n width: 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n DeviceManager?: React.FC<DeviceManagerPropsProps>;\n customComponents?: { [componentType: string]: typeof ConfigGeneric<ConfigGenericProps, any> };\n}\n\ninterface JsonConfigState {\n schema?: ConfigItemPanel | ConfigItemTabs;\n data?: Record<string, unknown>;\n originalData?: Record<string, unknown>;\n updateData: number;\n common?: ioBroker.InstanceCommon;\n changed: boolean;\n confirmDialog: boolean;\n theme: IobTheme;\n saveConfigDialog: boolean;\n hash: string;\n error?: boolean;\n}\n\nclass JsonConfig extends Router<JsonConfigProps, JsonConfigState> {\n private fileSubscribed: string[] = [];\n\n private fileLangSubscribed = '';\n\n private secret: string;\n\n constructor(props: JsonConfigProps) {\n super(props);\n\n this.state = {\n updateData: 0,\n changed: false,\n confirmDialog: false,\n theme: Theme(props.themeName), // buttons require special theme\n saveConfigDialog: false,\n hash: '_',\n };\n\n this.secret = props.secret || '';\n\n void this.getInstanceObject().then(obj =>\n this.getConfigFile().then(schema =>\n // load language\n JsonConfigComponent.loadI18n(this.props.socket, schema?.i18n, this.props.adapterName).then(\n (langFileName: string) => {\n if (langFileName) {\n // subscribe on changes\n if (!this.fileLangSubscribed) {\n this.fileLangSubscribed = langFileName;\n void this.props.socket.subscribeFiles(\n `${this.props.adapterName}.admin`,\n this.fileLangSubscribed,\n this.onFileChange,\n );\n }\n }\n\n if (obj) {\n this.setState({\n schema: schema || undefined,\n data: obj.native,\n common: obj.common,\n hash: MD5(JSON.stringify(schema)).toString(),\n });\n } else {\n window.alert(\n `Instance system.adapter.${this.props.adapterName}.${this.props.instance} not found!`,\n );\n }\n },\n ),\n ),\n );\n }\n\n componentWillUnmount(): void {\n super.componentWillUnmount();\n if (this.fileSubscribed.length) {\n this.props.socket.unsubscribeFiles(\n `${this.props.adapterName}.admin`,\n this.fileSubscribed,\n this.onFileChange,\n );\n this.fileSubscribed = [];\n }\n if (this.fileLangSubscribed) {\n this.props.socket.unsubscribeFiles(\n `${this.props.adapterName}.admin`,\n this.fileLangSubscribed,\n this.onFileChange,\n );\n this.fileLangSubscribed = '';\n }\n }\n\n private handleFileSelect = (evt: Record<string, any>): void => {\n const f = evt.target.files[0];\n if (f) {\n const r = new FileReader();\n r.onload = (e: ProgressEvent<FileReader>): void => {\n if (!e.target) {\n return;\n }\n\n const contents = e.target.result as string;\n try {\n const data = JSON.parse(contents);\n this.setState({ data, changed: JSON.stringify(data) !== JSON.stringify(this.state.originalData) });\n } catch {\n window.alert(I18n.t('jc_[JsonConfig] Failed to parse JSON file'));\n }\n };\n r.readAsText(f);\n } else {\n window.alert(I18n.t('jc_[JsonConfig] Failed to open JSON File'));\n }\n };\n\n getExportImportButtons(): React.JSX.Element {\n return (\n <div style={styles.exportImportButtons}>\n <Tooltip\n title={this.props.t('jc_Import settings from JSON file')}\n slotProps={{ popper: { sx: styles.tooltip } }}\n >\n <Fab\n size=\"small\"\n sx={{ '&.MuiFab-root': styles.button }}\n onClick={() => {\n const input = document.createElement('input');\n input.setAttribute('type', 'file');\n input.setAttribute('id', 'files');\n // @ts-expect-error check\n input.setAttribute('opacity', 0);\n input.addEventListener('change', e => this.handleFileSelect(e), false);\n input.click();\n }}\n >\n <PublishIcon />\n </Fab>\n </Tooltip>\n <Tooltip\n title={this.props.t('jc_Export setting to JSON file')}\n slotProps={{ popper: { sx: styles.tooltip } }}\n >\n <Fab\n size=\"small\"\n sx={{ '&.MuiFab-root': styles.button }}\n onClick={() => {\n if (!this.state.data) {\n return;\n }\n\n Utils.generateFile(\n `${this.props.adapterName}.${this.props.instance}.json`,\n this.state.data,\n );\n }}\n >\n <PublishIcon style={{ transform: 'rotate(180deg)' }} />\n </Fab>\n </Tooltip>\n </div>\n );\n }\n\n onFileChange = async (id: string, fileName: string, size: number | null): Promise<void> => {\n if (id === `${this.props.adapterName}.admin` && size) {\n if (fileName === this.fileLangSubscribed) {\n try {\n await JsonConfigComponent.loadI18n(\n this.props.socket,\n this.state.schema?.i18n,\n this.props.adapterName,\n );\n this.setState({ hash: `${this.state.hash}1` });\n } catch {\n // ignore errors\n }\n } else if (this.fileSubscribed.includes(fileName)) {\n try {\n const schema = await this.getConfigFile(this.fileSubscribed[0]);\n this.setState({ schema: schema || undefined, hash: MD5(JSON.stringify(schema)).toString() });\n } catch {\n // ignore errors\n }\n }\n }\n };\n\n async getInstanceObject(): Promise<ioBroker.InstanceObject | null> {\n try {\n const obj = await this.props.socket.getObject(\n `system.adapter.${this.props.adapterName}.${this.props.instance}`,\n );\n // decode all native attributes listed in obj.encryptedNative\n if (Array.isArray(obj?.encryptedNative)) {\n if (!this.secret) {\n const systemConfig = await this.props.socket.getSystemConfig();\n await loadScript('../../lib/js/crypto-js/crypto-js.js', 'crypto-js');\n this.secret = systemConfig.native.secret;\n }\n obj.encryptedNative?.forEach(attr => {\n if (obj.native[attr]) {\n obj.native[attr] = decrypt(this.secret, obj.native[attr]);\n }\n });\n return obj;\n }\n return obj || null;\n } catch (e) {\n window.alert(`[JsonConfig] Cannot read instance object: ${e}`);\n }\n return null;\n }\n\n renderDialogConfirm(): React.JSX.Element | null {\n if (!this.state.confirmDialog) {\n return null;\n }\n return (\n <DialogConfirm\n title={I18n.t('jc_Please confirm')}\n text={I18n.t('jc_Some data are not stored. Discard?')}\n ok={I18n.t('jc_Discard')}\n cancel={I18n.t('jc_Cancel')}\n onClose={(isYes: boolean) =>\n this.setState({ confirmDialog: false }, () => isYes && Router.doNavigate(null))\n }\n />\n );\n }\n\n async scanForInclude(json: Record<string, any>, filePaths: string[]): Promise<Record<string, any>> {\n if (typeof json['#include'] === 'string') {\n // load file\n const data = await this._getConfigFile(json['#include'], [...filePaths]);\n delete json['#include'];\n if (data) {\n // merge data\n json = { ...json, ...data };\n }\n return json;\n }\n const keys = Object.keys(json);\n for (let k = 0; k < keys.length; k++) {\n if (json[keys[k]] && typeof json[keys[k]] === 'object') {\n json[keys[k]] = await this.scanForInclude(json[keys[k]], filePaths);\n }\n }\n return json;\n }\n\n async getConfigFile(fileName?: string): Promise<ConfigItemPanel | ConfigItemTabs | null> {\n return this._getConfigFile(fileName);\n }\n\n async _getConfigFile(fileName?: string, _filePaths?: string[]): Promise<ConfigItemPanel | ConfigItemTabs | null> {\n fileName = fileName || 'jsonConfig.json5';\n _filePaths = _filePaths || [];\n\n if (_filePaths.includes(fileName)) {\n window.alert(`[JsonConfig] Circular reference in file: ${fileName} => ${_filePaths.join(' => ')}`);\n return null;\n }\n _filePaths.push(fileName);\n\n try {\n const exist = await this.props.socket.fileExists(`${this.props.adapterName}.admin`, fileName);\n if (!exist) {\n fileName = 'jsonConfig.json';\n }\n const data: {\n file: string;\n mimeType: string;\n } = await this.props.socket.readFile(`${this.props.adapterName}.admin`, fileName);\n let content = '';\n let file: string | BufferObject = '';\n\n if (data.file !== undefined) {\n file = data.file;\n }\n\n if (typeof file === 'string') {\n content = file;\n // @ts-expect-error revisit\n } else if (file.type === 'Buffer') {\n let binary = '';\n // @ts-expect-error revisit\n const bytes = new Uint8Array(file.data);\n const len = bytes.byteLength;\n for (let i = 0; i < len; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n content = binary;\n }\n\n // subscribe on changes\n if (!this.fileSubscribed.includes(fileName)) {\n this.fileSubscribed.push(fileName);\n await this.props.socket.subscribeFiles(`${this.props.adapterName}.admin`, fileName, this.onFileChange);\n }\n\n try {\n // detect #include attr\n return (await this.scanForInclude(JSON5.parse(content), _filePaths)) as\n ConfigItemPanel | ConfigItemTabs;\n } catch (e) {\n window.alert('[JsonConfig] Cannot parse json5 config!');\n console.log(e);\n }\n } catch (e1) {\n if (!this.state.schema) {\n window.alert(`[JsonConfig] Cannot read file \"${fileName}: ${e1}`);\n }\n }\n return null;\n }\n\n renderSaveConfigDialog(): React.JSX.Element | null {\n if (!this.state.saveConfigDialog) {\n return null;\n }\n return (\n <DialogConfirm\n title={I18n.t('jc_Please confirm')}\n text={I18n.t('jc_Save configuration?')}\n ok={I18n.t('jc_Save')}\n cancel={I18n.t('jc_Cancel')}\n onClose={(isYes: boolean) =>\n this.setState({ saveConfigDialog: false }, () => isYes && this.onSave(true))\n }\n />\n );\n }\n\n findAttr(attr: string, schema?: ConfigItemPanel | ConfigItemTabs): ConfigItemAny | null {\n schema = schema || this.state.schema;\n if (schema?.items) {\n if (attr in schema.items) {\n return schema.items[attr];\n }\n for (const _item of Object.values(schema.items)) {\n const item = this.findAttr(attr, _item as ConfigItemPanel | ConfigItemTabs);\n if (item) {\n return item;\n }\n }\n }\n\n return null;\n }\n\n // this function is called recursively and trims all text fields that must be trimmed\n postProcessing(data: Record<string, unknown>, attr: string, schema: ConfigItemAny): void {\n schema = schema || this.state.schema;\n if (!data) {\n // should not happen\n console.error(`Data is empty in postProcessing: ${attr}, ${JSON.stringify(schema)}`);\n return;\n }\n\n const dataAttr = data[attr];\n\n if ((schema as ConfigItemTabs).items) {\n if (schema.type === 'table') {\n const table = dataAttr;\n\n if (!Array.isArray(table)) {\n return;\n }\n\n for (const entry of table) {\n if (schema.items) {\n for (const tItem of schema.items) {\n if (tItem.attr) {\n this.postProcessing(entry, tItem.attr, tItem);\n }\n }\n }\n }\n } else {\n for (const [_attr, item] of Object.entries((schema as ConfigItemTabs).items)) {\n if (\n (item as any).type === 'panel' ||\n (item as any).type === 'tabs' ||\n (item as any).type === 'accordion'\n ) {\n return;\n }\n this.postProcessing(data, _attr, item);\n }\n }\n } else if (attr && typeof dataAttr === 'string') {\n // postprocessing\n if (schema.type === 'text') {\n if (schema.trim !== false) {\n data[attr] = dataAttr.trim();\n }\n } else if (schema.type === 'ip') {\n // should not happen\n data[attr] = dataAttr.trim();\n } else if (schema.type === 'number') {\n const dataVal = parseFloat(dataAttr.toString().replace(',', '.'));\n\n if (schema.min !== undefined && dataVal < schema.min) {\n data[attr] = schema.min;\n } else if (schema.max !== undefined && dataVal > schema.max) {\n data[attr] = schema.max;\n } else {\n data[attr] = dataVal;\n }\n } else if (schema.type === 'port') {\n const dataVal = parseInt(dataAttr.toString(), 10);\n if (schema.min !== undefined && dataVal < schema.min) {\n data[attr] = schema.min;\n } else if (schema.max !== undefined && dataVal > schema.max) {\n data[attr] = schema.max;\n }\n if (data[attr] !== 0 && dataVal < 20) {\n data[attr] = 20;\n } else if (dataVal > 0xffff) {\n data[attr] = 0xffff;\n } else {\n data[attr] = dataVal;\n }\n } else if (schema.type === 'checkbox') {\n // should not happen\n data[attr] =\n data[attr] === true ||\n data[attr] === 'true' ||\n data[attr] === 'on' ||\n data[attr] === 1 ||\n data[attr] === '1';\n }\n }\n }\n\n async onSave(doSave: boolean, close?: boolean): Promise<void> {\n if (doSave) {\n const obj = await this.getInstanceObject();\n\n if (!obj) {\n console.error('Something went wrong: may be no connection?');\n window.alert('Something went wrong: may be no connection?');\n return;\n }\n\n if (!this.state.data || !this.state.schema) {\n return;\n }\n\n const doNotSaveAttributes: Record<string, any> = {};\n\n for (const attr of Object.keys(this.state.data)) {\n const item = this.findAttr(attr);\n if ((!item || !item.doNotSave || item.type === 'state') && !attr.startsWith('_')) {\n ConfigGeneric.setValue(obj.native, attr, this.state.data[attr]);\n } else {\n ConfigGeneric.setValue(obj.native, attr, null);\n doNotSaveAttributes[attr] = this.state.data[attr];\n }\n }\n\n try {\n const encryptedObj = JSON.parse(JSON.stringify(obj));\n // encode all native attributes listed in obj.encryptedNative\n if (Array.isArray(encryptedObj.encryptedNative)) {\n await loadScript('../../lib/js/crypto-js/crypto-js.js', 'crypto-js');\n\n for (const attr of encryptedObj.encryptedNative) {\n if (encryptedObj.native[attr]) {\n encryptedObj.native[attr] = encrypt(this.secret, encryptedObj.native[attr]);\n }\n }\n }\n\n await this.props.socket.setObject(encryptedObj._id, encryptedObj);\n } catch (e) {\n window.alert(`[JsonConfig] Cannot set object: ${e}`);\n }\n\n /** We want to preserve the doNotSaveAttributes too, just not save it */\n const nativeWithNonSaved = { ...obj.native, ...doNotSaveAttributes };\n console.log(nativeWithNonSaved);\n\n this.setState(\n {\n changed: false,\n data: nativeWithNonSaved,\n updateData: this.state.updateData + 1,\n originalData: nativeWithNonSaved,\n },\n () => close && Router.doNavigate(null),\n );\n } else if (this.state.changed) {\n this.setState({ confirmDialog: true });\n } else {\n Router.doNavigate(null);\n }\n }\n\n componentDidUpdate(_prevProps: JsonConfigProps, prevState: JsonConfigState): void {\n if (prevState.changed !== this.state.changed) {\n this.props.configStored(!this.state.changed);\n }\n }\n\n /**\n * Validate the JSON config once on mount\n */\n async componentDidMount(): Promise<void> {\n const link = `${window.location.protocol}//${window.location.host}${window.location.pathname}validate_config/${this.props.adapterName}`;\n console.log(`fetch ${link}`);\n await fetch(link);\n }\n\n render(): React.JSX.Element {\n if (!this.state.data || !this.state.schema) {\n return <LinearProgress />;\n }\n\n return (\n <div style={styles.root}>\n {this.renderDialogConfirm()}\n {this.getExportImportButtons()}\n {this.renderSaveConfigDialog()}\n <JsonConfigComponent\n key={this.state.hash}\n style={styles.scroll}\n socket={this.props.socket}\n themeName={this.props.themeName}\n themeType={this.props.themeType}\n adapterName={this.props.adapterName}\n instance={this.props.instance}\n isFloatComma={this.props.isFloatComma}\n dateFormat={this.props.dateFormat}\n schema={this.state.schema}\n common={this.state.common}\n expertMode={this.props.expertMode}\n data={this.state.data}\n updateData={this.state.updateData}\n onError={error => this.setState({ error })}\n onChange={(data, changed, saveConfigDialog) => {\n if (saveConfigDialog && this.state.error) {\n window.alert(I18n.t('jc_Cannot save configuration because of error in configuration'));\n saveConfigDialog = false;\n }\n if (saveConfigDialog && !this.state.changed && !changed) {\n saveConfigDialog = false;\n }\n if (data) {\n this.setState({ data, changed: !!changed, saveConfigDialog });\n } else if (saveConfigDialog !== undefined) {\n this.setState({ saveConfigDialog });\n }\n }}\n DeviceManager={this.props.DeviceManager}\n theme={this.state.theme}\n customComponents={this.props.customComponents}\n imagePrefix={'.'}\n />\n <SaveCloseButtons\n isIFrame={false}\n dense\n paddingLeft={0}\n newReact\n theme={this.state.theme}\n noTextOnButtons={\n this.props.width === 'xs' || this.props.width === 'sm' || this.props.width === 'md'\n }\n changed={!!(this.state.error || this.state.changed)}\n error={!!this.state.error}\n onSave={(close: boolean) => this.onSave(true, close)}\n onClose={() => this.onSave(false)}\n />\n </div>\n );\n }\n}\n\nexport default JsonConfig;\n"]}
1
+ {"version":3,"file":"JsonConfig.js","sourceRoot":"src/","sources":["JsonConfig.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\nimport JSON5 from 'json5';\nimport MD5 from 'crypto-js/md5';\n\nimport { Box, Fab, Tooltip, LinearProgress } from '@mui/material';\nimport { Publish as PublishIcon } from '@mui/icons-material';\n\nimport {\n I18n,\n Router,\n SaveCloseButtons,\n Theme,\n DialogConfirm,\n type AdminConnection,\n type IobTheme,\n type ThemeName,\n type ThemeType,\n Utils,\n} from '@iobroker/gui-components';\n\nimport type { ConfigItemAny, ConfigItemPanel, ConfigItemTabs } from './types';\nimport ConfigGeneric, {\n type ConfigGenericProps,\n type DeviceManagerPropsProps,\n} from './JsonConfigComponent/ConfigGeneric';\nimport JsonConfigComponent from './JsonConfigComponent';\n\nconst styles: Record<string, React.CSSProperties> = {\n root: {\n width: '100%',\n height: '100%',\n overflow: 'hidden',\n position: 'relative',\n },\n scroll: {\n height: 'calc(100% - 48px)',\n overflowY: 'auto',\n },\n exportImportButtons: {\n position: 'absolute',\n top: 5,\n right: 0,\n zIndex: 3,\n },\n button: {\n marginRight: '5px',\n },\n tooltip: {\n pointerEvents: 'none',\n },\n};\n\n/**\n * Decrypt the password/value with given key\n *\n * @param key - Secret key\n * @param value - value to decrypt\n */\nfunction decryptLegacy(key: string, value: string): string {\n let result = '';\n for (let i = 0; i < value.length; i++) {\n result += String.fromCharCode(key[i % key.length].charCodeAt(0) ^ value.charCodeAt(i));\n }\n return result;\n}\n\n/**\n * Encrypt the password/value with given key\n *\n * @param key - Secret key\n * @param value - value to encrypt\n */\nfunction encryptLegacy(key: string, value: string): string {\n let result = '';\n for (let i = 0; i < value.length; i++) {\n result += String.fromCharCode(key[i % key.length].charCodeAt(0) ^ value.charCodeAt(i));\n }\n return result;\n}\n\n/**\n * Decrypt the password/value with the given key\n * Usage:\n * ```js\n * function load(settings, onChange) {\n * if (settings.password) {\n * settings.password = decrypt(systemSecret, settings.password);\n * // same as\n * settings.password = decrypt(settings.password);\n * }\n * // ...\n * }\n * ```\n *\n * @param key - Secret key\n * @param value - value to decrypt\n */\nfunction decrypt(key: string, value: string): string {\n if (typeof value !== 'string') {\n return value;\n }\n\n // if not encrypted as aes-192 or key not a valid 48-digit hex -> fallback\n if (!value.startsWith('$/aes-192-cbc:') || !/^[0-9a-f]{48}$/.test(key)) {\n return decryptLegacy(key, value);\n }\n\n // algorithm:iv:encryptedValue\n const textParts = value.split(':', 3);\n\n const _key = window.CryptoJS.enc.Hex.parse(key);\n const iv = window.CryptoJS.enc.Hex.parse(textParts[1]);\n\n const cipherParams = window.CryptoJS.lib.CipherParams.create({\n ciphertext: window.CryptoJS.enc.Hex.parse(textParts[2]),\n });\n\n const decryptedBinary = window.CryptoJS.AES.decrypt(cipherParams, _key, { iv });\n\n return window.CryptoJS.enc.Utf8.stringify(decryptedBinary);\n}\n\n/**\n * Encrypt the password/value with given key\n * Usage:\n * ```\n * function save(callback) {\n * ...\n * if (obj.password) {\n * obj.password = encrypt(systemSecret, obj.password);\n * // same as\n * obj.password = decrypt(obj.password);\n * }\n * ...\n * }\n * ```\n *\n * @param key - Secret key\n * @param value - value to encrypt\n * @param _iv - optional initial vector for tests\n */\nfunction encrypt(key: string, value: string, _iv?: string): string {\n if (typeof value !== 'string') {\n return value;\n }\n\n if (!/^[0-9a-f]{48}$/.test(key)) {\n // key length is not matching for AES-192-CBC, or key is no valid hex - fallback to old encryption\n return encryptLegacy(key, value);\n }\n\n let iv;\n if (_iv) {\n iv = window.CryptoJS.enc.Hex.parse(_iv);\n } else {\n iv = window.CryptoJS.lib.WordArray.random(128 / 8);\n }\n\n const _key = window.CryptoJS.enc.Hex.parse(key);\n const encrypted = window.CryptoJS.AES.encrypt(value, _key, { iv }).ciphertext;\n\n return `$/aes-192-cbc:${window.CryptoJS.enc.Hex.stringify(iv)}:${encrypted}`;\n}\n\nfunction loadScript(\n src: string,\n id: string,\n): ((this: GlobalEventHandlers, ev: Event) => any) | null | undefined | Promise<void> {\n if (!id || !document.getElementById(id)) {\n return new Promise(resolve => {\n const script = document.createElement('script');\n script.setAttribute('id', id);\n script.onload = resolve as unknown as (this: GlobalEventHandlers, ev: Event) => any;\n script.src = src;\n document.getElementsByTagName('head')[0].appendChild(script);\n });\n }\n return document.getElementById(id)?.onload;\n}\n\ninterface BufferObject {\n type: 'Buffer';\n data: Buffer;\n}\n\ninterface JsonConfigProps {\n adapterName: string;\n instance: number;\n isFloatComma: boolean;\n dateFormat: string;\n secret?: string;\n socket: AdminConnection;\n theme: IobTheme;\n themeName: ThemeName;\n themeType: ThemeType;\n expertMode?: boolean;\n /** Translate method */\n t: typeof I18n.t;\n configStored: (notChanged: boolean) => void;\n width: 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n DeviceManager?: React.FC<DeviceManagerPropsProps>;\n customComponents?: { [componentType: string]: typeof ConfigGeneric<ConfigGenericProps, any> };\n}\n\ninterface JsonConfigState {\n schema?: ConfigItemPanel | ConfigItemTabs;\n data?: Record<string, unknown>;\n originalData?: Record<string, unknown>;\n updateData: number;\n common?: ioBroker.InstanceCommon;\n changed: boolean;\n confirmDialog: boolean;\n theme: IobTheme;\n saveConfigDialog: boolean;\n hash: string;\n error?: boolean;\n}\n\nclass JsonConfig extends Router<JsonConfigProps, JsonConfigState> {\n private fileSubscribed: string[] = [];\n\n private fileLangSubscribed = '';\n\n private secret: string;\n\n constructor(props: JsonConfigProps) {\n super(props);\n\n this.state = {\n updateData: 0,\n changed: false,\n confirmDialog: false,\n theme: Theme(props.themeName), // buttons require special theme\n saveConfigDialog: false,\n hash: '_',\n };\n\n this.secret = props.secret || '';\n\n void this.getInstanceObject().then(obj =>\n this.getConfigFile().then(schema =>\n // load language\n JsonConfigComponent.loadI18n(this.props.socket, schema?.i18n, this.props.adapterName).then(\n (langFileName: string) => {\n if (langFileName) {\n // subscribe on changes\n if (!this.fileLangSubscribed) {\n this.fileLangSubscribed = langFileName;\n void this.props.socket.subscribeFiles(\n `${this.props.adapterName}.admin`,\n this.fileLangSubscribed,\n this.onFileChange,\n );\n }\n }\n\n if (obj) {\n this.setState({\n schema: schema || undefined,\n data: obj.native,\n common: obj.common,\n hash: MD5(JSON.stringify(schema)).toString(),\n });\n } else {\n window.alert(\n `Instance system.adapter.${this.props.adapterName}.${this.props.instance} not found!`,\n );\n }\n },\n ),\n ),\n );\n }\n\n componentWillUnmount(): void {\n super.componentWillUnmount();\n if (this.fileSubscribed.length) {\n this.props.socket.unsubscribeFiles(\n `${this.props.adapterName}.admin`,\n this.fileSubscribed,\n this.onFileChange,\n );\n this.fileSubscribed = [];\n }\n if (this.fileLangSubscribed) {\n this.props.socket.unsubscribeFiles(\n `${this.props.adapterName}.admin`,\n this.fileLangSubscribed,\n this.onFileChange,\n );\n this.fileLangSubscribed = '';\n }\n }\n\n private handleFileSelect = (evt: Record<string, any>): void => {\n const f = evt.target.files[0];\n if (f) {\n const r = new FileReader();\n r.onload = (e: ProgressEvent<FileReader>): void => {\n if (!e.target) {\n return;\n }\n\n const contents = e.target.result as string;\n try {\n const data = JSON.parse(contents);\n this.setState({ data, changed: JSON.stringify(data) !== JSON.stringify(this.state.originalData) });\n } catch {\n window.alert(I18n.t('jc_[JsonConfig] Failed to parse JSON file'));\n }\n };\n r.readAsText(f);\n } else {\n window.alert(I18n.t('jc_[JsonConfig] Failed to open JSON File'));\n }\n };\n\n getExportImportButtons(): React.JSX.Element {\n return (\n <Box\n sx={{\n ...styles.exportImportButtons,\n // On xs displays the buttons would hide the tabs, so do not show them there\n display: { xs: 'none', sm: 'block' },\n }}\n >\n <Tooltip\n title={this.props.t('jc_Import settings from JSON file')}\n slotProps={{ popper: { sx: styles.tooltip } }}\n >\n <Fab\n size=\"small\"\n sx={{ '&.MuiFab-root': styles.button }}\n onClick={() => {\n const input = document.createElement('input');\n input.setAttribute('type', 'file');\n input.setAttribute('id', 'files');\n // @ts-expect-error check\n input.setAttribute('opacity', 0);\n input.addEventListener('change', e => this.handleFileSelect(e), false);\n input.click();\n }}\n >\n <PublishIcon />\n </Fab>\n </Tooltip>\n <Tooltip\n title={this.props.t('jc_Export setting to JSON file')}\n slotProps={{ popper: { sx: styles.tooltip } }}\n >\n <Fab\n size=\"small\"\n sx={{ '&.MuiFab-root': styles.button }}\n onClick={() => {\n if (!this.state.data) {\n return;\n }\n\n Utils.generateFile(\n `${this.props.adapterName}.${this.props.instance}.json`,\n this.state.data,\n );\n }}\n >\n <PublishIcon style={{ transform: 'rotate(180deg)' }} />\n </Fab>\n </Tooltip>\n </Box>\n );\n }\n\n onFileChange = async (id: string, fileName: string, size: number | null): Promise<void> => {\n if (id === `${this.props.adapterName}.admin` && size) {\n if (fileName === this.fileLangSubscribed) {\n try {\n await JsonConfigComponent.loadI18n(\n this.props.socket,\n this.state.schema?.i18n,\n this.props.adapterName,\n );\n this.setState({ hash: `${this.state.hash}1` });\n } catch {\n // ignore errors\n }\n } else if (this.fileSubscribed.includes(fileName)) {\n try {\n const schema = await this.getConfigFile(this.fileSubscribed[0]);\n this.setState({ schema: schema || undefined, hash: MD5(JSON.stringify(schema)).toString() });\n } catch {\n // ignore errors\n }\n }\n }\n };\n\n async getInstanceObject(): Promise<ioBroker.InstanceObject | null> {\n try {\n const obj = await this.props.socket.getObject(\n `system.adapter.${this.props.adapterName}.${this.props.instance}`,\n );\n // decode all native attributes listed in obj.encryptedNative\n if (Array.isArray(obj?.encryptedNative)) {\n if (!this.secret) {\n const systemConfig = await this.props.socket.getSystemConfig();\n await loadScript('../../lib/js/crypto-js/crypto-js.js', 'crypto-js');\n this.secret = systemConfig.native.secret;\n }\n obj.encryptedNative?.forEach(attr => {\n if (obj.native[attr]) {\n obj.native[attr] = decrypt(this.secret, obj.native[attr]);\n }\n });\n return obj;\n }\n return obj || null;\n } catch (e) {\n window.alert(`[JsonConfig] Cannot read instance object: ${e}`);\n }\n return null;\n }\n\n renderDialogConfirm(): React.JSX.Element | null {\n if (!this.state.confirmDialog) {\n return null;\n }\n return (\n <DialogConfirm\n title={I18n.t('jc_Please confirm')}\n text={I18n.t('jc_Some data are not stored. Discard?')}\n ok={I18n.t('jc_Discard')}\n cancel={I18n.t('jc_Cancel')}\n onClose={(isYes: boolean) =>\n this.setState({ confirmDialog: false }, () => isYes && Router.doNavigate(null))\n }\n />\n );\n }\n\n async scanForInclude(json: Record<string, any>, filePaths: string[]): Promise<Record<string, any>> {\n if (typeof json['#include'] === 'string') {\n // load file\n const data = await this._getConfigFile(json['#include'], [...filePaths]);\n delete json['#include'];\n if (data) {\n // merge data\n json = { ...json, ...data };\n }\n return json;\n }\n const keys = Object.keys(json);\n for (let k = 0; k < keys.length; k++) {\n if (json[keys[k]] && typeof json[keys[k]] === 'object') {\n json[keys[k]] = await this.scanForInclude(json[keys[k]], filePaths);\n }\n }\n return json;\n }\n\n async getConfigFile(fileName?: string): Promise<ConfigItemPanel | ConfigItemTabs | null> {\n return this._getConfigFile(fileName);\n }\n\n async _getConfigFile(fileName?: string, _filePaths?: string[]): Promise<ConfigItemPanel | ConfigItemTabs | null> {\n fileName = fileName || 'jsonConfig.json5';\n _filePaths = _filePaths || [];\n\n if (_filePaths.includes(fileName)) {\n window.alert(`[JsonConfig] Circular reference in file: ${fileName} => ${_filePaths.join(' => ')}`);\n return null;\n }\n _filePaths.push(fileName);\n\n try {\n const exist = await this.props.socket.fileExists(`${this.props.adapterName}.admin`, fileName);\n if (!exist) {\n fileName = 'jsonConfig.json';\n }\n const data: {\n file: string;\n mimeType: string;\n } = await this.props.socket.readFile(`${this.props.adapterName}.admin`, fileName);\n let content = '';\n let file: string | BufferObject = '';\n\n if (data.file !== undefined) {\n file = data.file;\n }\n\n if (typeof file === 'string') {\n content = file;\n // @ts-expect-error revisit\n } else if (file.type === 'Buffer') {\n let binary = '';\n // @ts-expect-error revisit\n const bytes = new Uint8Array(file.data);\n const len = bytes.byteLength;\n for (let i = 0; i < len; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n content = binary;\n }\n\n // subscribe on changes\n if (!this.fileSubscribed.includes(fileName)) {\n this.fileSubscribed.push(fileName);\n await this.props.socket.subscribeFiles(`${this.props.adapterName}.admin`, fileName, this.onFileChange);\n }\n\n try {\n // detect #include attr\n return (await this.scanForInclude(JSON5.parse(content), _filePaths)) as\n ConfigItemPanel | ConfigItemTabs;\n } catch (e) {\n window.alert('[JsonConfig] Cannot parse json5 config!');\n console.log(e);\n }\n } catch (e1) {\n if (!this.state.schema) {\n window.alert(`[JsonConfig] Cannot read file \"${fileName}: ${e1}`);\n }\n }\n return null;\n }\n\n renderSaveConfigDialog(): React.JSX.Element | null {\n if (!this.state.saveConfigDialog) {\n return null;\n }\n return (\n <DialogConfirm\n title={I18n.t('jc_Please confirm')}\n text={I18n.t('jc_Save configuration?')}\n ok={I18n.t('jc_Save')}\n cancel={I18n.t('jc_Cancel')}\n onClose={(isYes: boolean) =>\n this.setState({ saveConfigDialog: false }, () => isYes && this.onSave(true))\n }\n />\n );\n }\n\n findAttr(attr: string, schema?: ConfigItemPanel | ConfigItemTabs): ConfigItemAny | null {\n schema = schema || this.state.schema;\n if (schema?.items) {\n if (attr in schema.items) {\n return schema.items[attr];\n }\n for (const _item of Object.values(schema.items)) {\n const item = this.findAttr(attr, _item as ConfigItemPanel | ConfigItemTabs);\n if (item) {\n return item;\n }\n }\n }\n\n return null;\n }\n\n // this function is called recursively and trims all text fields that must be trimmed\n postProcessing(data: Record<string, unknown>, attr: string, schema: ConfigItemAny): void {\n schema = schema || this.state.schema;\n if (!data) {\n // should not happen\n console.error(`Data is empty in postProcessing: ${attr}, ${JSON.stringify(schema)}`);\n return;\n }\n\n const dataAttr = data[attr];\n\n if ((schema as ConfigItemTabs).items) {\n if (schema.type === 'table') {\n const table = dataAttr;\n\n if (!Array.isArray(table)) {\n return;\n }\n\n for (const entry of table) {\n if (schema.items) {\n for (const tItem of schema.items) {\n if (tItem.attr) {\n this.postProcessing(entry, tItem.attr, tItem);\n }\n }\n }\n }\n } else {\n for (const [_attr, item] of Object.entries((schema as ConfigItemTabs).items)) {\n if (\n (item as any).type === 'panel' ||\n (item as any).type === 'tabs' ||\n (item as any).type === 'accordion'\n ) {\n return;\n }\n this.postProcessing(data, _attr, item);\n }\n }\n } else if (attr && typeof dataAttr === 'string') {\n // postprocessing\n if (schema.type === 'text') {\n if (schema.trim !== false) {\n data[attr] = dataAttr.trim();\n }\n } else if (schema.type === 'ip') {\n // should not happen\n data[attr] = dataAttr.trim();\n } else if (schema.type === 'number') {\n const dataVal = parseFloat(dataAttr.toString().replace(',', '.'));\n\n if (schema.min !== undefined && dataVal < schema.min) {\n data[attr] = schema.min;\n } else if (schema.max !== undefined && dataVal > schema.max) {\n data[attr] = schema.max;\n } else {\n data[attr] = dataVal;\n }\n } else if (schema.type === 'port') {\n const dataVal = parseInt(dataAttr.toString(), 10);\n if (schema.min !== undefined && dataVal < schema.min) {\n data[attr] = schema.min;\n } else if (schema.max !== undefined && dataVal > schema.max) {\n data[attr] = schema.max;\n }\n if (data[attr] !== 0 && dataVal < 20) {\n data[attr] = 20;\n } else if (dataVal > 0xffff) {\n data[attr] = 0xffff;\n } else {\n data[attr] = dataVal;\n }\n } else if (schema.type === 'checkbox') {\n // should not happen\n data[attr] =\n data[attr] === true ||\n data[attr] === 'true' ||\n data[attr] === 'on' ||\n data[attr] === 1 ||\n data[attr] === '1';\n }\n }\n }\n\n async onSave(doSave: boolean, close?: boolean): Promise<void> {\n if (doSave) {\n const obj = await this.getInstanceObject();\n\n if (!obj) {\n console.error('Something went wrong: may be no connection?');\n window.alert('Something went wrong: may be no connection?');\n return;\n }\n\n if (!this.state.data || !this.state.schema) {\n return;\n }\n\n const doNotSaveAttributes: Record<string, any> = {};\n\n for (const attr of Object.keys(this.state.data)) {\n const item = this.findAttr(attr);\n if ((!item || !item.doNotSave || item.type === 'state') && !attr.startsWith('_')) {\n ConfigGeneric.setValue(obj.native, attr, this.state.data[attr]);\n } else {\n ConfigGeneric.setValue(obj.native, attr, null);\n doNotSaveAttributes[attr] = this.state.data[attr];\n }\n }\n\n try {\n const encryptedObj = JSON.parse(JSON.stringify(obj));\n // encode all native attributes listed in obj.encryptedNative\n if (Array.isArray(encryptedObj.encryptedNative)) {\n await loadScript('../../lib/js/crypto-js/crypto-js.js', 'crypto-js');\n\n for (const attr of encryptedObj.encryptedNative) {\n if (encryptedObj.native[attr]) {\n encryptedObj.native[attr] = encrypt(this.secret, encryptedObj.native[attr]);\n }\n }\n }\n\n await this.props.socket.setObject(encryptedObj._id, encryptedObj);\n } catch (e) {\n window.alert(`[JsonConfig] Cannot set object: ${e}`);\n }\n\n /** We want to preserve the doNotSaveAttributes too, just not save it */\n const nativeWithNonSaved = { ...obj.native, ...doNotSaveAttributes };\n console.log(nativeWithNonSaved);\n\n this.setState(\n {\n changed: false,\n data: nativeWithNonSaved,\n updateData: this.state.updateData + 1,\n originalData: nativeWithNonSaved,\n },\n () => close && Router.doNavigate(null),\n );\n } else if (this.state.changed) {\n this.setState({ confirmDialog: true });\n } else {\n Router.doNavigate(null);\n }\n }\n\n componentDidUpdate(_prevProps: JsonConfigProps, prevState: JsonConfigState): void {\n if (prevState.changed !== this.state.changed) {\n this.props.configStored(!this.state.changed);\n }\n }\n\n /**\n * Validate the JSON config once on mount\n */\n async componentDidMount(): Promise<void> {\n const link = `${window.location.protocol}//${window.location.host}${window.location.pathname}validate_config/${this.props.adapterName}`;\n console.log(`fetch ${link}`);\n await fetch(link);\n }\n\n render(): React.JSX.Element {\n if (!this.state.data || !this.state.schema) {\n return <LinearProgress />;\n }\n\n return (\n <div style={styles.root}>\n {this.renderDialogConfirm()}\n {this.getExportImportButtons()}\n {this.renderSaveConfigDialog()}\n <JsonConfigComponent\n key={this.state.hash}\n style={styles.scroll}\n socket={this.props.socket}\n themeName={this.props.themeName}\n themeType={this.props.themeType}\n adapterName={this.props.adapterName}\n instance={this.props.instance}\n isFloatComma={this.props.isFloatComma}\n dateFormat={this.props.dateFormat}\n schema={this.state.schema}\n common={this.state.common}\n expertMode={this.props.expertMode}\n data={this.state.data}\n updateData={this.state.updateData}\n onError={error => this.setState({ error })}\n onChange={(data, changed, saveConfigDialog) => {\n if (saveConfigDialog && this.state.error) {\n window.alert(I18n.t('jc_Cannot save configuration because of error in configuration'));\n saveConfigDialog = false;\n }\n if (saveConfigDialog && !this.state.changed && !changed) {\n saveConfigDialog = false;\n }\n if (data) {\n this.setState({ data, changed: !!changed, saveConfigDialog });\n } else if (saveConfigDialog !== undefined) {\n this.setState({ saveConfigDialog });\n }\n }}\n DeviceManager={this.props.DeviceManager}\n theme={this.state.theme}\n customComponents={this.props.customComponents}\n imagePrefix={'.'}\n />\n <SaveCloseButtons\n isIFrame={false}\n dense\n paddingLeft={0}\n newReact\n theme={this.state.theme}\n noTextOnButtons={\n this.props.width === 'xs' || this.props.width === 'sm' || this.props.width === 'md'\n }\n changed={!!(this.state.error || this.state.changed)}\n error={!!this.state.error}\n onSave={(close: boolean) => this.onSave(true, close)}\n onClose={() => this.onSave(false)}\n />\n </div>\n );\n }\n}\n\nexport default JsonConfig;\n"]}
@@ -90,8 +90,60 @@ export default class ConfigGeneric<Props extends ConfigGenericProps = ConfigGene
90
90
  private reportedHidden;
91
91
  private calculateTimeout;
92
92
  private readonly AsyncFunction;
93
+ /** Resolved `dependsOnStates` of this element: alias => state ID */
94
+ protected stateAliases: Record<string, string> | null;
95
+ /** True if this element has subscribed on states, so it must unsubscribe if `dependsOnStates` disappears */
96
+ protected statesSubscribed: boolean;
93
97
  constructor(props: Props);
94
98
  protected getCachedObject(id: string): Promise<ioBroker.Object | null>;
99
+ /**
100
+ * Bring the `dependsOnStates` attribute into the form `{ alias: stateID }`.
101
+ * In the short array form the state ID is used as an alias too.
102
+ *
103
+ * @param dependsOnStates value of the `dependsOnStates` attribute
104
+ * @returns aliases with the still unresolved state IDs
105
+ */
106
+ static normalizeDependsOnStates(dependsOnStates: Record<string, string> | string[] | undefined): Record<string, string>;
107
+ /**
108
+ * Build the real state ID out of a `dependsOnStates` entry: resolve the `${data.xxx}` patterns and
109
+ * expand a leading dot (`.info.running`) to the namespace of the own instance.
110
+ *
111
+ * @param id state ID from the schema
112
+ * @returns the resolved state ID or an empty string if it cannot be used
113
+ */
114
+ protected resolveStateId(id: string): Promise<string>;
115
+ /**
116
+ * Resolve all state IDs of a `dependsOnStates` attribute.
117
+ *
118
+ * @param dependsOnStates value of the `dependsOnStates` attribute
119
+ * @returns aliases with the resolved state IDs
120
+ */
121
+ protected resolveDependsOnStates(dependsOnStates: Record<string, string> | string[] | undefined): Promise<Record<string, string>>;
122
+ /**
123
+ * Subscribe on the given state IDs. The promise is resolved as soon as all values are known,
124
+ * so the following calculation does not run with unknown states.
125
+ *
126
+ * @param ids resolved state IDs
127
+ */
128
+ protected subscribeOnStateIds(ids: string[]): Promise<void>;
129
+ /**
130
+ * Resolve the `dependsOnStates` attribute of this element and subscribe on the states.
131
+ *
132
+ * It is called before every calculation and not only once, because a state ID can contain a
133
+ * `${data.xxx}` pattern and so it can change if the user changes the configuration.
134
+ */
135
+ protected updateStateSubscriptions(): Promise<void>;
136
+ /** True if this element depends on ioBroker states */
137
+ protected usesDependsOnStates(): boolean;
138
+ /** One of the states from `dependsOnStates` changed => recalculate `hidden`, `disabled`, ... */
139
+ protected onDependsOnStateChanged: () => void;
140
+ /**
141
+ * Values of the subscribed states for the JS functions and patterns (`_states.<alias>`).
142
+ *
143
+ * @param aliases alias => state ID. If omitted, the aliases of this element are used
144
+ * @returns alias => state object. `null` if the state does not exist
145
+ */
146
+ protected getStateValues(aliases?: Record<string, string> | null): Record<string, ioBroker.State | null>;
95
147
  componentDidMount(): Promise<void>;
96
148
  private defaultSendTo;
97
149
  componentWillUnmount(): void;
@@ -104,7 +156,9 @@ export default class ConfigGeneric<Props extends ConfigGenericProps = ConfigGene
104
156
  getText(text: ioBroker.StringOrTranslated | undefined | null | {
105
157
  /** @deprecated */
106
158
  func: ioBroker.StringOrTranslated;
107
- }, noTranslation?: boolean): string;
159
+ }, noTranslation?: boolean,
160
+ /** Values for `_states`. If omitted, the states of this element are used */
161
+ states?: Record<string, ioBroker.State | null>): string;
108
162
  getTextAsync(text: ioBroker.StringOrTranslated, noTranslation?: boolean): Promise<string>;
109
163
  renderDialogConfirm(): JSX.Element | null;
110
164
  getIcon(iconSettings?: ConfigIconType | null): JSX.Element | null;
@@ -147,8 +201,12 @@ export default class ConfigGeneric<Props extends ConfigGenericProps = ConfigGene
147
201
  * @returns false if the element must not be shown on this host
148
202
  */
149
203
  static isHostAllowed(schema: Pick<ConfigItem, 'os' | 'notOs' | 'docker'>, hostInfo?: JsonConfigHostInfo): boolean;
150
- execute(func: string | boolean | Record<string, string> | undefined, defaultValue: string | number | boolean | undefined, data: Record<string, any> | undefined, arrayIndex: number | undefined, globalData: Record<string, any> | undefined, funcName?: string): Promise<string | number | boolean | undefined>;
151
- executeCustom(func: string | boolean | Record<string, string> | undefined, data: Record<string, any>, customObj: Record<string, any> | undefined, instanceObj: ioBroker.InstanceObject | undefined, arrayIndex: number | undefined, globalData: Record<string, any> | undefined, funcName?: string): Promise<string | boolean | number | null | undefined>;
204
+ execute(func: string | boolean | Record<string, string> | undefined, defaultValue: string | number | boolean | undefined, data: Record<string, any> | undefined, arrayIndex: number | undefined, globalData: Record<string, any> | undefined, funcName?: string,
205
+ /** Values for `_states`. If omitted, the states of this element are used */
206
+ states?: Record<string, ioBroker.State | null>): Promise<string | number | boolean | undefined>;
207
+ executeCustom(func: string | boolean | Record<string, string> | undefined, data: Record<string, any>, customObj: Record<string, any> | undefined, instanceObj: ioBroker.InstanceObject | undefined, arrayIndex: number | undefined, globalData: Record<string, any> | undefined, funcName?: string,
208
+ /** Values for `_states`. If omitted, the states of this element are used */
209
+ states?: Record<string, ioBroker.State | null>): Promise<string | boolean | number | null | undefined>;
152
210
  calculate(schema: Record<string, any>): Promise<{
153
211
  error: boolean;
154
212
  disabled: boolean;
@@ -164,10 +222,14 @@ export default class ConfigGeneric<Props extends ConfigGenericProps = ConfigGene
164
222
  getObject: (id: string) => Promise<ioBroker.Object | null>;
165
223
  getPatternAsync(pattern: string | {
166
224
  func: string;
167
- }, data?: Record<string, any> | null, noTranslation?: boolean): Promise<string>;
225
+ }, data?: Record<string, any> | null, noTranslation?: boolean,
226
+ /** Values for `_states`. If omitted, the states of this element are used */
227
+ states?: Record<string, ioBroker.State | null>): Promise<string>;
168
228
  getPattern(pattern: string | {
169
229
  func: string;
170
- }, data?: Record<string, any>, noTranslation?: boolean): string;
230
+ }, data?: Record<string, any>, noTranslation?: boolean,
231
+ /** Values for `_states`. If omitted, the states of this element are used */
232
+ states?: Record<string, ioBroker.State | null>): string;
171
233
  updateCalculatedValues(): void;
172
234
  render(): string | JSX.Element | null;
173
235
  }