@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.
- package/package.json +27 -27
- package/src/JsonConfig.tsx +0 -710
- package/src/JsonConfigComponent/ChipInput.tsx +0 -752
- package/src/JsonConfigComponent/ConfigAccordion.tsx +0 -278
- package/src/JsonConfigComponent/ConfigAlive.tsx +0 -74
- package/src/JsonConfigComponent/ConfigAutocomplete.tsx +0 -108
- package/src/JsonConfigComponent/ConfigAutocompleteSendTo.tsx +0 -183
- package/src/JsonConfigComponent/ConfigCRON.jsx +0 -101
- package/src/JsonConfigComponent/ConfigCertCollection.tsx +0 -102
- package/src/JsonConfigComponent/ConfigCertificateSelect.tsx +0 -92
- package/src/JsonConfigComponent/ConfigCertificates.tsx +0 -202
- package/src/JsonConfigComponent/ConfigCheckLicense.jsx +0 -662
- package/src/JsonConfigComponent/ConfigCheckbox.tsx +0 -67
- package/src/JsonConfigComponent/ConfigChip.jsx +0 -81
- package/src/JsonConfigComponent/ConfigColor.tsx +0 -86
- package/src/JsonConfigComponent/ConfigCoordinates.tsx +0 -234
- package/src/JsonConfigComponent/ConfigCustom.tsx +0 -246
- package/src/JsonConfigComponent/ConfigDatePicker.tsx +0 -48
- package/src/JsonConfigComponent/ConfigDeviceManager.tsx +0 -33
- package/src/JsonConfigComponent/ConfigFile.jsx +0 -181
- package/src/JsonConfigComponent/ConfigFileSelector.jsx +0 -520
- package/src/JsonConfigComponent/ConfigFunc.jsx +0 -90
- package/src/JsonConfigComponent/ConfigGeneric.tsx +0 -1027
- package/src/JsonConfigComponent/ConfigIP.jsx +0 -96
- package/src/JsonConfigComponent/ConfigImageSendTo.jsx +0 -79
- package/src/JsonConfigComponent/ConfigImageUpload.jsx +0 -114
- package/src/JsonConfigComponent/ConfigInstanceSelect.jsx +0 -172
- package/src/JsonConfigComponent/ConfigInterface.jsx +0 -112
- package/src/JsonConfigComponent/ConfigJsonEditor.jsx +0 -103
- package/src/JsonConfigComponent/ConfigLanguage.tsx +0 -153
- package/src/JsonConfigComponent/ConfigLicense.jsx +0 -148
- package/src/JsonConfigComponent/ConfigNumber.tsx +0 -207
- package/src/JsonConfigComponent/ConfigObjectId.jsx +0 -113
- package/src/JsonConfigComponent/ConfigPanel.tsx +0 -360
- package/src/JsonConfigComponent/ConfigPassword.jsx +0 -160
- package/src/JsonConfigComponent/ConfigPattern.jsx +0 -50
- package/src/JsonConfigComponent/ConfigPort.tsx +0 -232
- package/src/JsonConfigComponent/ConfigRoom.jsx +0 -90
- package/src/JsonConfigComponent/ConfigSelect.jsx +0 -124
- package/src/JsonConfigComponent/ConfigSelectSendTo.tsx +0 -251
- package/src/JsonConfigComponent/ConfigSendto.tsx +0 -340
- package/src/JsonConfigComponent/ConfigSetState.jsx +0 -116
- package/src/JsonConfigComponent/ConfigSlider.jsx +0 -97
- package/src/JsonConfigComponent/ConfigStaticDivider.jsx +0 -51
- package/src/JsonConfigComponent/ConfigStaticHeader.jsx +0 -63
- package/src/JsonConfigComponent/ConfigStaticImage.jsx +0 -48
- package/src/JsonConfigComponent/ConfigStaticText.jsx +0 -72
- package/src/JsonConfigComponent/ConfigTable.tsx +0 -1040
- package/src/JsonConfigComponent/ConfigTabs.tsx +0 -150
- package/src/JsonConfigComponent/ConfigText.tsx +0 -188
- package/src/JsonConfigComponent/ConfigTextSendTo.tsx +0 -102
- package/src/JsonConfigComponent/ConfigTimePicker.tsx +0 -63
- package/src/JsonConfigComponent/ConfigTopic.jsx +0 -78
- package/src/JsonConfigComponent/ConfigUUID.tsx +0 -55
- package/src/JsonConfigComponent/ConfigUser.jsx +0 -104
- package/src/JsonConfigComponent/index.tsx +0 -435
- package/src/JsonConfigComponent/wrapper/Components/CustomModal.jsx +0 -145
- package/src/JsonConfigComponent/wrapper/Components/Editor.jsx +0 -65
- package/src/Utils.jsx +0 -1683
- package/src/index.tsx +0 -14
- 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);
|