@iobroker/gui-components 8.0.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 (368) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +1450 -0
  3. package/build/AdminConnection.d.ts +1 -0
  4. package/build/AdminConnection.js +2 -0
  5. package/build/AdminConnection.js.map +1 -0
  6. package/build/Components/404.d.ts +4 -0
  7. package/build/Components/404.js +97 -0
  8. package/build/Components/404.js.map +1 -0
  9. package/build/Components/ColorPicker.d.ts +86 -0
  10. package/build/Components/ColorPicker.js +222 -0
  11. package/build/Components/ColorPicker.js.map +1 -0
  12. package/build/Components/ComplexCron.d.ts +40 -0
  13. package/build/Components/ComplexCron.js +401 -0
  14. package/build/Components/ComplexCron.js.map +1 -0
  15. package/build/Components/CopyToClipboard.d.ts +14 -0
  16. package/build/Components/CopyToClipboard.js +160 -0
  17. package/build/Components/CopyToClipboard.js.map +1 -0
  18. package/build/Components/CustomModal.d.ts +26 -0
  19. package/build/Components/CustomModal.js +62 -0
  20. package/build/Components/CustomModal.js.map +1 -0
  21. package/build/Components/DeviceType/DeviceTypeIcon.d.ts +29 -0
  22. package/build/Components/DeviceType/DeviceTypeIcon.js +108 -0
  23. package/build/Components/DeviceType/DeviceTypeIcon.js.map +1 -0
  24. package/build/Components/DeviceType/DeviceTypeOptions.d.ts +2 -0
  25. package/build/Components/DeviceType/DeviceTypeOptions.js +69 -0
  26. package/build/Components/DeviceType/DeviceTypeOptions.js.map +1 -0
  27. package/build/Components/DeviceType/DeviceTypeSelector.d.ts +20 -0
  28. package/build/Components/DeviceType/DeviceTypeSelector.js +83 -0
  29. package/build/Components/DeviceType/DeviceTypeSelector.js.map +1 -0
  30. package/build/Components/DeviceType/deviceTypeTranslations.d.ts +1 -0
  31. package/build/Components/DeviceType/deviceTypeTranslations.js +30 -0
  32. package/build/Components/DeviceType/deviceTypeTranslations.js.map +1 -0
  33. package/build/Components/DeviceType/i18n/de.json +46 -0
  34. package/build/Components/DeviceType/i18n/en.json +46 -0
  35. package/build/Components/DeviceType/i18n/fr.json +46 -0
  36. package/build/Components/DeviceType/i18n/it.json +46 -0
  37. package/build/Components/DeviceType/i18n/nl.json +46 -0
  38. package/build/Components/DeviceType/i18n/pl.json +46 -0
  39. package/build/Components/DeviceType/i18n/pt.json +46 -0
  40. package/build/Components/DeviceType/i18n/ru.json +46 -0
  41. package/build/Components/DeviceType/i18n/uk.json +46 -0
  42. package/build/Components/DeviceType/i18n/zh-cn.json +46 -0
  43. package/build/Components/DeviceType/icons/Cleaner.d.ts +3 -0
  44. package/build/Components/DeviceType/icons/Cleaner.js +14 -0
  45. package/build/Components/DeviceType/icons/Cleaner.js.map +1 -0
  46. package/build/Components/DeviceType/icons/DoorClosed.d.ts +3 -0
  47. package/build/Components/DeviceType/icons/DoorClosed.js +7 -0
  48. package/build/Components/DeviceType/icons/DoorClosed.js.map +1 -0
  49. package/build/Components/DeviceType/icons/DoorOpened.d.ts +3 -0
  50. package/build/Components/DeviceType/icons/DoorOpened.js +7 -0
  51. package/build/Components/DeviceType/icons/DoorOpened.js.map +1 -0
  52. package/build/Components/DeviceType/icons/FireOff.d.ts +3 -0
  53. package/build/Components/DeviceType/icons/FireOff.js +8 -0
  54. package/build/Components/DeviceType/icons/FireOff.js.map +1 -0
  55. package/build/Components/DeviceType/icons/FireOn.d.ts +3 -0
  56. package/build/Components/DeviceType/icons/FireOn.js +14 -0
  57. package/build/Components/DeviceType/icons/FireOn.js.map +1 -0
  58. package/build/Components/DeviceType/icons/FloodOff.d.ts +3 -0
  59. package/build/Components/DeviceType/icons/FloodOff.js +11 -0
  60. package/build/Components/DeviceType/icons/FloodOff.js.map +1 -0
  61. package/build/Components/DeviceType/icons/FloodOn.d.ts +3 -0
  62. package/build/Components/DeviceType/icons/FloodOn.js +18 -0
  63. package/build/Components/DeviceType/icons/FloodOn.js.map +1 -0
  64. package/build/Components/DeviceType/icons/Gate.d.ts +3 -0
  65. package/build/Components/DeviceType/icons/Gate.js +8 -0
  66. package/build/Components/DeviceType/icons/Gate.js.map +1 -0
  67. package/build/Components/DeviceType/icons/HeatValve.d.ts +3 -0
  68. package/build/Components/DeviceType/icons/HeatValve.js +6 -0
  69. package/build/Components/DeviceType/icons/HeatValve.js.map +1 -0
  70. package/build/Components/DeviceType/icons/Home.d.ts +3 -0
  71. package/build/Components/DeviceType/icons/Home.js +6 -0
  72. package/build/Components/DeviceType/icons/Home.js.map +1 -0
  73. package/build/Components/DeviceType/icons/Humidity.d.ts +3 -0
  74. package/build/Components/DeviceType/icons/Humidity.js +8 -0
  75. package/build/Components/DeviceType/icons/Humidity.js.map +1 -0
  76. package/build/Components/DeviceType/icons/IconHome.d.ts +5 -0
  77. package/build/Components/DeviceType/icons/IconHome.js +21 -0
  78. package/build/Components/DeviceType/icons/IconHome.js.map +1 -0
  79. package/build/Components/DeviceType/icons/Jalousie.d.ts +3 -0
  80. package/build/Components/DeviceType/icons/Jalousie.js +7 -0
  81. package/build/Components/DeviceType/icons/Jalousie.js.map +1 -0
  82. package/build/Components/DeviceType/icons/Material.d.ts +3 -0
  83. package/build/Components/DeviceType/icons/Material.js +8 -0
  84. package/build/Components/DeviceType/icons/Material.js.map +1 -0
  85. package/build/Components/DeviceType/icons/MotionOff.d.ts +3 -0
  86. package/build/Components/DeviceType/icons/MotionOff.js +11 -0
  87. package/build/Components/DeviceType/icons/MotionOff.js.map +1 -0
  88. package/build/Components/DeviceType/icons/MotionOn.d.ts +3 -0
  89. package/build/Components/DeviceType/icons/MotionOn.js +7 -0
  90. package/build/Components/DeviceType/icons/MotionOn.js.map +1 -0
  91. package/build/Components/DeviceType/icons/PushButton.d.ts +3 -0
  92. package/build/Components/DeviceType/icons/PushButton.js +9 -0
  93. package/build/Components/DeviceType/icons/PushButton.js.map +1 -0
  94. package/build/Components/DeviceType/icons/RGB.d.ts +3 -0
  95. package/build/Components/DeviceType/icons/RGB.js +43 -0
  96. package/build/Components/DeviceType/icons/RGB.js.map +1 -0
  97. package/build/Components/DeviceType/icons/RepairExpert.d.ts +3 -0
  98. package/build/Components/DeviceType/icons/RepairExpert.js +6 -0
  99. package/build/Components/DeviceType/icons/RepairExpert.js.map +1 -0
  100. package/build/Components/DeviceType/icons/Socket.d.ts +3 -0
  101. package/build/Components/DeviceType/icons/Socket.js +8 -0
  102. package/build/Components/DeviceType/icons/Socket.js.map +1 -0
  103. package/build/Components/DeviceType/icons/Thermometer.d.ts +3 -0
  104. package/build/Components/DeviceType/icons/Thermometer.js +7 -0
  105. package/build/Components/DeviceType/icons/Thermometer.js.map +1 -0
  106. package/build/Components/DeviceType/icons/ThermometerSimple.d.ts +3 -0
  107. package/build/Components/DeviceType/icons/ThermometerSimple.js +8 -0
  108. package/build/Components/DeviceType/icons/ThermometerSimple.js.map +1 -0
  109. package/build/Components/DeviceType/icons/Thermostat.d.ts +3 -0
  110. package/build/Components/DeviceType/icons/Thermostat.js +9 -0
  111. package/build/Components/DeviceType/icons/Thermostat.js.map +1 -0
  112. package/build/Components/DeviceType/icons/Valve.d.ts +3 -0
  113. package/build/Components/DeviceType/icons/Valve.js +7 -0
  114. package/build/Components/DeviceType/icons/Valve.js.map +1 -0
  115. package/build/Components/DeviceType/icons/WindowClosed.d.ts +3 -0
  116. package/build/Components/DeviceType/icons/WindowClosed.js +8 -0
  117. package/build/Components/DeviceType/icons/WindowClosed.js.map +1 -0
  118. package/build/Components/DeviceType/icons/WindowOpened.d.ts +3 -0
  119. package/build/Components/DeviceType/icons/WindowOpened.js +9 -0
  120. package/build/Components/DeviceType/icons/WindowOpened.js.map +1 -0
  121. package/build/Components/DeviceType/icons/WindowTilted.d.ts +3 -0
  122. package/build/Components/DeviceType/icons/WindowTilted.js +8 -0
  123. package/build/Components/DeviceType/icons/WindowTilted.js.map +1 -0
  124. package/build/Components/DeviceType/icons/index.d.ts +28 -0
  125. package/build/Components/DeviceType/icons/index.js +28 -0
  126. package/build/Components/DeviceType/icons/index.js.map +1 -0
  127. package/build/Components/FileBrowser.d.ts +187 -0
  128. package/build/Components/FileBrowser.js +1711 -0
  129. package/build/Components/FileBrowser.js.map +1 -0
  130. package/build/Components/FileViewer.d.ts +49 -0
  131. package/build/Components/FileViewer.js +247 -0
  132. package/build/Components/FileViewer.js.map +1 -0
  133. package/build/Components/Icon.d.ts +35 -0
  134. package/build/Components/Icon.js +140 -0
  135. package/build/Components/Icon.js.map +1 -0
  136. package/build/Components/IconPicker.d.ts +25 -0
  137. package/build/Components/IconPicker.js +72 -0
  138. package/build/Components/IconPicker.js.map +1 -0
  139. package/build/Components/IconSelector.d.ts +33 -0
  140. package/build/Components/IconSelector.js +2086 -0
  141. package/build/Components/IconSelector.js.map +1 -0
  142. package/build/Components/Image.d.ts +31 -0
  143. package/build/Components/Image.js +126 -0
  144. package/build/Components/Image.js.map +1 -0
  145. package/build/Components/InfoBox.d.ts +37 -0
  146. package/build/Components/InfoBox.js +115 -0
  147. package/build/Components/InfoBox.js.map +1 -0
  148. package/build/Components/IobUri.d.ts +14 -0
  149. package/build/Components/IobUri.js +168 -0
  150. package/build/Components/IobUri.js.map +1 -0
  151. package/build/Components/Loader.d.ts +31 -0
  152. package/build/Components/Loader.js +265 -0
  153. package/build/Components/Loader.js.map +1 -0
  154. package/build/Components/Loaders/MV.d.ts +17 -0
  155. package/build/Components/Loaders/MV.js +61 -0
  156. package/build/Components/Loaders/MV.js.map +1 -0
  157. package/build/Components/Loaders/PT.d.ts +27 -0
  158. package/build/Components/Loaders/PT.js +150 -0
  159. package/build/Components/Loaders/PT.js.map +1 -0
  160. package/build/Components/Loaders/Vendor.d.ts +22 -0
  161. package/build/Components/Loaders/Vendor.js +52 -0
  162. package/build/Components/Loaders/Vendor.js.map +1 -0
  163. package/build/Components/Logo.d.ts +18 -0
  164. package/build/Components/Logo.js +109 -0
  165. package/build/Components/Logo.js.map +1 -0
  166. package/build/Components/MDUtils.d.ts +11 -0
  167. package/build/Components/MDUtils.js +99 -0
  168. package/build/Components/MDUtils.js.map +1 -0
  169. package/build/Components/ObjectBrowser.d.ts +665 -0
  170. package/build/Components/ObjectBrowser.js +6245 -0
  171. package/build/Components/ObjectBrowser.js.map +1 -0
  172. package/build/Components/Router.d.ts +21 -0
  173. package/build/Components/Router.js +77 -0
  174. package/build/Components/Router.js.map +1 -0
  175. package/build/Components/SaveCloseButtons.d.ts +20 -0
  176. package/build/Components/SaveCloseButtons.js +65 -0
  177. package/build/Components/SaveCloseButtons.js.map +1 -0
  178. package/build/Components/Schedule.d.ts +62 -0
  179. package/build/Components/Schedule.js +1266 -0
  180. package/build/Components/Schedule.js.map +1 -0
  181. package/build/Components/SelectWithIcon.d.ts +37 -0
  182. package/build/Components/SelectWithIcon.js +139 -0
  183. package/build/Components/SelectWithIcon.js.map +1 -0
  184. package/build/Components/SimpleCron/cronText.d.ts +10 -0
  185. package/build/Components/SimpleCron/cronText.js +14 -0
  186. package/build/Components/SimpleCron/cronText.js.map +1 -0
  187. package/build/Components/SimpleCron/index.d.ts +55 -0
  188. package/build/Components/SimpleCron/index.js +698 -0
  189. package/build/Components/SimpleCron/index.js.map +1 -0
  190. package/build/Components/TabContainer.d.ts +15 -0
  191. package/build/Components/TabContainer.js +23 -0
  192. package/build/Components/TabContainer.js.map +1 -0
  193. package/build/Components/TabContent.d.ts +11 -0
  194. package/build/Components/TabContent.js +20 -0
  195. package/build/Components/TabContent.js.map +1 -0
  196. package/build/Components/TabHeader.d.ts +6 -0
  197. package/build/Components/TabHeader.js +6 -0
  198. package/build/Components/TabHeader.js.map +1 -0
  199. package/build/Components/TableResize.d.ts +45 -0
  200. package/build/Components/TableResize.js +204 -0
  201. package/build/Components/TableResize.js.map +1 -0
  202. package/build/Components/TextWithIcon.d.ts +21 -0
  203. package/build/Components/TextWithIcon.js +113 -0
  204. package/build/Components/TextWithIcon.js.map +1 -0
  205. package/build/Components/ToggleThemeMenu.d.ts +12 -0
  206. package/build/Components/ToggleThemeMenu.js +13 -0
  207. package/build/Components/ToggleThemeMenu.js.map +1 -0
  208. package/build/Components/TreeTable.d.ts +79 -0
  209. package/build/Components/TreeTable.js +538 -0
  210. package/build/Components/TreeTable.js.map +1 -0
  211. package/build/Components/UploadImage.d.ts +23 -0
  212. package/build/Components/UploadImage.js +516 -0
  213. package/build/Components/UploadImage.js.map +1 -0
  214. package/build/Components/Utils.d.ts +331 -0
  215. package/build/Components/Utils.js +1605 -0
  216. package/build/Components/Utils.js.map +1 -0
  217. package/build/Components/withWidth.d.ts +2 -0
  218. package/build/Components/withWidth.js +22 -0
  219. package/build/Components/withWidth.js.map +1 -0
  220. package/build/Connection.d.ts +1 -0
  221. package/build/Connection.js +2 -0
  222. package/build/Connection.js.map +1 -0
  223. package/build/Dialogs/ComplexCron.d.ts +24 -0
  224. package/build/Dialogs/ComplexCron.js +85 -0
  225. package/build/Dialogs/ComplexCron.js.map +1 -0
  226. package/build/Dialogs/Confirm.d.ts +39 -0
  227. package/build/Dialogs/Confirm.js +83 -0
  228. package/build/Dialogs/Confirm.js.map +1 -0
  229. package/build/Dialogs/Cron.d.ts +29 -0
  230. package/build/Dialogs/Cron.js +72 -0
  231. package/build/Dialogs/Cron.js.map +1 -0
  232. package/build/Dialogs/Error.d.ts +18 -0
  233. package/build/Dialogs/Error.js +27 -0
  234. package/build/Dialogs/Error.js.map +1 -0
  235. package/build/Dialogs/Message.d.ts +20 -0
  236. package/build/Dialogs/Message.js +29 -0
  237. package/build/Dialogs/Message.js.map +1 -0
  238. package/build/Dialogs/SelectFile.d.ts +85 -0
  239. package/build/Dialogs/SelectFile.js +115 -0
  240. package/build/Dialogs/SelectFile.js.map +1 -0
  241. package/build/Dialogs/SelectID.d.ts +102 -0
  242. package/build/Dialogs/SelectID.js +151 -0
  243. package/build/Dialogs/SelectID.js.map +1 -0
  244. package/build/Dialogs/SimpleCron.d.ts +19 -0
  245. package/build/Dialogs/SimpleCron.js +46 -0
  246. package/build/Dialogs/SimpleCron.js.map +1 -0
  247. package/build/Dialogs/TextInput.d.ts +2 -0
  248. package/build/Dialogs/TextInput.js +31 -0
  249. package/build/Dialogs/TextInput.js.map +1 -0
  250. package/build/GenericApp.d.ts +209 -0
  251. package/build/GenericApp.js +842 -0
  252. package/build/GenericApp.js.map +1 -0
  253. package/build/LegacyConnection.d.ts +938 -0
  254. package/build/LegacyConnection.js +2849 -0
  255. package/build/LegacyConnection.js.map +1 -0
  256. package/build/Prompt.d.ts +5 -0
  257. package/build/Prompt.js +19 -0
  258. package/build/Prompt.js.map +1 -0
  259. package/build/Theme.d.ts +5 -0
  260. package/build/Theme.js +344 -0
  261. package/build/Theme.js.map +1 -0
  262. package/build/assets/devices/parseNames.d.ts +0 -0
  263. package/build/assets/devices/parseNames.js +35 -0
  264. package/build/assets/devices/parseNames.js.map +1 -0
  265. package/build/assets/devices.json +1 -0
  266. package/build/assets/lamp_ceiling.svg +9 -0
  267. package/build/assets/lamp_table.svg +8 -0
  268. package/build/assets/no_icon.svg +9 -0
  269. package/build/assets/rooms/parseNames.d.ts +0 -0
  270. package/build/assets/rooms/parseNames.js +35 -0
  271. package/build/assets/rooms/parseNames.js.map +1 -0
  272. package/build/assets/rooms.json +1 -0
  273. package/build/dictionary.d.ts +1 -0
  274. package/build/dictionary.js +25 -0
  275. package/build/dictionary.js.map +1 -0
  276. package/build/globals.d.ts +19 -0
  277. package/build/i18n/de.json +480 -0
  278. package/build/i18n/en.json +480 -0
  279. package/build/i18n/es.json +480 -0
  280. package/build/i18n/fr.json +480 -0
  281. package/build/i18n/it.json +475 -0
  282. package/build/i18n/nl.json +475 -0
  283. package/build/i18n/pl.json +475 -0
  284. package/build/i18n/pt.json +475 -0
  285. package/build/i18n/ru.json +475 -0
  286. package/build/i18n/uk.json +475 -0
  287. package/build/i18n/zh-cn.json +475 -0
  288. package/build/i18n.d.ts +84 -0
  289. package/build/i18n.js +224 -0
  290. package/build/i18n.js.map +1 -0
  291. package/build/icons/IconAdapter.d.ts +3 -0
  292. package/build/icons/IconAdapter.js +7 -0
  293. package/build/icons/IconAdapter.js.map +1 -0
  294. package/build/icons/IconAlias.d.ts +3 -0
  295. package/build/icons/IconAlias.js +7 -0
  296. package/build/icons/IconAlias.js.map +1 -0
  297. package/build/icons/IconButtonImage.d.ts +3 -0
  298. package/build/icons/IconButtonImage.js +9 -0
  299. package/build/icons/IconButtonImage.js.map +1 -0
  300. package/build/icons/IconChannel.d.ts +3 -0
  301. package/build/icons/IconChannel.js +10 -0
  302. package/build/icons/IconChannel.js.map +1 -0
  303. package/build/icons/IconClearFilter.d.ts +3 -0
  304. package/build/icons/IconClearFilter.js +8 -0
  305. package/build/icons/IconClearFilter.js.map +1 -0
  306. package/build/icons/IconClosed.d.ts +3 -0
  307. package/build/icons/IconClosed.js +7 -0
  308. package/build/icons/IconClosed.js.map +1 -0
  309. package/build/icons/IconCopy.d.ts +3 -0
  310. package/build/icons/IconCopy.js +6 -0
  311. package/build/icons/IconCopy.js.map +1 -0
  312. package/build/icons/IconDevice.d.ts +3 -0
  313. package/build/icons/IconDevice.js +16 -0
  314. package/build/icons/IconDevice.js.map +1 -0
  315. package/build/icons/IconDocument.d.ts +3 -0
  316. package/build/icons/IconDocument.js +7 -0
  317. package/build/icons/IconDocument.js.map +1 -0
  318. package/build/icons/IconDocumentReadOnly.d.ts +3 -0
  319. package/build/icons/IconDocumentReadOnly.js +8 -0
  320. package/build/icons/IconDocumentReadOnly.js.map +1 -0
  321. package/build/icons/IconExpert.d.ts +3 -0
  322. package/build/icons/IconExpert.js +7 -0
  323. package/build/icons/IconExpert.js.map +1 -0
  324. package/build/icons/IconFx.d.ts +3 -0
  325. package/build/icons/IconFx.js +6 -0
  326. package/build/icons/IconFx.js.map +1 -0
  327. package/build/icons/IconInstance.d.ts +3 -0
  328. package/build/icons/IconInstance.js +7 -0
  329. package/build/icons/IconInstance.js.map +1 -0
  330. package/build/icons/IconLogout.d.ts +3 -0
  331. package/build/icons/IconLogout.js +7 -0
  332. package/build/icons/IconLogout.js.map +1 -0
  333. package/build/icons/IconNoIcon.d.ts +3 -0
  334. package/build/icons/IconNoIcon.js +6 -0
  335. package/build/icons/IconNoIcon.js.map +1 -0
  336. package/build/icons/IconOpen.d.ts +3 -0
  337. package/build/icons/IconOpen.js +7 -0
  338. package/build/icons/IconOpen.js.map +1 -0
  339. package/build/icons/IconState.d.ts +3 -0
  340. package/build/icons/IconState.js +7 -0
  341. package/build/icons/IconState.js.map +1 -0
  342. package/build/icons/IconVacuum.d.ts +3 -0
  343. package/build/icons/IconVacuum.js +12 -0
  344. package/build/icons/IconVacuum.js.map +1 -0
  345. package/build/index.css +56 -0
  346. package/build/index.d.ts +87 -0
  347. package/build/index.js +85 -0
  348. package/build/index.js.map +1 -0
  349. package/build/modulefederation.admin.config.d.ts +13 -0
  350. package/build/modulefederation.admin.config.js +45 -0
  351. package/build/modulefederation.admin.config.js.map +1 -0
  352. package/build/types.d.ts +236 -0
  353. package/i18n/de.json +480 -0
  354. package/i18n/en.json +480 -0
  355. package/i18n/es.json +480 -0
  356. package/i18n/fr.json +480 -0
  357. package/i18n/it.json +475 -0
  358. package/i18n/nl.json +475 -0
  359. package/i18n/pl.json +475 -0
  360. package/i18n/pt.json +475 -0
  361. package/i18n/ru.json +475 -0
  362. package/i18n/uk.json +475 -0
  363. package/i18n/zh-cn.json +475 -0
  364. package/index.css +56 -0
  365. package/modulefederation.admin.config.d.ts +20 -0
  366. package/modulefederation.admin.config.js +54 -0
  367. package/package.json +86 -0
  368. package/tasksExample.js +91 -0
@@ -0,0 +1,247 @@
1
+ // File viewer in adapter-react does not support write
2
+ // import { Buffer } from 'buffer';
3
+ import React, { Component } from 'react';
4
+ import { TextField, Button, Dialog, DialogActions, DialogContent, DialogTitle, IconButton } from '@mui/material';
5
+ // Icons
6
+ import { Close as CloseIcon, Save as SaveIcon, Brightness6 as Brightness5Icon, ContentCopy as CopyIcon, } from '@mui/icons-material';
7
+ import { IconNoIcon } from '../icons/IconNoIcon';
8
+ import { withWidth } from './withWidth';
9
+ import { Utils } from './Utils';
10
+ import { Icon } from './Icon';
11
+ const styles = {
12
+ dialog: {
13
+ height: '100%',
14
+ },
15
+ paper: {
16
+ height: 'calc(100% - 64px)',
17
+ },
18
+ content: {
19
+ textAlign: 'center',
20
+ },
21
+ textarea: {
22
+ width: '100%',
23
+ height: '100%',
24
+ },
25
+ img: {
26
+ width: 'auto',
27
+ height: 'calc(100% - 5px)',
28
+ objectFit: 'contain',
29
+ },
30
+ dialogTitle: {
31
+ justifyContent: 'space-between',
32
+ display: 'flex',
33
+ },
34
+ };
35
+ export const EXTENSIONS = {
36
+ images: ['png', 'jpg', 'svg', 'jpeg', 'bmp', 'gif', 'apng', 'avif', 'webp', 'ico'],
37
+ code: ['js', 'json', 'json5', 'md'],
38
+ txt: ['log', 'txt', 'html', 'css', 'xml', 'ics', 'csv'],
39
+ audio: ['mp3', 'wav', 'ogg', 'acc'],
40
+ video: ['mp4', 'mov', 'avi'],
41
+ };
42
+ function bufferToBase64(buffer, isFull) {
43
+ let binary = '';
44
+ const bytes = new Uint8Array(buffer?.data || buffer);
45
+ const len = bytes.byteLength;
46
+ for (let i = 0; i < len && (isFull || i < 50); i++) {
47
+ binary += String.fromCharCode(bytes[i]);
48
+ }
49
+ return window.btoa(binary);
50
+ }
51
+ export class FileViewerClass extends Component {
52
+ timeout = null;
53
+ constructor(props) {
54
+ super(props);
55
+ const ext = Utils.getFileExtension(props.href);
56
+ this.state = {
57
+ text: null,
58
+ code: null,
59
+ ext,
60
+ // File viewer in adapter-react does not support write
61
+ editing: /* !!this.props.formatEditFile || */ false,
62
+ editingValue: null,
63
+ copyPossible: !!ext && (EXTENSIONS.code.includes(ext) || EXTENSIONS.txt.includes(ext)),
64
+ forceUpdate: Date.now(),
65
+ changed: false,
66
+ imgError: false,
67
+ };
68
+ }
69
+ readFile() {
70
+ if (this.props.href) {
71
+ const parts = this.props.href.split('/');
72
+ parts.splice(0, 2);
73
+ const adapter = parts[0];
74
+ const name = parts.splice(1).join('/');
75
+ this.props.socket
76
+ .readFile(adapter, name)
77
+ .then((data) => {
78
+ let fileData = '';
79
+ if (data.file !== undefined) {
80
+ fileData = data.file;
81
+ }
82
+ const newState = {
83
+ copyPossible: this.state.copyPossible,
84
+ ext: this.state.ext,
85
+ };
86
+ // try to detect valid extension
87
+ if (fileData.type === 'Buffer') {
88
+ if (name.toLowerCase().endsWith('.json5')) {
89
+ newState.ext = 'json5';
90
+ newState.copyPossible = true;
91
+ try {
92
+ fileData = atob(bufferToBase64(fileData, true));
93
+ }
94
+ catch {
95
+ console.error('Cannot convert base64 to string');
96
+ fileData = '';
97
+ }
98
+ }
99
+ else {
100
+ const ext = Utils.detectMimeType(bufferToBase64(fileData));
101
+ if (ext) {
102
+ newState.ext = ext;
103
+ newState.copyPossible = EXTENSIONS.code.includes(ext) || EXTENSIONS.txt.includes(ext);
104
+ }
105
+ }
106
+ }
107
+ if (newState.copyPossible) {
108
+ if (newState.ext && EXTENSIONS.txt.includes(newState.ext)) {
109
+ newState.text = fileData;
110
+ newState.editingValue = fileData;
111
+ }
112
+ else if (newState.ext && EXTENSIONS.code.includes(newState.ext)) {
113
+ newState.code = fileData;
114
+ newState.editingValue = fileData;
115
+ }
116
+ }
117
+ this.setState(newState);
118
+ })
119
+ .catch(e => window.alert(`Cannot read file: ${e}`));
120
+ }
121
+ }
122
+ componentDidMount() {
123
+ this.readFile();
124
+ const parts = this.props.href.split('/');
125
+ parts.splice(0, 2);
126
+ const adapter = parts[0];
127
+ const name = parts.splice(1).join('/');
128
+ if (this.props.supportSubscribes) {
129
+ this.props.socket
130
+ .subscribeFiles(adapter, name, this.onFileChanged)
131
+ .catch(e => window.alert(`Cannot subscribe on file: ${e}`));
132
+ }
133
+ }
134
+ componentWillUnmount() {
135
+ if (this.timeout) {
136
+ clearTimeout(this.timeout);
137
+ this.timeout = null;
138
+ }
139
+ const parts = this.props.href.split('/');
140
+ parts.splice(0, 2);
141
+ const adapter = parts[0];
142
+ const name = parts.splice(1).join('/');
143
+ if (this.props.supportSubscribes) {
144
+ this.props.socket
145
+ .subscribeFiles(adapter, name, this.onFileChanged)
146
+ .catch(e => window.alert(`Cannot subscribe on file: ${e}`));
147
+ }
148
+ }
149
+ onFileChanged = (_id, _fileName, size) => {
150
+ if (!this.state.changed) {
151
+ if (this.timeout) {
152
+ clearTimeout(this.timeout);
153
+ }
154
+ this.timeout = setTimeout(() => {
155
+ this.timeout = null;
156
+ if (size === null) {
157
+ window.alert('Show file was deleted!');
158
+ }
159
+ else if (this.state.text !== null || this.state.code !== null) {
160
+ this.readFile();
161
+ }
162
+ else {
163
+ this.setState({ forceUpdate: Date.now() });
164
+ }
165
+ }, 300);
166
+ }
167
+ };
168
+ getEditorOrViewer() {
169
+ return (React.createElement(TextField, { variant: "standard", style: styles.textarea, multiline: true, value: this.state.editingValue || this.state.code || this.state.text,
170
+ // onChange={newValue => this.setState({ editingValue: newValue, changed: true })}
171
+ slotProps: {
172
+ htmlInput: {
173
+ readOnly: !this.state.editing,
174
+ },
175
+ } }));
176
+ }
177
+ getContent() {
178
+ if (this.state.ext && EXTENSIONS.images.includes(this.state.ext)) {
179
+ if (this.state.imgError) {
180
+ return React.createElement(IconNoIcon, { style: { ...styles.img, ...this.props.getStyleBackgroundImage() } });
181
+ }
182
+ return (React.createElement(Icon, { onError: e => {
183
+ e.target.onerror = null;
184
+ this.setState({ imgError: true });
185
+ }, style: { ...styles.img, ...this.props.getStyleBackgroundImage() }, src: `${this.props.href}?ts=${this.state.forceUpdate}`, alt: this.props.href }));
186
+ }
187
+ if (this.state.ext && EXTENSIONS.audio.includes(this.state.ext)) {
188
+ return (React.createElement("div", { style: {
189
+ width: '100%',
190
+ height: '100%',
191
+ display: 'flex',
192
+ justifyContent: 'center',
193
+ alignItems: 'center',
194
+ } },
195
+ React.createElement("audio", { style: { width: '100%' }, src: this.props.href, controls: true })));
196
+ }
197
+ if (this.state.ext && EXTENSIONS.video.includes(this.state.ext)) {
198
+ return (React.createElement("div", { style: {
199
+ width: '100%',
200
+ height: '100%',
201
+ display: 'flex',
202
+ justifyContent: 'center',
203
+ alignItems: 'center',
204
+ } },
205
+ React.createElement("video", { style: { width: '100%', height: '100%' }, controls: true },
206
+ React.createElement("source", { src: this.props.href, type: `video/${this.state.ext}}` }))));
207
+ }
208
+ if (this.state.code !== null || this.state.text !== null || this.state.editing) {
209
+ // File viewer in adapter-react does not support write
210
+ // return <Editor
211
+ // mode={this.getEditFile(this.props.formatEditFile)}
212
+ // themeType={this.props.themeType}
213
+ // value={this.state.editingValue || this.state.code || this.state.text}
214
+ // onChange={this.state.editing ? newValue => this.setState({ editingValue: newValue, changed: true }) : undefined}
215
+ // />;
216
+ return this.getEditorOrViewer();
217
+ }
218
+ return null;
219
+ }
220
+ // eslint-disable-next-line class-methods-use-this
221
+ onSave() {
222
+ // Do nothing as the file viewer in adapter-react does not support writing
223
+ }
224
+ render() {
225
+ return (React.createElement(Dialog, { sx: {
226
+ '&.MuiDialog-scrollPaper': styles.dialog,
227
+ '& .MuiDialog-paper': styles.paper,
228
+ }, scroll: "paper", open: !!this.props.href, onClose: () => this.props.onClose(), fullWidth: true, maxWidth: "xl", "aria-labelledby": "ar_dialog_file_view_title" },
229
+ React.createElement("div", { style: styles.dialogTitle },
230
+ React.createElement(DialogTitle, { id: "ar_dialog_file_view_title" }, `${this.props.t(this.state.editing ? 'Edit' : 'View')}: ${this.props.href}`),
231
+ this.state.ext && EXTENSIONS.images.includes(this.state.ext) && (React.createElement("div", null,
232
+ React.createElement(IconButton, { size: "large", color: "inherit", onClick: this.props.setStateBackgroundImage },
233
+ React.createElement(Brightness5Icon, null))))),
234
+ React.createElement(DialogContent, { style: styles.content }, this.getContent()),
235
+ React.createElement(DialogActions, null,
236
+ this.state.copyPossible ? (React.createElement(Button, { color: "grey", onClick: e => {
237
+ e.stopPropagation();
238
+ e.preventDefault();
239
+ Utils.copyToClipboard(this.state.text || this.state.code || '');
240
+ }, startIcon: React.createElement(CopyIcon, null) }, this.props.t('Copy content'))) : null,
241
+ this.state.editing ? (React.createElement(Button, { color: "grey", disabled: this.state.editingValue === this.state.code ||
242
+ this.state.editingValue === this.state.text, variant: "contained", onClick: () => this.onSave(), startIcon: React.createElement(SaveIcon, null) }, this.props.t('Save'))) : null,
243
+ React.createElement(Button, { variant: "contained", onClick: () => this.props.onClose(), color: "primary", startIcon: React.createElement(CloseIcon, null) }, this.props.t('Close')))));
244
+ }
245
+ }
246
+ export const FileViewer = withWidth()(FileViewerClass);
247
+ //# sourceMappingURL=FileViewer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileViewer.js","sourceRoot":"./src/","sources":["Components/FileViewer.tsx"],"names":[],"mappings":"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","sourcesContent":["// File viewer in adapter-react does not support write\n// import { Buffer } from 'buffer';\nimport React, { Component, type JSX } from 'react';\n\nimport { TextField, Button, Dialog, DialogActions, DialogContent, DialogTitle, IconButton } from '@mui/material';\n\n// Icons\nimport {\n Close as CloseIcon,\n Save as SaveIcon,\n Brightness6 as Brightness5Icon,\n ContentCopy as CopyIcon,\n} from '@mui/icons-material';\n\nimport type { Connection } from '@iobroker/socket-client';\n\nimport { IconNoIcon } from '../icons/IconNoIcon';\nimport { withWidth } from './withWidth';\nimport { Utils } from './Utils';\nimport type { ThemeType, Translate } from '../types';\nimport { Icon } from './Icon';\n\nconst styles: Record<string, React.CSSProperties> = {\n dialog: {\n height: '100%',\n },\n paper: {\n height: 'calc(100% - 64px)',\n },\n content: {\n textAlign: 'center',\n },\n textarea: {\n width: '100%',\n height: '100%',\n },\n img: {\n width: 'auto',\n height: 'calc(100% - 5px)',\n objectFit: 'contain',\n },\n dialogTitle: {\n justifyContent: 'space-between',\n display: 'flex',\n },\n};\n\nexport const EXTENSIONS = {\n images: ['png', 'jpg', 'svg', 'jpeg', 'bmp', 'gif', 'apng', 'avif', 'webp', 'ico'],\n code: ['js', 'json', 'json5', 'md'],\n txt: ['log', 'txt', 'html', 'css', 'xml', 'ics', 'csv'],\n audio: ['mp3', 'wav', 'ogg', 'acc'],\n video: ['mp4', 'mov', 'avi'],\n};\n\nfunction bufferToBase64(buffer: Buffer, isFull?: boolean): string {\n let binary = '';\n const bytes = new Uint8Array((buffer as unknown as { data: number[]; type: 'Buffer' })?.data || buffer);\n const len = bytes.byteLength;\n for (let i = 0; i < len && (isFull || i < 50); i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return window.btoa(binary);\n}\n\nexport interface FileViewerProps {\n /** Translation function */\n t: Translate;\n /** Callback when the viewer is closed. */\n onClose: () => void;\n /** The URL (file path) to the file to be displayed. */\n href: string;\n formatEditFile?: string;\n socket: Connection;\n setStateBackgroundImage: () => void;\n themeType: ThemeType;\n getStyleBackgroundImage: () => React.CSSProperties | null;\n /** Flag is the js-controller support subscribe on file */\n supportSubscribes?: boolean;\n}\n\nexport interface FileViewerState {\n text: string | null;\n code: string | null;\n ext: string | null;\n editing: boolean;\n editingValue: string | null;\n copyPossible: boolean;\n forceUpdate: number;\n changed: boolean;\n imgError: boolean;\n}\n\nexport class FileViewerClass extends Component<FileViewerProps, FileViewerState> {\n private timeout: ReturnType<typeof setTimeout> | null = null;\n\n constructor(props: FileViewerProps) {\n super(props);\n const ext = Utils.getFileExtension(props.href);\n\n this.state = {\n text: null,\n code: null,\n ext,\n // File viewer in adapter-react does not support write\n editing: /* !!this.props.formatEditFile || */ false,\n editingValue: null,\n copyPossible: !!ext && (EXTENSIONS.code.includes(ext) || EXTENSIONS.txt.includes(ext)),\n forceUpdate: Date.now(),\n changed: false,\n imgError: false,\n };\n }\n\n readFile(): void {\n if (this.props.href) {\n const parts = this.props.href.split('/');\n parts.splice(0, 2);\n const adapter = parts[0];\n const name = parts.splice(1).join('/');\n\n this.props.socket\n .readFile(adapter, name)\n .then((data: { file: string | Buffer; mimeType: string }) => {\n let fileData: string | Buffer = '';\n if (data.file !== undefined) {\n fileData = (data as { file: string; mimeType: string }).file;\n }\n\n const newState: Partial<FileViewerState> = {\n copyPossible: this.state.copyPossible,\n ext: this.state.ext,\n };\n // try to detect valid extension\n if ((fileData as unknown as { data: Buffer; type: string }).type === 'Buffer') {\n if (name.toLowerCase().endsWith('.json5')) {\n newState.ext = 'json5';\n newState.copyPossible = true;\n try {\n fileData = atob(bufferToBase64(fileData as unknown as Buffer, true));\n } catch {\n console.error('Cannot convert base64 to string');\n fileData = '';\n }\n } else {\n const ext = Utils.detectMimeType(bufferToBase64(fileData as unknown as Buffer));\n if (ext) {\n newState.ext = ext;\n newState.copyPossible = EXTENSIONS.code.includes(ext) || EXTENSIONS.txt.includes(ext);\n }\n }\n }\n\n if (newState.copyPossible) {\n if (newState.ext && EXTENSIONS.txt.includes(newState.ext)) {\n newState.text = fileData;\n newState.editingValue = fileData;\n } else if (newState.ext && EXTENSIONS.code.includes(newState.ext)) {\n newState.code = fileData;\n newState.editingValue = fileData;\n }\n }\n\n this.setState(newState as FileViewerState);\n })\n .catch(e => window.alert(`Cannot read file: ${e}`));\n }\n }\n\n componentDidMount(): void {\n this.readFile();\n\n const parts = this.props.href.split('/');\n parts.splice(0, 2);\n const adapter = parts[0];\n const name = parts.splice(1).join('/');\n\n if (this.props.supportSubscribes) {\n this.props.socket\n .subscribeFiles(adapter, name, this.onFileChanged)\n .catch(e => window.alert(`Cannot subscribe on file: ${e}`));\n }\n }\n\n componentWillUnmount(): void {\n if (this.timeout) {\n clearTimeout(this.timeout);\n this.timeout = null;\n }\n const parts = this.props.href.split('/');\n parts.splice(0, 2);\n const adapter = parts[0];\n const name = parts.splice(1).join('/');\n if (this.props.supportSubscribes) {\n this.props.socket\n .subscribeFiles(adapter, name, this.onFileChanged)\n .catch(e => window.alert(`Cannot subscribe on file: ${e}`));\n }\n }\n\n onFileChanged = (_id: string, _fileName: string, size: number | null): void => {\n if (!this.state.changed) {\n if (this.timeout) {\n clearTimeout(this.timeout);\n }\n this.timeout = setTimeout(() => {\n this.timeout = null;\n if (size === null) {\n window.alert('Show file was deleted!');\n } else if (this.state.text !== null || this.state.code !== null) {\n this.readFile();\n } else {\n this.setState({ forceUpdate: Date.now() });\n }\n }, 300);\n }\n };\n\n getEditorOrViewer(): JSX.Element {\n return (\n <TextField\n variant=\"standard\"\n style={styles.textarea}\n multiline\n value={this.state.editingValue || this.state.code || this.state.text}\n // onChange={newValue => this.setState({ editingValue: newValue, changed: true })}\n slotProps={{\n htmlInput: {\n readOnly: !this.state.editing,\n },\n }}\n />\n );\n }\n\n getContent(): React.JSX.Element | null {\n if (this.state.ext && EXTENSIONS.images.includes(this.state.ext)) {\n if (this.state.imgError) {\n return <IconNoIcon style={{ ...styles.img, ...this.props.getStyleBackgroundImage() }} />;\n }\n return (\n <Icon\n onError={e => {\n (e.target as HTMLImageElement).onerror = null;\n this.setState({ imgError: true });\n }}\n style={{ ...styles.img, ...this.props.getStyleBackgroundImage() }}\n src={`${this.props.href}?ts=${this.state.forceUpdate}`}\n alt={this.props.href}\n />\n );\n }\n if (this.state.ext && EXTENSIONS.audio.includes(this.state.ext)) {\n return (\n <div\n style={{\n width: '100%',\n height: '100%',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n }}\n >\n <audio\n style={{ width: '100%' }}\n src={this.props.href}\n controls\n ></audio>\n </div>\n );\n }\n if (this.state.ext && EXTENSIONS.video.includes(this.state.ext)) {\n return (\n <div\n style={{\n width: '100%',\n height: '100%',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n }}\n >\n <video\n style={{ width: '100%', height: '100%' }}\n controls\n >\n <source\n src={this.props.href}\n type={`video/${this.state.ext}}`}\n />\n </video>\n </div>\n );\n }\n if (this.state.code !== null || this.state.text !== null || this.state.editing) {\n // File viewer in adapter-react does not support write\n // return <Editor\n // mode={this.getEditFile(this.props.formatEditFile)}\n // themeType={this.props.themeType}\n // value={this.state.editingValue || this.state.code || this.state.text}\n // onChange={this.state.editing ? newValue => this.setState({ editingValue: newValue, changed: true }) : undefined}\n // />;\n return this.getEditorOrViewer();\n }\n return null;\n }\n\n // eslint-disable-next-line class-methods-use-this\n onSave(): void {\n // Do nothing as the file viewer in adapter-react does not support writing\n }\n\n render(): JSX.Element {\n return (\n <Dialog\n sx={{\n '&.MuiDialog-scrollPaper': styles.dialog,\n '& .MuiDialog-paper': styles.paper,\n }}\n scroll=\"paper\"\n open={!!this.props.href}\n onClose={() => this.props.onClose()}\n fullWidth\n maxWidth=\"xl\"\n aria-labelledby=\"ar_dialog_file_view_title\"\n >\n <div style={styles.dialogTitle}>\n <DialogTitle id=\"ar_dialog_file_view_title\">{`${this.props.t(this.state.editing ? 'Edit' : 'View')}: ${this.props.href}`}</DialogTitle>\n {this.state.ext && EXTENSIONS.images.includes(this.state.ext) && (\n <div>\n <IconButton\n size=\"large\"\n color=\"inherit\"\n onClick={this.props.setStateBackgroundImage}\n >\n <Brightness5Icon />\n </IconButton>\n </div>\n )}\n </div>\n <DialogContent style={styles.content}>{this.getContent()}</DialogContent>\n <DialogActions>\n {this.state.copyPossible ? (\n <Button\n color=\"grey\"\n onClick={e => {\n e.stopPropagation();\n e.preventDefault();\n Utils.copyToClipboard(this.state.text || this.state.code || '');\n }}\n startIcon={<CopyIcon />}\n >\n {this.props.t('Copy content')}\n </Button>\n ) : null}\n {this.state.editing ? (\n <Button\n color=\"grey\"\n disabled={\n this.state.editingValue === this.state.code ||\n this.state.editingValue === this.state.text\n }\n variant=\"contained\"\n onClick={() => this.onSave()}\n startIcon={<SaveIcon />}\n >\n {this.props.t('Save')}\n </Button>\n ) : null}\n <Button\n variant=\"contained\"\n onClick={() => this.props.onClose()}\n color=\"primary\"\n startIcon={<CloseIcon />}\n >\n {this.props.t('Close')}\n </Button>\n </DialogActions>\n </Dialog>\n );\n }\n}\nexport const FileViewer = withWidth()(FileViewerClass);\n"]}
@@ -0,0 +1,35 @@
1
+ import React, { type ReactEventHandler } from 'react';
2
+ /**
3
+ * Get icon by object type (state, channel, device, ...).
4
+ *
5
+ * @param obj Object
6
+ */
7
+ export declare function getSystemIcon(obj: ioBroker.Object | null): React.JSX.Element | null;
8
+ /**
9
+ * Get icon from the object.
10
+ *
11
+ * @param obj Object
12
+ * @param imagePrefix Prefix for image
13
+ */
14
+ export declare function getSelectIdIcon(obj: ioBroker.Object | null, imagePrefix?: string): string | null;
15
+ export interface IconProps {
16
+ /** URL, UTF-8 character, or svg code (data:image/svg...) */
17
+ src: string | React.JSX.Element | null | undefined;
18
+ /** Class name */
19
+ className?: string;
20
+ /** Style for image */
21
+ style?: React.CSSProperties;
22
+ /** Styles for mui */
23
+ sx?: Record<string, any>;
24
+ /** Tooltip */
25
+ title?: string;
26
+ /** Styles for utf-8 characters */
27
+ styleUTF8?: React.CSSProperties;
28
+ /** On error handler */
29
+ onError?: ReactEventHandler<HTMLImageElement>;
30
+ /** Reference to image */
31
+ ref?: React.RefObject<HTMLImageElement>;
32
+ /** Alternative text for image */
33
+ alt?: string;
34
+ }
35
+ export declare function Icon(props: IconProps): React.JSX.Element | null;
@@ -0,0 +1,140 @@
1
+ import React from 'react';
2
+ import SVG from 'react-inlinesvg';
3
+ import { Box } from '@mui/material';
4
+ import { SettingsApplications as IconSystem, Photo as IconPhoto, SupervisedUserCircle as IconGroup, PersonOutlined as IconUser, Router as IconHost, Wifi as IconConnection, Info as IconInfo, Description as IconMeta, } from '@mui/icons-material';
5
+ import { IconAlias } from '../icons/IconAlias';
6
+ import { Utils } from './Utils';
7
+ /**
8
+ * Get icon by object type (state, channel, device, ...).
9
+ *
10
+ * @param obj Object
11
+ */
12
+ export function getSystemIcon(obj) {
13
+ let icon;
14
+ const id = obj?._id;
15
+ if (!id) {
16
+ return null;
17
+ }
18
+ // system or design has special icons
19
+ if (id.startsWith('_design/') || id === 'system') {
20
+ icon = React.createElement(IconSystem, { className: "iconOwn" });
21
+ }
22
+ else if (id === '0_userdata' || id === '0_userdata.0') {
23
+ icon = React.createElement(IconPhoto, { className: "iconOwn" });
24
+ }
25
+ else if (id === 'alias' || id === 'alias.0') {
26
+ icon = React.createElement(IconAlias, { className: "iconOwn" });
27
+ }
28
+ else if (id === 'system.adapter') {
29
+ icon = React.createElement(IconSystem, { className: "iconOwn" });
30
+ }
31
+ else if (id === 'system.group') {
32
+ icon = React.createElement(IconGroup, { className: "iconOwn" });
33
+ }
34
+ else if (id === 'system.user') {
35
+ icon = React.createElement(IconUser, { className: "iconOwn" });
36
+ }
37
+ else if (id === 'system.host') {
38
+ icon = React.createElement(IconHost, { className: "iconOwn" });
39
+ }
40
+ else if (id.endsWith('.connection') || id.endsWith('.connected')) {
41
+ icon = React.createElement(IconConnection, { className: "iconOwn" });
42
+ }
43
+ else if (id.endsWith('.info')) {
44
+ icon = React.createElement(IconInfo, { className: "iconOwn" });
45
+ }
46
+ else if (obj?.type === 'meta') {
47
+ icon = React.createElement(IconMeta, { className: "iconOwn" });
48
+ }
49
+ return icon || null;
50
+ }
51
+ /**
52
+ * Get icon from the object.
53
+ *
54
+ * @param obj Object
55
+ * @param imagePrefix Prefix for image
56
+ */
57
+ export function getSelectIdIcon(obj, imagePrefix) {
58
+ imagePrefix = imagePrefix || '.'; // http://localhost:8081';
59
+ let src = '';
60
+ const common = obj?.common;
61
+ if (common) {
62
+ const cIcon = common.icon;
63
+ if (cIcon) {
64
+ if (!cIcon.startsWith('data:image/')) {
65
+ if (cIcon.includes('.')) {
66
+ let instance;
67
+ if (obj.type === 'instance' || obj.type === 'adapter') {
68
+ src = `${imagePrefix}/adapter/${common.name}/${cIcon}`;
69
+ }
70
+ else if (obj._id && obj._id.startsWith('system.adapter.')) {
71
+ instance = obj._id.split('.', 3);
72
+ if (cIcon[0] === '/') {
73
+ instance[2] += cIcon;
74
+ }
75
+ else {
76
+ instance[2] += `/${cIcon}`;
77
+ }
78
+ src = `${imagePrefix}/adapter/${instance[2]}`;
79
+ }
80
+ else {
81
+ instance = obj._id.split('.', 2);
82
+ if (cIcon[0] === '/') {
83
+ instance[0] += cIcon;
84
+ }
85
+ else {
86
+ instance[0] += `/${cIcon}`;
87
+ }
88
+ src = `${imagePrefix}/adapter/${instance[0]}`;
89
+ }
90
+ }
91
+ else {
92
+ return null;
93
+ }
94
+ }
95
+ else {
96
+ // base 64 image
97
+ src = cIcon;
98
+ }
99
+ }
100
+ }
101
+ return src || null;
102
+ }
103
+ const REMOTE_SERVER = window.location.hostname.endsWith('iobroker.in');
104
+ const REMOTE_PREFIX = window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/') + 1);
105
+ export function Icon(props) {
106
+ if (props.src) {
107
+ if (typeof props.src === 'string') {
108
+ if (props.src.length < 3) {
109
+ // utf-8 char
110
+ if (props.sx) {
111
+ return (React.createElement(Box, { component: "span", sx: props.sx, title: props.title || undefined, style: { height: 27, marginTop: -8, ...(props.styleUTF8 || props.style) }, className: Utils.clsx(props.className, 'iconOwn') }, props.src));
112
+ }
113
+ return (React.createElement("span", { title: props.title || undefined, style: { height: 27, marginTop: -8, ...(props.styleUTF8 || props.style) }, className: Utils.clsx(props.className, 'iconOwn') }, props.src));
114
+ }
115
+ if (props.src.startsWith('data:image/svg')) {
116
+ return (React.createElement(SVG, { title: props.title || undefined, src: props.src, className: Utils.clsx(props.className, 'iconOwn'), width: props.style?.width || 28, height: props.style?.height || props.style?.width || 28, style: props.style || undefined }));
117
+ }
118
+ if (REMOTE_SERVER && !props.src.startsWith('http://') && !props.src.startsWith('https://')) {
119
+ let src = props.src;
120
+ if (src.startsWith('./')) {
121
+ src = REMOTE_PREFIX + src.substring(2);
122
+ }
123
+ else if (!src.startsWith('/')) {
124
+ src = REMOTE_PREFIX + src;
125
+ }
126
+ if (props.sx) {
127
+ return (React.createElement(Box, { component: "img", sx: props.sx, title: props.title || undefined, style: props.style || undefined, className: Utils.clsx(props.className, 'iconOwn'), src: `https://remote-files.iobroker.in${src}`, alt: props.alt || undefined, ref: props.ref, onError: e => props.onError && props.onError(e) }));
128
+ }
129
+ return (React.createElement("img", { title: props.title || undefined, style: props.style || undefined, className: Utils.clsx(props.className, 'iconOwn'), src: `https://remote-files.iobroker.in${src}`, alt: props.alt || undefined, ref: props.ref, onError: e => props.onError && props.onError(e) }));
130
+ }
131
+ if (props.sx) {
132
+ return (React.createElement(Box, { component: "img", sx: props.sx, title: props.title || undefined, style: props.style || undefined, className: Utils.clsx(props.className, 'iconOwn'), src: props.src, alt: props.alt || undefined, ref: props.ref, onError: props.onError }));
133
+ }
134
+ return (React.createElement("img", { title: props.title || undefined, style: props.style || undefined, className: Utils.clsx(props.className, 'iconOwn'), src: props.src, alt: props.alt || undefined, ref: props.ref, onError: props.onError }));
135
+ }
136
+ return props.src;
137
+ }
138
+ return null;
139
+ }
140
+ //# sourceMappingURL=Icon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Icon.js","sourceRoot":"./src/","sources":["Components/Icon.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { type ReactEventHandler } from 'react';\r\nimport SVG from 'react-inlinesvg';\r\n\r\nimport { Box } from '@mui/material';\r\n\r\nimport {\r\n SettingsApplications as IconSystem,\r\n Photo as IconPhoto,\r\n SupervisedUserCircle as IconGroup,\r\n PersonOutlined as IconUser,\r\n Router as IconHost,\r\n Wifi as IconConnection,\r\n Info as IconInfo,\r\n Description as IconMeta,\r\n} from '@mui/icons-material';\r\n\r\nimport { IconAlias } from '../icons/IconAlias';\r\nimport { Utils } from './Utils';\r\n\r\n/**\r\n * Get icon by object type (state, channel, device, ...).\r\n *\r\n * @param obj Object\r\n */\r\nexport function getSystemIcon(obj: ioBroker.Object | null): React.JSX.Element | null {\r\n let icon;\r\n const id = obj?._id;\r\n\r\n if (!id) {\r\n return null;\r\n }\r\n\r\n // system or design has special icons\r\n if (id.startsWith('_design/') || id === 'system') {\r\n icon = <IconSystem className=\"iconOwn\" />;\r\n } else if (id === '0_userdata' || id === '0_userdata.0') {\r\n icon = <IconPhoto className=\"iconOwn\" />;\r\n } else if (id === 'alias' || id === 'alias.0') {\r\n icon = <IconAlias className=\"iconOwn\" />;\r\n } else if (id === 'system.adapter') {\r\n icon = <IconSystem className=\"iconOwn\" />;\r\n } else if (id === 'system.group') {\r\n icon = <IconGroup className=\"iconOwn\" />;\r\n } else if (id === 'system.user') {\r\n icon = <IconUser className=\"iconOwn\" />;\r\n } else if (id === 'system.host') {\r\n icon = <IconHost className=\"iconOwn\" />;\r\n } else if (id.endsWith('.connection') || id.endsWith('.connected')) {\r\n icon = <IconConnection className=\"iconOwn\" />;\r\n } else if (id.endsWith('.info')) {\r\n icon = <IconInfo className=\"iconOwn\" />;\r\n } else if (obj?.type === 'meta') {\r\n icon = <IconMeta className=\"iconOwn\" />;\r\n }\r\n\r\n return icon || null;\r\n}\r\n\r\n/**\r\n * Get icon from the object.\r\n *\r\n * @param obj Object\r\n * @param imagePrefix Prefix for image\r\n */\r\nexport function getSelectIdIcon(obj: ioBroker.Object | null, imagePrefix?: string): string | null {\r\n imagePrefix = imagePrefix || '.'; // http://localhost:8081';\r\n let src = '';\r\n const common = obj?.common;\r\n\r\n if (common) {\r\n const cIcon = common.icon;\r\n if (cIcon) {\r\n if (!cIcon.startsWith('data:image/')) {\r\n if (cIcon.includes('.')) {\r\n let instance;\r\n if (obj.type === 'instance' || obj.type === 'adapter') {\r\n src = `${imagePrefix}/adapter/${common.name as string}/${cIcon}`;\r\n } else if (obj._id && obj._id.startsWith('system.adapter.')) {\r\n instance = obj._id.split('.', 3);\r\n if (cIcon[0] === '/') {\r\n instance[2] += cIcon;\r\n } else {\r\n instance[2] += `/${cIcon}`;\r\n }\r\n src = `${imagePrefix}/adapter/${instance[2]}`;\r\n } else {\r\n instance = obj._id.split('.', 2);\r\n if (cIcon[0] === '/') {\r\n instance[0] += cIcon;\r\n } else {\r\n instance[0] += `/${cIcon}`;\r\n }\r\n src = `${imagePrefix}/adapter/${instance[0]}`;\r\n }\r\n } else {\r\n return null;\r\n }\r\n } else {\r\n // base 64 image\r\n src = cIcon;\r\n }\r\n }\r\n }\r\n\r\n return src || null;\r\n}\r\n\r\nexport interface IconProps {\r\n /** URL, UTF-8 character, or svg code (data:image/svg...) */\r\n src: string | React.JSX.Element | null | undefined;\r\n /** Class name */\r\n className?: string;\r\n /** Style for image */\r\n style?: React.CSSProperties;\r\n /** Styles for mui */\r\n sx?: Record<string, any>;\r\n /** Tooltip */\r\n title?: string;\r\n /** Styles for utf-8 characters */\r\n styleUTF8?: React.CSSProperties;\r\n /** On error handler */\r\n onError?: ReactEventHandler<HTMLImageElement>;\r\n /** Reference to image */\r\n ref?: React.RefObject<HTMLImageElement>;\r\n /** Alternative text for image */\r\n alt?: string;\r\n}\r\n\r\nconst REMOTE_SERVER = window.location.hostname.endsWith('iobroker.in');\r\nconst REMOTE_PREFIX = window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/') + 1);\r\n\r\nexport function Icon(props: IconProps): React.JSX.Element | null {\r\n if (props.src) {\r\n if (typeof props.src === 'string') {\r\n if (props.src.length < 3) {\r\n // utf-8 char\r\n if (props.sx) {\r\n return (\r\n <Box\r\n component=\"span\"\r\n sx={props.sx}\r\n title={props.title || undefined}\r\n style={{ height: 27, marginTop: -8, ...(props.styleUTF8 || props.style) }}\r\n className={Utils.clsx(props.className, 'iconOwn')}\r\n >\r\n {props.src}\r\n </Box>\r\n );\r\n }\r\n return (\r\n <span\r\n title={props.title || undefined}\r\n style={{ height: 27, marginTop: -8, ...(props.styleUTF8 || props.style) }}\r\n className={Utils.clsx(props.className, 'iconOwn')}\r\n >\r\n {props.src}\r\n </span>\r\n );\r\n }\r\n if (props.src.startsWith('data:image/svg')) {\r\n return (\r\n <SVG\r\n title={props.title || undefined}\r\n src={props.src}\r\n className={Utils.clsx(props.className, 'iconOwn')}\r\n width={props.style?.width || 28}\r\n height={props.style?.height || props.style?.width || 28}\r\n style={props.style || undefined}\r\n />\r\n );\r\n }\r\n if (REMOTE_SERVER && !props.src.startsWith('http://') && !props.src.startsWith('https://')) {\r\n let src = props.src;\r\n if (src.startsWith('./')) {\r\n src = REMOTE_PREFIX + src.substring(2);\r\n } else if (!src.startsWith('/')) {\r\n src = REMOTE_PREFIX + src;\r\n }\r\n\r\n if (props.sx) {\r\n return (\r\n <Box\r\n component=\"img\"\r\n sx={props.sx}\r\n title={props.title || undefined}\r\n style={props.style || undefined}\r\n className={Utils.clsx(props.className, 'iconOwn')}\r\n src={`https://remote-files.iobroker.in${src}`}\r\n alt={props.alt || undefined}\r\n ref={props.ref}\r\n onError={e => props.onError && props.onError(e)}\r\n />\r\n );\r\n }\r\n return (\r\n <img\r\n title={props.title || undefined}\r\n style={props.style || undefined}\r\n className={Utils.clsx(props.className, 'iconOwn')}\r\n src={`https://remote-files.iobroker.in${src}`}\r\n alt={props.alt || undefined}\r\n ref={props.ref}\r\n onError={e => props.onError && props.onError(e)}\r\n />\r\n );\r\n }\r\n if (props.sx) {\r\n return (\r\n <Box\r\n component=\"img\"\r\n sx={props.sx}\r\n title={props.title || undefined}\r\n style={props.style || undefined}\r\n className={Utils.clsx(props.className, 'iconOwn')}\r\n src={props.src}\r\n alt={props.alt || undefined}\r\n ref={props.ref}\r\n onError={props.onError}\r\n />\r\n );\r\n }\r\n return (\r\n <img\r\n title={props.title || undefined}\r\n style={props.style || undefined}\r\n className={Utils.clsx(props.className, 'iconOwn')}\r\n src={props.src}\r\n alt={props.alt || undefined}\r\n ref={props.ref}\r\n onError={props.onError}\r\n />\r\n );\r\n }\r\n\r\n return props.src;\r\n }\r\n return null;\r\n}\r\n"]}
@@ -0,0 +1,25 @@
1
+ import React from 'react';
2
+ import { type IconSelectorIcon } from './IconSelector';
3
+ interface IconPickerProps {
4
+ previewStyle?: React.CSSProperties;
5
+ previewClassName?: string;
6
+ /** Custom icon element. */
7
+ icon?: React.FC<{
8
+ style?: React.CSSProperties;
9
+ }>;
10
+ customStyles?: Record<string, React.CSSProperties>;
11
+ customClasses?: Record<string, string>;
12
+ /** The label. */
13
+ label?: string;
14
+ /** The value. */
15
+ value?: any;
16
+ /** Set to true to disable the icon picker. */
17
+ disabled?: boolean;
18
+ /** The icon change callback. */
19
+ onChange: (icon: string) => void;
20
+ icons?: IconSelectorIcon[];
21
+ onlyRooms?: boolean;
22
+ onlyDevices?: boolean;
23
+ }
24
+ export declare function IconPicker(props: IconPickerProps): React.JSX.Element;
25
+ export {};
@@ -0,0 +1,72 @@
1
+ import React, { useCallback } from 'react';
2
+ import { useDropzone } from 'react-dropzone';
3
+ import { InputLabel, FormControl, IconButton } from '@mui/material';
4
+ import { Clear as ClearIcon } from '@mui/icons-material';
5
+ import { IconSelector } from './IconSelector';
6
+ import { Icon } from './Icon';
7
+ import { I18n } from '../i18n';
8
+ import { Utils } from './Utils';
9
+ const styles = {
10
+ formContainer: {
11
+ display: 'flex',
12
+ justifyContent: 'left',
13
+ alignItems: 'center',
14
+ },
15
+ formControl: {
16
+ display: 'flex',
17
+ padding: 24,
18
+ flexGrow: 1000,
19
+ },
20
+ divContainer: {
21
+ width: 32 + 32,
22
+ height: 32,
23
+ whiteSpace: 'nowrap',
24
+ lineHeight: '32px',
25
+ marginRight: 8,
26
+ },
27
+ dragField: {
28
+ textAlign: 'center',
29
+ display: 'table',
30
+ minHeight: 90,
31
+ width: 'calc(100% - 60px)',
32
+ border: '2px dashed #777',
33
+ borderRadius: 10,
34
+ padding: 4,
35
+ },
36
+ formIcon: {
37
+ margin: 10,
38
+ opacity: 0.6,
39
+ },
40
+ text: {
41
+ display: 'table-cell',
42
+ verticalAlign: 'middle',
43
+ },
44
+ };
45
+ export function IconPicker(props) {
46
+ const IconCustom = props.icon;
47
+ const onChange = props.onChange;
48
+ const onDrop = useCallback((acceptedFiles) => {
49
+ const reader = new FileReader();
50
+ reader.addEventListener('load', () => onChange(reader.result), false);
51
+ if (acceptedFiles[0]) {
52
+ reader.readAsDataURL(acceptedFiles[0]);
53
+ }
54
+ }, [onChange]);
55
+ const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop });
56
+ return (React.createElement("div", { style: styles.formContainer },
57
+ IconCustom ? React.createElement(IconCustom, { style: styles.formIcon }) : null,
58
+ React.createElement(FormControl, { variant: "standard", style: { ...styles.formControl, padding: 3 } },
59
+ React.createElement(InputLabel, { shrink: true, sx: props.customStyles?.label ? { '&.MuiInputLabel-root': props.customStyles.label } : undefined, classes: { root: props.customClasses?.label } }, props.label),
60
+ React.createElement("div", { style: styles.formContainer },
61
+ props.value ? (React.createElement("div", { style: styles.divContainer },
62
+ React.createElement(Icon, { style: { ...props.previewStyle, ...(props.customStyles?.icon || undefined) }, src: props.value, className: Utils.clsx(props.previewClassName, props.customClasses?.icon) }),
63
+ !props.disabled && (React.createElement(IconButton, { style: { verticalAlign: 'top' }, title: I18n.t('ra_Clear icon'), size: "small", onClick: () => props.onChange('') },
64
+ React.createElement(ClearIcon, null))))) : (!props.disabled && (React.createElement(IconSelector, { icons: props.icons, onlyRooms: props.onlyRooms, onlyDevices: props.onlyDevices, onSelect: (base64) => props.onChange(base64), t: I18n.t, lang: I18n.getLanguage() }))),
65
+ !props.disabled && (React.createElement("div", { ...getRootProps(), style: {
66
+ ...styles.dragField,
67
+ ...(isDragActive ? { backgroundColor: 'rgba(0, 255, 0, 0.1)' } : { cursor: 'pointer' }),
68
+ } },
69
+ React.createElement("input", { ...getInputProps() }),
70
+ isDragActive ? (React.createElement("span", { style: styles.text }, I18n.t('ra_Drop the files here...'))) : (React.createElement("span", { style: styles.text }, I18n.t("ra_Drag 'n' drop some files here, or click to select files")))))))));
71
+ }
72
+ //# sourceMappingURL=IconPicker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IconPicker.js","sourceRoot":"./src/","sources":["Components/IconPicker.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useCallback } from 'react';\nimport { useDropzone } from 'react-dropzone';\n\nimport { InputLabel, FormControl, IconButton } from '@mui/material';\nimport { Clear as ClearIcon } from '@mui/icons-material';\n\nimport { IconSelector, type IconSelectorIcon } from './IconSelector';\nimport { Icon } from './Icon';\nimport { I18n } from '../i18n';\nimport { Utils } from './Utils';\n\nconst styles: Record<string, React.CSSProperties> = {\n formContainer: {\n display: 'flex',\n justifyContent: 'left',\n alignItems: 'center',\n },\n formControl: {\n display: 'flex',\n padding: 24,\n flexGrow: 1000,\n },\n divContainer: {\n width: 32 + 32,\n height: 32,\n whiteSpace: 'nowrap',\n lineHeight: '32px',\n marginRight: 8,\n },\n dragField: {\n textAlign: 'center',\n display: 'table',\n minHeight: 90,\n width: 'calc(100% - 60px)',\n border: '2px dashed #777',\n borderRadius: 10,\n padding: 4,\n },\n formIcon: {\n margin: 10,\n opacity: 0.6,\n },\n text: {\n display: 'table-cell',\n verticalAlign: 'middle',\n },\n};\n\ninterface IconPickerProps {\n previewStyle?: React.CSSProperties;\n previewClassName?: string;\n /** Custom icon element. */\n icon?: React.FC<{ style?: React.CSSProperties }>;\n customStyles?: Record<string, React.CSSProperties>;\n customClasses?: Record<string, string>;\n /** The label. */\n label?: string;\n /** The value. */\n value?: any;\n /** Set to true to disable the icon picker. */\n disabled?: boolean;\n /** The icon change callback. */\n onChange: (icon: string) => void;\n icons?: IconSelectorIcon[];\n onlyRooms?: boolean;\n onlyDevices?: boolean;\n}\n\nexport function IconPicker(props: IconPickerProps): React.JSX.Element {\n const IconCustom = props.icon;\n\n const onChange = props.onChange;\n\n const onDrop = useCallback(\n (acceptedFiles: File[]) => {\n const reader = new FileReader();\n\n reader.addEventListener('load', () => onChange(reader.result as string), false);\n\n if (acceptedFiles[0]) {\n reader.readAsDataURL(acceptedFiles[0]);\n }\n },\n [onChange],\n );\n\n const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop });\n\n return (\n <div style={styles.formContainer}>\n {IconCustom ? <IconCustom style={styles.formIcon} /> : null}\n <FormControl\n variant=\"standard\"\n style={{ ...styles.formControl, padding: 3 }}\n >\n <InputLabel\n shrink\n sx={props.customStyles?.label ? { '&.MuiInputLabel-root': props.customStyles.label } : undefined}\n classes={{ root: props.customClasses?.label }}\n >\n {props.label}\n </InputLabel>\n <div style={styles.formContainer}>\n {props.value ? (\n <div style={styles.divContainer}>\n <Icon\n style={{ ...props.previewStyle, ...(props.customStyles?.icon || undefined) }}\n src={props.value}\n className={Utils.clsx(props.previewClassName, props.customClasses?.icon)}\n />\n {!props.disabled && (\n <IconButton\n style={{ verticalAlign: 'top' }}\n title={I18n.t('ra_Clear icon')}\n size=\"small\"\n onClick={() => props.onChange('')}\n >\n <ClearIcon />\n </IconButton>\n )}\n </div>\n ) : (\n !props.disabled && (\n <IconSelector\n icons={props.icons}\n onlyRooms={props.onlyRooms}\n onlyDevices={props.onlyDevices}\n onSelect={(base64: string) => props.onChange(base64)}\n t={I18n.t}\n lang={I18n.getLanguage()}\n />\n )\n )}\n\n {!props.disabled && (\n <div\n {...getRootProps()}\n style={{\n ...styles.dragField,\n ...(isDragActive ? { backgroundColor: 'rgba(0, 255, 0, 0.1)' } : { cursor: 'pointer' }),\n }}\n >\n <input {...getInputProps()} />\n {isDragActive ? (\n <span style={styles.text}>{I18n.t('ra_Drop the files here...')}</span>\n ) : (\n <span style={styles.text}>\n {I18n.t(\"ra_Drag 'n' drop some files here, or click to select files\")}\n </span>\n )}\n </div>\n )}\n </div>\n </FormControl>\n </div>\n );\n}\n"]}