@iobroker/json-config 6.17.6 → 6.17.13

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 (173) hide show
  1. package/LICENSE +21 -21
  2. package/build/JsonConfig.d.ts +1 -1
  3. package/build/JsonConfig.js +18 -19
  4. package/build/JsonConfig.js.map +1 -1
  5. package/build/JsonConfigComponent/ChipInput.d.ts +89 -11
  6. package/build/JsonConfigComponent/ChipInput.js +48 -137
  7. package/build/JsonConfigComponent/ChipInput.js.map +1 -1
  8. package/build/JsonConfigComponent/ConfigAccordion.d.ts +7 -14
  9. package/build/JsonConfigComponent/ConfigAccordion.js +10 -21
  10. package/build/JsonConfigComponent/ConfigAccordion.js.map +1 -1
  11. package/build/JsonConfigComponent/ConfigAlive.d.ts +5 -1
  12. package/build/JsonConfigComponent/ConfigAlive.js +0 -1
  13. package/build/JsonConfigComponent/ConfigAlive.js.map +1 -1
  14. package/build/JsonConfigComponent/ConfigAutocomplete.d.ts +5 -29
  15. package/build/JsonConfigComponent/ConfigAutocomplete.js +7 -5
  16. package/build/JsonConfigComponent/ConfigAutocomplete.js.map +1 -1
  17. package/build/JsonConfigComponent/ConfigAutocompleteSendTo.d.ts +5 -14
  18. package/build/JsonConfigComponent/ConfigAutocompleteSendTo.js +3 -3
  19. package/build/JsonConfigComponent/ConfigAutocompleteSendTo.js.map +1 -1
  20. package/build/JsonConfigComponent/ConfigCRON.d.ts +1 -1
  21. package/build/JsonConfigComponent/ConfigCertCollection.d.ts +7 -13
  22. package/build/JsonConfigComponent/ConfigCertCollection.js +8 -18
  23. package/build/JsonConfigComponent/ConfigCertCollection.js.map +1 -1
  24. package/build/JsonConfigComponent/ConfigCertificateSelect.d.ts +7 -13
  25. package/build/JsonConfigComponent/ConfigCertificateSelect.js +5 -18
  26. package/build/JsonConfigComponent/ConfigCertificateSelect.js.map +1 -1
  27. package/build/JsonConfigComponent/ConfigCertificates.d.ts +7 -13
  28. package/build/JsonConfigComponent/ConfigCertificates.js +7 -18
  29. package/build/JsonConfigComponent/ConfigCertificates.js.map +1 -1
  30. package/build/JsonConfigComponent/ConfigCheckbox.d.ts +3 -11
  31. package/build/JsonConfigComponent/ConfigCheckbox.js +2 -2
  32. package/build/JsonConfigComponent/ConfigCheckbox.js.map +1 -1
  33. package/build/JsonConfigComponent/ConfigChip.d.ts +1 -1
  34. package/build/JsonConfigComponent/ConfigColor.d.ts +13 -20
  35. package/build/JsonConfigComponent/ConfigColor.js +9 -23
  36. package/build/JsonConfigComponent/ConfigColor.js.map +1 -1
  37. package/build/JsonConfigComponent/ConfigCoordinates.d.ts +8 -13
  38. package/build/JsonConfigComponent/ConfigCoordinates.js +29 -39
  39. package/build/JsonConfigComponent/ConfigCoordinates.js.map +1 -1
  40. package/build/JsonConfigComponent/ConfigCustom.d.ts +4 -50
  41. package/build/JsonConfigComponent/ConfigCustom.js +0 -1
  42. package/build/JsonConfigComponent/ConfigCustom.js.map +1 -1
  43. package/build/JsonConfigComponent/ConfigDatePicker.d.ts +8 -3
  44. package/build/JsonConfigComponent/ConfigDatePicker.js +21 -13
  45. package/build/JsonConfigComponent/ConfigDatePicker.js.map +1 -1
  46. package/build/JsonConfigComponent/ConfigDeviceManager.d.ts +5 -1
  47. package/build/JsonConfigComponent/ConfigDeviceManager.js +1 -1
  48. package/build/JsonConfigComponent/ConfigDeviceManager.js.map +1 -1
  49. package/build/JsonConfigComponent/ConfigFile.d.ts +1 -1
  50. package/build/JsonConfigComponent/ConfigFunc.d.ts +1 -1
  51. package/build/JsonConfigComponent/ConfigGeneric.d.ts +46 -32
  52. package/build/JsonConfigComponent/ConfigGeneric.js +23 -12
  53. package/build/JsonConfigComponent/ConfigGeneric.js.map +1 -1
  54. package/build/JsonConfigComponent/ConfigIP.d.ts +1 -1
  55. package/build/JsonConfigComponent/ConfigImageSendTo.d.ts +1 -1
  56. package/build/JsonConfigComponent/ConfigInstanceSelect.d.ts +1 -1
  57. package/build/JsonConfigComponent/ConfigInterface.d.ts +1 -1
  58. package/build/JsonConfigComponent/ConfigJsonEditor.d.ts +1 -1
  59. package/build/JsonConfigComponent/ConfigLanguage.d.ts +3 -2
  60. package/build/JsonConfigComponent/ConfigLanguage.js +2 -2
  61. package/build/JsonConfigComponent/ConfigLanguage.js.map +1 -1
  62. package/build/JsonConfigComponent/ConfigNumber.d.ts +3 -13
  63. package/build/JsonConfigComponent/ConfigNumber.js +2 -2
  64. package/build/JsonConfigComponent/ConfigNumber.js.map +1 -1
  65. package/build/JsonConfigComponent/ConfigObjectId.d.ts +1 -1
  66. package/build/JsonConfigComponent/ConfigPanel.d.ts +7 -2
  67. package/build/JsonConfigComponent/ConfigPanel.js +5 -40
  68. package/build/JsonConfigComponent/ConfigPanel.js.map +1 -1
  69. package/build/JsonConfigComponent/ConfigPassword.d.ts +1 -1
  70. package/build/JsonConfigComponent/ConfigPort.d.ts +6 -1
  71. package/build/JsonConfigComponent/ConfigPort.js +2 -3
  72. package/build/JsonConfigComponent/ConfigPort.js.map +1 -1
  73. package/build/JsonConfigComponent/ConfigRoom.d.ts +1 -1
  74. package/build/JsonConfigComponent/ConfigSelect.d.ts +1 -1
  75. package/build/JsonConfigComponent/ConfigSelectSendTo.d.ts +7 -16
  76. package/build/JsonConfigComponent/ConfigSelectSendTo.js +15 -61
  77. package/build/JsonConfigComponent/ConfigSelectSendTo.js.map +1 -1
  78. package/build/JsonConfigComponent/ConfigSendto.d.ts +3 -20
  79. package/build/JsonConfigComponent/ConfigSendto.js +8 -8
  80. package/build/JsonConfigComponent/ConfigSendto.js.map +1 -1
  81. package/build/JsonConfigComponent/ConfigSetState.d.ts +1 -1
  82. package/build/JsonConfigComponent/ConfigSlider.d.ts +1 -1
  83. package/build/JsonConfigComponent/ConfigStaticDivider.d.ts +1 -1
  84. package/build/JsonConfigComponent/ConfigStaticHeader.d.ts +1 -1
  85. package/build/JsonConfigComponent/ConfigStaticImage.d.ts +1 -1
  86. package/build/JsonConfigComponent/ConfigStaticText.d.ts +1 -1
  87. package/build/JsonConfigComponent/ConfigTable.d.ts +4 -25
  88. package/build/JsonConfigComponent/ConfigTable.js +5 -4
  89. package/build/JsonConfigComponent/ConfigTable.js.map +1 -1
  90. package/build/JsonConfigComponent/ConfigTabs.d.ts +8 -33
  91. package/build/JsonConfigComponent/ConfigTabs.js +10 -43
  92. package/build/JsonConfigComponent/ConfigTabs.js.map +1 -1
  93. package/build/JsonConfigComponent/ConfigText.d.ts +7 -13
  94. package/build/JsonConfigComponent/ConfigText.js +13 -18
  95. package/build/JsonConfigComponent/ConfigText.js.map +1 -1
  96. package/build/JsonConfigComponent/ConfigTextSendTo.d.ts +7 -9
  97. package/build/JsonConfigComponent/ConfigTextSendTo.js +11 -21
  98. package/build/JsonConfigComponent/ConfigTextSendTo.js.map +1 -1
  99. package/build/JsonConfigComponent/ConfigTimePicker.d.ts +9 -3
  100. package/build/JsonConfigComponent/ConfigTimePicker.js +28 -18
  101. package/build/JsonConfigComponent/ConfigTimePicker.js.map +1 -1
  102. package/build/JsonConfigComponent/ConfigTopic.d.ts +1 -1
  103. package/build/JsonConfigComponent/ConfigUUID.d.ts +12 -13
  104. package/build/JsonConfigComponent/ConfigUUID.js +1 -6
  105. package/build/JsonConfigComponent/ConfigUUID.js.map +1 -1
  106. package/build/JsonConfigComponent/ConfigUser.d.ts +1 -1
  107. package/build/JsonConfigComponent/index.d.ts +66 -25
  108. package/build/JsonConfigComponent/index.js +48 -61
  109. package/build/JsonConfigComponent/index.js.map +1 -1
  110. package/build/index.d.ts +2 -2
  111. package/build/index.js +2 -2
  112. package/build/index.js.map +1 -1
  113. package/package.json +27 -26
  114. package/src/JsonConfig.tsx +710 -0
  115. package/src/JsonConfigComponent/ChipInput.tsx +752 -0
  116. package/src/JsonConfigComponent/ConfigAccordion.tsx +278 -0
  117. package/src/JsonConfigComponent/ConfigAlive.tsx +74 -0
  118. package/src/JsonConfigComponent/ConfigAutocomplete.tsx +108 -0
  119. package/src/JsonConfigComponent/ConfigAutocompleteSendTo.tsx +183 -0
  120. package/src/JsonConfigComponent/ConfigCRON.jsx +101 -0
  121. package/src/JsonConfigComponent/ConfigCertCollection.tsx +102 -0
  122. package/src/JsonConfigComponent/ConfigCertificateSelect.tsx +92 -0
  123. package/src/JsonConfigComponent/ConfigCertificates.tsx +202 -0
  124. package/src/JsonConfigComponent/ConfigCheckLicense.jsx +662 -0
  125. package/src/JsonConfigComponent/ConfigCheckbox.tsx +67 -0
  126. package/src/JsonConfigComponent/ConfigChip.jsx +81 -0
  127. package/src/JsonConfigComponent/ConfigColor.tsx +86 -0
  128. package/src/JsonConfigComponent/ConfigCoordinates.tsx +234 -0
  129. package/src/JsonConfigComponent/ConfigCustom.tsx +246 -0
  130. package/src/JsonConfigComponent/ConfigDatePicker.tsx +48 -0
  131. package/src/JsonConfigComponent/ConfigDeviceManager.tsx +33 -0
  132. package/src/JsonConfigComponent/ConfigFile.jsx +181 -0
  133. package/src/JsonConfigComponent/ConfigFileSelector.jsx +520 -0
  134. package/src/JsonConfigComponent/ConfigFunc.jsx +90 -0
  135. package/src/JsonConfigComponent/ConfigGeneric.tsx +1027 -0
  136. package/src/JsonConfigComponent/ConfigIP.jsx +96 -0
  137. package/src/JsonConfigComponent/ConfigImageSendTo.jsx +79 -0
  138. package/src/JsonConfigComponent/ConfigImageUpload.jsx +114 -0
  139. package/src/JsonConfigComponent/ConfigInstanceSelect.jsx +172 -0
  140. package/src/JsonConfigComponent/ConfigInterface.jsx +112 -0
  141. package/src/JsonConfigComponent/ConfigJsonEditor.jsx +103 -0
  142. package/src/JsonConfigComponent/ConfigLanguage.tsx +153 -0
  143. package/src/JsonConfigComponent/ConfigLicense.jsx +148 -0
  144. package/src/JsonConfigComponent/ConfigNumber.tsx +207 -0
  145. package/src/JsonConfigComponent/ConfigObjectId.jsx +113 -0
  146. package/src/JsonConfigComponent/ConfigPanel.tsx +360 -0
  147. package/src/JsonConfigComponent/ConfigPassword.jsx +160 -0
  148. package/src/JsonConfigComponent/ConfigPattern.jsx +50 -0
  149. package/src/JsonConfigComponent/ConfigPort.tsx +232 -0
  150. package/src/JsonConfigComponent/ConfigRoom.jsx +90 -0
  151. package/src/JsonConfigComponent/ConfigSelect.jsx +124 -0
  152. package/src/JsonConfigComponent/ConfigSelectSendTo.tsx +251 -0
  153. package/src/JsonConfigComponent/ConfigSendto.tsx +340 -0
  154. package/src/JsonConfigComponent/ConfigSetState.jsx +116 -0
  155. package/src/JsonConfigComponent/ConfigSlider.jsx +97 -0
  156. package/src/JsonConfigComponent/ConfigStaticDivider.jsx +51 -0
  157. package/src/JsonConfigComponent/ConfigStaticHeader.jsx +63 -0
  158. package/src/JsonConfigComponent/ConfigStaticImage.jsx +48 -0
  159. package/src/JsonConfigComponent/ConfigStaticText.jsx +72 -0
  160. package/src/JsonConfigComponent/ConfigTable.tsx +1040 -0
  161. package/src/JsonConfigComponent/ConfigTabs.tsx +150 -0
  162. package/src/JsonConfigComponent/ConfigText.tsx +188 -0
  163. package/src/JsonConfigComponent/ConfigTextSendTo.tsx +102 -0
  164. package/src/JsonConfigComponent/ConfigTimePicker.tsx +63 -0
  165. package/src/JsonConfigComponent/ConfigTopic.jsx +78 -0
  166. package/src/JsonConfigComponent/ConfigUUID.tsx +55 -0
  167. package/src/JsonConfigComponent/ConfigUser.jsx +104 -0
  168. package/src/JsonConfigComponent/index.tsx +435 -0
  169. package/src/JsonConfigComponent/wrapper/Components/CustomModal.jsx +145 -0
  170. package/src/JsonConfigComponent/wrapper/Components/Editor.jsx +65 -0
  171. package/src/Utils.jsx +1683 -0
  172. package/src/index.tsx +14 -0
  173. package/src/types.d.ts +372 -0
@@ -0,0 +1,340 @@
1
+ import React from 'react';
2
+ import { withStyles } from '@mui/styles';
3
+
4
+ import { Button, CircularProgress } from '@mui/material';
5
+
6
+ import {
7
+ Warning as IconWarning,
8
+ Error as IconError,
9
+ Info as IconInfo,
10
+ } from '@mui/icons-material';
11
+
12
+ import {
13
+ Confirm as DialogConfirm, Error as DialogError, Message as DialogMessage, I18n,
14
+ } from '@iobroker/adapter-react-v5';
15
+
16
+ import type { ConfigItemSendTo } from '#JC/types';
17
+ import ConfigGeneric, { type ConfigGenericProps, type ConfigGenericState } from './ConfigGeneric';
18
+
19
+ const styles: Record<string, any> = {
20
+ fullWidth: {
21
+ width: '100%',
22
+ },
23
+ icon: {
24
+ width: 24,
25
+ height: 24,
26
+ marginRight: 4,
27
+ },
28
+ };
29
+
30
+ function ip2int(ip: string) {
31
+ // eslint-disable-next-line no-bitwise
32
+ return ip.split('.').reduce((ipInt, octet) => (ipInt << 8) + parseInt(octet, 10), 0) >>> 0;
33
+ }
34
+
35
+ // copied from iobroker.admin/src-rx/src/Utils.js
36
+ function findNetworkAddressOfHost(obj: Record<string, any>, localIp: string) {
37
+ const networkInterfaces = obj?.native?.hardware?.networkInterfaces;
38
+ if (!networkInterfaces) {
39
+ return null;
40
+ }
41
+
42
+ let hostIp: string | undefined;
43
+
44
+ // check ipv4 addresses
45
+ Object.keys(networkInterfaces).forEach(inter =>
46
+ networkInterfaces[inter].forEach((ip: Record<string, any>) => {
47
+ if (ip.internal) {
48
+ return;
49
+ }
50
+ if (localIp.includes(':') && ip.family !== 'IPv6') {
51
+ return;
52
+ }
53
+ if (localIp.includes('.') && !localIp.match(/[^.\d]/) && ip.family !== 'IPv4') {
54
+ return;
55
+ }
56
+ // if ip4 and not docker or wsl
57
+ if (ip.family === 'IPv4' && !ip.address.startsWith('172') && (localIp === '127.0.0.0' || localIp === 'localhost' || localIp.match(/[^.\d]/))) { // if DNS name
58
+ hostIp = ip.address;
59
+ } else if (!hostIp) {
60
+ if (ip.family === 'IPv4' && localIp.includes('.') &&
61
+ // eslint-disable-next-line no-bitwise
62
+ (ip2int(localIp) & ip2int(ip.netmask)) === (ip2int(ip.address) & ip2int(ip.netmask))) {
63
+ hostIp = ip.address;
64
+ } else {
65
+ hostIp = ip.address;
66
+ }
67
+ }
68
+ }));
69
+
70
+ // check ipv6 addresses
71
+ if (!hostIp) {
72
+ Object.keys(networkInterfaces).forEach(inter =>
73
+ networkInterfaces[inter].forEach((ip: Record<string, any>) => {
74
+ if (ip.internal) {
75
+ return;
76
+ } if (localIp.includes(':') && ip.family !== 'IPv6') {
77
+ return;
78
+ } if (localIp.includes('.') && !localIp.match(/[^.\d]/) && ip.family !== 'IPv4') {
79
+ return;
80
+ }
81
+ if (ip.family === 'IPv6' && (localIp === '127.0.0.0' || localIp === 'localhost' || localIp.match(/[^.\d]/))) { // if DNS name
82
+ hostIp = ip.address;
83
+ } else if (!hostIp) {
84
+ if (ip.family === 'IPv4' && localIp.includes('.') &&
85
+ // eslint-disable-next-line no-bitwise
86
+ (ip2int(localIp) & ip2int(ip.netmask)) === (ip2int(ip.address) & ip2int(ip.netmask))) {
87
+ hostIp = ip.address;
88
+ } else {
89
+ hostIp = ip.address;
90
+ }
91
+ }
92
+ }));
93
+ }
94
+
95
+ if (!hostIp) {
96
+ Object.keys(networkInterfaces).forEach(inter => {
97
+ networkInterfaces[inter].forEach((ip: Record<string, any>) => {
98
+ if (ip.internal) {
99
+ return;
100
+ } if (localIp.includes(':') && ip.family !== 'IPv6') {
101
+ return;
102
+ } if (localIp.includes('.') && !localIp.match(/[^.\d]/) && ip.family !== 'IPv4') {
103
+ return;
104
+ }
105
+ if (localIp === '127.0.0.0' || localIp === 'localhost' || localIp.match(/[^.\d]/)) { // if DNS name
106
+ hostIp = ip.address;
107
+ } else {
108
+ hostIp = ip.address;
109
+ }
110
+ });
111
+ });
112
+ }
113
+
114
+ if (!hostIp) {
115
+ Object.keys(networkInterfaces).forEach(inter => {
116
+ networkInterfaces[inter].forEach((ip: Record<string, any>) => {
117
+ if (ip.internal) {
118
+ return;
119
+ }
120
+ hostIp = ip.address;
121
+ });
122
+ });
123
+ }
124
+
125
+ return hostIp;
126
+ }
127
+
128
+ interface ConfigSendToProps extends ConfigGenericProps {
129
+ schema: ConfigItemSendTo;
130
+ }
131
+
132
+ interface ConfigSendToState extends ConfigGenericState {
133
+ _error: string;
134
+ _message: string;
135
+ hostname: string;
136
+ running?: boolean;
137
+ }
138
+
139
+ class ConfigSendto extends ConfigGeneric<ConfigSendToProps, ConfigSendToState> {
140
+ async componentDidMount() {
141
+ super.componentDidMount();
142
+
143
+ let hostname = window.location.hostname;
144
+ if (this.props.schema.openUrl) {
145
+ // read admin host
146
+ const adminInstance = await this.props.socket.getCurrentInstance();
147
+ const instanceObj = await this.props.socket.getObject(`system.adapter.${adminInstance}` as ioBroker.ObjectIDs.Instance);
148
+
149
+ if (instanceObj) {
150
+ const hostObj = await this.props.socket.getObject(`system.host.${instanceObj?.common?.host}`);
151
+ if (hostObj) {
152
+ const ip = findNetworkAddressOfHost(hostObj, window.location.hostname);
153
+ if (ip) {
154
+ hostname = `${ip}:${window.location.port}`;
155
+ } else {
156
+ console.warn(`Cannot find suitable IP in host ${instanceObj.common.host} for ${instanceObj._id}`);
157
+ return;
158
+ }
159
+ }
160
+ }
161
+ }
162
+
163
+ await new Promise<void>(resolve => { this.setState({ _error: '', _message: '', hostname }, resolve); });
164
+
165
+ if (this.props.schema.onLoaded) {
166
+ this._onClick();
167
+ }
168
+ }
169
+
170
+ renderErrorDialog() {
171
+ if (this.state._error) {
172
+ return <DialogError text={this.state._error} onClose={() => this.setState({ _error: '' })} />;
173
+ }
174
+ return null;
175
+ }
176
+
177
+ renderMessageDialog() {
178
+ if (this.state._message) {
179
+ return <DialogMessage text={this.state._message} onClose={() => this.setState({ _message: '' })} />;
180
+ }
181
+ return null;
182
+ }
183
+
184
+ _onClick() {
185
+ this.props.onCommandRunning(true);
186
+ this.setState({ running: true });
187
+
188
+ const _origin = `${window.location.protocol}//${window.location.host}${window.location.pathname.replace(/\/index\.html$/, '')}`;
189
+ const _originIp = `${window.location.protocol}//${this.state.hostname.split(':').length > 3 ? `[${this.state.hostname}]` : this.state.hostname}${window.location.pathname.replace(/\/index\.html$/, '')}`;
190
+
191
+ let data: Record<string, any> = this.props.schema.data;
192
+ if (data === undefined && this.props.schema.jsonData) {
193
+ const dataStr = this.getPattern(this.props.schema.jsonData, {
194
+ _origin,
195
+ _originIp,
196
+ ...this.props.data,
197
+ });
198
+
199
+ try {
200
+ data = JSON.parse(dataStr);
201
+ } catch (e) {
202
+ console.error(`Cannot parse json data: ${dataStr}`);
203
+ }
204
+ }
205
+ if (data === undefined) {
206
+ data = null;
207
+ }
208
+ if (this.props.schema.openUrl && !data) {
209
+ data = {
210
+ _origin,
211
+ _originIp,
212
+ };
213
+ }
214
+ let timeout: ReturnType<typeof setTimeout> | undefined;
215
+ if (this.props.schema.timeout) {
216
+ timeout = setTimeout(() => {
217
+ this.props.onCommandRunning(false);
218
+ this.setState({ _error: I18n.t('ra_Request timed out'), running: false });
219
+ }, parseInt(this.props.schema.timeout as any as string, 10) || 10000);
220
+ }
221
+
222
+ this.props.socket.sendTo(
223
+ `${this.props.adapterName}.${this.props.instance}`,
224
+ this.props.schema.command || 'send',
225
+ data,
226
+ )
227
+ .then(async (response: Record<string, any>) => {
228
+ if (timeout) {
229
+ clearTimeout(timeout);
230
+ timeout = undefined;
231
+ }
232
+ if (response?.error) {
233
+ if (this.props.schema.error && this.props.schema.error[response.error]) {
234
+ let error = this.getText(this.props.schema.error[response.error]);
235
+ if (response.args) {
236
+ response.args.forEach((arg: string) => error = error.replace('%s', arg));
237
+ }
238
+ this.setState({ _error: error });
239
+ } else {
240
+ this.setState({ _error: response.error ? I18n.t(response.error) : I18n.t('ra_Error') });
241
+ }
242
+ } else {
243
+ if (response?.reloadBrowser && this.props.schema.reloadBrowser) {
244
+ window.location.reload();
245
+ } else if (response?.openUrl && this.props.schema.openUrl) {
246
+ window.open(response.openUrl, response.window || this.props.schema.window || '_blank');
247
+ } else if (response?.result && this.props.schema.result && this.props.schema.result[response.result]) {
248
+ let text = this.getText(this.props.schema.result[response.result]);
249
+ if (response.args) {
250
+ response.args.forEach((arg: string) => text = text.replace('%s', arg));
251
+ }
252
+ window.alert(text);
253
+ }
254
+
255
+ if (response?.native && this.props.schema.useNative) {
256
+ for (const [attr, val] of Object.entries(response.native)) {
257
+ await this.onChangeAsync(attr, val);
258
+ }
259
+
260
+ setTimeout(() => this.props.forceUpdate(Object.keys(response.native), this.props.data), 300);
261
+ } else if (response?.result) {
262
+ window.alert(typeof response.result === 'object' ? JSON.stringify(response.result) : response.result);
263
+ } else {
264
+ window.alert(I18n.t('ra_Ok'));
265
+ }
266
+
267
+ if (response?.saveConfig) {
268
+ this.props.onChange(null, null, null, true);
269
+ }
270
+ }
271
+ })
272
+ .catch((e: any) => {
273
+ if (this.props.schema.error && this.props.schema.error[e.toString()]) {
274
+ this.setState({ _error: this.getText(this.props.schema.error[e.toString()]) });
275
+ } else {
276
+ this.setState({ _error: I18n.t(e.toString()) || I18n.t('ra_Error') });
277
+ }
278
+ })
279
+ .then(() => {
280
+ this.props.onCommandRunning(false);
281
+ this.setState({ running: false });
282
+ });
283
+ }
284
+
285
+ renderConfirmDialog() {
286
+ if (!this.state.confirmDialog) {
287
+ return null;
288
+ }
289
+ const confirm = this.state.confirmData || this.props.schema.confirm;
290
+ let icon = null;
291
+ if (confirm.type === 'warning') {
292
+ icon = <IconWarning />;
293
+ } else if (confirm.type === 'error') {
294
+ icon = <IconError />;
295
+ } else if (confirm.type === 'info') {
296
+ icon = <IconInfo />;
297
+ }
298
+
299
+ return <DialogConfirm
300
+ title={this.getText(confirm.title) || I18n.t('ra_Please confirm')}
301
+ text={this.getText(confirm.text)}
302
+ ok={this.getText(confirm.ok) || I18n.t('ra_Ok')}
303
+ cancel={this.getText(confirm.cancel) || I18n.t('ra_Cancel')}
304
+ icon={icon || undefined}
305
+ onClose={isOk =>
306
+ this.setState({ confirmDialog: false }, () =>
307
+ isOk && this._onClick())}
308
+ />;
309
+ }
310
+
311
+ renderItem(error: Error | undefined, disabled: boolean) {
312
+ const icon = this.getIcon();
313
+
314
+ return <div className={this.props.classes.fullWidth}>
315
+ <Button
316
+ variant={this.props.schema.variant || undefined}
317
+ // @ts-expect-error grey is valid color
318
+ color={this.props.schema.color || 'grey'}
319
+ className={this.props.classes.fullWidth}
320
+ disabled={disabled || !this.props.alive}
321
+ startIcon={icon}
322
+ title={this.props.alive ? this.getText(this.props.schema.title) || '' : I18n.t('ra_Instance is not alive')}
323
+ onClick={() => {
324
+ if (this.props.schema.confirm) {
325
+ this.setState({ confirmDialog: true });
326
+ } else {
327
+ this._onClick();
328
+ }
329
+ }}
330
+ >
331
+ {this.props.schema.showProcess && this.state.running ? <CircularProgress size={20} style={{ marginRight: 8 }} /> : null}
332
+ {this.getText(this.props.schema.label, this.props.schema.noTranslation)}
333
+ </Button>
334
+ {this.renderErrorDialog()}
335
+ {this.renderMessageDialog()}
336
+ </div>;
337
+ }
338
+ }
339
+
340
+ export default withStyles(styles)(ConfigSendto);
@@ -0,0 +1,116 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { withStyles } from '@mui/styles';
4
+
5
+ import { Button } from '@mui/material';
6
+
7
+ import {
8
+ Warning as IconWarning,
9
+ Error as IconError,
10
+ Info as IconInfo,
11
+ } from '@mui/icons-material';
12
+
13
+ import { Confirm as ConfirmDialog, Icon, I18n } from '@iobroker/adapter-react-v5';
14
+ import ConfigGeneric from './ConfigGeneric';
15
+
16
+ const styles = () => ({
17
+ fullWidth: {
18
+ width: '100%',
19
+ },
20
+ icon: {
21
+ width: 24,
22
+ height: 24,
23
+ marginRight: 4,
24
+ },
25
+ });
26
+
27
+ class ConfigSetState extends ConfigGeneric {
28
+ async _onClick() {
29
+ let val = this.props.schema.val;
30
+ if (typeof val === 'string' && val.includes('${')) {
31
+ val = this.getPattern(val);
32
+ const obj = await this.props.socket.getObject(this.props.schema.id);
33
+ if (obj?.common?.type === 'number') {
34
+ val = parseFloat(val);
35
+ } else if (obj?.common?.type === 'boolean') {
36
+ val = val === 'true' || val === true || val === '1' || val === 1;
37
+ }
38
+ }
39
+
40
+ const id = (this.props.schema.id || '').replace(/%INSTANCE%/g, this.props.instance);
41
+
42
+ try {
43
+ await this.props.socket.setState(id, { val, ack: !!this.props.schema.ack });
44
+ this.props.schema.okText && window.alert(this.getText(this.props.schema.okText));
45
+ } catch (e) {
46
+ if (this.props.schema.error && this.props.schema.error[e.toString()]) {
47
+ window.alert(this.getText(this.props.schema.error[e.toString()]));
48
+ } else {
49
+ window.alert(I18n.t(e.toString()) || I18n.t('ra_Error'));
50
+ }
51
+ }
52
+ }
53
+
54
+ renderConfirmDialog() {
55
+ if (!this.state.confirmDialog) {
56
+ return null;
57
+ }
58
+ const confirm = this.state.confirmData || this.props.schema.confirm;
59
+ let icon = null;
60
+ if (confirm.type === 'warning') {
61
+ icon = <IconWarning />;
62
+ } else if (confirm.type === 'error') {
63
+ icon = <IconError />;
64
+ } else if (confirm.type === 'info') {
65
+ icon = <IconInfo />;
66
+ }
67
+
68
+ return <ConfirmDialog
69
+ title={this.getText(confirm.title) || I18n.t('ra_Please confirm')}
70
+ text={this.getText(confirm.text)}
71
+ ok={this.getText(confirm.ok) || I18n.t('ra_Ok')}
72
+ cancel={this.getText(confirm.cancel) || I18n.t('ra_Cancel')}
73
+ icon={icon}
74
+ onClose={isOk =>
75
+ this.setState({ confirmDialog: false }, () =>
76
+ isOk && this._onClick())}
77
+ />;
78
+ }
79
+
80
+ renderItem(error, disabled /* , defaultValue */) {
81
+ return <Button
82
+ variant={this.props.schema.variant || undefined}
83
+ color={this.props.schema.color || 'grey'}
84
+ className={this.props.classes.fullWidth}
85
+ disabled={disabled}
86
+ onClick={async () => {
87
+ if (this.props.schema.confirm) {
88
+ this.setState({ confirmDialog: true });
89
+ } else {
90
+ await this._onClick();
91
+ }
92
+ }}
93
+ >
94
+ {this.props.schema.icon ? <Icon src={this.props.schema.icon} className={this.props.classes.icon} /> : null}
95
+ {this.getText(this.props.schema.label, this.props.schema.noTranslation)}
96
+ </Button>;
97
+ }
98
+ }
99
+
100
+ ConfigSetState.propTypes = {
101
+ socket: PropTypes.object.isRequired,
102
+ themeType: PropTypes.string,
103
+ themeName: PropTypes.string,
104
+ style: PropTypes.object,
105
+ className: PropTypes.string,
106
+ data: PropTypes.object.isRequired,
107
+ schema: PropTypes.object,
108
+ onError: PropTypes.func,
109
+ onChange: PropTypes.func,
110
+ adapterName: PropTypes.string,
111
+ instance: PropTypes.number,
112
+ commandRunning: PropTypes.bool,
113
+ onCommandRunning: PropTypes.func,
114
+ };
115
+
116
+ export default withStyles(styles)(ConfigSetState);
@@ -0,0 +1,97 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { withStyles } from '@mui/styles';
4
+
5
+ import { Box, Typography, Slider } from '@mui/material';
6
+
7
+ import ConfigGeneric from './ConfigGeneric';
8
+
9
+ const styles = () => ({
10
+ fullWidth: {
11
+ width: '100%',
12
+ },
13
+ slider: {
14
+ marginLeft: 10,
15
+ marginRight: 10,
16
+ width: 'calc(100% - 20px)',
17
+ },
18
+ });
19
+
20
+ class ConfigSlider extends ConfigGeneric {
21
+ componentDidMount() {
22
+ super.componentDidMount();
23
+ const _value = ConfigGeneric.getValue(this.props.data, this.props.attr);
24
+ this.setState({ _value });
25
+ }
26
+
27
+ static getDerivedStateFromProps(props, state) {
28
+ if (
29
+ (props.schema.min !== undefined && props.schema.min < 0) ||
30
+ (props.schema.max !== undefined && props.schema.max < 0)
31
+ ) {
32
+ return null;
33
+ }
34
+ const _value = ConfigGeneric.getValue(props.data, props.attr);
35
+ if (_value === null || _value === undefined || _value.toString() !== parseFloat(state._value).toString()) {
36
+ return { _value };
37
+ }
38
+
39
+ return null;
40
+ }
41
+
42
+ renderItem(error, disabled /* , defaultValue */) {
43
+ const min = this.props.schema.min || 0;
44
+ const max = this.props.schema.max || 100;
45
+ const unit = this.props.schema.unit || '';
46
+
47
+ const marks = [
48
+ { value: min, label: min + unit },
49
+ { value: max, label: max + unit },
50
+ ];
51
+
52
+ return (
53
+ <Box className={this.props.classes.fullWidth}>
54
+ {this.props.schema.label ? (
55
+ <Typography gutterBottom>{this.getText(this.props.schema.label)}</Typography>
56
+ ) : null}
57
+ <Slider
58
+ className={this.props.classes.slider}
59
+ value={this.state._value}
60
+ getAriaValueText={value => value + unit}
61
+ step={this.props.schema.step || (max - min) / 100}
62
+ valueLabelDisplay="auto"
63
+ marks={marks}
64
+ min={min}
65
+ max={max}
66
+ disabled={!!disabled}
67
+ error={error || ''}
68
+ onChange={e => {
69
+ const _value = e.target.value;
70
+ this.setState({ _value }, () => this.onChange(this.props.attr, _value));
71
+ }}
72
+ />
73
+ {this.props.schema.help ? <Typography>
74
+ {this.renderHelp(
75
+ this.props.schema.help,
76
+ this.props.schema.helpLink,
77
+ this.props.schema.noTranslation,
78
+ )}
79
+ </Typography> : null}
80
+ </Box>
81
+ );
82
+ }
83
+ }
84
+
85
+ ConfigSlider.propTypes = {
86
+ socket: PropTypes.object.isRequired,
87
+ themeType: PropTypes.string,
88
+ themeName: PropTypes.string,
89
+ style: PropTypes.object,
90
+ className: PropTypes.string,
91
+ data: PropTypes.object.isRequired,
92
+ schema: PropTypes.object,
93
+ onError: PropTypes.func,
94
+ onChange: PropTypes.func,
95
+ };
96
+
97
+ export default withStyles(styles)(ConfigSlider);
@@ -0,0 +1,51 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { withStyles } from '@mui/styles';
4
+
5
+ import { Utils } from '@iobroker/adapter-react-v5';
6
+
7
+ import ConfigGeneric from './ConfigGeneric';
8
+
9
+ const styles = theme => ({
10
+ fullWidth: {
11
+ width: '100%',
12
+ backgroundColor: theme.palette.mode === 'dark' ? '#FFF' : '#000',
13
+ borderStyle: 'hidden',
14
+ },
15
+ primary: {
16
+ backgroundColor: theme.palette.primary.main,
17
+ },
18
+ secondary: {
19
+ backgroundColor: theme.palette.secondary.main,
20
+ },
21
+ });
22
+
23
+ class ConfigStaticDivider extends ConfigGeneric {
24
+ renderItem() {
25
+ return <hr
26
+ className={Utils.clsx(
27
+ this.props.classes.fullWidth,
28
+ this.props.schema.color === 'primary' && this.props.classes.primary,
29
+ this.props.schema.color === 'secondary' && this.props.classes.secondary,
30
+ )}
31
+ style={{
32
+ height: this.props.schema.color ? this.props.schema.height || 2 : this.props.schema.height || 1,
33
+ backgroundColor: this.props.schema.color !== 'primary' && this.props.schema.color !== 'secondary' && this.props.schema.color ? this.props.schema.color : undefined,
34
+ }}
35
+ />;
36
+ }
37
+ }
38
+
39
+ ConfigStaticDivider.propTypes = {
40
+ socket: PropTypes.object.isRequired,
41
+ themeType: PropTypes.string,
42
+ themeName: PropTypes.string,
43
+ style: PropTypes.object,
44
+ className: PropTypes.string,
45
+ data: PropTypes.object.isRequired,
46
+ schema: PropTypes.object,
47
+ onError: PropTypes.func,
48
+ onChange: PropTypes.func,
49
+ };
50
+
51
+ export default withStyles(styles)(ConfigStaticDivider);
@@ -0,0 +1,63 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { withStyles } from '@mui/styles';
4
+
5
+ import ConfigGeneric from './ConfigGeneric';
6
+
7
+ const styles = theme => ({
8
+ header: {
9
+ width: '100%',
10
+ background: theme.palette.primary.main,
11
+ color: theme.palette.primary.contrastText,
12
+ padding: '4px !important',
13
+ borderRadius: 3,
14
+ marginBlockEnd: 0,
15
+ marginBlockStart: 0,
16
+ },
17
+ });
18
+
19
+ class ConfigStaticHeader extends ConfigGeneric {
20
+ renderItem() {
21
+ switch ((this.props.schema.size || 5).toString()) {
22
+ case '1':
23
+ return <h1 className={this.props.classes.header}>
24
+ {this.getText(this.props.schema.text, this.props.schema.noTranslation)}
25
+ </h1>;
26
+
27
+ case '2':
28
+ return <h2 className={this.props.classes.header}>
29
+ {this.getText(this.props.schema.text, this.props.schema.noTranslation)}
30
+ </h2>;
31
+
32
+ case '3':
33
+ return <h3 className={this.props.classes.header}>
34
+ {this.getText(this.props.schema.text, this.props.schema.noTranslation)}
35
+ </h3>;
36
+
37
+ case '4':
38
+ return <h4 className={this.props.classes.header}>
39
+ {this.getText(this.props.schema.text, this.props.schema.noTranslation)}
40
+ </h4>;
41
+
42
+ case '5':
43
+ default:
44
+ return <h5 className={this.props.classes.header}>
45
+ {this.getText(this.props.schema.text, this.props.schema.noTranslation)}
46
+ </h5>;
47
+ }
48
+ }
49
+ }
50
+
51
+ ConfigStaticHeader.propTypes = {
52
+ socket: PropTypes.object.isRequired,
53
+ themeType: PropTypes.string,
54
+ themeName: PropTypes.string,
55
+ style: PropTypes.object,
56
+ className: PropTypes.string,
57
+ data: PropTypes.object.isRequired,
58
+ schema: PropTypes.object,
59
+ onError: PropTypes.func,
60
+ onChange: PropTypes.func,
61
+ };
62
+
63
+ export default withStyles(styles)(ConfigStaticHeader);