@iobroker/adapter-react-v5 7.0.2 → 7.1.1

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 (307) hide show
  1. package/Components/404.d.ts +3 -2
  2. package/Components/404.js +3 -2
  3. package/Components/ColorPicker.d.ts +22 -8
  4. package/Components/ColorPicker.js +34 -17
  5. package/Components/ComplexCron.js +24 -24
  6. package/Components/CopyToClipboard.d.ts +10 -1
  7. package/Components/CopyToClipboard.js +17 -8
  8. package/Components/CustomModal.d.ts +1 -1
  9. package/Components/CustomModal.js +8 -8
  10. package/Components/FileBrowser.d.ts +11 -11
  11. package/Components/FileBrowser.js +135 -152
  12. package/Components/FileViewer.js +34 -23
  13. package/Components/Icon.d.ts +16 -2
  14. package/Components/Icon.js +19 -8
  15. package/Components/IconPicker.js +10 -14
  16. package/Components/IconSelector.d.ts +1 -1
  17. package/Components/IconSelector.js +64 -74
  18. package/Components/Image.d.ts +8 -4
  19. package/Components/Image.js +13 -32
  20. package/Components/Loader.d.ts +2 -2
  21. package/Components/Loader.js +21 -18
  22. package/Components/Loaders/MV.d.ts +6 -1
  23. package/Components/Loaders/MV.js +23 -7
  24. package/Components/Loaders/PT.d.ts +7 -2
  25. package/Components/Loaders/PT.js +20 -7
  26. package/Components/Loaders/Vendor.d.ts +2 -2
  27. package/Components/Loaders/Vendor.js +15 -7
  28. package/Components/Logo.js +16 -18
  29. package/Components/MDUtils.d.ts +1 -1
  30. package/Components/MDUtils.js +8 -4
  31. package/Components/ObjectBrowser.d.ts +40 -39
  32. package/Components/ObjectBrowser.js +550 -435
  33. package/Components/Router.d.ts +1 -3
  34. package/Components/Router.js +3 -1
  35. package/Components/SaveCloseButtons.d.ts +3 -3
  36. package/Components/SaveCloseButtons.js +3 -3
  37. package/Components/Schedule.d.ts +15 -15
  38. package/Components/Schedule.js +177 -154
  39. package/Components/SelectWithIcon.d.ts +2 -2
  40. package/Components/SelectWithIcon.js +45 -34
  41. package/Components/SimpleCron/index.js +83 -43
  42. package/Components/TabContainer.js +2 -2
  43. package/Components/TabContent.js +1 -1
  44. package/Components/TabHeader.js +1 -1
  45. package/Components/TableResize.d.ts +2 -2
  46. package/Components/TableResize.js +5 -5
  47. package/Components/TextWithIcon.d.ts +1 -1
  48. package/Components/TextWithIcon.js +10 -8
  49. package/Components/ToggleThemeMenu.d.ts +2 -2
  50. package/Components/ToggleThemeMenu.js +3 -3
  51. package/Components/TreeTable.d.ts +18 -18
  52. package/Components/TreeTable.js +76 -72
  53. package/Components/UploadImage.d.ts +2 -2
  54. package/Components/UploadImage.js +25 -21
  55. package/Components/Utils.d.ts +42 -22
  56. package/Components/Utils.js +66 -65
  57. package/Components/withWidth.d.ts +2 -2
  58. package/Components/withWidth.js +10 -6
  59. package/Dialogs/ComplexCron.d.ts +2 -2
  60. package/Dialogs/ComplexCron.js +3 -3
  61. package/Dialogs/Confirm.d.ts +4 -4
  62. package/Dialogs/Confirm.js +18 -8
  63. package/Dialogs/Cron.d.ts +3 -3
  64. package/Dialogs/Cron.js +21 -17
  65. package/Dialogs/Error.d.ts +3 -3
  66. package/Dialogs/Error.js +6 -4
  67. package/Dialogs/Message.d.ts +3 -3
  68. package/Dialogs/Message.js +6 -4
  69. package/Dialogs/SelectFile.d.ts +4 -4
  70. package/Dialogs/SelectFile.js +6 -4
  71. package/Dialogs/SelectID.d.ts +12 -10
  72. package/Dialogs/SelectID.js +12 -8
  73. package/Dialogs/SimpleCron.d.ts +2 -2
  74. package/Dialogs/SimpleCron.js +2 -2
  75. package/Dialogs/TextInput.d.ts +2 -2
  76. package/Dialogs/TextInput.js +3 -3
  77. package/GenericApp.d.ts +19 -13
  78. package/GenericApp.js +128 -85
  79. package/LegacyConnection.d.ts +240 -248
  80. package/LegacyConnection.js +500 -525
  81. package/README.md +1264 -1171
  82. package/Theme.d.ts +1 -1
  83. package/Theme.js +9 -12
  84. package/assets/devices.json +1 -0
  85. package/assets/rooms.json +1 -0
  86. package/craco-module-federation.js +3 -12
  87. package/i18n/de.json +434 -434
  88. package/i18n/en.json +434 -434
  89. package/i18n/es.json +434 -434
  90. package/i18n/fr.json +434 -434
  91. package/i18n/it.json +434 -434
  92. package/i18n/nl.json +434 -434
  93. package/i18n/pl.json +434 -434
  94. package/i18n/pt.json +434 -434
  95. package/i18n/ru.json +434 -434
  96. package/i18n/uk.json +434 -434
  97. package/i18n/zh-cn.json +434 -434
  98. package/i18n.d.ts +26 -19
  99. package/i18n.js +28 -22
  100. package/icons/IconAdapter.js +2 -2
  101. package/icons/IconAlias.js +2 -2
  102. package/icons/IconChannel.js +2 -2
  103. package/icons/IconClearFilter.js +2 -2
  104. package/icons/IconClosed.js +2 -2
  105. package/icons/IconCopy.js +2 -2
  106. package/icons/IconDevice.js +2 -2
  107. package/icons/IconDocument.js +2 -2
  108. package/icons/IconDocumentReadOnly.js +2 -2
  109. package/icons/IconExpert.js +2 -2
  110. package/icons/IconFx.js +2 -2
  111. package/icons/IconInstance.js +2 -2
  112. package/icons/IconLogout.js +2 -2
  113. package/icons/IconNoIcon.js +2 -2
  114. package/icons/IconOpen.d.ts +2 -2
  115. package/icons/IconOpen.js +2 -2
  116. package/icons/IconProps.d.ts +4 -3
  117. package/icons/IconState.d.ts +2 -2
  118. package/icons/IconState.js +2 -2
  119. package/index.css +3 -2
  120. package/package.json +4 -4
  121. package/src/Components/404.tsx +32 -31
  122. package/src/Components/ColorPicker.tsx +142 -114
  123. package/src/Components/ComplexCron.tsx +174 -137
  124. package/src/Components/CopyToClipboard.tsx +22 -9
  125. package/src/Components/CustomModal.tsx +76 -69
  126. package/src/Components/FileBrowser.tsx +959 -852
  127. package/src/Components/FileViewer.tsx +146 -127
  128. package/src/Components/Icon.tsx +80 -52
  129. package/src/Components/IconPicker.tsx +83 -67
  130. package/src/Components/IconSelector.tsx +159 -141
  131. package/src/Components/Image.tsx +43 -26
  132. package/src/Components/Loader.tsx +56 -32
  133. package/src/Components/Logo.tsx +62 -52
  134. package/src/Components/MDUtils.tsx +10 -6
  135. package/src/Components/ObjectBrowser.tsx +3198 -2478
  136. package/src/Components/Router.tsx +11 -11
  137. package/src/Components/SaveCloseButtons.tsx +43 -39
  138. package/src/Components/Schedule.tsx +1091 -853
  139. package/src/Components/SelectWithIcon.tsx +135 -93
  140. package/src/Components/TabContainer.tsx +22 -20
  141. package/src/Components/TabContent.tsx +13 -12
  142. package/src/Components/TabHeader.tsx +10 -9
  143. package/src/Components/TableResize.tsx +52 -37
  144. package/src/Components/TextWithIcon.tsx +30 -19
  145. package/src/Components/ToggleThemeMenu.tsx +31 -13
  146. package/src/Components/TreeTable.tsx +468 -385
  147. package/src/Components/UploadImage.tsx +153 -121
  148. package/src/Components/Utils.tsx +135 -127
  149. package/src/Components/loader.css +40 -31
  150. package/src/Components/withWidth.tsx +23 -12
  151. package/src/Connection.tsx +1 -3
  152. package/src/Dialogs/ComplexCron.tsx +55 -61
  153. package/src/Dialogs/Confirm.tsx +88 -65
  154. package/src/Dialogs/Cron.tsx +122 -112
  155. package/src/Dialogs/Error.tsx +37 -42
  156. package/src/Dialogs/Message.tsx +39 -37
  157. package/src/Dialogs/SelectFile.tsx +95 -85
  158. package/src/Dialogs/SelectID.tsx +141 -129
  159. package/src/Dialogs/SimpleCron.tsx +44 -44
  160. package/src/Dialogs/TextInput.tsx +60 -68
  161. package/src/GenericApp.tsx +342 -242
  162. package/src/LegacyConnection.tsx +972 -842
  163. package/src/Prompt.tsx +3 -1
  164. package/src/Theme.tsx +19 -26
  165. package/src/icons/IconAdapter.tsx +16 -14
  166. package/src/icons/IconAlias.tsx +16 -14
  167. package/src/icons/IconChannel.tsx +55 -16
  168. package/src/icons/IconClearFilter.tsx +17 -15
  169. package/src/icons/IconClosed.tsx +16 -11
  170. package/src/icons/IconCopy.tsx +16 -11
  171. package/src/icons/IconDevice.tsx +121 -22
  172. package/src/icons/IconDocument.tsx +16 -11
  173. package/src/icons/IconDocumentReadOnly.tsx +21 -12
  174. package/src/icons/IconExpert.tsx +20 -12
  175. package/src/icons/IconFx.tsx +16 -14
  176. package/src/icons/IconInstance.tsx +16 -14
  177. package/src/icons/IconLogout.tsx +20 -18
  178. package/src/icons/IconNoIcon.tsx +16 -14
  179. package/src/icons/IconOpen.tsx +17 -12
  180. package/src/icons/IconProps.tsx +4 -3
  181. package/src/icons/IconState.tsx +34 -13
  182. package/src/index.css +3 -2
  183. package/tasks.js +91 -0
  184. package/types.d.ts +141 -0
  185. package/Components/Loaders/PT.css +0 -109
  186. package/Components/Loaders/Vendor.css +0 -13
  187. package/Components/loader.css +0 -222
  188. package/Components/types.d.ts +0 -82
  189. package/assets/devices/Alarm Systems.svg +0 -19
  190. package/assets/devices/Amplifier.svg +0 -22
  191. package/assets/devices/Awnings.svg +0 -5
  192. package/assets/devices/Battery Status.svg +0 -5
  193. package/assets/devices/Ceiling Spotlights.svg +0 -16
  194. package/assets/devices/Chandelier.svg +0 -7
  195. package/assets/devices/Climate.svg +0 -12
  196. package/assets/devices/Coffee Makers.svg +0 -6
  197. package/assets/devices/Cold Water.svg +0 -31
  198. package/assets/devices/Computer.svg +0 -21
  199. package/assets/devices/Consumption.svg +0 -8
  200. package/assets/devices/Curtains.svg +0 -43
  201. package/assets/devices/Dishwashers.svg +0 -12
  202. package/assets/devices/Doors.svg +0 -6
  203. package/assets/devices/Doorstep.svg +0 -35
  204. package/assets/devices/Dryer.svg +0 -14
  205. package/assets/devices/Fan.svg +0 -20
  206. package/assets/devices/Floor Lamps.svg +0 -5
  207. package/assets/devices/Garage Doors.svg +0 -9
  208. package/assets/devices/Gates.svg +0 -32
  209. package/assets/devices/Hairdryer.svg +0 -23
  210. package/assets/devices/Handle.svg +0 -6
  211. package/assets/devices/Hanging Lamps.svg +0 -9
  212. package/assets/devices/Heater.svg +0 -44
  213. package/assets/devices/Hoods.svg +0 -12
  214. package/assets/devices/Hot Water.svg +0 -10
  215. package/assets/devices/Humidity.svg +0 -41
  216. package/assets/devices/Iron.svg +0 -5
  217. package/assets/devices/Irrigation.svg +0 -23
  218. package/assets/devices/Led Strip.svg +0 -31
  219. package/assets/devices/Light.svg +0 -30
  220. package/assets/devices/Lightings.svg +0 -46
  221. package/assets/devices/Lock.svg +0 -19
  222. package/assets/devices/Louvre.svg +0 -7
  223. package/assets/devices/Mowing Machine.svg +0 -9
  224. package/assets/devices/Music.svg +0 -13
  225. package/assets/devices/Outdoor Blinds.svg +0 -7
  226. package/assets/devices/People.svg +0 -19
  227. package/assets/devices/Pool.svg +0 -8
  228. package/assets/devices/Power Consumption.svg +0 -13
  229. package/assets/devices/Printer.svg +0 -10
  230. package/assets/devices/Pump.svg +0 -10
  231. package/assets/devices/Receiver.svg +0 -19
  232. package/assets/devices/Sconces.svg +0 -10
  233. package/assets/devices/Security.svg +0 -34
  234. package/assets/devices/Shading.svg +0 -5
  235. package/assets/devices/Shutters.svg +0 -11
  236. package/assets/devices/SmokeDetector.svg +0 -13
  237. package/assets/devices/Sockets.svg +0 -13
  238. package/assets/devices/Speaker.svg +0 -35
  239. package/assets/devices/Stove.svg +0 -12
  240. package/assets/devices/Table Lamps.svg +0 -12
  241. package/assets/devices/Temperature Sensors.svg +0 -28
  242. package/assets/devices/Tv.svg +0 -8
  243. package/assets/devices/Vacuum Cleaner.svg +0 -16
  244. package/assets/devices/Ventilation.svg +0 -12
  245. package/assets/devices/Washing Machines.svg +0 -16
  246. package/assets/devices/Water Consumption.svg +0 -6
  247. package/assets/devices/Water Heater.svg +0 -8
  248. package/assets/devices/Water.svg +0 -40
  249. package/assets/devices/Weather.svg +0 -28
  250. package/assets/devices/Window.svg +0 -8
  251. package/assets/rooms/Anteroom.svg +0 -53
  252. package/assets/rooms/Attic.svg +0 -21
  253. package/assets/rooms/Balcony.svg +0 -13
  254. package/assets/rooms/Barn.svg +0 -6
  255. package/assets/rooms/Basement.svg +0 -5
  256. package/assets/rooms/Bathroom.svg +0 -38
  257. package/assets/rooms/Bedroom.svg +0 -5
  258. package/assets/rooms/Boiler Room.svg +0 -13
  259. package/assets/rooms/Carport.svg +0 -17
  260. package/assets/rooms/Cellar.svg +0 -89
  261. package/assets/rooms/Chamber.svg +0 -9
  262. package/assets/rooms/Corridor.svg +0 -53
  263. package/assets/rooms/Dining Area.svg +0 -37
  264. package/assets/rooms/Dining Room.svg +0 -37
  265. package/assets/rooms/Dining.svg +0 -37
  266. package/assets/rooms/Dressing Room.svg +0 -5
  267. package/assets/rooms/Driveway.svg +0 -15
  268. package/assets/rooms/Entrance.svg +0 -44
  269. package/assets/rooms/Equipment Room.svg +0 -15
  270. package/assets/rooms/Front Yard.svg +0 -64
  271. package/assets/rooms/Gallery.svg +0 -14
  272. package/assets/rooms/Garage.svg +0 -20
  273. package/assets/rooms/Garden.svg +0 -13
  274. package/assets/rooms/Ground Floor.svg +0 -95
  275. package/assets/rooms/Guest Bathroom.svg +0 -33
  276. package/assets/rooms/Guest Room.svg +0 -5
  277. package/assets/rooms/Gym.svg +0 -5
  278. package/assets/rooms/Hall.svg +0 -19
  279. package/assets/rooms/Home Theater.svg +0 -8
  280. package/assets/rooms/Kitchen.svg +0 -18
  281. package/assets/rooms/Laundry Room.svg +0 -12
  282. package/assets/rooms/Living Area.svg +0 -11
  283. package/assets/rooms/Living Room.svg +0 -10
  284. package/assets/rooms/Locker Room.svg +0 -17
  285. package/assets/rooms/Nursery.svg +0 -5
  286. package/assets/rooms/Office.svg +0 -8
  287. package/assets/rooms/Outdoors.svg +0 -7
  288. package/assets/rooms/Playroom.svg +0 -6
  289. package/assets/rooms/Pool.svg +0 -8
  290. package/assets/rooms/Rear Wall.svg +0 -30
  291. package/assets/rooms/Second Floor.svg +0 -95
  292. package/assets/rooms/Shed.svg +0 -16
  293. package/assets/rooms/Sleeping Area.svg +0 -22
  294. package/assets/rooms/Stairway.svg +0 -5
  295. package/assets/rooms/Stairwell.svg +0 -15
  296. package/assets/rooms/Storeroom.svg +0 -5
  297. package/assets/rooms/Summer House.svg +0 -27
  298. package/assets/rooms/Swimming Pool.svg +0 -21
  299. package/assets/rooms/Terrace.svg +0 -7
  300. package/assets/rooms/Toilet.svg +0 -10
  301. package/assets/rooms/Upstairs.svg +0 -6
  302. package/assets/rooms/Wardrobe.svg +0 -60
  303. package/assets/rooms/Washroom.svg +0 -20
  304. package/assets/rooms/Wc.svg +0 -10
  305. package/assets/rooms/Windscreen.svg +0 -60
  306. package/assets/rooms/Workshop.svg +0 -23
  307. package/assets/rooms/Workspace.svg +0 -8
@@ -3,9 +3,9 @@
3
3
  *
4
4
  * MIT License
5
5
  *
6
- * */
7
- import React from 'react';
8
- import { PROGRESS, Connection, AdminConnection } from '@iobroker/socket-client';
6
+ */
7
+ import React, { type JSX } from 'react';
8
+ import { PROGRESS, Connection, type AdminConnection } from '@iobroker/socket-client';
9
9
  import * as Sentry from '@sentry/browser';
10
10
 
11
11
  import { Snackbar, IconButton } from '@mui/material';
@@ -21,7 +21,7 @@ import SaveCloseButtons from './Components/SaveCloseButtons';
21
21
  import ConfirmDialog from './Dialogs/Confirm';
22
22
  import I18n from './i18n';
23
23
  import DialogError from './Dialogs/Error';
24
- import {
24
+ import type {
25
25
  GenericAppProps,
26
26
  GenericAppState,
27
27
  GenericAppSettings,
@@ -31,6 +31,18 @@ import {
31
31
  Width,
32
32
  } from './types';
33
33
 
34
+ import langEn from './i18n/en.json';
35
+ import langDe from './i18n/de.json';
36
+ import langRu from './i18n/ru.json';
37
+ import langPt from './i18n/pt.json';
38
+ import langNl from './i18n/nl.json';
39
+ import langFr from './i18n/fr.json';
40
+ import langIt from './i18n/it.json';
41
+ import langEs from './i18n/es.json';
42
+ import langPl from './i18n/pl.json';
43
+ import langUk from './i18n/uk.json';
44
+ import langZhCn from './i18n/zh-cn.json';
45
+
34
46
  declare global {
35
47
  /** If config has been changed */
36
48
  // eslint-disable-next-line no-var
@@ -101,7 +113,10 @@ body {
101
113
  }
102
114
  `;
103
115
 
104
- class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extends GenericAppState = GenericAppState> extends Router<TProps, TState> {
116
+ class GenericApp<
117
+ TProps extends GenericAppProps = GenericAppProps,
118
+ TState extends GenericAppState = GenericAppState,
119
+ > extends Router<TProps, TState> {
105
120
  protected socket: AdminConnection;
106
121
 
107
122
  protected readonly instance: number;
@@ -134,7 +149,9 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
134
149
  private resizeTimer: ReturnType<typeof setTimeout> | null = null;
135
150
 
136
151
  constructor(props: TProps, settings?: GenericAppSettings) {
137
- const ConnectionClass = (props.Connection || settings?.Connection || Connection) as unknown as typeof AdminConnection;
152
+ const ConnectionClass = (props.Connection ||
153
+ settings?.Connection ||
154
+ Connection) as unknown as typeof AdminConnection;
138
155
  // const ConnectionClass = props.Connection === 'admin' || settings.Connection = 'admin' ? AdminConnection : (props.Connection || settings.Connection || Connection);
139
156
 
140
157
  if (!window.document.getElementById('generic-app-iobroker-component')) {
@@ -150,7 +167,7 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
150
167
  const io = new window.SocketClient();
151
168
  delete window.io;
152
169
  window.io = io;
153
- } catch (e) {
170
+ } catch {
154
171
  // ignore
155
172
  }
156
173
  }
@@ -161,78 +178,98 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
161
178
 
162
179
  const query = (window.location.search || '').replace(/^\?/, '').replace(/#.*$/, '');
163
180
  const args: Record<string, string | boolean> = {};
164
- query.trim().split('&').filter(t => t.trim()).forEach(b => {
165
- const parts = b.split('=');
166
- args[parts[0]] = parts.length === 2 ? parts[1] : true;
167
- if (args[parts[0]] === 'true') {
168
- args[parts[0]] = true;
169
- } else if (args[parts[0]] === 'false') {
170
- args[parts[0]] = false;
171
- }
172
- });
181
+ query
182
+ .trim()
183
+ .split('&')
184
+ .filter(t => t.trim())
185
+ .forEach(b => {
186
+ const parts = b.split('=');
187
+ args[parts[0]] = parts.length === 2 ? parts[1] : true;
188
+ if (args[parts[0]] === 'true') {
189
+ args[parts[0]] = true;
190
+ } else if (args[parts[0]] === 'false') {
191
+ args[parts[0]] = false;
192
+ }
193
+ });
173
194
 
174
195
  // extract instance from URL
175
- this.instance = settings?.instance ?? props.instance ?? (args.instance !== undefined ? parseInt(args.instance as string, 10) || 0 : (parseInt(window.location.search.slice(1), 10) || 0));
196
+ this.instance =
197
+ settings?.instance ??
198
+ props.instance ??
199
+ (args.instance !== undefined
200
+ ? parseInt(args.instance as string, 10) || 0
201
+ : parseInt(window.location.search.slice(1), 10) || 0);
176
202
  // extract adapter name from URL
177
203
  const tmp = window.location.pathname.split('/');
178
- this.adapterName = settings?.adapterName || props.adapterName || window.adapterName || tmp[tmp.length - 2] || 'iot';
179
- this.instanceId = `system.adapter.${this.adapterName}.${this.instance}`;
204
+ this.adapterName =
205
+ settings?.adapterName || props.adapterName || window.adapterName || tmp[tmp.length - 2] || 'iot';
206
+ this.instanceId = `system.adapter.${this.adapterName}.${this.instance}`;
180
207
  this.newReact = args.newReact === true; // it is admin5
181
208
 
182
209
  const location = Router.getLocation();
183
- location.tab = location.tab || ((window as any)._localStorage || window.localStorage).getItem(`${this.adapterName}-adapter`) || '';
210
+ location.tab =
211
+ location.tab ||
212
+ ((window as any)._localStorage || window.localStorage).getItem(`${this.adapterName}-adapter`) ||
213
+ '';
184
214
 
185
215
  const themeInstance = this.createTheme();
186
216
 
187
217
  this.state = {
188
218
  ...(this.state || {}), // keep the existing state
189
- selectedTab: ((window as any)._localStorage || window.localStorage).getItem(`${this.adapterName}-adapter`) || '',
219
+ selectedTab:
220
+ ((window as any)._localStorage || window.localStorage).getItem(`${this.adapterName}-adapter`) || '',
190
221
  selectedTabNum: -1,
191
- native: {},
192
- errorText: '',
193
- changed: false,
194
- connected: false,
195
- loaded: false,
222
+ native: {},
223
+ errorText: '',
224
+ changed: false,
225
+ connected: false,
226
+ loaded: false,
196
227
  isConfigurationError: '',
197
- expertMode: false,
198
- toast: '',
199
- theme: themeInstance,
200
- themeName: this.getThemeName(themeInstance),
201
- themeType: this.getThemeType(themeInstance),
202
- bottomButtons: (settings && settings.bottomButtons) === false ? false : (props?.bottomButtons !== false),
203
- width: GenericApp.getWidth(),
204
- confirmClose: false,
205
- _alert: false,
206
- _alertType: 'info',
207
- _alertMessage: '',
228
+ expertMode: false,
229
+ toast: '',
230
+ theme: themeInstance,
231
+ themeName: this.getThemeName(themeInstance),
232
+ themeType: this.getThemeType(themeInstance),
233
+ bottomButtons: (settings && settings.bottomButtons) === false ? false : props?.bottomButtons !== false,
234
+ width: GenericApp.getWidth(),
235
+ confirmClose: false,
236
+ _alert: false,
237
+ _alertType: 'info',
238
+ _alertMessage: '',
208
239
  } satisfies GenericAppState as TState;
209
240
 
210
241
  // init translations
211
242
  const translations: Record<ioBroker.Languages, Record<string, string>> = {
212
- en: require('./i18n/en.json'),
213
- de: require('./i18n/de.json'),
214
- ru: require('./i18n/ru.json'),
215
- pt: require('./i18n/pt.json'),
216
- nl: require('./i18n/nl.json'),
217
- fr: require('./i18n/fr.json'),
218
- it: require('./i18n/it.json'),
219
- es: require('./i18n/es.json'),
220
- pl: require('./i18n/pl.json'),
221
- uk: require('./i18n/uk.json'),
222
- 'zh-cn': require('./i18n/zh-cn.json'),
243
+ en: langEn,
244
+ de: langDe,
245
+ ru: langRu,
246
+ pt: langPt,
247
+ nl: langNl,
248
+ fr: langFr,
249
+ it: langIt,
250
+ es: langEs,
251
+ pl: langPl,
252
+ uk: langUk,
253
+ 'zh-cn': langZhCn,
223
254
  };
224
255
 
225
256
  // merge together
226
257
  if (settings && settings.translations) {
227
258
  Object.keys(settings.translations).forEach(lang => {
228
259
  if (settings.translations) {
229
- translations[lang as ioBroker.Languages] = Object.assign(translations[lang as ioBroker.Languages], settings.translations[lang as ioBroker.Languages] || {});
260
+ translations[lang as ioBroker.Languages] = Object.assign(
261
+ translations[lang as ioBroker.Languages],
262
+ settings.translations[lang as ioBroker.Languages] || {},
263
+ );
230
264
  }
231
265
  });
232
266
  } else if (props.translations) {
233
267
  Object.keys(props.translations).forEach(lang => {
234
268
  if (props.translations) {
235
- translations[lang as ioBroker.Languages] = Object.assign(translations[lang as ioBroker.Languages], props.translations[lang as ioBroker.Languages] || {});
269
+ translations[lang as ioBroker.Languages] = Object.assign(
270
+ translations[lang as ioBroker.Languages],
271
+ props.translations[lang as ioBroker.Languages] || {},
272
+ );
236
273
  }
237
274
  });
238
275
  }
@@ -288,18 +325,25 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
288
325
  I18n.setLanguage(this.socket.systemLang);
289
326
 
290
327
  // subscribe because of language and expert mode
291
- this.socket.subscribeObject('system.config', this.onSystemConfigChanged)
328
+ this.socket
329
+ .subscribeObject('system.config', this.onSystemConfigChanged)
292
330
  .then(() => this.getSystemConfig())
293
331
  .then(obj => {
294
- this._secret = (typeof obj !== 'undefined' && obj.native && obj.native.secret) || 'Zgfr56gFe87jJOM';
332
+ this._secret =
333
+ (typeof obj !== 'undefined' && obj.native && obj.native.secret) || 'Zgfr56gFe87jJOM';
295
334
  this._systemConfig = obj?.common || ({} as ioBroker.SystemConfigCommon);
296
335
  return this.socket.getObject(this.instanceId);
297
336
  })
298
337
  .then(async obj => {
299
338
  let waitPromise;
300
- const instanceObj: ioBroker.InstanceObject | null | undefined = obj as ioBroker.InstanceObject | null | undefined;
339
+ const instanceObj: ioBroker.InstanceObject | null | undefined = obj as
340
+ | ioBroker.InstanceObject
341
+ | null
342
+ | undefined;
301
343
 
302
- const sentryPluginEnabled = (await this.socket.getState(`${this.instanceId}.plugins.sentry.enabled`))?.val;
344
+ const sentryPluginEnabled = (
345
+ await this.socket.getState(`${this.instanceId}.plugins.sentry.enabled`)
346
+ )?.val;
303
347
 
304
348
  const sentryEnabled =
305
349
  sentryPluginEnabled !== false &&
@@ -309,7 +353,7 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
309
353
  instanceObj.common.version &&
310
354
  // @ts-expect-error will be extended in js-controller TODO: (BF: 2024.05.30) this is redundant to state `${this.instanceId}.plugins.sentry.enabled`, remove this in future when admin sets the state correctly
311
355
  !instanceObj.common.disableDataReporting &&
312
- window.location.host !== 'localhost:3000';
356
+ window.location.host !== 'localhost:3000';
313
357
 
314
358
  // activate sentry plugin
315
359
  if (!this.sentryStarted && this.sentryDSN && sentryEnabled) {
@@ -318,9 +362,7 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
318
362
  Sentry.init({
319
363
  dsn: this.sentryDSN,
320
364
  release: `iobroker.${instanceObj.common.name}@${instanceObj.common.version}`,
321
- integrations: [
322
- Sentry.dedupeIntegration(),
323
- ],
365
+ integrations: [Sentry.dedupeIntegration()],
324
366
  });
325
367
 
326
368
  console.log('Sentry initialized');
@@ -331,37 +373,37 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
331
373
  if (!this.sentryInited && sentryEnabled) {
332
374
  this.sentryInited = true;
333
375
 
334
- waitPromise = this.socket.getObject('system.meta.uuid')
335
- .then(uuidObj => {
336
- if (uuidObj && uuidObj.native && uuidObj.native.uuid) {
337
- const scope = Sentry.getCurrentScope();
338
- scope.setUser({ id: uuidObj.native.uuid });
339
- }
340
- });
376
+ waitPromise = this.socket.getObject('system.meta.uuid').then(uuidObj => {
377
+ if (uuidObj && uuidObj.native && uuidObj.native.uuid) {
378
+ const scope = Sentry.getCurrentScope();
379
+ scope.setUser({ id: uuidObj.native.uuid });
380
+ }
381
+ });
341
382
  }
342
383
 
343
384
  waitPromise = waitPromise || Promise.resolve();
344
385
 
345
- waitPromise
346
- .then(() => {
347
- if (instanceObj) {
348
- this.common = instanceObj?.common;
349
- this.onPrepareLoad(instanceObj.native, instanceObj.encryptedNative); // decode all secrets
350
- this.savedNative = JSON.parse(JSON.stringify(instanceObj.native));
351
- this.setState({ native: instanceObj.native, loaded: true, expertMode: this.getExpertMode() }, () =>
352
- this.onConnectionReady && this.onConnectionReady());
353
- } else {
354
- console.warn('Cannot load instance settings');
355
- this.setState(
356
- {
357
- native: {},
358
- loaded: true,
359
- expertMode: this.getExpertMode(),
360
- },
361
- () => this.onConnectionReady && this.onConnectionReady(),
362
- );
363
- }
364
- });
386
+ void waitPromise.then(() => {
387
+ if (instanceObj) {
388
+ this.common = instanceObj?.common;
389
+ this.onPrepareLoad(instanceObj.native, instanceObj.encryptedNative); // decode all secrets
390
+ this.savedNative = JSON.parse(JSON.stringify(instanceObj.native));
391
+ this.setState(
392
+ { native: instanceObj.native, loaded: true, expertMode: this.getExpertMode() },
393
+ () => this.onConnectionReady && this.onConnectionReady(),
394
+ );
395
+ } else {
396
+ console.warn('Cannot load instance settings');
397
+ this.setState(
398
+ {
399
+ native: {},
400
+ loaded: true,
401
+ expertMode: this.getExpertMode(),
402
+ },
403
+ () => this.onConnectionReady && this.onConnectionReady(),
404
+ );
405
+ }
406
+ });
365
407
  })
366
408
  .catch(e => window.alert(`Cannot settings: ${e}`));
367
409
  },
@@ -374,13 +416,14 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
374
416
 
375
417
  /**
376
418
  * Checks if this connection is running in a web adapter and not in an admin.
419
+ *
377
420
  * @returns True if running in a web adapter or in a socketio adapter.
378
421
  */
379
422
  static isWeb(): boolean {
380
423
  return window.socketUrl !== undefined;
381
424
  }
382
425
 
383
- showAlert(message: string, type?: 'info' | 'warning' | 'error' | 'success') {
426
+ showAlert(message: string, type?: 'info' | 'warning' | 'error' | 'success'): void {
384
427
  if (type !== 'error' && type !== 'warning' && type !== 'info' && type !== 'success') {
385
428
  type = 'info';
386
429
  }
@@ -392,21 +435,27 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
392
435
  });
393
436
  }
394
437
 
395
- renderAlertSnackbar() {
438
+ renderAlertSnackbar(): JSX.Element {
396
439
  this.alertDialogRendered = true;
397
440
 
398
- return <Snackbar
399
- style={this.state._alertType === 'error' ?
400
- { backgroundColor: '#f44336' } :
401
- (this.state._alertType === 'success' ? { backgroundColor: '#4caf50' } : undefined)}
402
- open={this.state._alert}
403
- autoHideDuration={6000}
404
- onClose={(_e, reason) => reason !== 'clickaway' && this.setState({ _alert: false })}
405
- message={this.state._alertMessage}
406
- />;
441
+ return (
442
+ <Snackbar
443
+ style={
444
+ this.state._alertType === 'error'
445
+ ? { backgroundColor: '#f44336' }
446
+ : this.state._alertType === 'success'
447
+ ? { backgroundColor: '#4caf50' }
448
+ : undefined
449
+ }
450
+ open={this.state._alert}
451
+ autoHideDuration={6000}
452
+ onClose={(_e, reason) => reason !== 'clickaway' && this.setState({ _alert: false })}
453
+ message={this.state._alertMessage}
454
+ />
455
+ );
407
456
  }
408
457
 
409
- onSystemConfigChanged = (id: string, obj: ioBroker.AnyObject | null | undefined) => {
458
+ onSystemConfigChanged = (id: string, obj: ioBroker.AnyObject | null | undefined): void => {
410
459
  if (obj && id === 'system.config') {
411
460
  if (this.socket.systemLang !== (obj as ioBroker.SystemConfigObject)?.common.language) {
412
461
  this.socket.systemLang = (obj as ioBroker.SystemConfigObject)?.common.language || 'en';
@@ -414,10 +463,12 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
414
463
  }
415
464
 
416
465
  if (this._systemConfig?.expertMode !== !!(obj as ioBroker.SystemConfigObject)?.common?.expertMode) {
417
- this._systemConfig = (obj as ioBroker.SystemConfigObject)?.common || ({} as ioBroker.SystemConfigCommon);
466
+ this._systemConfig =
467
+ (obj as ioBroker.SystemConfigObject)?.common || ({} as ioBroker.SystemConfigCommon);
418
468
  this.setState({ expertMode: this.getExpertMode() });
419
469
  } else {
420
- this._systemConfig = (obj as ioBroker.SystemConfigObject)?.common || ({} as ioBroker.SystemConfigCommon);
470
+ this._systemConfig =
471
+ (obj as ioBroker.SystemConfigObject)?.common || ({} as ioBroker.SystemConfigCommon);
421
472
  }
422
473
  }
423
474
  };
@@ -425,7 +476,7 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
425
476
  /**
426
477
  * Called immediately after a component is mounted. Setting state here will trigger re-rendering.
427
478
  */
428
- componentDidMount() {
479
+ componentDidMount(): void {
429
480
  window.addEventListener('resize', this.onResize, true);
430
481
  window.addEventListener('message', this.onReceiveMessage, false);
431
482
  super.componentDidMount();
@@ -434,13 +485,13 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
434
485
  /**
435
486
  * Called immediately before a component is destroyed.
436
487
  */
437
- componentWillUnmount() {
488
+ componentWillUnmount(): void {
438
489
  window.removeEventListener('resize', this.onResize, true);
439
490
  window.removeEventListener('message', this.onReceiveMessage, false);
440
491
  super.componentWillUnmount();
441
492
  }
442
493
 
443
- onReceiveMessage = (message: { data: string } | null) => {
494
+ onReceiveMessage = (message: { data: string } | null): void => {
444
495
  if (message?.data) {
445
496
  if (message.data === 'updateTheme') {
446
497
  const newThemeName = Utils.getThemeName();
@@ -448,24 +499,29 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
448
499
 
449
500
  const newTheme = this.createTheme(newThemeName);
450
501
 
451
- this.setState({
452
- theme: newTheme,
453
- themeName: this.getThemeName(newTheme),
454
- themeType: this.getThemeType(newTheme),
455
- }, () => {
456
- this.props.onThemeChange && this.props.onThemeChange(newThemeName);
457
- this.onThemeChanged && this.onThemeChanged(newThemeName);
458
- });
502
+ this.setState(
503
+ {
504
+ theme: newTheme,
505
+ themeName: this.getThemeName(newTheme),
506
+ themeType: this.getThemeType(newTheme),
507
+ },
508
+ () => {
509
+ this.props.onThemeChange && this.props.onThemeChange(newThemeName);
510
+ this.onThemeChanged && this.onThemeChanged(newThemeName);
511
+ },
512
+ );
459
513
  } else if (message.data === 'updateExpertMode') {
460
514
  this.onToggleExpertMode && this.onToggleExpertMode(this.getExpertMode());
461
- } else if (message.data !== 'chartReady') { // if not "echart ready" message
462
- // eslint-disable-next-line no-console
463
- console.debug(`Received unknown message: "${JSON.stringify(message.data)}". May be it will be processed later`);
515
+ } else if (message.data !== 'chartReady') {
516
+ // if not "echart ready" message
517
+ console.debug(
518
+ `Received unknown message: "${JSON.stringify(message.data)}". May be it will be processed later`,
519
+ );
464
520
  }
465
521
  }
466
522
  };
467
523
 
468
- private onResize = () => {
524
+ private onResize = (): void => {
469
525
  this.resizeTimer && clearTimeout(this.resizeTimer);
470
526
  this.resizeTimer = setTimeout(() => {
471
527
  this.resizeTimer = null;
@@ -475,7 +531,6 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
475
531
 
476
532
  /**
477
533
  * Gets the width depending on the window inner width.
478
- * @returns {import('./types').Width}
479
534
  */
480
535
  static getWidth(): Width {
481
536
  /**
@@ -500,15 +555,18 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
500
555
 
501
556
  /**
502
557
  * Get a theme
558
+ *
503
559
  * @param name Theme name
504
560
  */
505
- createTheme(name?: ThemeName | null | undefined): IobTheme {
561
+ // eslint-disable-next-line class-methods-use-this
562
+ createTheme(name?: ThemeName | null): IobTheme {
506
563
  return Theme(Utils.getThemeName(name));
507
564
  }
508
565
 
509
566
  /**
510
567
  * Get the theme name
511
568
  */
569
+ // eslint-disable-next-line class-methods-use-this
512
570
  getThemeName(currentTheme: IobTheme): ThemeName {
513
571
  return currentTheme.name;
514
572
  }
@@ -516,50 +574,57 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
516
574
  /**
517
575
  * Get the theme type
518
576
  */
577
+ // eslint-disable-next-line class-methods-use-this
519
578
  getThemeType(currentTheme: IobTheme): ThemeType {
520
579
  return currentTheme.palette.mode;
521
580
  }
522
581
 
523
- onThemeChanged(_newThemeName: string) {
524
-
525
- }
526
-
527
- onToggleExpertMode(_expertMode: boolean) {
582
+ // eslint-disable-next-line class-methods-use-this
583
+ onThemeChanged(_newThemeName: string): void {}
528
584
 
529
- }
585
+ // eslint-disable-next-line class-methods-use-this
586
+ onToggleExpertMode(_expertMode: boolean): void {}
530
587
 
531
588
  /**
532
589
  * Changes the current theme
533
- * */
534
- toggleTheme(newThemeName?: ThemeName) {
590
+ */
591
+ toggleTheme(newThemeName?: ThemeName): void {
535
592
  const themeName = this.state.themeName;
536
593
 
537
594
  // dark => blue => colored => light => dark
538
- newThemeName = newThemeName || (themeName === 'dark' ? 'blue' :
539
- (themeName === 'blue' ? 'colored' :
540
- (themeName === 'colored' ? 'light' : 'dark')));
595
+ newThemeName =
596
+ newThemeName ||
597
+ (themeName === 'dark'
598
+ ? 'light'
599
+ : themeName === 'blue'
600
+ ? 'light'
601
+ : themeName === 'colored'
602
+ ? 'light'
603
+ : 'dark');
541
604
 
542
605
  if (newThemeName !== themeName) {
543
606
  Utils.setThemeName(newThemeName);
544
607
 
545
608
  const newTheme = this.createTheme(newThemeName);
546
609
 
547
- this.setState({
548
- theme: newTheme,
549
- themeName: this.getThemeName(newTheme),
550
- themeType: this.getThemeType(newTheme),
551
- }, () => {
552
- this.props.onThemeChange && this.props.onThemeChange(newThemeName || 'light');
553
- this.onThemeChanged && this.onThemeChanged(newThemeName || 'light');
554
- });
610
+ this.setState(
611
+ {
612
+ theme: newTheme,
613
+ themeName: this.getThemeName(newTheme),
614
+ themeType: this.getThemeType(newTheme),
615
+ },
616
+ () => {
617
+ this.props.onThemeChange && this.props.onThemeChange(newThemeName || 'light');
618
+ this.onThemeChanged && this.onThemeChanged(newThemeName || 'light');
619
+ },
620
+ );
555
621
  }
556
622
  }
557
623
 
558
624
  /**
559
625
  * Gets the system configuration.
560
- * @returns {Promise<ioBroker.OtherObject>}
561
626
  */
562
- getSystemConfig() {
627
+ getSystemConfig(): Promise<ioBroker.SystemConfigObject> {
563
628
  return this.socket.getSystemConfig();
564
629
  }
565
630
 
@@ -574,8 +639,8 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
574
639
  * Gets called when the socket.io connection is ready.
575
640
  * You can overload this function to execute own commands.
576
641
  */
577
- onConnectionReady() {
578
- }
642
+ // eslint-disable-next-line class-methods-use-this
643
+ onConnectionReady(): void {}
579
644
 
580
645
  /**
581
646
  * Encrypts a string.
@@ -584,8 +649,9 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
584
649
  let result = '';
585
650
  if (this._secret) {
586
651
  for (let i = 0; i < value.length; i++) {
587
- // eslint-disable-next-line no-bitwise
588
- result += String.fromCharCode(this._secret[i % this._secret.length].charCodeAt(0) ^ value.charCodeAt(i));
652
+ result += String.fromCharCode(
653
+ this._secret[i % this._secret.length].charCodeAt(0) ^ value.charCodeAt(i),
654
+ );
589
655
  }
590
656
  }
591
657
  return result;
@@ -598,8 +664,9 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
598
664
  let result = '';
599
665
  if (this._secret) {
600
666
  for (let i = 0; i < value.length; i++) {
601
- // eslint-disable-next-line no-bitwise
602
- result += String.fromCharCode(this._secret[i % this._secret.length].charCodeAt(0) ^ value.charCodeAt(i));
667
+ result += String.fromCharCode(
668
+ this._secret[i % this._secret.length].charCodeAt(0) ^ value.charCodeAt(i),
669
+ );
603
670
  }
604
671
  }
605
672
  return result;
@@ -609,7 +676,7 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
609
676
  * Gets called when the navigation hash changes.
610
677
  * You may override this if needed.
611
678
  */
612
- onHashChanged() {
679
+ onHashChanged(): void {
613
680
  const location = Router.getLocation();
614
681
  if (location.tab !== this.state.selectedTab) {
615
682
  this.selectTab(location.tab);
@@ -619,7 +686,7 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
619
686
  /**
620
687
  * Selects the given tab.
621
688
  */
622
- selectTab(tab: string, index?: number) {
689
+ selectTab(tab: string, index?: number): void {
623
690
  ((window as any)._localStorage || window.localStorage).setItem(`${this.adapterName}-adapter`, tab);
624
691
  this.setState({ selectedTab: tab, selectedTabNum: index });
625
692
  }
@@ -630,11 +697,12 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
630
697
  */
631
698
  onPrepareSave(settings: Record<string, any>): boolean {
632
699
  // here you can encode values
633
- this.encryptedFields && this.encryptedFields.forEach(attr => {
634
- if (settings[attr]) {
635
- settings[attr] = this.encrypt(settings[attr]);
636
- }
637
- });
700
+ this.encryptedFields &&
701
+ this.encryptedFields.forEach(attr => {
702
+ if (settings[attr]) {
703
+ settings[attr] = this.encrypt(settings[attr]);
704
+ }
705
+ });
638
706
 
639
707
  return true;
640
708
  }
@@ -642,33 +710,40 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
642
710
  /**
643
711
  * Gets called after the settings are loaded.
644
712
  * You may override this if needed.
713
+ *
714
+ * @param settings instance settings from native part
645
715
  * @param encryptedNative optional list of fields to be decrypted
646
716
  */
647
- onPrepareLoad(settings: Record<string, any>, encryptedNative?: string[]) {
717
+ onPrepareLoad(settings: Record<string, any>, encryptedNative?: string[]): void {
648
718
  // here you can encode values
649
- this.encryptedFields && this.encryptedFields.forEach(attr => {
650
- if (settings[attr]) {
651
- settings[attr] = this.decrypt(settings[attr]);
652
- }
653
- });
654
- encryptedNative && encryptedNative.forEach(attr => {
655
- this.encryptedFields = this.encryptedFields || [];
656
- !this.encryptedFields.includes(attr) && this.encryptedFields.push(attr);
657
- if (settings[attr]) {
658
- settings[attr] = this.decrypt(settings[attr]);
659
- }
660
- });
719
+ this.encryptedFields &&
720
+ this.encryptedFields.forEach(attr => {
721
+ if (settings[attr]) {
722
+ settings[attr] = this.decrypt(settings[attr]);
723
+ }
724
+ });
725
+ encryptedNative &&
726
+ encryptedNative.forEach(attr => {
727
+ this.encryptedFields = this.encryptedFields || [];
728
+ !this.encryptedFields.includes(attr) && this.encryptedFields.push(attr);
729
+ if (settings[attr]) {
730
+ settings[attr] = this.decrypt(settings[attr]);
731
+ }
732
+ });
661
733
  }
662
734
 
663
735
  /**
664
736
  * Gets the extendable instances.
665
- * @returns {Promise<any[]>}
666
737
  */
667
738
  async getExtendableInstances(): Promise<ioBroker.InstanceObject[]> {
668
739
  try {
669
- const instances = await this.socket.getObjectViewSystem('instance', 'system.adapter.', 'system.adapter.\u9999');
740
+ const instances = await this.socket.getObjectViewSystem(
741
+ 'instance',
742
+ 'system.adapter.',
743
+ 'system.adapter.\u9999',
744
+ );
670
745
  return Object.values(instances).filter(instance => !!instance?.common?.webExtendable);
671
- } catch (e) {
746
+ } catch {
672
747
  return [];
673
748
  }
674
749
  }
@@ -692,16 +767,18 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
692
767
 
693
768
  /**
694
769
  * Saves the settings to the server.
770
+ *
695
771
  * @param isClose True if the user is closing the dialog.
696
772
  */
697
- onSave(isClose?: boolean) {
773
+ onSave(isClose?: boolean): void {
698
774
  let oldObj: ioBroker.InstanceObject;
699
775
  if (this.state.isConfigurationError) {
700
776
  this.setState({ errorText: this.state.isConfigurationError });
701
777
  return;
702
778
  }
703
779
 
704
- this.socket.getObject(this.instanceId)
780
+ this.socket
781
+ .getObject(this.instanceId)
705
782
  .then(_oldObj => {
706
783
  oldObj = (_oldObj || {}) as ioBroker.InstanceObject;
707
784
 
@@ -722,7 +799,9 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
722
799
  if (this.state.common[b] === null) {
723
800
  (oldObj as Record<string, any>).common[b] = null;
724
801
  } else if (this.state.common[b] !== undefined) {
725
- (oldObj as Record<string, any>).common[b] = JSON.parse(JSON.stringify(this.state.common[b]));
802
+ (oldObj as Record<string, any>).common[b] = JSON.parse(
803
+ JSON.stringify(this.state.common[b]),
804
+ );
726
805
  } else {
727
806
  delete (oldObj as Record<string, any>).common[b];
728
807
  }
@@ -740,7 +819,7 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
740
819
  globalThis.changed = false;
741
820
  try {
742
821
  window.parent.postMessage('nochange', '*');
743
- } catch (e) {
822
+ } catch {
744
823
  // ignore
745
824
  }
746
825
 
@@ -753,40 +832,42 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
753
832
  /**
754
833
  * Renders the toast.
755
834
  */
756
- renderToast() {
835
+ renderToast(): JSX.Element | null {
757
836
  if (!this.state.toast) {
758
837
  return null;
759
838
  }
760
839
 
761
- return <Snackbar
762
- anchorOrigin={{
763
- vertical: 'bottom',
764
- horizontal: 'left',
765
- }}
766
- open={!0}
767
- autoHideDuration={6000}
768
- onClose={() => this.setState({ toast: '' })}
769
- ContentProps={{ 'aria-describedby': 'message-id' }}
770
- message={<span id="message-id">{this.state.toast}</span>}
771
- action={[
772
- <IconButton
773
- key="close"
774
- aria-label="Close"
775
- color="inherit"
776
- className={this.props.classes?.close}
777
- onClick={() => this.setState({ toast: '' })}
778
- size="large"
779
- >
780
- <IconClose />
781
- </IconButton>,
782
- ]}
783
- />;
840
+ return (
841
+ <Snackbar
842
+ anchorOrigin={{
843
+ vertical: 'bottom',
844
+ horizontal: 'left',
845
+ }}
846
+ open={!0}
847
+ autoHideDuration={6000}
848
+ onClose={() => this.setState({ toast: '' })}
849
+ ContentProps={{ 'aria-describedby': 'message-id' }}
850
+ message={<span id="message-id">{this.state.toast}</span>}
851
+ action={[
852
+ <IconButton
853
+ key="close"
854
+ aria-label="Close"
855
+ color="inherit"
856
+ className={this.props.classes?.close}
857
+ onClick={() => this.setState({ toast: '' })}
858
+ size="large"
859
+ >
860
+ <IconClose />
861
+ </IconButton>,
862
+ ]}
863
+ />
864
+ );
784
865
  }
785
866
 
786
867
  /**
787
868
  * Closes the dialog.
788
869
  */
789
- static onClose() {
870
+ static onClose(): void {
790
871
  if (typeof window.parent !== 'undefined' && window.parent) {
791
872
  try {
792
873
  if (window.parent.$iframeDialog && typeof window.parent.$iframeDialog.close === 'function') {
@@ -794,7 +875,7 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
794
875
  } else {
795
876
  window.parent.postMessage('close', '*');
796
877
  }
797
- } catch (e) {
878
+ } catch {
798
879
  window.parent.postMessage('close', '*');
799
880
  }
800
881
  }
@@ -808,16 +889,22 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
808
889
  return null;
809
890
  }
810
891
 
811
- return <DialogError text={this.state.errorText} onClose={() => this.setState({ errorText: '' })} />;
892
+ return (
893
+ <DialogError
894
+ text={this.state.errorText}
895
+ onClose={() => this.setState({ errorText: '' })}
896
+ />
897
+ );
812
898
  }
813
899
 
814
900
  /**
815
901
  * Checks if the configuration has changed.
816
- * @param {Record<string, any>} [native] the new state
902
+ *
903
+ * @param native the new state
817
904
  */
818
905
  getIsChanged(native: Record<string, any>): boolean {
819
906
  native = native || this.state.native;
820
- const isChanged = JSON.stringify(native) !== JSON.stringify(this.savedNative);
907
+ const isChanged = JSON.stringify(native) !== JSON.stringify(this.savedNative);
821
908
 
822
909
  globalThis.changed = isChanged;
823
910
 
@@ -826,9 +913,10 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
826
913
 
827
914
  /**
828
915
  * Gets called when loading the configuration.
916
+ *
829
917
  * @param newNative The new configuration object.
830
918
  */
831
- onLoadConfig(newNative: Record<string, any>) {
919
+ onLoadConfig(newNative: Record<string, any>): void {
832
920
  if (JSON.stringify(newNative) !== JSON.stringify(this.state.native)) {
833
921
  this.setState({ native: newNative, changed: this.getIsChanged(newNative) });
834
922
  }
@@ -837,7 +925,7 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
837
925
  /**
838
926
  * Sets the configuration error.
839
927
  */
840
- setConfigurationError(errorText: string) {
928
+ setConfigurationError(errorText: string): void {
841
929
  if (this.state.isConfigurationError !== errorText) {
842
930
  this.setState({ isConfigurationError: errorText });
843
931
  }
@@ -851,31 +939,37 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
851
939
  return null;
852
940
  }
853
941
 
854
- return <>
855
- {this.state.bottomButtons ? <SaveCloseButtons
856
- theme={this.state.theme}
857
- newReact={this.newReact}
858
- noTextOnButtons={this.state.width === 'xs' || this.state.width === 'sm' || this.state.width === 'md'}
859
- changed={this.state.changed}
860
- onSave={isClose => this.onSave(isClose)}
861
- onClose={() => {
862
- if (this.state.changed) {
863
- this.setState({ confirmClose: true });
864
- } else {
865
- GenericApp.onClose();
866
- }
867
- }}
868
- /> : null}
869
- {this.state.confirmClose ? <ConfirmDialog
870
- title={I18n.t('ra_Please confirm')}
871
- text={I18n.t('ra_Some data are not stored. Discard?')}
872
- ok={I18n.t('ra_Discard')}
873
- cancel={I18n.t('ra_Cancel')}
874
- onClose={isYes =>
875
- this.setState({ confirmClose: false }, () =>
876
- isYes && GenericApp.onClose())}
877
- /> : null}
878
- </>;
942
+ return (
943
+ <>
944
+ {this.state.bottomButtons ? (
945
+ <SaveCloseButtons
946
+ theme={this.state.theme}
947
+ newReact={this.newReact}
948
+ noTextOnButtons={
949
+ this.state.width === 'xs' || this.state.width === 'sm' || this.state.width === 'md'
950
+ }
951
+ changed={this.state.changed}
952
+ onSave={isClose => this.onSave(isClose)}
953
+ onClose={() => {
954
+ if (this.state.changed) {
955
+ this.setState({ confirmClose: true });
956
+ } else {
957
+ GenericApp.onClose();
958
+ }
959
+ }}
960
+ />
961
+ ) : null}
962
+ {this.state.confirmClose ? (
963
+ <ConfirmDialog
964
+ title={I18n.t('ra_Please confirm')}
965
+ text={I18n.t('ra_Some data are not stored. Discard?')}
966
+ ok={I18n.t('ra_Discard')}
967
+ cancel={I18n.t('ra_Cancel')}
968
+ onClose={isYes => this.setState({ confirmClose: false }, () => isYes && GenericApp.onClose())}
969
+ />
970
+ ) : null}
971
+ </>
972
+ );
879
973
  }
880
974
 
881
975
  private _updateNativeValue(obj: Record<string, any>, attrs: string | string[], value: any): boolean {
@@ -908,11 +1002,12 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
908
1002
 
909
1003
  /**
910
1004
  * Update the native value
1005
+ *
911
1006
  * @param attr The attribute name with dots as delimiter.
912
1007
  * @param value The new value.
913
1008
  * @param cb Callback which will be called upon completion.
914
1009
  */
915
- updateNativeValue(attr: string, value: any, cb?: () => void) {
1010
+ updateNativeValue(attr: string, value: any, cb?: () => void): void {
916
1011
  const native = JSON.parse(JSON.stringify(this.state.native));
917
1012
  if (this._updateNativeValue(native, attr, value)) {
918
1013
  const changed = this.getIsChanged(native);
@@ -920,7 +1015,7 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
920
1015
  if (changed !== this.state.changed) {
921
1016
  try {
922
1017
  window.parent.postMessage(changed ? 'change' : 'nochange', '*');
923
- } catch (e) {
1018
+ } catch {
924
1019
  // ignore
925
1020
  }
926
1021
  }
@@ -932,13 +1027,14 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
932
1027
  /**
933
1028
  * Set the error text to be shown.
934
1029
  */
935
- showError(text: string | React.JSX.Element) {
1030
+ showError(text: string | React.JSX.Element): void {
936
1031
  this.setState({ errorText: text });
937
1032
  }
938
1033
 
939
1034
  /**
940
1035
  * Sets the toast to be shown.
941
- * @param {string} toast
1036
+ *
1037
+ * @param toast Text to be shown.
942
1038
  */
943
1039
  showToast(toast: string | React.JSX.Element): void {
944
1040
  this.setState({ toast });
@@ -948,12 +1044,14 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
948
1044
  * Renders helper dialogs
949
1045
  */
950
1046
  renderHelperDialogs(): React.JSX.Element {
951
- return <>
952
- {this.renderError()}
953
- {this.renderToast()}
954
- {this.renderSaveCloseButtons()}
955
- {this.renderAlertSnackbar()}
956
- </>;
1047
+ return (
1048
+ <>
1049
+ {this.renderError()}
1050
+ {this.renderToast()}
1051
+ {this.renderSaveCloseButtons()}
1052
+ {this.renderAlertSnackbar()}
1053
+ </>
1054
+ );
957
1055
  }
958
1056
 
959
1057
  /**
@@ -964,12 +1062,14 @@ class GenericApp<TProps extends GenericAppProps = GenericAppProps, TState extend
964
1062
  return <Loader themeType={this.state.themeType} />;
965
1063
  }
966
1064
 
967
- return <div className="App">
968
- {this.renderError()}
969
- {this.renderToast()}
970
- {this.renderSaveCloseButtons()}
971
- {this.renderAlertSnackbar()}
972
- </div>;
1065
+ return (
1066
+ <div className="App">
1067
+ {this.renderError()}
1068
+ {this.renderToast()}
1069
+ {this.renderSaveCloseButtons()}
1070
+ {this.renderAlertSnackbar()}
1071
+ </div>
1072
+ );
973
1073
  }
974
1074
  }
975
1075