@iobroker/json-config 8.2.8 → 8.2.10
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
|
@@ -563,12 +563,13 @@ See also [OAUTH2.md](OAUTH2.md) for more information.
|
|
|
563
563
|
|
|
564
564
|
object ID: show it with name, color and icon
|
|
565
565
|
|
|
566
|
-
| Property | Description
|
|
567
|
-
|
|
568
|
-
| `types` | Desired type: `channel`, `device`, ... (has only `state` by default). It is plural, because `type` is already occupied.
|
|
569
|
-
| `root` | [optional] Show only this root object and its children
|
|
570
|
-
| `customFilter` | [optional] Cannot be used together with `type` settings. It is an object and not a JSON string.
|
|
571
|
-
| `filterFunc` | [optional] Cannot be used together with `type` settings. It is a function that will be called for every object and must return true or false. Example: `obj.common.type === 'number'`
|
|
566
|
+
| Property | Description |
|
|
567
|
+
|----------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
568
|
+
| `types` | Desired type: `channel`, `device`, ... (has only `state` by default). It is plural, because `type` is already occupied. |
|
|
569
|
+
| `root` | [optional] Show only this root object and its children |
|
|
570
|
+
| `customFilter` | [optional] Cannot be used together with `type` settings. It is an object and not a JSON string. |
|
|
571
|
+
| `filterFunc` | [optional] Cannot be used together with `type` settings. It is a function that will be called for every object and must return true or false. Example: `obj.common.type === 'number'` |
|
|
572
|
+
| `fillOnSelect` | [optional] Fill other config fields when an object ID is selected. Format: `pathInObject=>attr,pathInObject=>attr(X)`. Append `(X)` to overwrite non-empty fields. Example: `common.name=>name,common.color=>color(X)` fills the `name` field with the object's name and overwrites `color` with the object's color. |
|
|
572
573
|
|
|
573
574
|
#### Examples for `customFilter`
|
|
574
575
|
|
|
@@ -1746,8 +1747,12 @@ The schema is used here: https://github.com/SchemaStore/schemastore/blob/6da29cd
|
|
|
1746
1747
|
### **WORK IN PROGRESS**
|
|
1747
1748
|
-->
|
|
1748
1749
|
## Changelog
|
|
1750
|
+
### 8.2.10 (2026-03-20)
|
|
1751
|
+
- (@GermanBluefox) Correcting unit in schema
|
|
1752
|
+
- (@GermanBluefox) Fill other config fields when an object ID is selected
|
|
1753
|
+
|
|
1749
1754
|
### 8.2.8 (2026-03-15)
|
|
1750
|
-
- (@GermanBluefox) Added radio button control for state component ('select')
|
|
1755
|
+
- (@GermanBluefox) Added radio button control for the state component ('select')
|
|
1751
1756
|
|
|
1752
1757
|
### 8.2.7 (2026-03-14)
|
|
1753
1758
|
- (@GermanBluefox) Made the secondary text in 'select' and 'selectSendTo' smaller, italic and semi-transparent
|
|
@@ -9,7 +9,9 @@ interface ConfigObjectIdState extends ConfigGenericState {
|
|
|
9
9
|
initialized?: boolean;
|
|
10
10
|
}
|
|
11
11
|
declare class ConfigObjectId extends ConfigGeneric<ConfigObjectIdProps, ConfigObjectIdState> {
|
|
12
|
+
private fillOnSelect;
|
|
12
13
|
componentDidMount(): void;
|
|
14
|
+
onObjectChanged: (attr: string, value: string) => void;
|
|
13
15
|
renderItem(error: string, disabled: boolean): JSX.Element;
|
|
14
16
|
}
|
|
15
17
|
export default ConfigObjectId;
|
|
@@ -13,12 +13,56 @@ const styles = {
|
|
|
13
13
|
},
|
|
14
14
|
};
|
|
15
15
|
class ConfigObjectId extends ConfigGeneric {
|
|
16
|
+
fillOnSelect = [];
|
|
16
17
|
componentDidMount() {
|
|
17
18
|
super.componentDidMount();
|
|
18
19
|
const { data, attr } = this.props;
|
|
19
20
|
const value = ConfigGeneric.getValue(data, attr) || '';
|
|
21
|
+
if (this.props.schema.fillOnSelect) {
|
|
22
|
+
// parse common.name=>name,common.color=>color(X)
|
|
23
|
+
const items = this.props.schema.fillOnSelect.split(',').map(it => it.trim());
|
|
24
|
+
for (const item of items) {
|
|
25
|
+
const parts = item.split('=>');
|
|
26
|
+
if (parts.length === 2) {
|
|
27
|
+
const fillItem = {
|
|
28
|
+
pathInObject: parts[0],
|
|
29
|
+
attr: parts[1],
|
|
30
|
+
};
|
|
31
|
+
if (fillItem.attr.includes('(X)') || fillItem.attr.includes('(x)')) {
|
|
32
|
+
fillItem.overwrite = true;
|
|
33
|
+
fillItem.attr = fillItem.attr.replace(/\(X\)|\(x\)/g, '');
|
|
34
|
+
}
|
|
35
|
+
this.fillOnSelect.push(fillItem);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
console.error(`Invalid format for fillOnSelect: ${this.props.schema.fillOnSelect}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
20
42
|
this.setState({ value, initialized: true });
|
|
21
43
|
}
|
|
44
|
+
onObjectChanged = (attr, value) => {
|
|
45
|
+
void this.onChange(attr, value, async () => {
|
|
46
|
+
if (this.fillOnSelect.length) {
|
|
47
|
+
try {
|
|
48
|
+
const obj = await this.props.oContext.socket.getObject(value);
|
|
49
|
+
for (const item of this.fillOnSelect) {
|
|
50
|
+
if (item.overwrite || !ConfigGeneric.getValue(this.props.data, item.attr)) {
|
|
51
|
+
let objVal = ConfigGeneric.getValue(obj, item.pathInObject);
|
|
52
|
+
// Special case for translated name
|
|
53
|
+
if (typeof objVal === 'object') {
|
|
54
|
+
objVal = this.getText(objVal, true);
|
|
55
|
+
}
|
|
56
|
+
await this.onChange(item.attr, objVal);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch (e) {
|
|
61
|
+
console.error(e.toString());
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
};
|
|
22
66
|
renderItem(error, disabled /* , defaultValue */) {
|
|
23
67
|
if (!this.state.initialized) {
|
|
24
68
|
return null;
|
|
@@ -30,11 +74,15 @@ class ConfigObjectId extends ConfigGeneric {
|
|
|
30
74
|
schema.label ? React.createElement(InputLabel, { shrink: true }, this.getText(schema.label)) : null,
|
|
31
75
|
React.createElement("div", { style: styles.flex },
|
|
32
76
|
React.createElement(TextField, { variant: "standard", fullWidth: true, value: value, error: !!error, disabled: disabled, placeholder: this.getText(schema.placeholder), label: this.getText(schema.label), helperText: this.renderHelp(schema.help, schema.helpLink, schema.noTranslation), onChange: e => {
|
|
33
|
-
|
|
34
|
-
|
|
77
|
+
// Store it to have the possibility to access it in onObjectChanged
|
|
78
|
+
const value = Array.isArray(e.target.value) ? e.target.value[0] : e.target.value;
|
|
79
|
+
this.setState({ value }, () => this.onObjectChanged(attr, value));
|
|
35
80
|
} }),
|
|
36
81
|
React.createElement(Button, { color: "grey", disabled: disabled, style: styles.button, size: "small", variant: "outlined", onClick: () => this.setState({ showSelectId: true }) }, "...")),
|
|
37
|
-
showSelectId ? (React.createElement(DialogSelectID, { imagePrefix: this.props.oContext.imagePrefix === undefined ? '../..' : this.props.oContext.imagePrefix, dialogName: `admin.${this.props.oContext.adapterName}`, filterFunc: schema.filterFunc, themeType: this.props.oContext.themeType, theme: this.props.oContext.theme, types: schema.types ? (Array.isArray(schema.types) ? schema.types : [schema.types]) : undefined, customFilter: schema.customFilter, filters: schema.filters, socket: socket, selected: value, root: schema.root, onClose: () => this.setState({ showSelectId: false }), onOk: value_ =>
|
|
82
|
+
showSelectId ? (React.createElement(DialogSelectID, { imagePrefix: this.props.oContext.imagePrefix === undefined ? '../..' : this.props.oContext.imagePrefix, dialogName: `admin.${this.props.oContext.adapterName}`, filterFunc: schema.filterFunc, themeType: this.props.oContext.themeType, theme: this.props.oContext.theme, types: schema.types ? (Array.isArray(schema.types) ? schema.types : [schema.types]) : undefined, customFilter: schema.customFilter, filters: schema.filters, socket: socket, selected: value, root: schema.root, onClose: () => this.setState({ showSelectId: false }), onOk: value_ => {
|
|
83
|
+
const val = Array.isArray(value_) ? value_[0] : value_;
|
|
84
|
+
this.setState({ showSelectId: false, value: val }, () => this.onObjectChanged(attr, val));
|
|
85
|
+
} })) : null));
|
|
38
86
|
}
|
|
39
87
|
}
|
|
40
88
|
export default ConfigObjectId;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConfigObjectId.js","sourceRoot":"./src/","sources":["JsonConfigComponent/ConfigObjectId.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE3E,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAG5D,OAAO,aAAmE,MAAM,iBAAiB,CAAC;AAElG,MAAM,MAAM,GAAwC;IAChD,IAAI,EAAE;QACF,OAAO,EAAE,MAAM;KAClB;IACD,MAAM,EAAE;QACJ,SAAS,EAAE,EAAE;QACb,UAAU,EAAE,CAAC;QACb,QAAQ,EAAE,EAAE;KACf;CACJ,CAAC;AAWF,MAAM,cAAe,SAAQ,aAAuD;IAChF,iBAAiB;QACb,KAAK,CAAC,iBAAiB,EAAE,CAAC;QAC1B,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QAClC,MAAM,KAAK,GAAG,aAAa,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;QACvD,IAAI,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,UAAU,CAAC,KAAa,EAAE,QAAiB,CAAC,oBAAoB;QAC5D,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YAC1B,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;QAC1C,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QACpC,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QAE3C,OAAO,CACH,oBAAC,WAAW,IACR,SAAS,QACT,OAAO,EAAC,UAAU;YAEjB,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,oBAAC,UAAU,IAAC,MAAM,UAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAc,CAAC,CAAC,CAAC,IAAI;YACnF,6BAAK,KAAK,EAAE,MAAM,CAAC,IAAI;gBACnB,oBAAC,SAAS,IACN,OAAO,EAAC,UAAU,EAClB,SAAS,QACT,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,CAAC,CAAC,KAAK,EACd,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,EAC7C,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EACjC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,aAAa,CAAC,EAC/E,QAAQ,EAAE,CAAC,CAAC,EAAE;wBACV,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;wBAC9B,IAAI,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;oBACxE,CAAC,GACH;gBACF,oBAAC,MAAM,IACH,KAAK,EAAC,MAAM,EACZ,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,MAAM,CAAC,MAAM,EACpB,IAAI,EAAC,OAAO,EACZ,OAAO,EAAC,UAAU,EAClB,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,UAG/C,CACP;YACL,YAAY,CAAC,CAAC,CAAC,CACZ,oBAAC,cAAc,IACX,WAAW,EACP,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,EAE7F,UAAU,EAAE,SAAS,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,EAAE,EACtD,UAAU,EAAE,MAAM,CAAC,UAAU,EAC7B,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,EACxC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,EAChC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAC/F,YAAY,EAAE,MAAM,CAAC,YAAY,EACjC,OAAO,EAAE,MAAM,CAAC,OAAO,EACvB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,KAAK,EACf,IAAI,EAAE,MAAM,CAAC,IAAI,EACjB,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,EACrD,IAAI,EAAE,MAAM,CAAC,EAAE,CACX,IAAI,CAAC,QAAQ,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,GAE9F,CACL,CAAC,CAAC,CAAC,IAAI,CACE,CACjB,CAAC;IACN,CAAC;CACJ;AAED,eAAe,cAAc,CAAC","sourcesContent":["import React, { type JSX } from 'react';\n\nimport { InputLabel, FormControl, Button, TextField } from '@mui/material';\n\nimport { DialogSelectID } from '@iobroker/adapter-react-v5';\n\nimport type { ConfigItemObjectId } from '../types';\nimport ConfigGeneric, { type ConfigGenericProps, type ConfigGenericState } from './ConfigGeneric';\n\nconst styles: Record<string, React.CSSProperties> = {\n flex: {\n display: 'flex',\n },\n button: {\n maxHeight: 48,\n marginLeft: 4,\n minWidth: 48,\n },\n};\n\ninterface ConfigObjectIdProps extends ConfigGenericProps {\n schema: ConfigItemObjectId;\n}\n\ninterface ConfigObjectIdState extends ConfigGenericState {\n showSelectId?: boolean;\n initialized?: boolean;\n}\n\nclass ConfigObjectId extends ConfigGeneric<ConfigObjectIdProps, ConfigObjectIdState> {\n componentDidMount(): void {\n super.componentDidMount();\n const { data, attr } = this.props;\n const value = ConfigGeneric.getValue(data, attr) || '';\n this.setState({ value, initialized: true });\n }\n\n renderItem(error: string, disabled: boolean /* , defaultValue */): JSX.Element {\n if (!this.state.initialized) {\n return null;\n }\n const socket = this.props.oContext.socket;\n const { schema, attr } = this.props;\n const { value, showSelectId } = this.state;\n\n return (\n <FormControl\n fullWidth\n variant=\"standard\"\n >\n {schema.label ? <InputLabel shrink>{this.getText(schema.label)}</InputLabel> : null}\n <div style={styles.flex}>\n <TextField\n variant=\"standard\"\n fullWidth\n value={value}\n error={!!error}\n disabled={disabled}\n placeholder={this.getText(schema.placeholder)}\n label={this.getText(schema.label)}\n helperText={this.renderHelp(schema.help, schema.helpLink, schema.noTranslation)}\n onChange={e => {\n const value_ = e.target.value;\n this.setState({ value: value_ }, () => this.onChange(attr, value_));\n }}\n />\n <Button\n color=\"grey\"\n disabled={disabled}\n style={styles.button}\n size=\"small\"\n variant=\"outlined\"\n onClick={() => this.setState({ showSelectId: true })}\n >\n ...\n </Button>\n </div>\n {showSelectId ? (\n <DialogSelectID\n imagePrefix={\n this.props.oContext.imagePrefix === undefined ? '../..' : this.props.oContext.imagePrefix\n }\n dialogName={`admin.${this.props.oContext.adapterName}`}\n filterFunc={schema.filterFunc}\n themeType={this.props.oContext.themeType}\n theme={this.props.oContext.theme}\n types={schema.types ? (Array.isArray(schema.types) ? schema.types : [schema.types]) : undefined}\n customFilter={schema.customFilter}\n filters={schema.filters}\n socket={socket}\n selected={value}\n root={schema.root}\n onClose={() => this.setState({ showSelectId: false })}\n onOk={value_ =>\n this.setState({ showSelectId: false, value: value_ }, () => this.onChange(attr, value_))\n }\n />\n ) : null}\n </FormControl>\n );\n }\n}\n\nexport default ConfigObjectId;\n"]}
|
|
1
|
+
{"version":3,"file":"ConfigObjectId.js","sourceRoot":"./src/","sources":["JsonConfigComponent/ConfigObjectId.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { type JSX } from 'react';\n\nimport { InputLabel, FormControl, Button, TextField } from '@mui/material';\n\nimport { DialogSelectID } from '@iobroker/adapter-react-v5';\n\nimport type { ConfigItemObjectId } from '../types';\nimport ConfigGeneric, { type ConfigGenericProps, type ConfigGenericState } from './ConfigGeneric';\n\nconst styles: Record<string, React.CSSProperties> = {\n flex: {\n display: 'flex',\n },\n button: {\n maxHeight: 48,\n marginLeft: 4,\n minWidth: 48,\n },\n};\n\ninterface ConfigObjectIdProps extends ConfigGenericProps {\n schema: ConfigItemObjectId;\n}\n\ninterface ConfigObjectIdState extends ConfigGenericState {\n showSelectId?: boolean;\n initialized?: boolean;\n}\n\nclass ConfigObjectId extends ConfigGeneric<ConfigObjectIdProps, ConfigObjectIdState> {\n private fillOnSelect: { attr: string; pathInObject: string; overwrite?: boolean }[] = [];\n\n componentDidMount(): void {\n super.componentDidMount();\n const { data, attr } = this.props;\n const value = ConfigGeneric.getValue(data, attr) || '';\n if (this.props.schema.fillOnSelect) {\n // parse common.name=>name,common.color=>color(X)\n const items = this.props.schema.fillOnSelect.split(',').map(it => it.trim());\n for (const item of items) {\n const parts = item.split('=>');\n if (parts.length === 2) {\n const fillItem: { attr: string; pathInObject: string; overwrite?: boolean } = {\n pathInObject: parts[0],\n attr: parts[1],\n };\n if (fillItem.attr.includes('(X)') || fillItem.attr.includes('(x)')) {\n fillItem.overwrite = true;\n fillItem.attr = fillItem.attr.replace(/\\(X\\)|\\(x\\)/g, '');\n }\n this.fillOnSelect.push(fillItem);\n } else {\n console.error(`Invalid format for fillOnSelect: ${this.props.schema.fillOnSelect}`);\n }\n }\n }\n\n this.setState({ value, initialized: true });\n }\n\n onObjectChanged = (attr: string, value: string): void => {\n void this.onChange(attr, value, async (): Promise<void> => {\n if (this.fillOnSelect.length) {\n try {\n const obj = await this.props.oContext.socket.getObject(value);\n for (const item of this.fillOnSelect) {\n if (item.overwrite || !ConfigGeneric.getValue(this.props.data, item.attr)) {\n let objVal = ConfigGeneric.getValue(obj, item.pathInObject);\n // Special case for translated name\n if (typeof objVal === 'object') {\n objVal = this.getText(objVal, true);\n }\n await this.onChange(item.attr, objVal);\n }\n }\n } catch (e) {\n console.error(e.toString());\n }\n }\n });\n };\n\n renderItem(error: string, disabled: boolean /* , defaultValue */): JSX.Element {\n if (!this.state.initialized) {\n return null;\n }\n const socket = this.props.oContext.socket;\n const { schema, attr } = this.props;\n const { value, showSelectId } = this.state;\n\n return (\n <FormControl\n fullWidth\n variant=\"standard\"\n >\n {schema.label ? <InputLabel shrink>{this.getText(schema.label)}</InputLabel> : null}\n <div style={styles.flex}>\n <TextField\n variant=\"standard\"\n fullWidth\n value={value}\n error={!!error}\n disabled={disabled}\n placeholder={this.getText(schema.placeholder)}\n label={this.getText(schema.label)}\n helperText={this.renderHelp(schema.help, schema.helpLink, schema.noTranslation)}\n onChange={e => {\n // Store it to have the possibility to access it in onObjectChanged\n const value = Array.isArray(e.target.value) ? e.target.value[0] : e.target.value;\n this.setState({ value }, () => this.onObjectChanged(attr, value));\n }}\n />\n <Button\n color=\"grey\"\n disabled={disabled}\n style={styles.button}\n size=\"small\"\n variant=\"outlined\"\n onClick={() => this.setState({ showSelectId: true })}\n >\n ...\n </Button>\n </div>\n {showSelectId ? (\n <DialogSelectID\n imagePrefix={\n this.props.oContext.imagePrefix === undefined ? '../..' : this.props.oContext.imagePrefix\n }\n dialogName={`admin.${this.props.oContext.adapterName}`}\n filterFunc={schema.filterFunc}\n themeType={this.props.oContext.themeType}\n theme={this.props.oContext.theme}\n types={schema.types ? (Array.isArray(schema.types) ? schema.types : [schema.types]) : undefined}\n customFilter={schema.customFilter}\n filters={schema.filters}\n socket={socket}\n selected={value}\n root={schema.root}\n onClose={() => this.setState({ showSelectId: false })}\n onOk={value_ => {\n const val = Array.isArray(value_) ? value_[0] : value_;\n this.setState({ showSelectId: false, value: val }, () => this.onObjectChanged(attr, val));\n }}\n />\n ) : null}\n </FormControl>\n );\n }\n}\n\nexport default ConfigObjectId;\n"]}
|
package/build/types.d.ts
CHANGED
|
@@ -443,6 +443,8 @@ export interface ConfigItemObjectId extends ConfigItem {
|
|
|
443
443
|
};
|
|
444
444
|
/** Cannot be used together with `type` settings. It is a function that will be called for every object and must return true or false. Example: `obj.common.type === 'number'` */
|
|
445
445
|
filterFunc?: (obj: ioBroker.Object) => boolean;
|
|
446
|
+
/** Special case to fill other field, when the ID is selected. Example "common.name=>name,common.color=>color(X)" - fills the field name and color with object name and colors. The color will be overwritten with the new value event when it is not empty */
|
|
447
|
+
fillOnSelect?: string;
|
|
446
448
|
}
|
|
447
449
|
|
|
448
450
|
export interface ConfigItemSlider extends ConfigItem {
|