@iobroker/json-config 6.17.12 → 6.17.14

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.
Files changed (61) hide show
  1. package/package.json +27 -27
  2. package/src/JsonConfig.tsx +0 -710
  3. package/src/JsonConfigComponent/ChipInput.tsx +0 -752
  4. package/src/JsonConfigComponent/ConfigAccordion.tsx +0 -278
  5. package/src/JsonConfigComponent/ConfigAlive.tsx +0 -74
  6. package/src/JsonConfigComponent/ConfigAutocomplete.tsx +0 -108
  7. package/src/JsonConfigComponent/ConfigAutocompleteSendTo.tsx +0 -183
  8. package/src/JsonConfigComponent/ConfigCRON.jsx +0 -101
  9. package/src/JsonConfigComponent/ConfigCertCollection.tsx +0 -102
  10. package/src/JsonConfigComponent/ConfigCertificateSelect.tsx +0 -92
  11. package/src/JsonConfigComponent/ConfigCertificates.tsx +0 -202
  12. package/src/JsonConfigComponent/ConfigCheckLicense.jsx +0 -662
  13. package/src/JsonConfigComponent/ConfigCheckbox.tsx +0 -67
  14. package/src/JsonConfigComponent/ConfigChip.jsx +0 -81
  15. package/src/JsonConfigComponent/ConfigColor.tsx +0 -86
  16. package/src/JsonConfigComponent/ConfigCoordinates.tsx +0 -234
  17. package/src/JsonConfigComponent/ConfigCustom.tsx +0 -246
  18. package/src/JsonConfigComponent/ConfigDatePicker.tsx +0 -48
  19. package/src/JsonConfigComponent/ConfigDeviceManager.tsx +0 -33
  20. package/src/JsonConfigComponent/ConfigFile.jsx +0 -181
  21. package/src/JsonConfigComponent/ConfigFileSelector.jsx +0 -520
  22. package/src/JsonConfigComponent/ConfigFunc.jsx +0 -90
  23. package/src/JsonConfigComponent/ConfigGeneric.tsx +0 -1027
  24. package/src/JsonConfigComponent/ConfigIP.jsx +0 -96
  25. package/src/JsonConfigComponent/ConfigImageSendTo.jsx +0 -79
  26. package/src/JsonConfigComponent/ConfigImageUpload.jsx +0 -114
  27. package/src/JsonConfigComponent/ConfigInstanceSelect.jsx +0 -172
  28. package/src/JsonConfigComponent/ConfigInterface.jsx +0 -112
  29. package/src/JsonConfigComponent/ConfigJsonEditor.jsx +0 -103
  30. package/src/JsonConfigComponent/ConfigLanguage.tsx +0 -153
  31. package/src/JsonConfigComponent/ConfigLicense.jsx +0 -148
  32. package/src/JsonConfigComponent/ConfigNumber.tsx +0 -207
  33. package/src/JsonConfigComponent/ConfigObjectId.jsx +0 -113
  34. package/src/JsonConfigComponent/ConfigPanel.tsx +0 -360
  35. package/src/JsonConfigComponent/ConfigPassword.jsx +0 -160
  36. package/src/JsonConfigComponent/ConfigPattern.jsx +0 -50
  37. package/src/JsonConfigComponent/ConfigPort.tsx +0 -232
  38. package/src/JsonConfigComponent/ConfigRoom.jsx +0 -90
  39. package/src/JsonConfigComponent/ConfigSelect.jsx +0 -124
  40. package/src/JsonConfigComponent/ConfigSelectSendTo.tsx +0 -251
  41. package/src/JsonConfigComponent/ConfigSendto.tsx +0 -340
  42. package/src/JsonConfigComponent/ConfigSetState.jsx +0 -116
  43. package/src/JsonConfigComponent/ConfigSlider.jsx +0 -97
  44. package/src/JsonConfigComponent/ConfigStaticDivider.jsx +0 -51
  45. package/src/JsonConfigComponent/ConfigStaticHeader.jsx +0 -63
  46. package/src/JsonConfigComponent/ConfigStaticImage.jsx +0 -48
  47. package/src/JsonConfigComponent/ConfigStaticText.jsx +0 -72
  48. package/src/JsonConfigComponent/ConfigTable.tsx +0 -1040
  49. package/src/JsonConfigComponent/ConfigTabs.tsx +0 -150
  50. package/src/JsonConfigComponent/ConfigText.tsx +0 -188
  51. package/src/JsonConfigComponent/ConfigTextSendTo.tsx +0 -102
  52. package/src/JsonConfigComponent/ConfigTimePicker.tsx +0 -63
  53. package/src/JsonConfigComponent/ConfigTopic.jsx +0 -78
  54. package/src/JsonConfigComponent/ConfigUUID.tsx +0 -55
  55. package/src/JsonConfigComponent/ConfigUser.jsx +0 -104
  56. package/src/JsonConfigComponent/index.tsx +0 -435
  57. package/src/JsonConfigComponent/wrapper/Components/CustomModal.jsx +0 -145
  58. package/src/JsonConfigComponent/wrapper/Components/Editor.jsx +0 -65
  59. package/src/Utils.jsx +0 -1683
  60. package/src/index.tsx +0 -14
  61. package/src/types.d.ts +0 -372
@@ -1,278 +0,0 @@
1
- import React from 'react';
2
- import { withStyles } from '@mui/styles';
3
-
4
- import {
5
- FormHelperText,
6
- Accordion, AccordionSummary, AccordionDetails,
7
- IconButton, Paper,
8
- Toolbar, Tooltip,
9
- Typography, type Theme,
10
- } from '@mui/material';
11
-
12
- import {
13
- Add as AddIcon,
14
- Delete as DeleteIcon,
15
- ArrowUpward as UpIcon,
16
- ArrowDownward as DownIcon,
17
- ContentCopy as CopyContentIcon,
18
- ExpandMore as ExpandMoreIcon,
19
- } from '@mui/icons-material';
20
-
21
- import { Utils, I18n } from '@iobroker/adapter-react-v5';
22
-
23
- import ConfigGeneric, { type ConfigGenericProps, type ConfigGenericState } from './ConfigGeneric';
24
- // eslint-disable-next-line import/no-cycle
25
- import ConfigPanel from './ConfigPanel';
26
- import type {ConfigItemAccordion, ConfigItemIndexed, ConfigItemPanel} from "#JC/types";
27
-
28
- const styles: Record<string, any> = (theme: Theme) => ({
29
- fullWidth: {
30
- width: '100%',
31
- },
32
- accordionSummary: {
33
- backgroundColor: theme.palette.mode === 'dark' ? 'rgba(255, 255, 255, 0.08)' : 'rgba(0, 0, 0, 0.08)',
34
- },
35
- accordionTitle: {
36
- // fontWeight: 'bold',
37
- },
38
- toolbar: {
39
- backgroundColor: theme.palette.mode === 'dark' ? 'rgba(255, 255, 255, 0.08)' : 'rgba(0, 0, 0, 0.08)',
40
- borderRadius: 3,
41
- },
42
- });
43
-
44
- interface ConfigAccordionProps extends ConfigGenericProps {
45
- schema: ConfigItemAccordion;
46
- }
47
-
48
- interface ConfigAccordionState extends ConfigGenericState {
49
- value: Record<string, any>[];
50
- activeIndex: number;
51
- iteration: number;
52
- }
53
-
54
- class ConfigAccordion extends ConfigGeneric<ConfigAccordionProps, ConfigAccordionState> {
55
- private typingTimer: ReturnType<typeof setTimeout> | null = null;
56
-
57
- constructor(props: ConfigAccordionProps) {
58
- super(props);
59
- this.props.schema.items = this.props.schema.items || [];
60
- }
61
-
62
- async componentDidMount() {
63
- super.componentDidMount();
64
-
65
- let value = ConfigGeneric.getValue(this.props.data, this.props.attr) || [];
66
-
67
- if (!Array.isArray(value)) {
68
- value = [];
69
- }
70
-
71
- this.setState({
72
- value,
73
- activeIndex: -1,
74
- iteration: 0,
75
- });
76
- }
77
-
78
- componentWillUnmount() {
79
- this.typingTimer && clearTimeout(this.typingTimer);
80
- this.typingTimer = null;
81
- super.componentWillUnmount();
82
- }
83
-
84
- itemAccordion(data: Record<string, any>, idx: number) {
85
- const { value } = this.state;
86
- const { schema } = this.props;
87
-
88
- const schemaItem: ConfigItemPanel = {
89
- type: 'panel',
90
- items: schema.items.reduce((accumulator: Record<string, ConfigItemIndexed>, currentValue: ConfigItemIndexed) => {
91
- accumulator[currentValue.attr] = currentValue;
92
- return accumulator;
93
- }, {}),
94
- style: { marginLeft: -8, marginTop: 10, marginBottom: 10 },
95
- };
96
-
97
- return <ConfigPanel
98
- index={idx + this.state.iteration}
99
- arrayIndex={idx}
100
- changed={this.props.changed}
101
- globalData={this.props.data}
102
- socket={this.props.socket}
103
- adapterName={this.props.adapterName}
104
- instance={this.props.instance}
105
- common={this.props.common}
106
- alive={this.props.alive}
107
- themeType={this.props.themeType}
108
- themeName={this.props.themeName}
109
- data={data}
110
- custom
111
- schema={schemaItem}
112
- systemConfig={this.props.systemConfig}
113
- originalData={this.props.originalData}
114
- customs={this.props.customs}
115
- dateFormat={this.props.dateFormat}
116
- isFloatComma={this.props.isFloatComma}
117
- forceUpdate={this.props.forceUpdate}
118
- imagePrefix={this.props.imagePrefix}
119
- onCommandRunning={this.props.onCommandRunning}
120
- onChange={(attr, valueChange) => {
121
- const newObj = JSON.parse(JSON.stringify(value));
122
- (newObj[idx] as Record<string, any>)[attr as string] = valueChange;
123
- this.setState({ value: newObj }, () =>
124
- this.onChangeWrapper(newObj));
125
- }}
126
- onError={(error, attr) => this.onError(error, attr)}
127
- table={this.props.table}
128
- />;
129
- }
130
-
131
- onDelete = (index: number) => () => {
132
- const newValue = JSON.parse(JSON.stringify(this.state.value));
133
- newValue.splice(index, 1);
134
-
135
- this.setState({ value: newValue, iteration: this.state.iteration + 10000 }, () => this.onChangeWrapper(newValue));
136
- };
137
-
138
- onClone = (index: number) => () => {
139
- const newValue = JSON.parse(JSON.stringify(this.state.value)) as Record<string, any>[];
140
- const cloned = JSON.parse(JSON.stringify(newValue[index]));
141
- if (typeof this.props.schema.clone === 'string' && typeof cloned[this.props.schema.clone] === 'string') {
142
- let i = 1;
143
- let text = cloned[this.props.schema.clone];
144
- const pattern = text.match(/(\d+)$/);
145
- if (pattern) {
146
- text = text.replace(pattern[0], '');
147
- i = parseInt(pattern[0], 10) + 1;
148
- } else {
149
- text += '_';
150
- }
151
- // eslint-disable-next-line no-loop-func
152
- while (newValue.find(it => it[this.props.schema.clone as string] === text + i.toString())) {
153
- i++;
154
- }
155
- cloned[this.props.schema.clone] = `${cloned[this.props.schema.clone]}_${i}`;
156
- }
157
-
158
- newValue.splice(index, 0, cloned);
159
-
160
- this.setState({ value: newValue, activeIndex: -1, iteration: this.state.iteration + 10000 }, () => this.onChangeWrapper(newValue));
161
- };
162
-
163
- onChangeWrapper = (newValue: any) => {
164
- this.typingTimer && clearTimeout(this.typingTimer);
165
-
166
- this.typingTimer = setTimeout(value => {
167
- this.typingTimer = null;
168
-
169
- this.onChange(this.props.attr, value);
170
- }, 300, newValue);
171
- };
172
-
173
- onAdd = () => {
174
- const { schema } = this.props;
175
- const newValue = JSON.parse(JSON.stringify(this.state.value));
176
- const newItem: Record<string, any> = schema.items && schema.items.reduce((accumulator: Record<string, any>, currentValue: ConfigItemIndexed) => {
177
- let defaultValue;
178
- if (currentValue.defaultFunc) {
179
- if (this.props.custom) {
180
- defaultValue = currentValue.defaultFunc ? this.executeCustom(currentValue.defaultFunc, this.props.data, this.props.customObj, this.props.instanceObj, newValue.length, this.props.data) : this.props.schema.default;
181
- } else {
182
- defaultValue = currentValue.defaultFunc ? this.execute(currentValue.defaultFunc, this.props.schema.default, this.props.data, newValue.length, this.props.data) : this.props.schema.default;
183
- }
184
- } else {
185
- defaultValue = currentValue.default === undefined ? null : currentValue.default;
186
- }
187
-
188
- accumulator[currentValue.attr] = defaultValue;
189
- return accumulator;
190
- }, {});
191
-
192
- newValue.push(newItem);
193
-
194
- this.setState({ value: newValue, activeIndex: newValue.length - 1 }, () => this.onChangeWrapper(newValue));
195
- };
196
-
197
- onMoveUp(idx: number) {
198
- const newValue = JSON.parse(JSON.stringify(this.state.value));
199
- const item = newValue[idx];
200
- newValue.splice(idx, 1);
201
- newValue.splice(idx - 1, 0, item);
202
-
203
- const newIndex = this.state.activeIndex - 1;
204
- this.setState({ value: newValue, activeIndex: newIndex, iteration: this.state.iteration + 10000 }, () => this.onChangeWrapper(newValue));
205
- }
206
-
207
- onMoveDown(idx: number) {
208
- const newValue = JSON.parse(JSON.stringify(this.state.value));
209
- const item = newValue[idx];
210
- newValue.splice(idx, 1);
211
- newValue.splice(idx + 1, 0, item);
212
-
213
- const newIndex = this.state.activeIndex + 1;
214
- this.setState({ value: newValue, activeIndex: newIndex, iteration: this.state.iteration + 10000 }, () => this.onChangeWrapper(newValue));
215
- }
216
-
217
- renderItem(/* error, disabled, defaultValue */) {
218
- const { classes, schema } = this.props;
219
- const { value } = this.state;
220
-
221
- if (!value) {
222
- return null;
223
- }
224
-
225
- return <Paper>
226
- {schema.label || !schema.noDelete ? <Toolbar variant="dense">
227
- {schema.label ? <Typography className={classes.title} variant="h6" id="tableTitle" component="div">
228
- {this.getText(schema.label)}
229
- </Typography> : null}
230
- {!schema.noDelete ? <IconButton size="small" color="primary" onClick={this.onAdd}>
231
- <AddIcon />
232
- </IconButton> : null}
233
- </Toolbar> : null}
234
- {value.map((idx, i) =>
235
- <Accordion key={`${idx}_${i}`} expanded={this.state.activeIndex === i} onChange={(e, expanded) => { this.setState({ activeIndex: expanded ? i : -1 }); }}>
236
- <AccordionSummary
237
- expandIcon={<ExpandMoreIcon />}
238
- className={Utils.clsx(classes.fullWidth, classes.accordionSummary)}
239
- >
240
- <Typography className={classes.accordionTitle}>{idx[schema.titleAttr]}</Typography>
241
- </AccordionSummary>
242
- <AccordionDetails style={({ ...schema.style, ...(this.props.themeType ? schema.darkStyle : {}) })}>
243
- {this.itemAccordion(value[i], i)}
244
- <Toolbar className={classes.toolbar}>
245
- {i ? <Tooltip title={I18n.t('ra_Move up')}>
246
- <IconButton size="small" onClick={() => this.onMoveUp(i)}>
247
- <UpIcon />
248
- </IconButton>
249
- </Tooltip> : <div className={classes.buttonEmpty} />}
250
- {i < value.length - 1 ? <Tooltip title={I18n.t('ra_Move down')}>
251
- <IconButton size="small" onClick={() => this.onMoveDown(i)}>
252
- <DownIcon />
253
- </IconButton>
254
- </Tooltip> : <div className={classes.buttonEmpty} />}
255
- {!schema.noDelete ? <Tooltip title={I18n.t('ra_Delete current row')}>
256
- <IconButton size="small" onClick={this.onDelete(i)}>
257
- <DeleteIcon />
258
- </IconButton>
259
- </Tooltip> : null}
260
- {schema.clone ? <Tooltip title={I18n.t('ra_Clone current row')}>
261
- <IconButton size="small" onClick={this.onClone(i)}>
262
- <CopyContentIcon />
263
- </IconButton>
264
- </Tooltip> : null}
265
- </Toolbar>
266
- </AccordionDetails>
267
- </Accordion>)}
268
- {!schema.noDelete && value.length > 0 ? <Toolbar variant="dense" className={classes.rootTool}>
269
- <IconButton size="small" color="primary" onClick={this.onAdd}>
270
- <AddIcon />
271
- </IconButton>
272
- </Toolbar> : null}
273
- {schema.help ? <FormHelperText>{this.renderHelp(this.props.schema.help, this.props.schema.helpLink, this.props.schema.noTranslation)}</FormHelperText> : null}
274
- </Paper>;
275
- }
276
- }
277
-
278
- export default withStyles(styles)(ConfigAccordion);
@@ -1,74 +0,0 @@
1
- import React from 'react';
2
- import { withStyles } from '@mui/styles';
3
-
4
- import { Utils, I18n } from '@iobroker/adapter-react-v5';
5
- import type { ConfigItemAlive } from '#JC/types';
6
- import ConfigGeneric, { type ConfigGenericProps, type ConfigGenericState } from './ConfigGeneric';
7
-
8
- const styles: Record<string, any> = {
9
- root: {
10
- width: '100%',
11
- },
12
- notAlive: {
13
- color: '#a30000',
14
- },
15
- };
16
-
17
- interface ConfigAliveProps extends ConfigGenericProps {
18
- schema: ConfigItemAlive;
19
- }
20
-
21
- interface ConfigAliveState extends ConfigGenericState {
22
- alive?: boolean | null;
23
- instance?: string;
24
- }
25
-
26
- class ConfigAlive extends ConfigGeneric<ConfigAliveProps, ConfigAliveState> {
27
- componentDidMount() {
28
- super.componentDidMount();
29
-
30
- const instance = this.getInstance();
31
-
32
- this.props.socket.getState(`${instance}.alive`)
33
- .then(state => this.setState({ alive: !!(state && state.val), instance }));
34
- }
35
-
36
- getInstance() {
37
- let instance = this.props.schema.instance || (`${this.props.adapterName}.${this.props.instance}`);
38
- if (instance.includes('${')) {
39
- instance = this.getPattern(instance);
40
- }
41
- if (instance && !instance.startsWith('system.adapter.')) {
42
- instance = `system.adapter.${instance}`;
43
- }
44
- return instance;
45
- }
46
-
47
- renderItem() {
48
- if (this.getInstance() !== this.state.instance) {
49
- setTimeout(() => {
50
- const instance = this.getInstance();
51
- if (instance) {
52
- this.props.socket.getState(`${instance}.alive`)
53
- .then(state => this.setState({ alive: !!(state && state.val), instance }));
54
- } else {
55
- this.setState({ alive: null, instance });
56
- }
57
- }, 200);
58
- }
59
-
60
- if (this.state.alive !== false && this.state.alive !== true) {
61
- return null;
62
- }
63
-
64
- const instance = this.state.instance.replace(/^system.adapter./, '');
65
- return <div className={Utils.clsx(this.props.classes.root, !this.state.alive && this.props.classes.notAlive)}>
66
- {this.state.alive ?
67
- this.props.schema.textAlive !== undefined ? (this.props.schema.textAlive ? I18n.t(this.props.schema.textAlive, instance) : '') : I18n.t('ra_Instance %s is alive', instance)
68
- :
69
- this.props.schema.textNotAlive !== undefined ? (this.props.schema.textNotAlive ? I18n.t(this.props.schema.textNotAlive, instance) : '') : I18n.t('ra_Instance %s is not alive', instance)}
70
- </div>;
71
- }
72
- }
73
-
74
- export default withStyles(styles)(ConfigAlive);
@@ -1,108 +0,0 @@
1
- import React from 'react';
2
- import { withStyles } from '@mui/styles';
3
-
4
- import { Autocomplete, TextField } from '@mui/material';
5
-
6
- import { I18n } from '@iobroker/adapter-react-v5';
7
-
8
- import type { ConfigItemAutocomplete, ConfigItemSelectOption } from '#JC/types';
9
- import ConfigGeneric, { type ConfigGenericState, type ConfigGenericProps } from './ConfigGeneric';
10
-
11
- const styles: Record<string, any> = {
12
- fullWidth: {
13
- width: '100%',
14
- },
15
- };
16
-
17
- export interface ConfigAutocompleteProps extends ConfigGenericProps {
18
- schema: ConfigItemAutocomplete;
19
- }
20
-
21
- export interface ConfigAutocompleteState extends ConfigGenericState {
22
- selectOptions: { value: string; label: string }[];
23
- }
24
-
25
- class ConfigAutocomplete extends ConfigGeneric<ConfigAutocompleteProps, ConfigAutocompleteState> {
26
- componentDidMount(): void {
27
- super.componentDidMount();
28
- const value = ConfigGeneric.getValue(this.props.data, this.props.attr);
29
-
30
- const selectOptions = this.props.schema.options.map((item: any) => (typeof item === 'string' ? { label: item, value: item } : JSON.parse(JSON.stringify(item))));
31
-
32
- // if __different
33
- if (Array.isArray(value)) {
34
- selectOptions.unshift({ label: I18n.t(ConfigGeneric.DIFFERENT_LABEL), value: ConfigGeneric.DIFFERENT_VALUE });
35
- this.setState({ value: ConfigGeneric.DIFFERENT_VALUE, selectOptions });
36
- } else {
37
- this.setState({ value, selectOptions });
38
- }
39
- }
40
-
41
- renderItem(error: unknown, disabled: boolean): React.JSX.Element | null {
42
- if (!this.state.selectOptions) {
43
- return null;
44
- }
45
-
46
- let item;
47
- const options: (string | ConfigItemSelectOption)[] = JSON.parse(JSON.stringify(this.state.selectOptions));
48
- const isIndeterminate = Array.isArray(this.state.value) || this.state.value === ConfigGeneric.DIFFERENT_VALUE;
49
-
50
- if (isIndeterminate) {
51
- [...this.state.value]
52
- .filter(val => !options.find(it => (typeof it === 'object' ? (it as ConfigItemSelectOption).value === val : (it as string) === val)))
53
- .forEach(it => options.push({ label: it.toString(), value: it }));
54
-
55
- item = { label: I18n.t(ConfigGeneric.DIFFERENT_LABEL), value: ConfigGeneric.DIFFERENT_VALUE };
56
- options.unshift(item);
57
- } else {
58
- item = this.state.value !== null &&
59
- this.state.value !== undefined &&
60
- // eslint-disable-next-line eqeqeq
61
- options.find(_item => (typeof _item === 'object' ? _item.value == this.state.value : _item == this.state.value)); // let "==" be and not ===
62
-
63
- if (this.state.value !== null && this.state.value !== undefined && !item && this.props.schema.freeSolo) {
64
- item = { value: this.state.value, label: this.state.value };
65
- options.push(item);
66
- }
67
- }
68
-
69
- return <Autocomplete
70
- className={this.props.classes.indeterminate}
71
- fullWidth
72
- freeSolo={!!this.props.schema.freeSolo}
73
- value={item}
74
- options={options}
75
- // autoComplete
76
- onInputChange={e => {
77
- if (!e || !this.props.schema.freeSolo) {
78
- return;
79
- }
80
-
81
- const val = (e.target as HTMLInputElement).value;
82
- if (val !== this.state.value) {
83
- this.setState({ value: val }, () => this.onChange(this.props.attr, val));
84
- }
85
- }}
86
- onChange={(_, value) => {
87
- const val = typeof value === 'object' ? (value ? value.value : '') : value;
88
- if (val !== this.state.value) {
89
- this.setState({ value: val }, () => this.onChange(this.props.attr, val));
90
- }
91
- }}
92
- getOptionLabel={option => (typeof option === 'object' ? (option?.label ?? '') : '')}
93
- renderInput={params => <TextField
94
- variant="standard"
95
- {...params}
96
- error={!!error}
97
- // inputProps are important and will be given in params
98
- // inputProps={{maxLength: this.props.schema.maxLength || this.props.schema.max || undefined}}
99
- placeholder={this.getText(this.props.schema.placeholder)}
100
- label={this.getText(this.props.schema.label)}
101
- helperText={this.renderHelp(this.props.schema.help, this.props.schema.helpLink, this.props.schema.noTranslation)}
102
- disabled={disabled}
103
- />}
104
- />;
105
- }
106
- }
107
-
108
- export default withStyles(styles)(ConfigAutocomplete);
@@ -1,183 +0,0 @@
1
- import React from 'react';
2
- import { withStyles } from '@mui/styles';
3
-
4
- import { Autocomplete, TextField } from '@mui/material';
5
-
6
- import { I18n } from '@iobroker/adapter-react-v5';
7
-
8
- import type { ConfigItemAutocompleteSendTo } from '#JC/types';
9
- import ConfigGeneric, { type ConfigGenericProps } from './ConfigGeneric';
10
- import type { ConfigAutocompleteState } from './ConfigAutocomplete';
11
-
12
- interface ConfigAutocompleteSendToProps extends ConfigGenericProps {
13
- schema: ConfigItemAutocompleteSendTo;
14
- }
15
-
16
- interface ConfigAutocompleteSendToState extends ConfigAutocompleteState {
17
- context: string;
18
- }
19
-
20
- const styles: Record<string, any> = {
21
- fullWidth: {
22
- width: '100%',
23
- },
24
- };
25
-
26
- class ConfigAutocompleteSendTo extends ConfigGeneric<ConfigAutocompleteSendToProps, ConfigAutocompleteSendToState> {
27
- componentDidMount() {
28
- super.componentDidMount();
29
-
30
- this.askInstance();
31
- }
32
-
33
- askInstance() {
34
- const value = ConfigGeneric.getValue(this.props.data, this.props.attr);
35
- const selectOptions = this.props.schema.options ?
36
- this.props.schema.options.map((item: any) => (typeof item === 'string' ? { label: item, value: item } : JSON.parse(JSON.stringify(item))))
37
- :
38
- [];
39
-
40
- if (this.props.alive) {
41
- let data = this.props.schema.data;
42
- if (data === undefined && this.props.schema.jsonData) {
43
- data = this.getPattern(this.props.schema.jsonData);
44
- try {
45
- if (typeof data === 'string') {
46
- data = JSON.parse(data);
47
- }
48
- } catch (e) {
49
- console.error(`Cannot parse json data: ${data}`);
50
- }
51
- }
52
-
53
- if (data === undefined) {
54
- data = null;
55
- }
56
-
57
- this.props.socket.sendTo(`${this.props.adapterName}.${this.props.instance}`, this.props.schema.command || 'send', data)
58
- .then((list: unknown) => {
59
- if (list && Array.isArray(list)) {
60
- list.forEach(item =>
61
- selectOptions.push(typeof item === 'string' ? { label: item, value: item } : JSON.parse(JSON.stringify(item))));
62
- }
63
-
64
- // if __different
65
- if (Array.isArray(value)) {
66
- selectOptions.unshift({ label: I18n.t(ConfigGeneric.DIFFERENT_LABEL), value: ConfigGeneric.DIFFERENT_VALUE });
67
- this.setState({ value: ConfigGeneric.DIFFERENT_VALUE, selectOptions, context: this.getContext() });
68
- } else {
69
- this.setState({ value, selectOptions, context: this.getContext() });
70
- }
71
- });
72
- } else if (Array.isArray(value)) {
73
- // if __different
74
- selectOptions.unshift({ label: I18n.t(ConfigGeneric.DIFFERENT_LABEL), value: ConfigGeneric.DIFFERENT_VALUE });
75
- this.setState({ value: ConfigGeneric.DIFFERENT_VALUE, selectOptions });
76
- } else {
77
- this.setState({ value, selectOptions });
78
- }
79
- }
80
-
81
- getContext(): string {
82
- const context: Record<string, any> = {};
83
- if (Array.isArray(this.props.schema.alsoDependsOn)) {
84
- this.props.schema.alsoDependsOn.forEach(attr =>
85
- context[attr] = ConfigGeneric.getValue(this.props.data, attr));
86
- }
87
- return JSON.stringify(context);
88
- }
89
-
90
- renderItem(error: unknown, disabled: boolean): React.JSX.Element | null {
91
- if (!this.state.selectOptions) {
92
- return null;
93
- }
94
-
95
- if (this.props.alive) {
96
- const context = this.getContext();
97
- if (context !== this.state.context) {
98
- setTimeout(() => this.askInstance(), 300);
99
- }
100
- }
101
-
102
- let item;
103
- const options = JSON.parse(JSON.stringify(this.state.selectOptions));
104
- const isIndeterminate = Array.isArray(this.state.value) || this.state.value === ConfigGeneric.DIFFERENT_LABEL;
105
-
106
- if (isIndeterminate) {
107
- [...this.state.value]
108
- .filter(val => !options.find((it: any) => it.value === val))
109
- .forEach(it => options.push({ label: it.toString(), value: it }));
110
-
111
- item = { label: I18n.t(ConfigGeneric.DIFFERENT_LABEL), value: ConfigGeneric.DIFFERENT_VALUE };
112
- options.unshift(item);
113
- } else {
114
- item = this.state.value !== null && this.state.value !== undefined &&
115
- // eslint-disable-next-line
116
- options.find((item: any) => item.value == this.state.value); // let "==" be and not ===
117
-
118
- if (this.state.value !== null && this.state.value !== undefined && !item && this.props.schema.freeSolo) {
119
- item = { value: this.state.value, label: this.state.value };
120
- options.push(item);
121
- }
122
- item = item || null;
123
- }
124
-
125
- if (!options.length) {
126
- return <TextField
127
- variant="standard"
128
- fullWidth
129
- value={this.state.value === null || this.state.value === undefined ? '' : this.state.value}
130
- error={!!error}
131
- disabled={disabled}
132
- inputProps={{ maxLength: this.props.schema.maxLength || this.props.schema.max || undefined }}
133
- onChange={e => {
134
- const value = e.target.value;
135
- this.setState({ value }, () =>
136
- this.onChange(this.props.attr, (value || '').trim()));
137
- }}
138
- placeholder={this.getText(this.props.schema.placeholder)}
139
- label={this.getText(this.props.schema.label)}
140
- helperText={this.renderHelp(this.props.schema.help, this.props.schema.helpLink, this.props.schema.noTranslation)}
141
- />;
142
- }
143
- return <Autocomplete
144
- value={item}
145
- fullWidth
146
- freeSolo={!!this.props.schema.freeSolo}
147
- options={options}
148
- // autoComplete
149
- getOptionLabel={option => option?.label ?? ''}
150
- className={this.props.classes.indeterminate}
151
- onInputChange={e => {
152
- if (!e || !this.props.schema.freeSolo) {
153
- return;
154
- }
155
-
156
- const val = (e.target as HTMLInputElement).value;
157
- if (val !== this.state.value) {
158
- this.setState({ value: val }, () => this.onChange(this.props.attr, val));
159
- }
160
- }}
161
- onChange={(_, value) => {
162
- const val = typeof value === 'object' ? (value ? value.value : '') : value;
163
- if (val !== this.state.value) {
164
- this.setState({ value: val }, () => this.onChange(this.props.attr, val));
165
- }
166
- }}
167
- renderInput={params =>
168
- <TextField
169
- variant="standard"
170
- {...params}
171
- // inputProps are important and will be given in params
172
- // inputProps={{maxLength: this.props.schema.maxLength || this.props.schema.max || undefined}}
173
- error={!!error}
174
- placeholder={this.getText(this.props.schema.placeholder)}
175
- label={this.getText(this.props.schema.label)}
176
- helperText={this.renderHelp(this.props.schema.help, this.props.schema.helpLink, this.props.schema.noTranslation)}
177
- disabled={disabled}
178
- />}
179
- />;
180
- }
181
- }
182
-
183
- export default withStyles(styles)(ConfigAutocompleteSendTo);