@iobroker/json-config 6.17.6 → 6.17.12

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,96 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { withStyles } from '@mui/styles';
4
+
5
+ import {
6
+ InputLabel,
7
+ TextField,
8
+ FormHelperText,
9
+ MenuItem,
10
+ FormControl,
11
+ Select,
12
+ } from '@mui/material';
13
+
14
+ import { I18n } from '@iobroker/adapter-react-v5';
15
+
16
+ import ConfigGeneric from './ConfigGeneric';
17
+
18
+ const styles = () => ({
19
+ fullWidth: {
20
+ width: '100%',
21
+ },
22
+ });
23
+
24
+ class ConfigIP extends ConfigGeneric {
25
+ componentDidMount() {
26
+ super.componentDidMount();
27
+ this.props.socket.getHostByIp(this.props.common.host)
28
+ .then(ips => {
29
+ // [{name, address, family}]
30
+ if (!this.props.schema.listenOnAllPorts) {
31
+ ips = ips.filter(item => item.address !== '0.0.0.0' && item.address !== '::');
32
+ }
33
+ if (this.props.schema.onlyIp4) {
34
+ ips = ips.filter(item => item.family === 'ipv4');
35
+ } else if (this.props.schema.onlyIp6) {
36
+ ips = ips.filter(item => item.family === 'ipv6');
37
+ }
38
+ if (this.props.schema.noInternal) {
39
+ ips = ips.filter(item => !item.internal);
40
+ }
41
+ ips.forEach(item => {
42
+ if (item.address === '0.0.0.0') {
43
+ item.name = `[IPv4] 0.0.0.0 - ${I18n.t('ra_Listen on all IPs')}`;
44
+ } else if (item.address === '::') {
45
+ item.name = `[IPv6] :: - ${I18n.t('ra_Listen on all IPs')}`;
46
+ }
47
+ });
48
+ this.setState({ ips });
49
+ });
50
+ }
51
+
52
+ renderItem(error, disabled /* , defaultValue */) {
53
+ const value = ConfigGeneric.getValue(this.props.data, this.props.attr);
54
+ const item = this.state.ips?.find(it => it.address === value);
55
+
56
+ return <FormControl className={this.props.classes.fullWidth} variant="standard">
57
+ {this.state.ips && this.props.schema.label ? <InputLabel>{this.getText(this.props.schema.label)}</InputLabel> : null}
58
+ {!this.state.ips ?
59
+ <TextField
60
+ fullWidth
61
+ variant="standard"
62
+ error={!!error}
63
+ disabled={!!disabled}
64
+ value={value}
65
+ onChange={e => this.onChange(this.props.attr, e.target.value)}
66
+ label={this.getText(this.props.schema.label)}
67
+ /> :
68
+ <Select
69
+ variant="standard"
70
+ error={!!error}
71
+ disabled={!!disabled}
72
+ value={value}
73
+ renderValue={val => item?.name || val}
74
+ onChange={e => this.onChange(this.props.attr, e.target.value)}
75
+ >
76
+ {this.state.ips?.map((it, i) =>
77
+ <MenuItem key={i} value={it.address}>{it.name}</MenuItem>)}
78
+ </Select>}
79
+ {this.props.schema.help ? <FormHelperText>{this.renderHelp(this.props.schema.help, this.props.schema.helpLink, this.props.schema.noTranslation)}</FormHelperText> : null}
80
+ </FormControl>;
81
+ }
82
+ }
83
+
84
+ ConfigIP.propTypes = {
85
+ socket: PropTypes.object.isRequired,
86
+ themeType: PropTypes.string,
87
+ themeName: PropTypes.string,
88
+ style: PropTypes.object,
89
+ className: PropTypes.string,
90
+ data: PropTypes.object.isRequired,
91
+ schema: PropTypes.object,
92
+ onError: PropTypes.func,
93
+ onChange: PropTypes.func,
94
+ };
95
+
96
+ export default withStyles(styles)(ConfigIP);
@@ -0,0 +1,79 @@
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 = () => ({
8
+ fullWidth: {
9
+ width: '100%',
10
+ },
11
+ });
12
+
13
+ class ConfigImageSendTo extends ConfigGeneric {
14
+ componentDidMount() {
15
+ super.componentDidMount();
16
+
17
+ this.askInstance();
18
+ }
19
+
20
+ askInstance() {
21
+ if (this.props.alive) {
22
+ let data = this.props.schema.data;
23
+ if (data === undefined && this.props.schema.jsonData) {
24
+ data = this.getPattern(this.props.schema.jsonData);
25
+ try {
26
+ data = JSON.parse(data);
27
+ } catch (e) {
28
+ console.error(`Cannot parse json data: ${data}`);
29
+ }
30
+ }
31
+
32
+ if (data === undefined) {
33
+ data = null;
34
+ }
35
+
36
+ this.props.socket.sendTo(`${this.props.adapterName}.${this.props.instance}`, this.props.schema.command || 'send', data)
37
+ .then(image => this.setState({ image: image || '', context: this.getContext() }));
38
+ }
39
+ }
40
+
41
+ getContext() {
42
+ const context = {};
43
+ if (Array.isArray(this.props.schema.alsoDependsOn)) {
44
+ this.props.schema.alsoDependsOn.forEach(attr =>
45
+ context[attr] = ConfigGeneric.getValue(this.props.data, attr));
46
+ }
47
+ return JSON.stringify(context);
48
+ }
49
+
50
+ renderItem(/* error, disabled, defaultValue */) {
51
+ if (this.state.image === undefined) {
52
+ return null;
53
+ }
54
+
55
+ if (this.props.alive) {
56
+ const context = this.getContext();
57
+ if (context !== this.state.context) {
58
+ setTimeout(() => this.askInstance(), 300);
59
+ }
60
+ }
61
+
62
+ return <img
63
+ className={this.props.classes.fullWidth}
64
+ alt="dynamic content"
65
+ src={this.state.image}
66
+ style={{ width: this.props.schema.width, height: this.props.schema.height }}
67
+ />;
68
+ }
69
+ }
70
+
71
+ ConfigImageSendTo.propTypes = {
72
+ socket: PropTypes.object.isRequired,
73
+ data: PropTypes.object.isRequired,
74
+ schema: PropTypes.object,
75
+ adapterName: PropTypes.string,
76
+ instance: PropTypes.number,
77
+ };
78
+
79
+ export default withStyles(styles)(ConfigImageSendTo);
@@ -0,0 +1,114 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { withStyles } from '@mui/styles';
4
+
5
+ import {
6
+ InputLabel,
7
+ FormHelperText,
8
+ FormControl,
9
+ } from '@mui/material';
10
+
11
+ import { UploadImage, I18n } from '@iobroker/adapter-react-v5';
12
+
13
+ import ConfigGeneric from './ConfigGeneric';
14
+
15
+ const styles = () => ({
16
+ fullWidth: {
17
+ width: '100%',
18
+ },
19
+ image: {
20
+ width: 100,
21
+ },
22
+ });
23
+
24
+ class ConfigImageUpload extends ConfigGeneric {
25
+ constructor(props) {
26
+ super(props);
27
+ this.index = Date.now();
28
+ }
29
+
30
+ async componentDidMount() {
31
+ super.componentDidMount();
32
+
33
+ if (this.props.schema.base64) {
34
+ const value = ConfigGeneric.getValue(this.props.data, this.props.attr);
35
+ this.setState({ value });
36
+ } else {
37
+ this.props.socket.fileExists(`${this.props.adapterName}.${this.props.instance}`, this.props.attr)
38
+ .then(exist => exist && this.loadImage());
39
+ }
40
+ }
41
+
42
+ _getUrl(update) {
43
+ if (update) {
44
+ this.index = Date.now();
45
+ }
46
+ let url = `files/${this.props.adapterName}.${this.props.instance}/${this.props.attr}?t=${this.index}`;
47
+ if (window.location.port === '3000') {
48
+ url = `${window.location.protocol}//${window.location.hostname}:8081/${url}`;
49
+ }
50
+
51
+ return url;
52
+ }
53
+
54
+ loadImage() {
55
+ fetch(this._getUrl())
56
+ .then(res => res.blob())
57
+ .then(blob => {
58
+ const reader = new FileReader();
59
+ reader.onload = () => {
60
+ this.setState({ value: reader.result });
61
+ };
62
+ reader.readAsDataURL(blob);
63
+ })
64
+ .catch(e => console.error(e));
65
+ }
66
+
67
+ renderItem(error, disabled /* , defaultValue */) {
68
+ // eslint-disable-next-line
69
+ return <FormControl className={this.props.classes.fullWidth} variant="standard">
70
+ {this.props.schema.label ? <InputLabel shrink>{this.getText(this.props.schema.label)}</InputLabel> : null}
71
+ <UploadImage
72
+ error={!!error}
73
+ disabled={disabled}
74
+ accept={this.props.schema.accept}
75
+ crop={this.props.schema.crop}
76
+ maxSize={this.props.schema.maxSize || 256 * 1024}
77
+ icon={this.state.value || undefined}
78
+ removeIconFunc={() => this.setState({ value: null }, () => {
79
+ if (this.props.schema.base64) {
80
+ this.onChange(this.props.attr, this.state.value);
81
+ } else {
82
+ // delete file to /instance/attr
83
+ this.props.socket.deleteFile(`${this.props.adapterName}.${this.props.instance}`, this.props.attr);
84
+ }
85
+ })}
86
+ onChange={base64 => this.setState({ value: base64 }, () => {
87
+ if (this.props.schema.base64) {
88
+ this.onChange(this.props.attr, this.state.value);
89
+ } else if (base64.startsWith('data')) {
90
+ base64 = base64.split(',')[1];
91
+ }
92
+ // upload file to /instance/attr
93
+ this.props.socket.writeFile64(`${this.props.adapterName}.${this.props.instance}`, this.props.attr, base64);
94
+ })}
95
+ t={I18n.t}
96
+ />
97
+ {this.props.schema.help ? <FormHelperText>{this.renderHelp(this.props.schema.help, this.props.schema.helpLink, this.props.schema.noTranslation)}</FormHelperText> : null}
98
+ </FormControl>;
99
+ }
100
+ }
101
+
102
+ ConfigImageUpload.propTypes = {
103
+ socket: PropTypes.object.isRequired,
104
+ themeType: PropTypes.string,
105
+ themeName: PropTypes.string,
106
+ style: PropTypes.object,
107
+ className: PropTypes.string,
108
+ data: PropTypes.object.isRequired,
109
+ schema: PropTypes.object,
110
+ onError: PropTypes.func,
111
+ onChange: PropTypes.func,
112
+ };
113
+
114
+ export default withStyles(styles)(ConfigImageUpload);
@@ -0,0 +1,172 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { withStyles } from '@mui/styles';
4
+
5
+ import {
6
+ InputLabel,
7
+ MenuItem,
8
+ FormHelperText,
9
+ FormControl,
10
+ Select,
11
+ } from '@mui/material';
12
+
13
+ import { 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: 20,
22
+ height: 20,
23
+ marginRight: 4,
24
+ },
25
+ });
26
+
27
+ class ConfigInstanceSelect extends ConfigGeneric {
28
+ async componentDidMount() {
29
+ super.componentDidMount();
30
+ const value = ConfigGeneric.getValue(this.props.data, this.props.attr);
31
+
32
+ let adapter = this.props.schema.adapter;
33
+ if (adapter === '_dataSources') {
34
+ adapter = undefined;
35
+ }
36
+
37
+ this.props.socket.getAdapterInstances(adapter, true)
38
+ .then(async instances => {
39
+ if (this.props.schema.adapter === '_dataSources') {
40
+ // get only "data-sources", like history, sql, influx
41
+ instances = instances.filter(instance => instance?.common?.getHistory);
42
+ } else if (this.props.schema.adapter) {
43
+ instances = instances.filter(instance => instance?._id.startsWith(`system.adapter.${this.props.schema.adapter}.`));
44
+ } else if (this.props.schema.adapters && Array.isArray(this.props.schema.adapters)) {
45
+ instances = instances.filter(instance => this.props.schema.adapters.includes(instance?.common?.name));
46
+ }
47
+
48
+ if (this.props.schema.onlyEnabled) {
49
+ instances = instances.filter(instance => instance?.common?.enabled);
50
+ }
51
+
52
+ const selectOptions = instances.map(instance => ({
53
+ value: this.props.schema.long ? instance._id :
54
+ (this.props.schema.short ? instance._id.split('.').pop() : instance._id.replace(/^system\.adapter\./, '')),
55
+ label: `${instance.common.name} [${instance._id.replace(/^system\.adapter\./, '')}]`,
56
+ icon: `adapter/${instance.common.name}/${instance.common.icon}`,
57
+ }));
58
+
59
+ selectOptions.sort((a, b) => {
60
+ if (a.value > b.value) {
61
+ return 1;
62
+ } if (a.value < b.value) {
63
+ return -1;
64
+ }
65
+ return 0;
66
+ });
67
+
68
+ if (this.props.schema.allowDeactivate !== false) {
69
+ selectOptions.unshift({ label: I18n.t(ConfigGeneric.NONE_LABEL), value: ConfigGeneric.NONE_VALUE });
70
+ }
71
+ if (this.props.schema.all) {
72
+ selectOptions.unshift({ label: I18n.t('sch_all'), value: '*' });
73
+ }
74
+
75
+ this.setState({ value: value || '', selectOptions });
76
+
77
+ await this.props.socket.subscribeObject(`system.adapter.${adapter ? `${adapter}.` : ''}*`, this.onInstancesUpdate);
78
+ });
79
+ }
80
+
81
+ componentWillUnmount() {
82
+ this.props.socket.unsubscribeObject('system.adapter.*', this.onInstancesUpdate)
83
+ .then(() => {});
84
+ super.componentWillUnmount();
85
+ }
86
+
87
+ onInstancesUpdate = (id, obj) => {
88
+ if (!id.match(/^system\.adapter\.[-_a-z\d]+\.\d+$/)) {
89
+ return;
90
+ }
91
+ const _id = this.props.schema.long ? id : (this.props.schema.short ? id.split('.').pop() : id.replace(/^system\.adapter\./, ''));
92
+ const index = this.state.selectOptions.findIndex(item => item.value === _id);
93
+ if (!obj) {
94
+ // deleted
95
+ if (index !== -1) {
96
+ const selectOptions = JSON.parse(JSON.stringify(this.state.selectOptions));
97
+
98
+ const newState = {};
99
+ if (this.state.value === selectOptions[index].value) {
100
+ newState.value = ConfigGeneric.NONE_VALUE;
101
+ }
102
+ selectOptions.splice(index, 1);
103
+ newState.selectOptions = selectOptions;
104
+
105
+ this.setState(newState);
106
+ }
107
+ } else {
108
+ if (this.props.schema.adapter === '_dataSources' && (!obj.common || !obj.common.getHistory)) {
109
+ return;
110
+ }
111
+
112
+ if (index === -1) {
113
+ const selectOptions = JSON.parse(JSON.stringify(this.state.selectOptions));
114
+ selectOptions.push({
115
+ value: this.props.schema.long ? obj._id :
116
+ (this.props.schema.short ? obj._id.split('.').pop() : obj._id.replace(/^system\.adapter\./, '')),
117
+ label: `${obj.common.name} [${obj._id.replace(/^system\.adapter\./, '')}]`,
118
+ icon: `adapter/${obj.common.name}/${obj.common.icon}`,
119
+ });
120
+ selectOptions.sort((a, b) => (a.label > b.label ? 1 : (a.label < b.label ? -1 : 0)));
121
+ this.setState({ selectOptions });
122
+ }
123
+ }
124
+ };
125
+
126
+ renderItem(error, disabled /* , defaultValue */) {
127
+ if (!this.state.selectOptions) {
128
+ return null;
129
+ }
130
+
131
+ const item = this.state.selectOptions?.find(it => it.value === this.state.value);
132
+
133
+ return <FormControl className={this.props.classes.fullWidth} key={this.props.attr} variant="standard">
134
+ {this.props.schema.label ? <InputLabel shrink>{this.getText(this.props.schema.label)}</InputLabel> : null }
135
+ <Select
136
+ variant="standard"
137
+ error={!!error}
138
+ displayEmpty
139
+ disabled={!!disabled}
140
+ value={this.state.value}
141
+ renderValue={() => <span style={{ display: 'flex' }}>
142
+ {item?.icon ? <img src={`./${item.icon}`} alt={item.value} className={this.props.classes.icon} /> : null}
143
+ {this.getText(item?.label, true)}
144
+ </span>}
145
+ onChange={e =>
146
+ this.setState({ value: e.target.value }, () =>
147
+ this.onChange(this.props.attr, this.state.value))}
148
+ >
149
+ {this.state.selectOptions.map(it =>
150
+ <MenuItem key={it.value} value={it.value} style={it.value === ConfigGeneric.NONE_VALUE ? { opacity: 0.5 } : {}}>
151
+ {it.icon ? <img src={`./${it.icon}`} alt={it.value} className={this.props.classes.icon} /> : null}
152
+ {this.getText(it.label, true)}
153
+ </MenuItem>)}
154
+ </Select>
155
+ {this.props.schema.help ? <FormHelperText>{this.renderHelp(this.props.schema.help, this.props.schema.helpLink, this.props.schema.noTranslation)}</FormHelperText> : null}
156
+ </FormControl>;
157
+ }
158
+ }
159
+
160
+ ConfigInstanceSelect.propTypes = {
161
+ socket: PropTypes.object.isRequired,
162
+ themeType: PropTypes.string,
163
+ themeName: PropTypes.string,
164
+ style: PropTypes.object,
165
+ className: PropTypes.string,
166
+ data: PropTypes.object.isRequired,
167
+ schema: PropTypes.object,
168
+ onError: PropTypes.func,
169
+ onChange: PropTypes.func,
170
+ };
171
+
172
+ export default withStyles(styles)(ConfigInstanceSelect);
@@ -0,0 +1,112 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { withStyles } from '@mui/styles';
4
+
5
+ import {
6
+ InputLabel,
7
+ TextField,
8
+ FormHelperText,
9
+ MenuItem,
10
+ FormControl,
11
+ Select,
12
+ } from '@mui/material';
13
+
14
+ import ConfigGeneric from './ConfigGeneric';
15
+
16
+ const styles = () => ({
17
+ fullWidth: {
18
+ width: '100%',
19
+ },
20
+ address: {
21
+ fontSize: 'smaller',
22
+ opacity: 0.5,
23
+ marginLeft: 8,
24
+ },
25
+ });
26
+
27
+ class ConfigInterface extends ConfigGeneric {
28
+ componentDidMount() {
29
+ super.componentDidMount();
30
+ this.props.socket.getObject(`system.host.${this.props.common.host}`)
31
+ .then(obj => {
32
+ const interfaces = [];
33
+ if (obj?.native?.hardware?.networkInterfaces) {
34
+ const list = obj.native.hardware.networkInterfaces;
35
+ Object.keys(list).forEach(inter => {
36
+ if (this.props.schema.ignoreInternal && !list[inter].find(_ip => !_ip.internal)) {
37
+ return;
38
+ }
39
+ if (this.props.schema.ignoreLoopback && list[inter].find(_ip => _ip.address === '127.0.0.1' || _ip.address === '::1')) {
40
+ return;
41
+ }
42
+
43
+ // find ipv4 address
44
+ let ip = list[inter].find(_ip => _ip.family === 'IPv4');
45
+ ip = ip || list[inter].find(_ip => _ip.family === 'IPv6');
46
+ interfaces.push({ value: inter, address: ip.address });
47
+ });
48
+ }
49
+
50
+ this.setState({ interfaces });
51
+ })
52
+ .catch(e => window.alert(`Cannot read interfaces: ${e}`));
53
+ }
54
+
55
+ renderItem(error, disabled /* , defaultValue */) {
56
+ const value = ConfigGeneric.getValue(this.props.data, this.props.attr);
57
+ const item = this.state.interfaces?.find(it => it.value === value);
58
+
59
+ return <FormControl className={this.props.classes.fullWidth} variant="standard">
60
+ {this.state.interfaces?.length && this.props.schema.label ? <InputLabel>{this.getText(this.props.schema.label)}</InputLabel> : null}
61
+ {!this.state.interfaces?.length ?
62
+ <TextField
63
+ fullWidth
64
+ variant="standard"
65
+ error={!!error}
66
+ disabled={!!disabled}
67
+ value={value}
68
+ onChange={e => this.onChange(this.props.attr, e.target.value)}
69
+ label={this.getText(this.props.schema.label)}
70
+ /> :
71
+ <Select
72
+ variant="standard"
73
+ error={!!error}
74
+ disabled={!!disabled}
75
+ value={value}
76
+ renderValue={val => {
77
+ if (item) {
78
+ return <span>
79
+ {item.value}
80
+ <span className={this.props.classes.address}>{item.address}</span>
81
+ </span>;
82
+ }
83
+ return val;
84
+ }}
85
+ onChange={e => this.onChange(this.props.attr, e.target.value)}
86
+ >
87
+ {this.state.interfaces.map((it, i) =>
88
+ <MenuItem key={i} value={it.value}>
89
+ <span>
90
+ {it.value}
91
+ <span className={this.props.classes.address}>{it.address}</span>
92
+ </span>
93
+ </MenuItem>)}
94
+ </Select>}
95
+ {this.props.schema.help ? <FormHelperText>{this.renderHelp(this.props.schema.help, this.props.schema.helpLink, this.props.schema.noTranslation)}</FormHelperText> : null}
96
+ </FormControl>;
97
+ }
98
+ }
99
+
100
+ ConfigInterface.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
+ };
111
+
112
+ export default withStyles(styles)(ConfigInterface);
@@ -0,0 +1,103 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { withStyles } from '@mui/styles';
4
+
5
+ import {
6
+ FormHelperText,
7
+ FormControl,
8
+ Button,
9
+ } from '@mui/material';
10
+
11
+ import { I18n } from '@iobroker/adapter-react-v5';
12
+ import ConfigGeneric from './ConfigGeneric';
13
+ import CustomModal from './wrapper/Components/CustomModal';
14
+ import Editor from './wrapper/Components/Editor';
15
+
16
+ const styles = () => ({
17
+ fullWidth: {
18
+ width: '100%',
19
+ },
20
+ flex: {
21
+ display: 'flex',
22
+ },
23
+ button: {
24
+ height: 48,
25
+ // marginLeft: 4,
26
+ minWidth: 48,
27
+ },
28
+ wrapper: {
29
+ width: 'calc(100vw - 40px)',
30
+ height: 'calc(100vh - 188px)',
31
+ },
32
+ });
33
+
34
+ class ConfigJsonEditor extends ConfigGeneric {
35
+ async componentDidMount() {
36
+ super.componentDidMount();
37
+ const { data, attr } = this.props;
38
+ const value = ConfigGeneric.getValue(data, attr) || {};
39
+ this.setState({ value, initialized: true });
40
+ }
41
+
42
+ renderItem(/* error, disabled, defaultValue */) {
43
+ if (!this.state.initialized) {
44
+ return null;
45
+ }
46
+
47
+ const {
48
+ classes, schema, data, attr,
49
+ } = this.props;
50
+ const { value, showSelectId } = this.state;
51
+
52
+ return <FormControl className={classes.fullWidth} variant="standard">
53
+ <div className={classes.flex}>
54
+ <Button
55
+ color="grey"
56
+ className={classes.button}
57
+ size="small"
58
+ variant="outlined"
59
+ onClick={() => this.setState({ showSelectId: true })}
60
+ >
61
+ {I18n.t('ra_JSON editor')}
62
+ </Button>
63
+ </div>
64
+ {showSelectId ? <CustomModal
65
+ title={this.getText(schema.label)}
66
+ open={showSelectId}
67
+ overflowHidden
68
+ onClose={() =>
69
+ this.setState({ showSelectId: false, value: ConfigGeneric.getValue(data, attr) || {} })}
70
+ onApply={() => this.setState({ showSelectId: false }, () => this.onChange(attr, value))}
71
+ >
72
+ <div className={classes.wrapper}>
73
+ <Editor
74
+ value={typeof value === 'object' ? JSON.stringify(value) : value}
75
+ onChange={newValue => this.setState({ value: newValue })}
76
+ name="ConfigJsonEditor"
77
+ themeType={this.props.themeType}
78
+ />
79
+ </div>
80
+ </CustomModal> : null}
81
+ {schema.help ? <FormHelperText>
82
+ {this.renderHelp(
83
+ this.props.schema.help,
84
+ this.props.schema.helpLink,
85
+ this.props.schema.noTranslation,
86
+ )}
87
+ </FormHelperText> : null}
88
+ </FormControl>;
89
+ }
90
+ }
91
+
92
+ ConfigJsonEditor.propTypes = {
93
+ socket: PropTypes.object.isRequired,
94
+ themeType: PropTypes.string,
95
+ style: PropTypes.object,
96
+ className: PropTypes.string,
97
+ data: PropTypes.object.isRequired,
98
+ schema: PropTypes.object,
99
+ onError: PropTypes.func,
100
+ onChange: PropTypes.func,
101
+ };
102
+
103
+ export default withStyles(styles)(ConfigJsonEditor);