iobroker.mywebui 1.91.0 → 1.93.0

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 (242) hide show
  1. package/default-controls/controls/WebuiConnectionMonitor1.control +1 -1
  2. package/default-controls/controls/alarms/alarm-viewer.control +1 -0
  3. package/default-controls/controls/input_controls/input_with_button.control +1 -1
  4. package/default-controls/controls/logout.control +1 -1
  5. package/dist/backend/3d-editor-integration.js +1 -1
  6. package/dist/backend/ImportmapCreator.js +1 -1
  7. package/dist/backend/UploadHelper.js +1 -1
  8. package/dist/backend/main.js +1 -1
  9. package/io-package.json +1 -1
  10. package/package.json +1 -1
  11. package/scripts/_build_alarmviewer.py +215 -0
  12. package/www/3d-editor/js/Animation.js +1 -1
  13. package/www/3d-editor/js/AnimationResizer.js +1 -1
  14. package/www/3d-editor/js/Command.js +1 -1
  15. package/www/3d-editor/js/Config.js +1 -1
  16. package/www/3d-editor/js/Editor.js +1 -1
  17. package/www/3d-editor/js/EditorControls.js +1 -1
  18. package/www/3d-editor/js/GLTFImportDialog.js +1 -1
  19. package/www/3d-editor/js/History.js +1 -1
  20. package/www/3d-editor/js/Loader.js +1 -1
  21. package/www/3d-editor/js/LoaderUtils.js +1 -1
  22. package/www/3d-editor/js/Menubar.Add.js +1 -1
  23. package/www/3d-editor/js/Menubar.Edit.js +1 -1
  24. package/www/3d-editor/js/Menubar.File.js +1 -1
  25. package/www/3d-editor/js/Menubar.Help.js +1 -1
  26. package/www/3d-editor/js/Menubar.Render.js +1 -1
  27. package/www/3d-editor/js/Menubar.Status.js +1 -1
  28. package/www/3d-editor/js/Menubar.View.js +1 -1
  29. package/www/3d-editor/js/Menubar.js +1 -1
  30. package/www/3d-editor/js/Player.js +1 -1
  31. package/www/3d-editor/js/Resizer.js +1 -1
  32. package/www/3d-editor/js/Script.js +1 -1
  33. package/www/3d-editor/js/Selector.js +1 -1
  34. package/www/3d-editor/js/Sidebar.Geometry.BoxGeometry.js +1 -1
  35. package/www/3d-editor/js/Sidebar.Geometry.BufferGeometry.js +1 -1
  36. package/www/3d-editor/js/Sidebar.Geometry.CapsuleGeometry.js +1 -1
  37. package/www/3d-editor/js/Sidebar.Geometry.CircleGeometry.js +1 -1
  38. package/www/3d-editor/js/Sidebar.Geometry.CylinderGeometry.js +1 -1
  39. package/www/3d-editor/js/Sidebar.Geometry.DodecahedronGeometry.js +1 -1
  40. package/www/3d-editor/js/Sidebar.Geometry.ExtrudeGeometry.js +1 -1
  41. package/www/3d-editor/js/Sidebar.Geometry.IcosahedronGeometry.js +1 -1
  42. package/www/3d-editor/js/Sidebar.Geometry.LatheGeometry.js +1 -1
  43. package/www/3d-editor/js/Sidebar.Geometry.Modifiers.js +1 -1
  44. package/www/3d-editor/js/Sidebar.Geometry.OctahedronGeometry.js +1 -1
  45. package/www/3d-editor/js/Sidebar.Geometry.PlaneGeometry.js +1 -1
  46. package/www/3d-editor/js/Sidebar.Geometry.RingGeometry.js +1 -1
  47. package/www/3d-editor/js/Sidebar.Geometry.ShapeGeometry.js +1 -1
  48. package/www/3d-editor/js/Sidebar.Geometry.SphereGeometry.js +1 -1
  49. package/www/3d-editor/js/Sidebar.Geometry.TetrahedronGeometry.js +1 -1
  50. package/www/3d-editor/js/Sidebar.Geometry.TextGeometry.js +1 -1
  51. package/www/3d-editor/js/Sidebar.Geometry.TorusGeometry.js +1 -1
  52. package/www/3d-editor/js/Sidebar.Geometry.TorusKnotGeometry.js +1 -1
  53. package/www/3d-editor/js/Sidebar.Geometry.TubeGeometry.js +1 -1
  54. package/www/3d-editor/js/Sidebar.Geometry.js +1 -1
  55. package/www/3d-editor/js/Sidebar.Material.BooleanProperty.js +1 -1
  56. package/www/3d-editor/js/Sidebar.Material.ColorProperty.js +1 -1
  57. package/www/3d-editor/js/Sidebar.Material.ConstantProperty.js +1 -1
  58. package/www/3d-editor/js/Sidebar.Material.MapProperty.js +1 -1
  59. package/www/3d-editor/js/Sidebar.Material.NumberProperty.js +1 -1
  60. package/www/3d-editor/js/Sidebar.Material.Program.js +1 -1
  61. package/www/3d-editor/js/Sidebar.Material.RangeValueProperty.js +1 -1
  62. package/www/3d-editor/js/Sidebar.Material.js +1 -1
  63. package/www/3d-editor/js/Sidebar.Object.js +1 -1
  64. package/www/3d-editor/js/Sidebar.Project.App.js +1 -1
  65. package/www/3d-editor/js/Sidebar.Project.Materials.js +1 -1
  66. package/www/3d-editor/js/Sidebar.Project.Renderer.js +1 -1
  67. package/www/3d-editor/js/Sidebar.Project.Resources.js +1 -1
  68. package/www/3d-editor/js/Sidebar.Project.js +1 -1
  69. package/www/3d-editor/js/Sidebar.Properties.js +1 -1
  70. package/www/3d-editor/js/Sidebar.Scene.js +1 -1
  71. package/www/3d-editor/js/Sidebar.Script.js +1 -1
  72. package/www/3d-editor/js/Sidebar.Settings.History.js +1 -1
  73. package/www/3d-editor/js/Sidebar.Settings.Shortcuts.js +1 -1
  74. package/www/3d-editor/js/Sidebar.Settings.js +1 -1
  75. package/www/3d-editor/js/Sidebar.js +1 -1
  76. package/www/3d-editor/js/Storage.js +1 -1
  77. package/www/3d-editor/js/Strings.js +1 -1
  78. package/www/3d-editor/js/TextureParametersDialog.js +1 -1
  79. package/www/3d-editor/js/Toolbar.js +1 -1
  80. package/www/3d-editor/js/Viewport.Controls.js +1 -1
  81. package/www/3d-editor/js/Viewport.Info.js +1 -1
  82. package/www/3d-editor/js/Viewport.Pathtracer.js +1 -1
  83. package/www/3d-editor/js/Viewport.ViewHelper.js +1 -1
  84. package/www/3d-editor/js/Viewport.XR.js +1 -1
  85. package/www/3d-editor/js/Viewport.js +1 -1
  86. package/www/3d-editor/js/commands/AddObjectCommand.js +1 -1
  87. package/www/3d-editor/js/commands/AddScriptCommand.js +1 -1
  88. package/www/3d-editor/js/commands/Commands.js +1 -1
  89. package/www/3d-editor/js/commands/MoveObjectCommand.js +1 -1
  90. package/www/3d-editor/js/commands/MultiCmdsCommand.js +1 -1
  91. package/www/3d-editor/js/commands/RemoveObjectCommand.js +1 -1
  92. package/www/3d-editor/js/commands/RemoveScriptCommand.js +1 -1
  93. package/www/3d-editor/js/commands/SetColorCommand.js +1 -1
  94. package/www/3d-editor/js/commands/SetGeometryCommand.js +1 -1
  95. package/www/3d-editor/js/commands/SetGeometryValueCommand.js +1 -1
  96. package/www/3d-editor/js/commands/SetMaterialColorCommand.js +1 -1
  97. package/www/3d-editor/js/commands/SetMaterialCommand.js +1 -1
  98. package/www/3d-editor/js/commands/SetMaterialMapCommand.js +1 -1
  99. package/www/3d-editor/js/commands/SetMaterialRangeCommand.js +1 -1
  100. package/www/3d-editor/js/commands/SetMaterialValueCommand.js +1 -1
  101. package/www/3d-editor/js/commands/SetMaterialVectorCommand.js +1 -1
  102. package/www/3d-editor/js/commands/SetPositionCommand.js +1 -1
  103. package/www/3d-editor/js/commands/SetRotationCommand.js +1 -1
  104. package/www/3d-editor/js/commands/SetScaleCommand.js +1 -1
  105. package/www/3d-editor/js/commands/SetSceneCommand.js +1 -1
  106. package/www/3d-editor/js/commands/SetScriptValueCommand.js +1 -1
  107. package/www/3d-editor/js/commands/SetShadowValueCommand.js +1 -1
  108. package/www/3d-editor/js/commands/SetTextureParametersCommand.js +1 -1
  109. package/www/3d-editor/js/commands/SetUuidCommand.js +1 -1
  110. package/www/3d-editor/js/commands/SetValueCommand.js +1 -1
  111. package/www/dist/frontend/bundle/chunk-3C6XC7RW.js +1 -1
  112. package/www/dist/frontend/bundle/chunk-3WGNLIWJ.js +2 -2
  113. package/www/dist/frontend/bundle/chunk-3YK3Y2SJ.js +1 -1
  114. package/www/dist/frontend/bundle/chunk-43HEBO5G.js +3 -3
  115. package/www/dist/frontend/bundle/chunk-5MUGMRXU.js +1 -1
  116. package/www/dist/frontend/bundle/chunk-5UBRCTRX.js +3 -3
  117. package/www/dist/frontend/bundle/chunk-65A3PNMG.js +1 -1
  118. package/www/dist/frontend/bundle/chunk-7CWDQGAG.js +3 -3
  119. package/www/dist/frontend/bundle/chunk-7PT7IGUJ.js +3 -3
  120. package/www/dist/frontend/bundle/chunk-AI5PDLDE.js +3 -3
  121. package/www/dist/frontend/bundle/chunk-AWKVUUKN.js +2 -2
  122. package/www/dist/frontend/bundle/chunk-B6NXWGSB.js +1 -1
  123. package/www/dist/frontend/bundle/chunk-BHSHNRXW.js +1 -1
  124. package/www/dist/frontend/bundle/chunk-BVONDEOL.js +3 -3
  125. package/www/dist/frontend/bundle/chunk-C7OGVQZC.js +1 -1
  126. package/www/dist/frontend/bundle/chunk-CHDKROX5.js +2 -2
  127. package/www/dist/frontend/bundle/chunk-DNCD2F6X.js +2 -2
  128. package/www/dist/frontend/bundle/chunk-FHF6DL5U.js +1 -1
  129. package/www/dist/frontend/bundle/chunk-FO56TEZH.js +3 -3
  130. package/www/dist/frontend/bundle/chunk-FSRRPQMX.js +3 -3
  131. package/www/dist/frontend/bundle/chunk-GLQNGCFL.js +1 -1
  132. package/www/dist/frontend/bundle/chunk-JBDSDK2C.js +2 -2
  133. package/www/dist/frontend/bundle/chunk-JSC66ZLQ.js +1 -1
  134. package/www/dist/frontend/bundle/chunk-K6IV7LKW.js +1 -1
  135. package/www/dist/frontend/bundle/chunk-KY73TL6O.js +2 -2
  136. package/www/dist/frontend/bundle/chunk-M6VVTDVX.js +3 -3
  137. package/www/dist/frontend/bundle/chunk-MECWXZRN.js +1 -1
  138. package/www/dist/frontend/bundle/chunk-N2YIZTB2.js +1 -1
  139. package/www/dist/frontend/bundle/chunk-NQ7L7KNT.js +3 -3
  140. package/www/dist/frontend/bundle/chunk-P7EOR36H.js +1 -1
  141. package/www/dist/frontend/bundle/chunk-PJYK24KZ.js +1 -1
  142. package/www/dist/frontend/bundle/chunk-PYLAW6UA.js +3 -3
  143. package/www/dist/frontend/bundle/chunk-QJJGP23I.js +1 -1
  144. package/www/dist/frontend/bundle/chunk-QV4IBWXA.js +1 -1
  145. package/www/dist/frontend/bundle/chunk-R6IQDPAP.js +3 -3
  146. package/www/dist/frontend/bundle/chunk-RTTBZOQU.js +3 -3
  147. package/www/dist/frontend/bundle/chunk-S4TLNW5D.js +1 -1
  148. package/www/dist/frontend/bundle/chunk-SE6N4ZEN.js +1 -1
  149. package/www/dist/frontend/bundle/chunk-SQHXO2IT.js +3 -3
  150. package/www/dist/frontend/bundle/chunk-T4AIQBBH.js +2 -2
  151. package/www/dist/frontend/bundle/chunk-TWQQHCU7.js +3 -3
  152. package/www/dist/frontend/bundle/chunk-U5Q332OH.js +1 -1
  153. package/www/dist/frontend/bundle/chunk-UIP324PP.js +1 -1
  154. package/www/dist/frontend/bundle/chunk-V27IRYSL.js +1 -1
  155. package/www/dist/frontend/bundle/chunk-V4C5FGJL.js +3 -3
  156. package/www/dist/frontend/bundle/chunk-WED7CGWA.js +3 -3
  157. package/www/dist/frontend/bundle/chunk-WQ5H5LTG.js +2 -2
  158. package/www/dist/frontend/bundle/chunk-WU54NCEU.js +1 -1
  159. package/www/dist/frontend/bundle/chunk-XFO5FUCN.js +1 -1
  160. package/www/dist/frontend/bundle/chunk-XWAQ2BWM.js +3 -3
  161. package/www/dist/frontend/bundle/chunk-YTQCHNRQ.js +2 -2
  162. package/www/dist/frontend/bundle/chunk-YUSK4FN3.js +3 -3
  163. package/www/dist/frontend/bundle/chunk-Z34BSG5O.js +3 -3
  164. package/www/dist/frontend/bundle/common/IobrokerHandler.js +1 -1
  165. package/www/dist/frontend/bundle/runtime/CustomControls.js +1 -1
  166. package/www/dist/frontend/bundle/runtime/ScreenViewer.js +1 -1
  167. package/www/dist/frontend/bundle/runtime/controls.js +4 -4
  168. package/www/dist/frontend/bundle/runtime/init.js +3 -3
  169. package/www/dist/frontend/common/Common.globals.js +1 -1
  170. package/www/dist/frontend/common/IobrokerHandler.js +1 -1
  171. package/www/dist/frontend/common/Runtime.js +1 -1
  172. package/www/dist/frontend/config/CommandHandling.js +1 -1
  173. package/www/dist/frontend/config/ConfigureWebcomponentDesigner.js +1 -1
  174. package/www/dist/frontend/config/DockHelper.js +1 -1
  175. package/www/dist/frontend/config/IobrokerWebui3DDriveEngine.js +1 -1
  176. package/www/dist/frontend/config/IobrokerWebui3DScreenEditor.js +3 -3
  177. package/www/dist/frontend/config/IobrokerWebui3DScreenPropertiesPanel.js +2 -2
  178. package/www/dist/frontend/config/IobrokerWebui3DScreenViewer.js +2 -2
  179. package/www/dist/frontend/config/IobrokerWebuiAppShell.js +2 -2
  180. package/www/dist/frontend/config/IobrokerWebuiBindingsEditor.js +1 -1
  181. package/www/dist/frontend/config/IobrokerWebuiConfirmationWrapper.js +2 -2
  182. package/www/dist/frontend/config/IobrokerWebuiControlPropertiesEditor.js +3 -3
  183. package/www/dist/frontend/config/IobrokerWebuiDynamicPropsEditor.js +1 -1
  184. package/www/dist/frontend/config/IobrokerWebuiEventAssignment.js +1 -1
  185. package/www/dist/frontend/config/IobrokerWebuiIconsView.js +3 -3
  186. package/www/dist/frontend/config/IobrokerWebuiMonacoEditor.js +3 -3
  187. package/www/dist/frontend/config/IobrokerWebuiPropertyGrid.js +1 -1
  188. package/www/dist/frontend/config/IobrokerWebuiScreenEditor.js +1 -1
  189. package/www/dist/frontend/config/IobrokerWebuiScreensView.js +3 -3
  190. package/www/dist/frontend/config/IobrokerWebuiSignalPropertyEditor.js +1 -1
  191. package/www/dist/frontend/config/IobrokerWebuiSolutionExplorer.js +3 -3
  192. package/www/dist/frontend/config/IobrokerWebuiTranslationEditor.js +1 -1
  193. package/www/dist/frontend/config/IobrokerWebuiWidgetGallery.js +3 -3
  194. package/www/dist/frontend/helper/DialogHelper.js +3 -3
  195. package/www/dist/frontend/helper/EsprimaHelper.js +1 -1
  196. package/www/dist/frontend/helper/Helper.js +1 -1
  197. package/www/dist/frontend/helper/LayoutHelper.js +1 -1
  198. package/www/dist/frontend/helper/XmlHelper.js +1 -1
  199. package/www/dist/frontend/helper/ZipHelper.js +1 -1
  200. package/www/dist/frontend/runtime/AnimationService.js +1 -1
  201. package/www/dist/frontend/runtime/CustomControls.js +1 -1
  202. package/www/dist/frontend/runtime/DynamicElementProperties.js +1 -1
  203. package/www/dist/frontend/runtime/HabPanelLikeMenu.js +2 -2
  204. package/www/dist/frontend/runtime/NavigationShell.js +1 -1
  205. package/www/dist/frontend/runtime/RuntimeTheme.js +1 -1
  206. package/www/dist/frontend/runtime/ScreenViewer.js +3 -3
  207. package/www/dist/frontend/runtime/TranslateableText.js +2 -2
  208. package/www/dist/frontend/runtime/VisibilityService.js +1 -1
  209. package/www/dist/frontend/runtime/controls.js +1 -1
  210. package/www/dist/frontend/runtime/init.js +1 -1
  211. package/www/dist/frontend/scripting/IobrokerWebuiScriptSystem.js +1 -1
  212. package/www/dist/frontend/scripting/blockly/OpenScreen.js +1 -1
  213. package/www/dist/frontend/scripting/blockly/webuiBlocklyToolbox.js +1 -1
  214. package/www/dist/frontend/services/DynamicPropertiesHelper.js +1 -1
  215. package/www/dist/frontend/services/IobrokerWebuiBindableLocalObjectsService.js +1 -1
  216. package/www/dist/frontend/services/IobrokerWebuiBindableObjectDragDropService.js +1 -1
  217. package/www/dist/frontend/services/IobrokerWebuiBindableObjectsForPropertiesService.js +1 -1
  218. package/www/dist/frontend/services/IobrokerWebuiBindableObjectsService.js +1 -1
  219. package/www/dist/frontend/services/IobrokerWebuiConfigButtonProvider.js +1 -1
  220. package/www/dist/frontend/services/IobrokerWebuiCopyPasteService.js +1 -1
  221. package/www/dist/frontend/services/IobrokerWebuiCustomControlEventsService.js +1 -1
  222. package/www/dist/frontend/services/IobrokerWebuiCustomElementContextMenu.js +1 -1
  223. package/www/dist/frontend/services/IobrokerWebuiDemoProviderService.js +1 -1
  224. package/www/dist/frontend/services/IobrokerWebuiDynamicPropertiesService.js +1 -1
  225. package/www/dist/frontend/services/IobrokerWebuiEventsService.js +1 -1
  226. package/www/dist/frontend/services/IobrokerWebuiExternalDragDropService.js +1 -1
  227. package/www/dist/frontend/services/IobrokerWebuiLitPropertiesService.js +1 -1
  228. package/www/dist/frontend/services/IobrokerWebuiPropertiesService.js +1 -1
  229. package/www/dist/frontend/services/IobrokerWebuiPropertyGroupsService.js +1 -1
  230. package/www/dist/frontend/services/IobrokerWebuiRefactorService.js +1 -1
  231. package/www/dist/frontend/services/IobrokerWebuiScreenContextMenu.js +1 -1
  232. package/www/dist/frontend/services/IobrokerWebuiSpecialPropertiesService.js +1 -1
  233. package/www/dist/frontend/services/IobrokerWebuiSpectrumEditorService.js +1 -1
  234. package/www/dist/frontend/services/IobrokerWebuiVisibilityPropertiesService.js +1 -1
  235. package/www/dist/frontend/services/LayoutComponentsPropertiesService.js +1 -1
  236. package/www/dist/frontend/widgets/OrthoFlowLineTool.js +1 -1
  237. package/www/dist/frontend/widgets/customElementsObserver.js +1 -1
  238. package/www/dist/frontend/widgets/importWidgetFiles.js +1 -1
  239. package/www/dist/frontend/widgets/importWidgetFilesRuntime.js +1 -1
  240. package/www/dist/frontend/widgets/layout-components.js +1 -1
  241. package/www/dist/frontend/widgets/layout-placement-services.js +1 -1
  242. package/www/dist/frontend/widgets/testElement.js +1 -1
@@ -1 +1 @@
1
- {"html": "<div id=\"monitor\" class=\"connection-monitor\"><div class=\"status-indicator\">\n <svg class=\"status-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\">\n <circle id=\"circle\" cx=\"12\" cy=\"12\" r=\"9\"></circle>\n <path id=\"check\" d=\"M9 12l2 2 4-4\" display=\"none\"></path>\n <path id=\"cross\" d=\"M9 9l6 6 M15 9l-6 6\" display=\"none\"></path>\n </svg>\n<span id=\"statusText\" class=\"status-text\"></span>\n</div><div class=\"pulse-ring\"></div></div>\n<!-- Popup Modal -->\n<div id=\"connectionPopup\" class=\"connection-popup\" style=\"display:none;\">\n <div class=\"popup-overlay\"></div>\n <div class=\"popup-content\">\n <div class=\"popup-icon-wrapper\">\n <svg id=\"popupIcon\" class=\"popup-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <circle cx=\"12\" cy=\"12\" r=\"9\"></circle>\n <path id=\"popupCheck\" d=\"M9 12l2 2 4-4\" display=\"none\"></path>\n <path id=\"popupCross\" d=\"M9 9l6 6 M15 9l-6 6\" display=\"none\"></path>\n </svg>\n<div class=\"popup-pulse-ring\"></div>\n </div>\n <h2 id=\"popupTitle\" class=\"popup-title\"></h2>\n <p id=\"popupMessage\" class=\"popup-message\"></p>\n </div>\n</div>\n", "style": ":host {\n display: inline-block;\n font-family: system-ui, -apple-system, sans-serif;\n}\n\n* {\n box-sizing: border-box;\n}\n\n.connection-monitor {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 10px 16px;\n border-radius: 10px;\n background: rgba(255, 255, 255, 0.95);\n box-shadow: 0 3px 10px rgba(0, 0, 0, 0.15);\n backdrop-filter: blur(8px);\n transition: all 0.3s ease;\n border: 2px solid transparent;\n}\n\n.status-indicator {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.status-icon {\n width: 24px;\n height: 24px;\n transition: all 0.3s ease;\n}\n\n.status-text {\n font-size: 14px;\n font-weight: 600;\n white-space: nowrap;\n}\n\n/* Bağlı vəziyyət (Yaşıl) */\n.connection-monitor.connected {\n background: rgba(16, 185, 129, 0.1);\n border-color: var(--ui-ok,#10b981);\n}\n\n.connection-monitor.connected .status-icon {\n color: var(--ui-ok,#10b981);\n}\n\n.connection-monitor.connected .status-text {\n color: var(--ui-ok,#10b981);\n}\n\n.connection-monitor.connected .pulse-ring {\n animation: pulse-green 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;\n}\n\n/* Kəsilmiş vəziyyət (Qırmızı) */\n.connection-monitor.disconnected {\n background: rgba(239, 68, 68, 0.1);\n border-color: var(--ui-error,#ef4444);\n animation: shake 0.5s ease;\n}\n\n.connection-monitor.disconnected .status-icon {\n color: var(--ui-error,#ef4444);\n}\n\n.connection-monitor.disconnected .status-text {\n color: var(--ui-error,#ef4444);\n}\n\n.connection-monitor.disconnected .pulse-ring {\n animation: pulse-red 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;\n}\n\n/* Yoxlanma vəziyyəti (Sarı) */\n.connection-monitor.checking {\n background: rgba(251, 191, 36, 0.1);\n border-color: var(--ui-warn,#fbbf24);\n}\n\n.connection-monitor.checking .status-icon {\n color: var(--ui-warn,#fbbf24);\n animation: rotate 1.5s linear infinite;\n}\n\n.connection-monitor.checking .status-text {\n color: var(--ui-warn,#fbbf24);\n}\n\n/* Pulse halqası */\n.pulse-ring {\n position: absolute;\n top: 50%;\n left: 15px;\n width: 24px;\n height: 24px;\n border-radius: 50%;\n pointer-events: none;\n transform: translate(-50%, -50%);\n}\n\n/* ==================== POPUP STYLES ==================== */\n\n.connection-popup {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 999999;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: fadeIn 0.3s ease;\n}\n\n.popup-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.7);\n backdrop-filter: blur(8px);\n}\n\n.popup-content {\n position: relative;\n background: white;\n border-radius: 24px;\n padding: 48px 64px;\n box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);\n text-align: center;\n max-width: 500px;\n width: 90%;\n animation: slideUp 0.4s ease;\n}\n\n.popup-icon-wrapper {\n position: relative;\n width: 120px;\n height: 120px;\n margin: 0 auto 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.popup-icon {\n width: 120px;\n height: 120px;\n transition: all 0.3s ease;\n}\n\n.popup-pulse-ring {\n position: absolute;\n top: 50%;\n left: 50%;\n width: 120px;\n height: 120px;\n border-radius: 50%;\n pointer-events: none;\n transform: translate(-50%, -50%);\n}\n\n.popup-title {\n font-size: 32px;\n font-weight: 700;\n margin: 0 0 16px 0;\n color: var(--ui-surface,#1f2937);\n}\n\n.popup-message {\n font-size: 20px;\n font-weight: 500;\n margin: 0;\n color: #6b7280;\n}\n\n/* Popup Connected State */\n.connection-popup.connected .popup-icon {\n color: var(--ui-ok,#10b981);\n}\n\n.connection-popup.connected .popup-pulse-ring {\n animation: pulse-green-big 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;\n}\n\n.connection-popup.connected .popup-title {\n color: var(--ui-ok,#10b981);\n}\n\n.connection-popup.connected .popup-message {\n color: #059669;\n}\n\n/* Popup Disconnected State */\n.connection-popup.disconnected .popup-icon {\n color: var(--ui-error,#ef4444);\n animation: shake-big 0.5s ease;\n}\n\n.connection-popup.disconnected .popup-pulse-ring {\n animation: pulse-red-big 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;\n}\n\n.connection-popup.disconnected .popup-title {\n color: var(--ui-error,#ef4444);\n}\n\n.connection-popup.disconnected .popup-message {\n color: #dc2626;\n}\n\n/* Popup Checking State */\n.connection-popup.checking .popup-icon {\n color: var(--ui-warn,#fbbf24);\n animation: rotate 1.5s linear infinite;\n}\n\n.connection-popup.checking .popup-title {\n color: var(--ui-warn,#fbbf24);\n}\n\n.connection-popup.checking .popup-message {\n color: #f59e0b;\n}\n\n/* Animasiyalar */\n@keyframes pulse-green {\n 0%, 100% {\n box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.7);\n }\n 50% {\n box-shadow: 0 0 0 12px rgba(16, 185, 129, 0);\n }\n}\n\n@keyframes pulse-red {\n 0%, 100% {\n box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7);\n }\n 50% {\n box-shadow: 0 0 0 12px rgba(239, 68, 68, 0);\n }\n}\n\n@keyframes pulse-green-big {\n 0%, 100% {\n box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.7);\n }\n 50% {\n box-shadow: 0 0 0 30px rgba(16, 185, 129, 0);\n }\n}\n\n@keyframes pulse-red-big {\n 0%, 100% {\n box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7);\n }\n 50% {\n box-shadow: 0 0 0 30px rgba(239, 68, 68, 0);\n }\n}\n\n@keyframes shake {\n 0%, 100% { transform: translateX(0); }\n 25% { transform: translateX(-4px); }\n 75% { transform: translateX(4px); }\n}\n\n@keyframes shake-big {\n 0%, 100% { transform: translateX(0) rotate(0deg); }\n 25% { transform: translateX(-10px) rotate(-5deg); }\n 75% { transform: translateX(10px) rotate(5deg); }\n}\n\n@keyframes rotate {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n@keyframes slideUp {\n from {\n opacity: 0;\n transform: translateY(50px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n/* Qaranlıq tema */\n@media (prefers-color-scheme: dark) {\n .connection-monitor {\n background: rgba(31, 41, 55, 0.95);\n box-shadow: 0 3px 10px rgba(0, 0, 0, 0.4);\n }\n \n .popup-content {\n -webkit-backdrop-filter:var(--ui-backdrop,none);backdrop-filter:var(--ui-backdrop,none);background: var(--ui-surface,#1f2937);\n }\n \n .popup-title {\n color: #f3f4f6;\n }\n \n .popup-message {\n color: #d1d5db;\n }\n}\n\n/* Kiçik ölçü */\n.connection-monitor.size-small {\n padding: 6px 12px;\n font-size: 12px;\n}\n\n.connection-monitor.size-small .status-icon {\n width: 18px;\n height: 18px;\n}\n\n/* Böyük ölçü */\n.connection-monitor.size-large {\n padding: 14px 20px;\n font-size: 16px;\n}\n\n.connection-monitor.size-large .status-icon {\n width: 32px;\n height: 32px;\n}", "script": "let checkInterval = null;\nlet isConnected = false;\nlet onConnectHandler = null;\nlet onDisconnectHandler = null;\nlet onReconnectHandler = null;\nlet onErrorHandler = null;\nlet popupTimeout = null;\nlet currentStatus = 'checking';\nlet _langChangedHandler = null;\n\n/**\n* @param {BaseScreenViewerAndControl} instance\n*/\nexport function connectedCallback(instance) {\n const monitorEl = instance._getDomElement('monitor');\n const statusTextEl = instance._getDomElement('statusText');\n const checkIcon = instance._getDomElement('check');\n const crossIcon = instance._getDomElement('cross');\n const circleIcon = instance._getDomElement('circle');\n \n // Popup elementləri\n const popupEl = instance._getDomElement('connectionPopup');\n const popupTitleEl = instance._getDomElement('popupTitle');\n const popupMessageEl = instance._getDomElement('popupMessage');\n const popupCheckIcon = instance._getDomElement('popupCheck');\n const popupCrossIcon = instance._getDomElement('popupCross');\n \n // Ölçü classı əlavə et\n if (instance.size) {\n monitorEl.classList.add('size-' + instance.size);\n }\n \n // IOB connection hazır olana qədər gözlə\n const waitForConnection = setInterval(() => {\n if (window.IOB && window.IOB.connection) {\n clearInterval(waitForConnection);\n setupMonitoring();\n }\n }, 100);\n \n function setupMonitoring() {\n const connection = window.IOB.connection;\n \n console.log('[ConnectionMonitor] 🚀 Monitoring başladı');\n console.log('[ConnectionMonitor] Connection obyekti:', connection);\n console.log('[ConnectionMonitor] İlkin status:', connection.connected);\n \n // İlk status yoxlaması\n checkConnection();\n \n // Dövri yoxlama\n const interval = instance.checkInterval || 5000;\n checkInterval = setInterval(() => {\n checkConnection();\n }, interval);\n \n // Socket event-lərinə abunə ol\n if (connection._socket) {\n const socket = connection._socket;\n \n onConnectHandler = function() {\n console.log('[ConnectionMonitor] ✅ Socket CONNECT event');\n handleConnectionSuccess();\n };\n \n onReconnectHandler = function() {\n console.log('[ConnectionMonitor] 🔄 Socket RECONNECT event');\n handleConnectionSuccess();\n };\n \n onDisconnectHandler = function(reason) {\n console.log('[ConnectionMonitor] ❌ Socket DISCONNECT event:', reason);\n handleConnectionFailure();\n };\n \n onErrorHandler = function(error) {\n console.error('[ConnectionMonitor] ⚠️ Socket ERROR event:', error);\n handleConnectionFailure();\n };\n \n socket.on('connect', onConnectHandler);\n socket.on('reconnect', onReconnectHandler);\n socket.on('disconnect', onDisconnectHandler);\n socket.on('connect_error', onErrorHandler);\n socket.on('error', onErrorHandler);\n }\n }\n \n function checkConnection() {\n if (!window.IOB || !window.IOB.connection) {\n handleConnectionFailure();\n return;\n }\n \n const connection = window.IOB.connection;\n \n // Connection obyektinin connected property-sini yoxla\n if (connection.connected === true) {\n handleConnectionSuccess();\n } \n // Socket-in connected statusunu yoxla\n else if (connection._socket && connection._socket.connected === true) {\n handleConnectionSuccess();\n }\n // Navigator.onLine yoxla (fallback)\n else if (navigator.onLine === false) {\n handleConnectionFailure();\n }\n else {\n // Əlaqə statusu qeyri-müəyyəndirsə, yoxlanılır statusu göstər\n updateStatus('checking');\n }\n }\n \n function handleConnectionSuccess() {\n const wasDisconnected = !isConnected;\n \n if (wasDisconnected) {\n console.log('[ConnectionMonitor] 💚 Server əlaqəsi BƏRPA OLUNDU');\n isConnected = true;\n \n // Əlaqə bərpa olundu popup-u göstər (3 saniyə)\n showPopup('connected');\n if (popupTimeout) clearTimeout(popupTimeout);\n popupTimeout = setTimeout(() => {\n hidePopup();\n }, 3000);\n }\n \n updateStatus('connected');\n }\n \n function handleConnectionFailure() {\n if (isConnected) {\n console.error('[ConnectionMonitor] 💔 Server əlaqəsi KƏSİLDİ');\n isConnected = false;\n \n // Əlaqə kəsildi popup-u göstər (daimi)\n showPopup('disconnected');\n }\n \n updateStatus('disconnected');\n }\n \n function updateStatus(status) {\n currentStatus = status;\n monitorEl.classList.remove('connected', 'disconnected', 'checking');\n monitorEl.classList.add(status);\n \n checkIcon.style.display = 'none';\n crossIcon.style.display = 'none';\n circleIcon.style.display = 'block';\n \n if (status === 'connected') {\n statusTextEl.textContent = t('WebuiConnectionMonitor.connectedtext');\n checkIcon.style.display = 'block';\n circleIcon.style.display = 'none';\n } else if (status === 'disconnected') {\n statusTextEl.textContent = t('WebuiConnectionMonitor.disconnectedtext');\n crossIcon.style.display = 'block';\n circleIcon.style.display = 'none';\n } else if (status === 'checking') {\n statusTextEl.textContent = t('WebuiConnectionMonitor.checkingtext');\n }\n \n if (instance.showText === false) {\n statusTextEl.style.display = 'none';\n } else {\n statusTextEl.style.display = 'inline';\n }\n }\n \n function showPopup(status) {\n popupEl.style.display = 'flex';\n popupEl.classList.remove('connected', 'disconnected', 'checking');\n popupEl.classList.add(status);\n \n // İkonları yenilə\n popupCheckIcon.style.display = 'none';\n popupCrossIcon.style.display = 'none';\n \n if (status === 'connected') {\n popupTitleEl.textContent = t('WebuiConnectionMonitor.connectedtext');\n popupMessageEl.textContent = t('WebuiConnectionMonitor.popupmessageconnected');\n popupCheckIcon.style.display = 'block';\n } else if (status === 'disconnected') {\n popupTitleEl.textContent = t('WebuiConnectionMonitor.disconnectedtext');\n popupMessageEl.textContent = t('WebuiConnectionMonitor.popupmessagedisconnected');\n popupCrossIcon.style.display = 'block';\n } else if (status === 'checking') {\n popupTitleEl.textContent = t('WebuiConnectionMonitor.checkingtext');\n popupMessageEl.textContent = t('WebuiConnectionMonitor.popupmessagechecking');\n }\n }\n \n function hidePopup() {\n popupEl.style.display = 'none';\n if (popupTimeout) {\n clearTimeout(popupTimeout);\n popupTimeout = null;\n }\n }\n\n _langChangedHandler = () => updateStatus(currentStatus);\n window.addEventListener('languageChanged', _langChangedHandler);\n}\n\n/**\n* @param {BaseScreenViewerAndControl} instance\n*/\nexport function disconnectedCallback(instance) {\n if (checkInterval) {\n clearInterval(checkInterval);\n checkInterval = null;\n }\n \n if (_langChangedHandler) {\n window.removeEventListener('languageChanged', _langChangedHandler);\n _langChangedHandler = null;\n }\n\n if (popupTimeout) {\n clearTimeout(popupTimeout);\n popupTimeout = null;\n }\n \n // Event listener-ləri təmizlə\n if (window.IOB && window.IOB.connection && window.IOB.connection._socket) {\n const socket = window.IOB.connection._socket;\n \n if (onConnectHandler) socket.off('connect', onConnectHandler);\n if (onReconnectHandler) socket.off('reconnect', onReconnectHandler);\n if (onDisconnectHandler) socket.off('disconnect', onDisconnectHandler);\n if (onErrorHandler) {\n socket.off('connect_error', onErrorHandler);\n socket.off('error', onErrorHandler);\n }\n }\n}", "properties": {"checkInterval": {"type": "number", "default": "5000"}, "showText": {"type": "boolean", "default": "false"}, "size": {"type": "enum", "default": "medium", "values": ["small", "medium", "large"]}}, "settings": {"visibilityEnabled": "false", "visibilityGroups": "", "visibilityAction": "hide", "visibilityRedirectScreen": ""}}
1
+ {"html": "<div id=\"monitor\" class=\"connection-monitor\"><div class=\"status-indicator\">\n <svg class=\"status-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\">\n <circle id=\"circle\" cx=\"12\" cy=\"12\" r=\"9\"></circle>\n <path id=\"check\" d=\"M9 12l2 2 4-4\" display=\"none\"></path>\n <path id=\"cross\" d=\"M9 9l6 6 M15 9l-6 6\" display=\"none\"></path>\n </svg>\n<span id=\"statusText\" class=\"status-text\"></span>\n</div><div class=\"pulse-ring\"></div></div>\n<!-- Popup Modal -->\n<div id=\"connectionPopup\" class=\"connection-popup\" style=\"display:none;\">\n <div class=\"popup-overlay\"></div>\n <div class=\"popup-content\">\n <div class=\"popup-icon-wrapper\">\n <svg id=\"popupIcon\" class=\"popup-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <circle cx=\"12\" cy=\"12\" r=\"9\"></circle>\n <path id=\"popupCheck\" d=\"M9 12l2 2 4-4\" display=\"none\"></path>\n <path id=\"popupCross\" d=\"M9 9l6 6 M15 9l-6 6\" display=\"none\"></path>\n </svg>\n<div class=\"popup-pulse-ring\"></div>\n </div>\n <h2 id=\"popupTitle\" class=\"popup-title\"></h2>\n <p id=\"popupMessage\" class=\"popup-message\"></p>\n </div>\n</div>\n", "style": ":host {\n display: inline-block;\n font-family: system-ui, -apple-system, sans-serif;\n}\n\n* {\n box-sizing: border-box;\n}\n\n.connection-monitor {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 10px 16px;\n border-radius: 10px;\n background: rgba(255, 255, 255, 0.95);\n box-shadow: 0 3px 10px rgba(0, 0, 0, 0.15);\n backdrop-filter: blur(8px);\n transition: all 0.3s ease;\n border: 2px solid transparent;\n}\n\n.status-indicator {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.status-icon {\n width: 24px;\n height: 24px;\n transition: all 0.3s ease;\n}\n\n.status-text {\n font-size: 14px;\n font-weight: 600;\n white-space: nowrap;\n}\n\n/* Bağlı vəziyyət (Yaşıl) */\n.connection-monitor.connected {\n background: rgba(16, 185, 129, 0.1);\n border-color: var(--ui-ok,#10b981);\n}\n\n.connection-monitor.connected .status-icon {\n color: var(--ui-ok,#10b981);\n}\n\n.connection-monitor.connected .status-text {\n color: var(--ui-ok,#10b981);\n}\n\n.connection-monitor.connected .pulse-ring {\n animation: pulse-green 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;\n}\n\n/* Kəsilmiş vəziyyət (Qırmızı) */\n.connection-monitor.disconnected {\n background: rgba(239, 68, 68, 0.1);\n border-color: var(--ui-error,#ef4444);\n animation: shake 0.5s ease;\n}\n\n.connection-monitor.disconnected .status-icon {\n color: var(--ui-error,#ef4444);\n}\n\n.connection-monitor.disconnected .status-text {\n color: var(--ui-error,#ef4444);\n}\n\n.connection-monitor.disconnected .pulse-ring {\n animation: pulse-red 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;\n}\n\n/* Yoxlanma vəziyyəti (Sarı) */\n.connection-monitor.checking {\n background: rgba(251, 191, 36, 0.1);\n border-color: var(--ui-warn,#fbbf24);\n}\n\n.connection-monitor.checking .status-icon {\n color: var(--ui-warn,#fbbf24);\n animation: rotate 1.5s linear infinite;\n}\n\n.connection-monitor.checking .status-text {\n color: var(--ui-warn,#fbbf24);\n}\n\n/* Pulse halqası */\n.pulse-ring {\n position: absolute;\n top: 50%;\n left: 15px;\n width: 24px;\n height: 24px;\n border-radius: 50%;\n pointer-events: none;\n transform: translate(-50%, -50%);\n}\n\n/* ==================== POPUP STYLES ==================== */\n\n.connection-popup {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 999999;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: fadeIn 0.3s ease;\n}\n\n.popup-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.7);\n backdrop-filter: blur(8px);\n}\n\n.popup-content {\n position: relative;\n background: white;\n border-radius: 24px;\n padding: 48px 64px;\n box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);\n text-align: center;\n max-width: 500px;\n width: 90%;\n animation: slideUp 0.4s ease;\n}\n\n.popup-icon-wrapper {\n position: relative;\n width: 120px;\n height: 120px;\n margin: 0 auto 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.popup-icon {\n width: 120px;\n height: 120px;\n transition: all 0.3s ease;\n}\n\n.popup-pulse-ring {\n position: absolute;\n top: 50%;\n left: 50%;\n width: 120px;\n height: 120px;\n border-radius: 50%;\n pointer-events: none;\n transform: translate(-50%, -50%);\n}\n\n.popup-title {\n font-size: 32px;\n font-weight: 700;\n margin: 0 0 16px 0;\n color: var(--ui-surface,#1f2937);\n}\n\n.popup-message {\n font-size: 20px;\n font-weight: 500;\n margin: 0;\n color: #6b7280;\n}\n\n/* Popup Connected State */\n.connection-popup.connected .popup-icon {\n color: var(--ui-ok,#10b981);\n}\n\n.connection-popup.connected .popup-pulse-ring {\n animation: pulse-green-big 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;\n}\n\n.connection-popup.connected .popup-title {\n color: var(--ui-ok,#10b981);\n}\n\n.connection-popup.connected .popup-message {\n color: #059669;\n}\n\n/* Popup Disconnected State */\n.connection-popup.disconnected .popup-icon {\n color: var(--ui-error,#ef4444);\n animation: shake-big 0.5s ease;\n}\n\n.connection-popup.disconnected .popup-pulse-ring {\n animation: pulse-red-big 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;\n}\n\n.connection-popup.disconnected .popup-title {\n color: var(--ui-error,#ef4444);\n}\n\n.connection-popup.disconnected .popup-message {\n color: #dc2626;\n}\n\n/* Popup Checking State */\n.connection-popup.checking .popup-icon {\n color: var(--ui-warn,#fbbf24);\n animation: rotate 1.5s linear infinite;\n}\n\n.connection-popup.checking .popup-title {\n color: var(--ui-warn,#fbbf24);\n}\n\n.connection-popup.checking .popup-message {\n color: #f59e0b;\n}\n\n/* Animasiyalar */\n@keyframes pulse-green {\n 0%, 100% {\n box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.7);\n }\n 50% {\n box-shadow: 0 0 0 12px rgba(16, 185, 129, 0);\n }\n}\n\n@keyframes pulse-red {\n 0%, 100% {\n box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7);\n }\n 50% {\n box-shadow: 0 0 0 12px rgba(239, 68, 68, 0);\n }\n}\n\n@keyframes pulse-green-big {\n 0%, 100% {\n box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.7);\n }\n 50% {\n box-shadow: 0 0 0 30px rgba(16, 185, 129, 0);\n }\n}\n\n@keyframes pulse-red-big {\n 0%, 100% {\n box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7);\n }\n 50% {\n box-shadow: 0 0 0 30px rgba(239, 68, 68, 0);\n }\n}\n\n@keyframes shake {\n 0%, 100% { transform: translateX(0); }\n 25% { transform: translateX(-4px); }\n 75% { transform: translateX(4px); }\n}\n\n@keyframes shake-big {\n 0%, 100% { transform: translateX(0) rotate(0deg); }\n 25% { transform: translateX(-10px) rotate(-5deg); }\n 75% { transform: translateX(10px) rotate(5deg); }\n}\n\n@keyframes rotate {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n@keyframes slideUp {\n from {\n opacity: 0;\n transform: translateY(50px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n/* Qaranlıq tema */\n@media (prefers-color-scheme: dark) {\n .connection-monitor {\n background: rgba(31, 41, 55, 0.95);\n box-shadow: 0 3px 10px rgba(0, 0, 0, 0.4);\n }\n \n .popup-content {\n -webkit-backdrop-filter:var(--ui-backdrop,none);backdrop-filter:var(--ui-backdrop,none);background: var(--ui-surface,#1f2937);\n }\n \n .popup-title {\n color: #f3f4f6;\n }\n \n .popup-message {\n color: #d1d5db;\n }\n}\n\n/* Kiçik ölçü */\n.connection-monitor.size-small {\n padding: 6px 12px;\n font-size: 12px;\n}\n\n.connection-monitor.size-small .status-icon {\n width: 18px;\n height: 18px;\n}\n\n/* Böyük ölçü */\n.connection-monitor.size-large {\n padding: 14px 20px;\n font-size: 16px;\n}\n\n.connection-monitor.size-large .status-icon {\n width: 32px;\n height: 32px;\n}", "script": "let checkInterval = null;\nlet isConnected = false;\nlet onConnectHandler = null;\nlet onDisconnectHandler = null;\nlet onReconnectHandler = null;\nlet onErrorHandler = null;\nlet popupTimeout = null;\nlet currentStatus = 'checking';\nlet _langChangedHandler = null;\n\n/**\n* @param {BaseScreenViewerAndControl} instance\n*/\nexport function connectedCallback(instance) {\n const monitorEl = instance._getDomElement('monitor');\n const statusTextEl = instance._getDomElement('statusText');\n const checkIcon = instance._getDomElement('check');\n const crossIcon = instance._getDomElement('cross');\n const circleIcon = instance._getDomElement('circle');\n \n // Popup elementləri\n const popupEl = instance._getDomElement('connectionPopup');\n const popupTitleEl = instance._getDomElement('popupTitle');\n const popupMessageEl = instance._getDomElement('popupMessage');\n const popupCheckIcon = instance._getDomElement('popupCheck');\n const popupCrossIcon = instance._getDomElement('popupCross');\n \n // Ölçü classı əlavə et\n if (instance.size) {\n monitorEl.classList.add('size-' + instance.size);\n }\n \n // IOB connection hazır olana qədər gözlə\n const waitForConnection = setInterval(() => {\n if (window.IOB && window.IOB.connection) {\n clearInterval(waitForConnection);\n setupMonitoring();\n }\n }, 100);\n \n function setupMonitoring() {\n const connection = window.IOB.connection;\n \n console.log('[ConnectionMonitor] 🚀 Monitoring başladı');\n console.log('[ConnectionMonitor] Connection obyekti:', connection);\n console.log('[ConnectionMonitor] İlkin status:', connection.connected);\n \n // İlk status yoxlaması\n checkConnection();\n \n // Dövri yoxlama\n const interval = instance.checkInterval || 5000;\n checkInterval = setInterval(() => {\n checkConnection();\n }, interval);\n \n // Socket event-lərinə abunə ol\n if (connection._socket) {\n const socket = connection._socket;\n \n onConnectHandler = function() {\n console.log('[ConnectionMonitor] ✅ Socket CONNECT event');\n handleConnectionSuccess();\n };\n \n onReconnectHandler = function() {\n console.log('[ConnectionMonitor] 🔄 Socket RECONNECT event');\n handleConnectionSuccess();\n };\n \n onDisconnectHandler = function(reason) {\n console.log('[ConnectionMonitor] ❌ Socket DISCONNECT event:', reason);\n handleConnectionFailure();\n };\n \n onErrorHandler = function(error) {\n console.error('[ConnectionMonitor] ⚠️ Socket ERROR event:', error);\n handleConnectionFailure();\n };\n \n socket.on('connect', onConnectHandler);\n socket.on('reconnect', onReconnectHandler);\n socket.on('disconnect', onDisconnectHandler);\n socket.on('connect_error', onErrorHandler);\n socket.on('error', onErrorHandler);\n }\n }\n \n function checkConnection() {\n if (!window.IOB || !window.IOB.connection) {\n handleConnectionFailure();\n return;\n }\n \n const connection = window.IOB.connection;\n \n // Connection obyektinin connected property-sini yoxla\n if (connection.connected === true) {\n handleConnectionSuccess();\n } \n // Socket-in connected statusunu yoxla\n else if (connection._socket && connection._socket.connected === true) {\n handleConnectionSuccess();\n }\n // Navigator.onLine yoxla (fallback)\n else if (navigator.onLine === false) {\n handleConnectionFailure();\n }\n else {\n // Əlaqə statusu qeyri-müəyyəndirsə, yoxlanılır statusu göstər\n updateStatus('checking');\n }\n }\n \n function handleConnectionSuccess() {\n const wasDisconnected = !isConnected;\n \n if (wasDisconnected) {\n console.log('[ConnectionMonitor] 💚 Server əlaqəsi BƏRPA OLUNDU');\n isConnected = true;\n \n // Əlaqə bərpa olundu popup-u göstər (3 saniyə)\n showPopup('connected');\n if (popupTimeout) clearTimeout(popupTimeout);\n popupTimeout = setTimeout(() => {\n hidePopup();\n }, 3000);\n }\n \n updateStatus('connected');\n }\n \n function handleConnectionFailure() {\n if (isConnected) {\n console.error('[ConnectionMonitor] 💔 Server əlaqəsi KƏSİLDİ');\n isConnected = false;\n \n // Əlaqə kəsildi popup-u göstər (daimi)\n showPopup('disconnected');\n }\n \n updateStatus('disconnected');\n }\n \n function updateStatus(status) {\n currentStatus = status;\n monitorEl.classList.remove('connected', 'disconnected', 'checking');\n monitorEl.classList.add(status);\n \n checkIcon.style.display = 'none';\n crossIcon.style.display = 'none';\n circleIcon.style.display = 'block';\n \n if (status === 'connected') {\n statusTextEl.textContent = t('WebuiConnectionMonitor.connectedtext', statusTextEl);\n checkIcon.style.display = 'block';\n circleIcon.style.display = 'none';\n } else if (status === 'disconnected') {\n statusTextEl.textContent = t('WebuiConnectionMonitor.disconnectedtext', statusTextEl);\n crossIcon.style.display = 'block';\n circleIcon.style.display = 'none';\n } else if (status === 'checking') {\n statusTextEl.textContent = t('WebuiConnectionMonitor.checkingtext', statusTextEl);\n }\n \n if (instance.showText === false) {\n statusTextEl.style.display = 'none';\n } else {\n statusTextEl.style.display = 'inline';\n }\n }\n \n function showPopup(status) {\n popupEl.style.display = 'flex';\n popupEl.classList.remove('connected', 'disconnected', 'checking');\n popupEl.classList.add(status);\n \n // İkonları yenilə\n popupCheckIcon.style.display = 'none';\n popupCrossIcon.style.display = 'none';\n \n if (status === 'connected') {\n popupTitleEl.textContent = t('WebuiConnectionMonitor.connectedtext', popupTitleEl);\n popupMessageEl.textContent = t('WebuiConnectionMonitor.popupmessageconnected', popupMessageEl);\n popupCheckIcon.style.display = 'block';\n } else if (status === 'disconnected') {\n popupTitleEl.textContent = t('WebuiConnectionMonitor.disconnectedtext', popupTitleEl);\n popupMessageEl.textContent = t('WebuiConnectionMonitor.popupmessagedisconnected', popupMessageEl);\n popupCrossIcon.style.display = 'block';\n } else if (status === 'checking') {\n popupTitleEl.textContent = t('WebuiConnectionMonitor.checkingtext', popupTitleEl);\n popupMessageEl.textContent = t('WebuiConnectionMonitor.popupmessagechecking', popupMessageEl);\n }\n }\n \n function hidePopup() {\n popupEl.style.display = 'none';\n if (popupTimeout) {\n clearTimeout(popupTimeout);\n popupTimeout = null;\n }\n }\n\n _langChangedHandler = () => updateStatus(currentStatus);\n window.addEventListener('languageChanged', _langChangedHandler);\n}\n\n/**\n* @param {BaseScreenViewerAndControl} instance\n*/\nexport function disconnectedCallback(instance) {\n if (checkInterval) {\n clearInterval(checkInterval);\n checkInterval = null;\n }\n \n if (_langChangedHandler) {\n window.removeEventListener('languageChanged', _langChangedHandler);\n _langChangedHandler = null;\n }\n\n if (popupTimeout) {\n clearTimeout(popupTimeout);\n popupTimeout = null;\n }\n \n // Event listener-ləri təmizlə\n if (window.IOB && window.IOB.connection && window.IOB.connection._socket) {\n const socket = window.IOB.connection._socket;\n \n if (onConnectHandler) socket.off('connect', onConnectHandler);\n if (onReconnectHandler) socket.off('reconnect', onReconnectHandler);\n if (onDisconnectHandler) socket.off('disconnect', onDisconnectHandler);\n if (onErrorHandler) {\n socket.off('connect_error', onErrorHandler);\n socket.off('error', onErrorHandler);\n }\n }\n}", "properties": {"checkInterval": {"type": "number", "default": "5000"}, "showText": {"type": "boolean", "default": "false"}, "size": {"type": "enum", "default": "medium", "values": ["small", "medium", "large"]}}, "settings": {"visibilityEnabled": "false", "visibilityGroups": "", "visibilityAction": "hide", "visibilityRedirectScreen": ""}, "translations": {"az": {"WebuiConnectionMonitor": {"connectedtext": "Serverlə əlaqə var", "disconnectedtext": "Serverlə əlaqə yoxdur", "checkingtext": "Yoxlanılır...", "popupmessageconnected": "Əlaqə uğurla bərpa olundu", "popupmessagedisconnected": "Zəhmət olmasa əlaqənizi yoxlayın", "popupmessagechecking": "Server əlaqəsi yoxlanılır"}}, "ru": {"WebuiConnectionMonitor": {"connectedtext": "Соединение с сервером установлено", "disconnectedtext": "Соединение с сервером потеряно", "checkingtext": "Проверяется...", "popupmessageconnected": "Соединение успешно восстановлено", "popupmessagedisconnected": "Пожалуйста, проверьте подключение", "popupmessagechecking": "Проверка соединения с сервером"}}, "de": {"WebuiConnectionMonitor": {"connectedtext": "Verbindung zum Server hergestellt", "disconnectedtext": "Verbindung zum Server unterbrochen", "checkingtext": "Wird geprüft...", "popupmessageconnected": "Verbindung erfolgreich wiederhergestellt", "popupmessagedisconnected": "Bitte überprüfen Sie Ihre Verbindung", "popupmessagechecking": "Serververbindung wird geprüft"}}, "en": {"WebuiConnectionMonitor": {"connectedtext": "Connected to server", "disconnectedtext": "Disconnected from server", "checkingtext": "Checking...", "popupmessageconnected": "Connection successfully restored", "popupmessagedisconnected": "Please check your connection", "popupmessagechecking": "Checking server connection"}}, "tr": {"WebuiConnectionMonitor": {"connectedtext": "Sunucuya bağlantı kuruldu", "disconnectedtext": "Sunucu bağlantısı kesildi", "checkingtext": "Kontrol ediliyor...", "popupmessageconnected": "Bağlantı başarıyla yeniden kuruldu", "popupmessagedisconnected": "Lütfen bağlantınızı kontrol edin", "popupmessagechecking": "Sunucu bağlantısı kontrol ediliyor"}}}}
@@ -0,0 +1 @@
1
+ {"properties": {"jsonsignal": {"type": "signal", "default": "myalarm.0.info.AlarmJson"}, "acksignal": {"type": "signal", "default": "myalarm.0.info.AcknowledgeId"}, "adapterinstance": {"type": "string", "default": "myalarm.0"}, "mode": {"type": "enum", "default": "live", "values": ["live", "history"]}, "showfilter": {"type": "enum", "default": "true", "values": ["true", "false"]}, "soundenabled": {"type": "enum", "default": "false", "values": ["true", "false"]}, "soundurl": {"type": "string", "default": ""}, "maxrows": {"type": "number", "default": 500}}, "settings": {"width": "1000px", "height": "420px"}, "html": "<div id=\"wrap\" class=\"av\"><audio id=\"snd\" loop style=\"display:none\"></audio><div class=\"av-bar\"><span class=\"av-title\"><t-t>alarm.title</t-t></span><span class=\"av-count\" css:display=\"[[this.unacked>0?'':'none']]\">[[this.unacked]]</span><span class=\"av-grow\"></span><div class=\"av-hist\" css:display=\"[[this.mode=='history'?'flex':'none']]\"><input id=\"from\" type=\"datetime-local\" class=\"av-inp\"><input id=\"to\" type=\"datetime-local\" class=\"av-inp\"><button class=\"av-btn\" @click=\"[[this._loadHistory()]]\"><t-t>alarm.Getalarms</t-t></button></div><button class=\"av-btn\" @click=\"[[this._exportCsv()]]\"><t-t>alarm.export</t-t></button><button class=\"av-btn av-accent\" css:display=\"[[this.mode=='live'?'':'none']]\" @click=\"[[this._ackAll()]]\"><t-t>alarm.ackall</t-t></button></div><div class=\"av-scroll\"><div class=\"av-grid av-head\"><span><t-t>alarm.id</t-t></span><span><t-t>alarm.tagname</t-t></span><span><t-t>alarm.type</t-t></span><span><t-t>alarm.time</t-t></span><span><t-t>alarm.description</t-t></span><span><t-t>alarm.limitvalue</t-t></span><span><t-t>alarm.limitmsg</t-t></span><span><t-t>alarm.highlow</t-t></span><span><t-t>alarm.value</t-t></span><span><t-t>alarm.ack</t-t></span><span><t-t>alarm.acktime</t-t></span><span><t-t>alarm.ackbtn</t-t></span></div><div class=\"av-grid av-filters\" css:display=\"[[this.showfilter=='false'?'none':'grid']]\"><input class=\"av-f\" data-f=\"id\"><input class=\"av-f\" data-f=\"Tagname\"><input class=\"av-f\" data-f=\"Alarmtype\"><input class=\"av-f\" data-f=\"alarmtime\"><input class=\"av-f\" data-f=\"Description\"><input class=\"av-f\" data-f=\"LimitValue\"><input class=\"av-f\" data-f=\"Limitmessage\"><input class=\"av-f\" data-f=\"HIGH_LOW\"><input class=\"av-f\" data-f=\"AlarmValue\"><input class=\"av-f\" data-f=\"Acknowledge\"><input class=\"av-f\" data-f=\"acknowledgetime\"><span></span></div><div class=\"av-body\"><template repeat:row=\"[[this.rows]]\"><div class=\"av-grid av-row\" class:unack=\"[[String(row.Acknowledge)!='true']]\" class:talarm=\"[[row.Alarmtype=='alarm']]\" class:twarning=\"[[row.Alarmtype=='warning']]\" class:tinfo=\"[[row.Alarmtype=='info']]\"><span title=\"[[row.id]]\">[[row.id]]</span><span title=\"[[row.Tagname]]\">[[row.Tagname]]</span><span title=\"[[row.Alarmtype]]\">[[row.Alarmtype]]</span><span title=\"[[row.alarmtime]]\">[[row.alarmtime]]</span><span title=\"[[row.Description]]\">[[row.Description]]</span><span title=\"[[row.LimitValue]]\">[[row.LimitValue]]</span><span title=\"[[row.Limitmessage]]\">[[row.Limitmessage]]</span><span title=\"[[row.HIGH_LOW]]\">[[row.HIGH_LOW]]</span><span title=\"[[row.AlarmValue]]\">[[row.AlarmValue]]</span><span>[[String(row.Acknowledge)=='true'?'\\u2713':'\\u2014']]</span><span title=\"[[row.acknowledgetime]]\">[[row.acknowledgetime]]</span><button class=\"av-ack\" @click=\"[[this._ack(row)]]\" css:visibility=\"[[String(row.Acknowledge)=='true'?'hidden':'visible']]\"><t-t>alarm.ackbtn</t-t></button></div></template><div class=\"av-empty\" css:display=\"[[this.rows.length?'none':'block']]\"><t-t>alarm.noalarms</t-t></div></div></div></div>", "style": ":host{display:block;width:100%;height:100%;font-family:'Segoe UI',system-ui,sans-serif;font-size:12px;}.av{display:flex;flex-direction:column;height:100%;box-sizing:border-box;border:1px solid var(--ui-border,#3b4250);border-radius:10px;overflow:hidden;background:var(--ui-surface,#252b38);color:var(--ui-text,#e2e6ec);-webkit-backdrop-filter:var(--ui-backdrop,none);backdrop-filter:var(--ui-backdrop,none);}.av-bar{display:flex;align-items:center;gap:8px;padding:8px 12px;flex:none;border-bottom:1px solid var(--ui-border,#3b4250);background:var(--ui-surface-2,#2f3545);}.av-title{font-size:14px;font-weight:700;}.av-grow{flex:1;}.av-count{background:var(--ui-error,#ef4d5e);color:#fff;font-weight:700;border-radius:999px;padding:1px 8px;font-size:11px;}.av-hist{display:flex;align-items:center;gap:6px;}.av-inp{background:var(--ui-input,#3a3f4b);color:var(--ui-text,#e2e6ec);border:1px solid var(--ui-border,#3b4250);border-radius:5px;padding:3px 6px;font-size:11px;color-scheme:inherit;}.av-btn{appearance:none;cursor:pointer;border-radius:6px;padding:4px 12px;font-size:12px;font-weight:600;background:color-mix(in srgb,var(--ui-text,#fff) 8%,transparent);color:var(--ui-text,#e2e6ec);border:1px solid var(--ui-border,#3b4250);}.av-btn:hover{background:color-mix(in srgb,var(--ui-text,#fff) 14%,transparent);}.av-accent{background:color-mix(in srgb,var(--accent,#2680eb) 25%,transparent);border-color:color-mix(in srgb,var(--accent,#2680eb) 55%,transparent);}.av-scroll{flex:1;overflow:auto;min-height:0;}.av-grid{display:grid;grid-template-columns:52px 120px 86px 150px minmax(140px,1fr) 86px 130px 80px 90px 58px 150px 74px;gap:0;align-items:center;min-width:1200px;}.av-grid>*{padding:5px 8px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}.av-head{position:sticky;top:0;z-index:2;background:var(--ui-surface-2,#2f3545);font-weight:700;font-size:11px;text-transform:uppercase;letter-spacing:.4px;color:var(--ui-dim,#9aa3b0);border-bottom:1px solid var(--ui-border,#3b4250);}.av-filters{position:sticky;top:26px;z-index:2;background:var(--ui-surface,#252b38);border-bottom:1px solid var(--ui-border,#3b4250);}.av-f{width:100%;box-sizing:border-box;background:var(--ui-input,#3a3f4b);color:var(--ui-text,#e2e6ec);border:1px solid var(--ui-border,#3b4250);border-radius:4px;padding:2px 5px;font-size:11px;margin:3px 4px;}.av-row{border-bottom:1px solid color-mix(in srgb,var(--ui-border,#3b4250) 55%,transparent);}.av-row:hover{background:color-mix(in srgb,var(--ui-text,#fff) 6%,transparent);}.av-row.talarm{background:color-mix(in srgb,var(--ui-error,#ef4d5e) 16%,transparent);}.av-row.twarning{background:color-mix(in srgb,var(--ui-warn,#f6b73c) 14%,transparent);}.av-row.tinfo{background:color-mix(in srgb,var(--ui-info,#2b8bff) 12%,transparent);}.av-row.unack{font-weight:700;}.av-row.unack.talarm{background:color-mix(in srgb,var(--ui-error,#ef4d5e) 30%,transparent);}.av-row.unack.twarning{background:color-mix(in srgb,var(--ui-warn,#f6b73c) 26%,transparent);}.av-ack{appearance:none;cursor:pointer;margin:2px 4px;padding:2px 8px;font-size:11px;font-weight:700;border-radius:5px;background:color-mix(in srgb,var(--ui-ok,#37d67a) 25%,transparent);color:var(--ui-text,#e2e6ec);border:1px solid color-mix(in srgb,var(--ui-ok,#37d67a) 55%,transparent);}.av-ack:hover{background:color-mix(in srgb,var(--ui-ok,#37d67a) 40%,transparent);}.av-empty{text-align:center;padding:26px;color:var(--ui-dim,#9aa3b0);}", "script": "function num(v,d){v=parseInt(v);return isNaN(v)?d:v;}\nfunction updateSound(instance){\n const a=instance._getDomElement('snd');\n if(!a) return;\n const on = instance.soundenabled==='true' && instance.unacked>0 && instance.soundurl;\n if(on){ if(a.getAttribute('src')!==instance.soundurl) a.setAttribute('src',instance.soundurl);\n a.play().catch(()=>{}); }\n else { a.pause(); }\n}\nfunction applyFilters(instance){\n let rows=instance._raw||[];\n const f=instance._filters||{};\n for(const k in f){ const v=String(f[k]||'').toLowerCase(); if(!v) continue;\n rows=rows.filter(r=>String(r[k]??'').toLowerCase().includes(v)); }\n instance.unacked=(instance._raw||[]).filter(r=>String(r.Acknowledge)!=='true').length;\n instance.rows=rows.slice(0,num(instance.maxrows,500));\n try{ instance._bindingsRefresh(); }catch(e){}\n updateSound(instance);\n}\nfunction setRows(instance,arr){ instance._raw=Array.isArray(arr)?arr:[]; applyFilters(instance); }\nfunction parseVal(instance,val){\n let arr=[]; try{ arr=JSON.parse(val||'[]'); }catch(e){ arr=[]; }\n setRows(instance,arr);\n}\nfunction inst(instance){ return instance.adapterinstance||'myalarm.0'; }\nexport function init(instance){\n instance.rows=[]; instance._filters={}; instance.unacked=0; instance._raw=[];\n instance._ack=(row)=>{\n if(!row||row.id==null) return;\n try{ window.IOB.connection._socket.emit('sendTo',inst(instance),'ackAlarm',{alarmId:row.id},()=>{}); }catch(e){}\n if(instance.acksignal){ try{ window.IOB.setState(instance.acksignal,{val:row.id}); }catch(e){} }\n };\n instance._ackAll=()=>{ for(const r of (instance._raw||[])) if(String(r.Acknowledge)!=='true') instance._ack(r); };\n instance._loadHistory=()=>{\n const f=instance._getDomElement('from')?.value, t=instance._getDomElement('to')?.value;\n try{ window.IOB.connection._socket.emit('sendTo',inst(instance),'getlog',{startdate:f,enddate:t},(cb)=>{\n let d=(cb&&cb.result!==undefined)?cb.result:cb;\n if(typeof d==='string'){ try{ d=JSON.parse(d); }catch(e){} }\n setRows(instance, Array.isArray(d)?d:(d&&d.rows)||[]);\n }); }catch(e){ console.warn('[alarm-viewer] getlog failed',e); }\n };\n instance._exportCsv=()=>{\n const cols=['id','Tagname','Alarmtype','alarmtime','Description','LimitValue','Limitmessage','HIGH_LOW','AlarmValue','Acknowledge','acknowledgetime'];\n const esc=(v)=>{ v=String(v??''); return (v.includes(',')||v.includes('\"')||v.includes('\\n'))?'\"'+v.replaceAll('\"','\"\"')+'\"':v; };\n const lines=[cols.join(',')];\n for(const r of instance.rows) lines.push(cols.map(c=>esc(r[c])).join(','));\n const blob=new Blob([''+lines.join('\\r\\n')],{type:'text/csv;charset=utf-8'});\n const a=document.createElement('a');\n a.href=URL.createObjectURL(blob); a.download='alarms.csv'; a.click();\n setTimeout(()=>URL.revokeObjectURL(a.href),2000);\n };\n for(const inp of instance._getDomElements('.av-f')){\n inp.addEventListener('input',()=>{ instance._filters[inp.dataset.f]=inp.value; applyFilters(instance); });\n }\n const sig=instance.jsonsignal||'myalarm.0.info.AlarmJson';\n try{ window.IOB.getState(sig).then(s=>parseVal(instance,s&&s.val)).catch(()=>{}); }catch(e){}\n instance.__avCb=(_id,s)=>parseVal(instance,s&&s.val);\n if((instance.mode||'live')==='live'){ try{ window.IOB.subscribeState(sig,instance.__avCb); }catch(e){} }\n}\nexport function disconnectedCallback(instance){\n try{ window.IOB.unsubscribeState(instance.jsonsignal||'myalarm.0.info.AlarmJson',instance.__avCb); }catch(e){}\n try{ instance._getDomElement('snd')?.pause(); }catch(e){}\n}", "translations": {"az": {"alarm": {"id": "No", "time": "Alarm Vaxtı", "type": "Alarm Tipi", "tagname": "Teq Adı", "description": "Açıqlama", "highlow": "Tip", "limitvalue": "Limit Dəyəri", "limitmsg": "Limit Mesajı", "value": "Alarm Dəyəri", "ack": "Təsdiq", "acktime": "Təsdiq Vaxtı", "ackbtn": "Təsdiqlə", "yes": "Bəli", "no": "Xeyr", "Getalarms": "Alarmları Gətir", "DownloadXLSX": "XLSX Yüklə", "DownloadCSV": "CSV Yüklə", "DownloadPDF": "PDF Yüklə", "selectdate": "Tarix aralığı seçin", "header": "Aktiv Alarmlar", "ackall": "Hamısını təsdiqlə", "clear": "Təsdiqlənənləri Sil", "mute": "Səsi Kəs", "unmute": "Səsi Aç", "title": "Alarmlar", "export": "CSV yüklə", "noalarms": "Alarm yoxdur"}}, "en": {"alarm": {"id": "ID", "time": "Alarm Time", "type": "Alarm Type", "tagname": "Tag Name", "description": "Description", "highlow": "Type", "limitvalue": "Limit Value", "limitmsg": "Limit Message", "value": "Alarm Value", "ack": "Acknowledge", "acktime": "Ack Time", "ackbtn": "ACK", "yes": "Yes", "no": "No", "Getalarms": "Get Alarms", "DownloadXLSX": "Download XLSX", "DownloadCSV": "Download CSV", "DownloadPDF": "Download PDF", "selectdate": "Select date range", "header": "Active Alarms", "ackall": "Acknowledge all", "clear": "Clear Acknowledged", "mute": "Mute Sound", "unmute": "Unmute Sound", "title": "Alarms", "export": "Export CSV", "noalarms": "No alarms"}}, "ru": {"alarm": {"id": "No", "time": "Время аларма", "type": "Тип аларма", "tagname": "Тег", "description": "Описание", "highlow": "Тип", "limitvalue": "Предел", "limitmsg": "Сообщение", "value": "Значение", "ack": "Квитирование", "acktime": "Время квит.", "ackbtn": "Квит.", "yes": "Да", "no": "Нет", "Getalarms": "Получить аларма", "DownloadXLSX": "Скачать XLSX", "DownloadCSV": "Скачать CSV", "DownloadPDF": "Скачать PDF", "selectdate": "Выберите дату", "header": "Активные аларма", "ackall": "Квитировать все", "clear": "Очистить", "mute": "Отключить звук", "unmute": "Включить звук", "title": "Алармы", "export": "Скачать CSV", "noalarms": "Нет алармов"}}, "de": {"alarm": {"id": "Nr", "time": "Alarmzeit", "type": "Alarmtyp", "tagname": "Tag-Name", "description": "Beschreibung", "highlow": "Typ", "limitvalue": "Grenzwert", "limitmsg": "Grenznachricht", "value": "Alarmwert", "ack": "Quittierung", "acktime": "Quitt.-Zeit", "ackbtn": "Quitt.", "yes": "Ja", "no": "Nein", "Getalarms": "Alarme abrufen", "DownloadXLSX": "XLSX laden", "DownloadCSV": "CSV laden", "DownloadPDF": "PDF laden", "selectdate": "Datumsbereich wählen", "header": "Aktive Alarme", "ackall": "Alle quittieren", "clear": "Bestätigte löschen", "mute": "Ton stumm", "unmute": "Ton ein", "title": "Alarme", "export": "CSV exportieren", "noalarms": "Keine Alarme"}}, "tr": {"alarm": {"id": "No", "time": "Alarm Zamanı", "type": "Alarm Tipi", "tagname": "Etiket Adı", "description": "Açıklama", "highlow": "Tip", "limitvalue": "Limit Değeri", "limitmsg": "Limit Mesajı", "value": "Alarm Değeri", "ack": "Onay", "acktime": "Onay Zamanı", "ackbtn": "Onayla", "yes": "Evet", "no": "Hayır", "Getalarms": "Alarmları Getir", "DownloadXLSX": "XLSX İndir", "DownloadCSV": "CSV İndir", "DownloadPDF": "PDF İndir", "selectdate": "Tarih Aralığı Seçin", "header": "Aktif Alarmlar", "ackall": "Tümünü onayla", "clear": "Onaylanları Sil", "mute": "Sesi Kapat", "unmute": "Sesi Aç", "title": "Alarmlar", "export": "CSV indir", "noalarms": "Alarm yok"}}}}
@@ -1 +1 @@
1
- {"html": "<div id=\"main-container\" style=\"display:flex;gap:8px;align-items:stretch;width:100%;height:100%;font:&quot;Times New Roman&quot;, serif;\">\n <!-- Input Container -->\n <div id=\"input-container\" style=\"position:relative;flex:1;display:flex;align-items:center;border:1px solid var(--ui-border,rgb(204, 204, 204));border-radius:4px;background:rgb(240, 240, 240);padding:4px 8px;\">\n <input id=\"text-input\" type=\"text\" placeholder style=\"flex:1;border:initial none initial;outline:none;padding:4px;color:var(--ui-text,#333);background:transparent;font:14px &quot;Times New Roman&quot;, serif;\">\n <!-- Numberpad Icon (hidden by default) --> <svg id=\"numberpad-icon\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" title=\"Numberpad\" style=\"cursor:pointer;fill:#666;margin-left:4px;display:none;\">\n <rect x=\"3\" y=\"3\" width=\"4\" height=\"4\" rx=\"1\"></rect>\n <rect x=\"10\" y=\"3\" width=\"4\" height=\"4\" rx=\"1\"></rect>\n <rect x=\"17\" y=\"3\" width=\"4\" height=\"4\" rx=\"1\"></rect>\n <rect x=\"3\" y=\"10\" width=\"4\" height=\"4\" rx=\"1\"></rect>\n <rect x=\"10\" y=\"10\" width=\"4\" height=\"4\" rx=\"1\"></rect>\n <rect x=\"17\" y=\"10\" width=\"4\" height=\"4\" rx=\"1\"></rect>\n <rect x=\"3\" y=\"17\" width=\"4\" height=\"4\" rx=\"1\"></rect>\n <rect x=\"10\" y=\"17\" width=\"11\" height=\"4\" rx=\"1\"></rect>\n </svg>\n </div>\n <!-- Button -->\n <button id=\"submit-btn\" style=\"color:var(--ui-text,#fff);border:initial none initial;border-radius:4px;cursor:pointer;white-space:nowrap;min-width:80px;background:rgb(108, 117, 125);font:14px &quot;Times New Roman&quot;, serif;padding:8px 16px;\">\n<t-t>input_with_button.volume</t-t>\n </button>\n</div>\n<!-- Numberpad Dialog -->\n<dialog id=\"numberpad-dialog\" style=\"border:2px solid var(--ui-surface,rgb(90, 122, 122));border-radius:8px;padding:0px;-webkit-backdrop-filter:var(--ui-backdrop,none);backdrop-filter:var(--ui-backdrop,none);background:var(--ui-input,rgb(255, 255, 255));\">\n <div id=\"dialog-header\" style=\"color:var(--ui-text,#fff);padding:12px;display:flex;justify-content:space-between;align-items:center;background:var(--ui-surface,rgb(90, 122, 122));\">\n <h3 id=\"dialog-title\" style=\"margin:0px;font:16px &quot;Times New Roman&quot;, serif;\">Numberpad</h3>\n <button id=\"close-numberpad\" style=\"border:initial none initial;color:var(--ui-text,#fff);cursor:pointer;padding:0px;width:30px;height:30px;background:transparent;font:24px &quot;Times New Roman&quot;, serif;\">×</button>\n </div>\n <div id=\"numberpad-body\" style=\"padding:16px;\">\n <!-- Display --><input id=\"numberpad-display\" type=\"text\" readonly style=\"width:100%;padding:2px;text-align:right;border:1px solid var(--ui-border,rgb(204, 204, 204));border-radius:4px;margin-bottom:12px;background:rgb(249, 249, 249);font:20px &quot;Times New Roman&quot;, serif;\"><!-- Numberpad Grid -->\n<div style=\"display:grid;grid-template-columns:repeat(3, 60px);gap:8px;\">\n <button class=\"num-btn\" data-value=\"7\" style=\"padding:16px;border:1px solid var(--ui-border,rgb(204, 204, 204));border-radius:4px;cursor:pointer;background:var(--ui-input,rgb(255, 255, 255));font:18px &quot;Times New Roman&quot;, serif;\">7</button>\n <button class=\"num-btn\" data-value=\"8\" style=\"padding:16px;border:1px solid var(--ui-border,rgb(204, 204, 204));border-radius:4px;cursor:pointer;background:var(--ui-input,rgb(255, 255, 255));font:18px &quot;Times New Roman&quot;, serif;\">8</button>\n <button class=\"num-btn\" data-value=\"9\" style=\"padding:16px;border:1px solid var(--ui-border,rgb(204, 204, 204));border-radius:4px;cursor:pointer;background:var(--ui-input,rgb(255, 255, 255));font:18px &quot;Times New Roman&quot;, serif;\">9</button>\n <button class=\"num-btn\" data-value=\"4\" style=\"padding:16px;border:1px solid var(--ui-border,rgb(204, 204, 204));border-radius:4px;cursor:pointer;background:var(--ui-input,rgb(255, 255, 255));font:18px &quot;Times New Roman&quot;, serif;\">4</button>\n <button class=\"num-btn\" data-value=\"5\" style=\"padding:16px;border:1px solid var(--ui-border,rgb(204, 204, 204));border-radius:4px;cursor:pointer;background:var(--ui-input,rgb(255, 255, 255));font:18px &quot;Times New Roman&quot;, serif;\">5</button>\n <button class=\"num-btn\" data-value=\"6\" style=\"padding:16px;border:1px solid var(--ui-border,rgb(204, 204, 204));border-radius:4px;cursor:pointer;background:var(--ui-input,rgb(255, 255, 255));font:18px &quot;Times New Roman&quot;, serif;\">6</button>\n <button class=\"num-btn\" data-value=\"1\" style=\"padding:16px;border:1px solid var(--ui-border,rgb(204, 204, 204));border-radius:4px;cursor:pointer;background:var(--ui-input,rgb(255, 255, 255));font:18px &quot;Times New Roman&quot;, serif;\">1</button>\n <button class=\"num-btn\" data-value=\"2\" style=\"padding:16px;border:1px solid var(--ui-border,rgb(204, 204, 204));border-radius:4px;cursor:pointer;background:var(--ui-input,rgb(255, 255, 255));font:18px &quot;Times New Roman&quot;, serif;\">2</button>\n <button class=\"num-btn\" data-value=\"3\" style=\"padding:16px;border:1px solid var(--ui-border,rgb(204, 204, 204));border-radius:4px;cursor:pointer;background:var(--ui-input,rgb(255, 255, 255));font:18px &quot;Times New Roman&quot;, serif;\">3</button>\n <button class=\"num-btn\" data-value=\"0\" style=\"padding:16px;border:1px solid var(--ui-border,rgb(204, 204, 204));border-radius:4px;cursor:pointer;grid-column:span 2;background:var(--ui-input,rgb(255, 255, 255));font:18px &quot;Times New Roman&quot;, serif;\">0</button>\n <button class=\"num-btn\" data-value=\".\" style=\"padding:16px;border:1px solid var(--ui-border,rgb(204, 204, 204));border-radius:4px;cursor:pointer;background:var(--ui-input,rgb(255, 255, 255));font:18px &quot;Times New Roman&quot;, serif;\">.</button>\n <button id=\"num-clear\" style=\"padding:16px;border:1px solid var(--ui-border,rgb(204, 204, 204));border-radius:4px;color:var(--ui-text,#fff);cursor:pointer;grid-column:span 2;background:rgb(255, 107, 107);font:14px &quot;Times New Roman&quot;, serif;\">\n<t-t>input_with_button.clear</t-t>\n </button>\n <button id=\"num-backspace\" style=\"padding:16px;border:1px solid var(--ui-border,rgb(204, 204, 204));border-radius:4px;color:var(--ui-text,#fff);cursor:pointer;background:rgb(255, 165, 0);font:14px &quot;Times New Roman&quot;, serif;\">←</button>\n </div>\n <!-- OK Button --><button id=\"num-ok\" style=\"width:100%;padding:12px;margin-top:12px;border:initial none initial;border-radius:4px;color:var(--ui-text,#fff);cursor:pointer;background:var(--ui-surface,rgb(90, 122, 122));font:16px &quot;Times New Roman&quot;, serif;\">OK</button>\n </div>\n</dialog>\n", "script": "export function init(instance) {\n //instance._bindingsRefresh();\n\n applyTheming(instance);\n updateControl(instance);\n\n instance._assignEvent('input-type-changed', () => updateControl(instance));\n instance._assignEvent('button-text-changed', () => updateControl(instance));\n instance._assignEvent('placeholder-changed', () => updateControl(instance));\n instance._assignEvent('theme-changed', () => applyTheming(instance));\n instance._assignEvent('state-id-changed', () => { });\n\n const input = instance._getDomElement('text-input');\n const submitBtn = instance._getDomElement('submit-btn');\n const numberpadIcon = instance._getDomElement('numberpad-icon');\n const numberpadDialog = instance._getDomElement('numberpad-dialog');\n const numberpadDisplay = instance._getDomElement('numberpad-display');\n const closeNumberpad = instance._getDomElement('close-numberpad');\n const numOk = instance._getDomElement('num-ok');\n const numClear = instance._getDomElement('num-clear');\n const numBackspace = instance._getDomElement('num-backspace');\n\n window.addEventListener('languageChanged', () => {\n if (input) {\n input.placeholder = t('input_with_button.addvalue');\n }\n });\n\n // Subscribe to state changes\n let stateSubscription = null;\n function subscribeToState() {\n // Unsubscribe from previous state\n if (stateSubscription) {\n window.IOB.unsubscribeState(stateSubscription);\n stateSubscription = null;\n }\n\n // Subscribe to new state\n const stateId = instance.stateId;\n if (stateId) {\n stateSubscription = window.IOB.subscribeState(stateId, (id, state) => {\n const input = instance._getDomElement('text-input');\n if (input && state && state.val !== undefined) {\n input.value = state.val;\n }\n });\n\n // Load initial value\n window.IOB.getState(stateId).then(state => {\n const input = instance._getDomElement('text-input');\n if (input && state && state.val !== undefined) {\n input.value = state.val;\n }\n });\n }\n }\n\n subscribeToState();\n\n // Submit function\n async function submitValue() {\n const value = input.value;\n const stateId = instance.stateId;\n\n if (!stateId) {\n console.error('State ID not configured');\n return;\n }\n\n try {\n let finalValue = value;\n\n // Convert based on input type\n if (instance.inputType === 'number') {\n finalValue = parseFloat(value);\n if (isNaN(finalValue)) {\n console.error('Invalid number:', value);\n return;\n }\n } else if (instance.inputType === 'integer') {\n finalValue = parseInt(value);\n if (isNaN(finalValue)) {\n console.error('Invalid integer:', value);\n return;\n }\n }\n\n await window.IOB.setState(stateId, finalValue);\n console.log('Value written to state:', stateId, finalValue);\n\n // Optional: Clear input after submit\n if (instance.clearAfterSubmit === true) {\n input.value = '';\n }\n } catch (err) {\n console.error('Error writing to state:', err);\n }\n }\n\n // Enter key handler\n if (input) {\n input.addEventListener('keypress', (e) => {\n if (e.key === 'Enter') {\n submitValue();\n }\n });\n }\n\n // Submit button handler\n if (submitBtn) {\n submitBtn.addEventListener('click', () => {\n submitValue();\n });\n }\n\n // Numberpad icon handler\n if (numberpadIcon && numberpadDialog) {\n numberpadIcon.addEventListener('click', () => {\n numberpadDisplay.value = input.value || '';\n numberpadDialog.showModal();\n });\n }\n // Numberpad buttons\n const numBtns = instance.shadowRoot.querySelectorAll('.num-btn');\n numBtns.forEach(btn => {\n btn.addEventListener('click', () => {\n numberpadDisplay.value += btn.dataset.value;\n });\n });\n\n // Numberpad clear\n if (numClear) {\n numClear.addEventListener('click', () => {\n numberpadDisplay.value = '';\n });\n }\n\n // Numberpad backspace\n if (numBackspace) {\n numBackspace.addEventListener('click', () => {\n numberpadDisplay.value = numberpadDisplay.value.slice(0, -1);\n });\n }\n\n // Numberpad OK\n if (numOk) {\n numOk.addEventListener('click', () => {\n input.value = numberpadDisplay.value;\n numberpadDialog.close();\n });\n }\n\n // Close numberpad\n if (closeNumberpad) {\n closeNumberpad.addEventListener('click', () => {\n numberpadDialog.close();\n });\n }\n\n // Close dialog on outside click\n if (numberpadDialog) {\n numberpadDialog.addEventListener('click', (e) => {\n const rect = numberpadDialog.getBoundingClientRect();\n if (e.clientX < rect.left || e.clientX > rect.right || e.clientY < rect.top || e.clientY > rect.bottom) {\n numberpadDialog.close();\n }\n });\n }\n}\n\n\nfunction updateControl(instance) {\n const input = instance._getDomElement('text-input');\n const submitBtn = instance._getDomElement('submit-btn');\n const numberpadIcon = instance._getDomElement('numberpad-icon');\n\n // Update input type\n if (input) {\n const inputType = instance.inputType || 'string';\n\n if (inputType === 'password') {\n input.type = 'password';\n } else if (inputType === 'number' || inputType === 'integer') {\n input.type = 'text';\n } else {\n input.type = 'text';\n }\n\n //input.placeholder = instance.placeholder || 'Dəyər daxil edin';\n }\n\n // Show/hide numberpad icon\n if (numberpadIcon) {\n const showNumberpad = instance.inputType === 'number' || instance.inputType === 'integer';\n numberpadIcon.style.display = showNumberpad ? 'block' : 'none';\n }\n\n}\n\nfunction applyTheming(instance) {\n const theme = instance.theme || 'default';\n\n const themes = {\n 'default': { inputBg: 'var(--ui-input,#f0f0f0)', inputBorder: 'var(--ui-border,#ccc)', inputText: 'var(--ui-text,#333)', btnBg: 'var(--ui-surface-2,#6c757d)', btnText: 'var(--ui-text,#fff)', headerBg: 'var(--ui-surface,#5a7a7a)' },\n 'dark': { inputBg: '#2d3436', inputBorder: '#000', inputText: '#fff', btnBg: '#636e72', btnText: '#fff', headerBg: '#2d3436' },\n 'light': { inputBg: '#fff', inputBorder: '#dfe6e9', inputText: '#2d3436', btnBg: '#b2bec3', btnText: '#2d3436', headerBg: '#dfe6e9' },\n 'blue': { inputBg: '#dfe6e9', inputBorder: '#74b9ff', inputText: '#0984e3', btnBg: '#0984e3', btnText: '#fff', headerBg: '#0984e3' },\n 'green': { inputBg: '#d4f1e8', inputBorder: '#55efc4', inputText: '#00b894', btnBg: '#00b894', btnText: '#fff', headerBg: '#00b894' },\n 'red': { inputBg: '#ffcccc', inputBorder: '#ff7675', inputText: '#d63031', btnBg: '#d63031', btnText: '#fff', headerBg: '#d63031' },\n 'purple': { inputBg: '#e5dbff', inputBorder: '#a29bfe', inputText: '#6c5ce7', btnBg: '#6c5ce7', btnText: '#fff', headerBg: '#6c5ce7' }\n };\n\n const colors = themes[theme] || themes['default'];\n\n // Input container\n const inputContainer = instance._getDomElement('input-container');\n if (inputContainer) {\n inputContainer.style.background = colors.inputBg;\n inputContainer.style.borderColor = colors.inputBorder;\n }\n\n // Input text\n const input = instance._getDomElement('text-input');\n if (input) {\n input.style.color = colors.inputText;\n }\n\n // Numberpad icon\n const numberpadIcon = instance._getDomElement('numberpad-icon');\n if (numberpadIcon) {\n numberpadIcon.style.fill = colors.inputText;\n }\n\n // Submit button\n const submitBtn = instance._getDomElement('submit-btn');\n if (submitBtn) {\n submitBtn.style.background = colors.btnBg;\n submitBtn.style.color = colors.btnText;\n }\n\n // Dialog header\n const dialogHeader = instance._getDomElement('dialog-header');\n if (dialogHeader) {\n dialogHeader.style.background = colors.headerBg;\n }\n\n // Dialog\n const dialog = instance._getDomElement('numberpad-dialog');\n if (dialog) {\n dialog.style.borderColor = colors.headerBg;\n }\n\n // OK button in numberpad\n const numOk = instance._getDomElement('num-ok');\n if (numOk) {\n numOk.style.background = colors.headerBg;\n }\n}", "properties": {"inputType": {"type": "enum", "default": "string", "values": ["string", "number", "integer", "password"]}, "placeholder": {"type": "string", "default": "Dəyər daxil edin"}, "stateId": {"type": "signal"}, "clearAfterSubmit": {"type": "boolean"}, "theme": {"type": "enum", "default": "default", "values": ["default", "dark", "light", "blue", "green", "red", "purple"]}}, "settings": {"visibilityEnabled": "false", "visibilityGroups": "", "visibilityAction": "hide", "visibilityRedirectScreen": ""}}
1
+ {"html": "<div id=\"main-container\" style=\"display:flex;gap:8px;align-items:stretch;width:100%;height:100%;font:&quot;Times New Roman&quot;, serif;\">\n <!-- Input Container -->\n <div id=\"input-container\" style=\"position:relative;flex:1;display:flex;align-items:center;border:1px solid var(--ui-border,rgb(204, 204, 204));border-radius:4px;background:rgb(240, 240, 240);padding:4px 8px;\">\n <input id=\"text-input\" type=\"text\" placeholder style=\"flex:1;border:initial none initial;outline:none;padding:4px;color:var(--ui-text,#333);background:transparent;font:14px &quot;Times New Roman&quot;, serif;\">\n <!-- Numberpad Icon (hidden by default) --> <svg id=\"numberpad-icon\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" title=\"Numberpad\" style=\"cursor:pointer;fill:#666;margin-left:4px;display:none;\">\n <rect x=\"3\" y=\"3\" width=\"4\" height=\"4\" rx=\"1\"></rect>\n <rect x=\"10\" y=\"3\" width=\"4\" height=\"4\" rx=\"1\"></rect>\n <rect x=\"17\" y=\"3\" width=\"4\" height=\"4\" rx=\"1\"></rect>\n <rect x=\"3\" y=\"10\" width=\"4\" height=\"4\" rx=\"1\"></rect>\n <rect x=\"10\" y=\"10\" width=\"4\" height=\"4\" rx=\"1\"></rect>\n <rect x=\"17\" y=\"10\" width=\"4\" height=\"4\" rx=\"1\"></rect>\n <rect x=\"3\" y=\"17\" width=\"4\" height=\"4\" rx=\"1\"></rect>\n <rect x=\"10\" y=\"17\" width=\"11\" height=\"4\" rx=\"1\"></rect>\n </svg>\n </div>\n <!-- Button -->\n <button id=\"submit-btn\" style=\"color:var(--ui-text,#fff);border:initial none initial;border-radius:4px;cursor:pointer;white-space:nowrap;min-width:80px;background:rgb(108, 117, 125);font:14px &quot;Times New Roman&quot;, serif;padding:8px 16px;\">\n<t-t>input_with_button.volume</t-t>\n </button>\n</div>\n<!-- Numberpad Dialog -->\n<dialog id=\"numberpad-dialog\" style=\"border:2px solid var(--ui-surface,rgb(90, 122, 122));border-radius:8px;padding:0px;-webkit-backdrop-filter:var(--ui-backdrop,none);backdrop-filter:var(--ui-backdrop,none);background:var(--ui-input,rgb(255, 255, 255));\">\n <div id=\"dialog-header\" style=\"color:var(--ui-text,#fff);padding:12px;display:flex;justify-content:space-between;align-items:center;background:var(--ui-surface,rgb(90, 122, 122));\">\n <h3 id=\"dialog-title\" style=\"margin:0px;font:16px &quot;Times New Roman&quot;, serif;\">Numberpad</h3>\n <button id=\"close-numberpad\" style=\"border:initial none initial;color:var(--ui-text,#fff);cursor:pointer;padding:0px;width:30px;height:30px;background:transparent;font:24px &quot;Times New Roman&quot;, serif;\">×</button>\n </div>\n <div id=\"numberpad-body\" style=\"padding:16px;\">\n <!-- Display --><input id=\"numberpad-display\" type=\"text\" readonly style=\"width:100%;padding:2px;text-align:right;border:1px solid var(--ui-border,rgb(204, 204, 204));border-radius:4px;margin-bottom:12px;background:rgb(249, 249, 249);font:20px &quot;Times New Roman&quot;, serif;\"><!-- Numberpad Grid -->\n<div style=\"display:grid;grid-template-columns:repeat(3, 60px);gap:8px;\">\n <button class=\"num-btn\" data-value=\"7\" style=\"padding:16px;border:1px solid var(--ui-border,rgb(204, 204, 204));border-radius:4px;cursor:pointer;background:var(--ui-input,rgb(255, 255, 255));font:18px &quot;Times New Roman&quot;, serif;\">7</button>\n <button class=\"num-btn\" data-value=\"8\" style=\"padding:16px;border:1px solid var(--ui-border,rgb(204, 204, 204));border-radius:4px;cursor:pointer;background:var(--ui-input,rgb(255, 255, 255));font:18px &quot;Times New Roman&quot;, serif;\">8</button>\n <button class=\"num-btn\" data-value=\"9\" style=\"padding:16px;border:1px solid var(--ui-border,rgb(204, 204, 204));border-radius:4px;cursor:pointer;background:var(--ui-input,rgb(255, 255, 255));font:18px &quot;Times New Roman&quot;, serif;\">9</button>\n <button class=\"num-btn\" data-value=\"4\" style=\"padding:16px;border:1px solid var(--ui-border,rgb(204, 204, 204));border-radius:4px;cursor:pointer;background:var(--ui-input,rgb(255, 255, 255));font:18px &quot;Times New Roman&quot;, serif;\">4</button>\n <button class=\"num-btn\" data-value=\"5\" style=\"padding:16px;border:1px solid var(--ui-border,rgb(204, 204, 204));border-radius:4px;cursor:pointer;background:var(--ui-input,rgb(255, 255, 255));font:18px &quot;Times New Roman&quot;, serif;\">5</button>\n <button class=\"num-btn\" data-value=\"6\" style=\"padding:16px;border:1px solid var(--ui-border,rgb(204, 204, 204));border-radius:4px;cursor:pointer;background:var(--ui-input,rgb(255, 255, 255));font:18px &quot;Times New Roman&quot;, serif;\">6</button>\n <button class=\"num-btn\" data-value=\"1\" style=\"padding:16px;border:1px solid var(--ui-border,rgb(204, 204, 204));border-radius:4px;cursor:pointer;background:var(--ui-input,rgb(255, 255, 255));font:18px &quot;Times New Roman&quot;, serif;\">1</button>\n <button class=\"num-btn\" data-value=\"2\" style=\"padding:16px;border:1px solid var(--ui-border,rgb(204, 204, 204));border-radius:4px;cursor:pointer;background:var(--ui-input,rgb(255, 255, 255));font:18px &quot;Times New Roman&quot;, serif;\">2</button>\n <button class=\"num-btn\" data-value=\"3\" style=\"padding:16px;border:1px solid var(--ui-border,rgb(204, 204, 204));border-radius:4px;cursor:pointer;background:var(--ui-input,rgb(255, 255, 255));font:18px &quot;Times New Roman&quot;, serif;\">3</button>\n <button class=\"num-btn\" data-value=\"0\" style=\"padding:16px;border:1px solid var(--ui-border,rgb(204, 204, 204));border-radius:4px;cursor:pointer;grid-column:span 2;background:var(--ui-input,rgb(255, 255, 255));font:18px &quot;Times New Roman&quot;, serif;\">0</button>\n <button class=\"num-btn\" data-value=\".\" style=\"padding:16px;border:1px solid var(--ui-border,rgb(204, 204, 204));border-radius:4px;cursor:pointer;background:var(--ui-input,rgb(255, 255, 255));font:18px &quot;Times New Roman&quot;, serif;\">.</button>\n <button id=\"num-clear\" style=\"padding:16px;border:1px solid var(--ui-border,rgb(204, 204, 204));border-radius:4px;color:var(--ui-text,#fff);cursor:pointer;grid-column:span 2;background:rgb(255, 107, 107);font:14px &quot;Times New Roman&quot;, serif;\">\n<t-t>input_with_button.clear</t-t>\n </button>\n <button id=\"num-backspace\" style=\"padding:16px;border:1px solid var(--ui-border,rgb(204, 204, 204));border-radius:4px;color:var(--ui-text,#fff);cursor:pointer;background:rgb(255, 165, 0);font:14px &quot;Times New Roman&quot;, serif;\">←</button>\n </div>\n <!-- OK Button --><button id=\"num-ok\" style=\"width:100%;padding:12px;margin-top:12px;border:initial none initial;border-radius:4px;color:var(--ui-text,#fff);cursor:pointer;background:var(--ui-surface,rgb(90, 122, 122));font:16px &quot;Times New Roman&quot;, serif;\">OK</button>\n </div>\n</dialog>\n", "script": "export function init(instance) {\n //instance._bindingsRefresh();\n\n applyTheming(instance);\n updateControl(instance);\n\n instance._assignEvent('input-type-changed', () => updateControl(instance));\n instance._assignEvent('button-text-changed', () => updateControl(instance));\n instance._assignEvent('placeholder-changed', () => updateControl(instance));\n instance._assignEvent('theme-changed', () => applyTheming(instance));\n instance._assignEvent('state-id-changed', () => { });\n\n const input = instance._getDomElement('text-input');\n const submitBtn = instance._getDomElement('submit-btn');\n const numberpadIcon = instance._getDomElement('numberpad-icon');\n const numberpadDialog = instance._getDomElement('numberpad-dialog');\n const numberpadDisplay = instance._getDomElement('numberpad-display');\n const closeNumberpad = instance._getDomElement('close-numberpad');\n const numOk = instance._getDomElement('num-ok');\n const numClear = instance._getDomElement('num-clear');\n const numBackspace = instance._getDomElement('num-backspace');\n\n window.addEventListener('languageChanged', () => {\n if (input) {\n input.placeholder = t('input_with_button.addvalue');\n }\n });\n\n // Subscribe to state changes\n let stateSubscription = null;\n function subscribeToState() {\n // Unsubscribe from previous state\n if (stateSubscription) {\n window.IOB.unsubscribeState(stateSubscription);\n stateSubscription = null;\n }\n\n // Subscribe to new state\n const stateId = instance.stateId;\n if (stateId) {\n stateSubscription = window.IOB.subscribeState(stateId, (id, state) => {\n const input = instance._getDomElement('text-input');\n if (input && state && state.val !== undefined) {\n input.value = state.val;\n }\n });\n\n // Load initial value\n window.IOB.getState(stateId).then(state => {\n const input = instance._getDomElement('text-input');\n if (input && state && state.val !== undefined) {\n input.value = state.val;\n }\n });\n }\n }\n\n subscribeToState();\n\n // Submit function\n async function submitValue() {\n const value = input.value;\n const stateId = instance.stateId;\n\n if (!stateId) {\n console.error('State ID not configured');\n return;\n }\n\n try {\n let finalValue = value;\n\n // Convert based on input type\n if (instance.inputType === 'number') {\n finalValue = parseFloat(value);\n if (isNaN(finalValue)) {\n console.error('Invalid number:', value);\n return;\n }\n } else if (instance.inputType === 'integer') {\n finalValue = parseInt(value);\n if (isNaN(finalValue)) {\n console.error('Invalid integer:', value);\n return;\n }\n }\n\n await window.IOB.setState(stateId, finalValue);\n console.log('Value written to state:', stateId, finalValue);\n\n // Optional: Clear input after submit\n if (instance.clearAfterSubmit === true) {\n input.value = '';\n }\n } catch (err) {\n console.error('Error writing to state:', err);\n }\n }\n\n // Enter key handler\n if (input) {\n input.addEventListener('keypress', (e) => {\n if (e.key === 'Enter') {\n submitValue();\n }\n });\n }\n\n // Submit button handler\n if (submitBtn) {\n submitBtn.addEventListener('click', () => {\n submitValue();\n });\n }\n\n // Numberpad icon handler\n if (numberpadIcon && numberpadDialog) {\n numberpadIcon.addEventListener('click', () => {\n numberpadDisplay.value = input.value || '';\n numberpadDialog.showModal();\n });\n }\n // Numberpad buttons\n const numBtns = instance.shadowRoot.querySelectorAll('.num-btn');\n numBtns.forEach(btn => {\n btn.addEventListener('click', () => {\n numberpadDisplay.value += btn.dataset.value;\n });\n });\n\n // Numberpad clear\n if (numClear) {\n numClear.addEventListener('click', () => {\n numberpadDisplay.value = '';\n });\n }\n\n // Numberpad backspace\n if (numBackspace) {\n numBackspace.addEventListener('click', () => {\n numberpadDisplay.value = numberpadDisplay.value.slice(0, -1);\n });\n }\n\n // Numberpad OK\n if (numOk) {\n numOk.addEventListener('click', () => {\n input.value = numberpadDisplay.value;\n numberpadDialog.close();\n });\n }\n\n // Close numberpad\n if (closeNumberpad) {\n closeNumberpad.addEventListener('click', () => {\n numberpadDialog.close();\n });\n }\n\n // Close dialog on outside click\n if (numberpadDialog) {\n numberpadDialog.addEventListener('click', (e) => {\n const rect = numberpadDialog.getBoundingClientRect();\n if (e.clientX < rect.left || e.clientX > rect.right || e.clientY < rect.top || e.clientY > rect.bottom) {\n numberpadDialog.close();\n }\n });\n }\n}\n\n\nfunction updateControl(instance) {\n const input = instance._getDomElement('text-input');\n const submitBtn = instance._getDomElement('submit-btn');\n const numberpadIcon = instance._getDomElement('numberpad-icon');\n\n // Update input type\n if (input) {\n const inputType = instance.inputType || 'string';\n\n if (inputType === 'password') {\n input.type = 'password';\n } else if (inputType === 'number' || inputType === 'integer') {\n input.type = 'text';\n } else {\n input.type = 'text';\n }\n\n //input.placeholder = instance.placeholder || 'Dəyər daxil edin';\n }\n\n // Show/hide numberpad icon\n if (numberpadIcon) {\n const showNumberpad = instance.inputType === 'number' || instance.inputType === 'integer';\n numberpadIcon.style.display = showNumberpad ? 'block' : 'none';\n }\n\n}\n\nfunction applyTheming(instance) {\n const theme = instance.theme || 'default';\n\n const themes = {\n 'default': { inputBg: 'var(--ui-input,#f0f0f0)', inputBorder: 'var(--ui-border,#ccc)', inputText: 'var(--ui-text,#333)', btnBg: 'var(--ui-surface-2,#6c757d)', btnText: 'var(--ui-text,#fff)', headerBg: 'var(--ui-surface,#5a7a7a)' },\n 'dark': { inputBg: '#2d3436', inputBorder: '#000', inputText: '#fff', btnBg: '#636e72', btnText: '#fff', headerBg: '#2d3436' },\n 'light': { inputBg: '#fff', inputBorder: '#dfe6e9', inputText: '#2d3436', btnBg: '#b2bec3', btnText: '#2d3436', headerBg: '#dfe6e9' },\n 'blue': { inputBg: '#dfe6e9', inputBorder: '#74b9ff', inputText: '#0984e3', btnBg: '#0984e3', btnText: '#fff', headerBg: '#0984e3' },\n 'green': { inputBg: '#d4f1e8', inputBorder: '#55efc4', inputText: '#00b894', btnBg: '#00b894', btnText: '#fff', headerBg: '#00b894' },\n 'red': { inputBg: '#ffcccc', inputBorder: '#ff7675', inputText: '#d63031', btnBg: '#d63031', btnText: '#fff', headerBg: '#d63031' },\n 'purple': { inputBg: '#e5dbff', inputBorder: '#a29bfe', inputText: '#6c5ce7', btnBg: '#6c5ce7', btnText: '#fff', headerBg: '#6c5ce7' }\n };\n\n const colors = themes[theme] || themes['default'];\n\n // Input container\n const inputContainer = instance._getDomElement('input-container');\n if (inputContainer) {\n inputContainer.style.background = colors.inputBg;\n inputContainer.style.borderColor = colors.inputBorder;\n }\n\n // Input text\n const input = instance._getDomElement('text-input');\n if (input) {\n input.style.color = colors.inputText;\n }\n\n // Numberpad icon\n const numberpadIcon = instance._getDomElement('numberpad-icon');\n if (numberpadIcon) {\n numberpadIcon.style.fill = colors.inputText;\n }\n\n // Submit button\n const submitBtn = instance._getDomElement('submit-btn');\n if (submitBtn) {\n submitBtn.style.background = colors.btnBg;\n submitBtn.style.color = colors.btnText;\n }\n\n // Dialog header\n const dialogHeader = instance._getDomElement('dialog-header');\n if (dialogHeader) {\n dialogHeader.style.background = colors.headerBg;\n }\n\n // Dialog\n const dialog = instance._getDomElement('numberpad-dialog');\n if (dialog) {\n dialog.style.borderColor = colors.headerBg;\n }\n\n // OK button in numberpad\n const numOk = instance._getDomElement('num-ok');\n if (numOk) {\n numOk.style.background = colors.headerBg;\n }\n}", "properties": {"inputType": {"type": "enum", "default": "string", "values": ["string", "number", "integer", "password"]}, "placeholder": {"type": "string", "default": "Dəyər daxil edin"}, "stateId": {"type": "signal"}, "clearAfterSubmit": {"type": "boolean"}, "theme": {"type": "enum", "default": "default", "values": ["default", "dark", "light", "blue", "green", "red", "purple"]}}, "settings": {"visibilityEnabled": "false", "visibilityGroups": "", "visibilityAction": "hide", "visibilityRedirectScreen": ""}, "translations": {"az": {"input_with_button": {"addvalue": "Dəyər daxil edin", "volume": "Həcm Yaz", "clear": "Təmizlə"}}, "ru": {"input_with_button": {"addvalue": "Введите значение", "volume": "Введите объём", "clear": "Очистить"}}, "de": {"input_with_button": {"addvalue": "Wert eingeben", "volume": "Volumen eingeben", "clear": "Löschen"}}, "en": {"input_with_button": {"addvalue": "Enter value", "volume": "Enter Volume", "clear": "Clear"}}, "tr": {"input_with_button": {"addvalue": "Değer girin", "volume": "Hacim Girin", "clear": "Temizle"}}}}
@@ -1 +1 @@
1
- {"properties": {"showlabel": {"type": "enum", "default": "true", "values": ["true", "false"]}}, "settings": {"width": "120px", "height": "40px", "visibilityEnabled": "false", "visibilityGroups": "", "visibilityAction": "hide", "visibilityRedirectScreen": ""}, "html": "<button id=\"logoutBtn\" class=\"lo\" @click=\"Logout\" data-visibility-action=\"hide\" type=\"button\" title=\"Logout\"><svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M17 7l-1.41 1.41L18.17 11H8v2h10.17l-2.58 2.58L17 17l5-5zM4 5h8V3H4c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h8v-2H4V5z\"/></svg><span class=\"lo-lbl\" bind-css:display=\"??showlabel;(__0===false||__0==='false')?'none':''\"><t-t>logout.button</t-t></span></button>", "style": ":host{display:inline-block;height:100%;font-family:'Segoe UI',system-ui,Roboto,sans-serif;}.lo{appearance:none;display:inline-flex;align-items:center;justify-content:center;gap:8px;height:100%;width:100%;padding:6px 16px;margin:0;box-sizing:border-box;cursor:pointer;border-radius:999px;background:color-mix(in srgb,var(--ui-text,#fff) 7%,transparent);border:1px solid var(--ui-border,#3b4250);color:var(--ui-text,#e2e6ec);font-size:13px;font-weight:600;letter-spacing:.3px;white-space:nowrap;-webkit-backdrop-filter:var(--ui-backdrop,none);backdrop-filter:var(--ui-backdrop,none);}.lo svg{width:18px;height:18px;fill:currentColor;flex:none;display:block;}.lo:hover{background:color-mix(in srgb,var(--ui-error,#ef4d5e) 18%,transparent);border-color:color-mix(in srgb,var(--ui-error,#ef4d5e) 60%,transparent);color:var(--ui-error,#ef4d5e);}.lo:active{background:color-mix(in srgb,var(--ui-error,#ef4d5e) 30%,transparent);}.lo:focus-visible{outline:2px solid var(--accent,#2680eb);outline-offset:2px;}", "script": "export function init(instance) {\n try{ instance._bindingsRefresh && instance._bindingsRefresh(); }catch(e){}\n}\nexport function Logout(event, eventRaisingElement, shadowRoot, instance, parameters) {\n window.location.href = '/logout';\n}"}
1
+ {"properties": {"showlabel": {"type": "enum", "default": "true", "values": ["true", "false"]}}, "settings": {"width": "120px", "height": "40px", "visibilityEnabled": "false", "visibilityGroups": "", "visibilityAction": "hide", "visibilityRedirectScreen": ""}, "html": "<button id=\"logoutBtn\" class=\"lo\" @click=\"Logout\" data-visibility-action=\"hide\" type=\"button\" title=\"Logout\"><svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M17 7l-1.41 1.41L18.17 11H8v2h10.17l-2.58 2.58L17 17l5-5zM4 5h8V3H4c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h8v-2H4V5z\"/></svg><span class=\"lo-lbl\" bind-css:display=\"??showlabel;(__0===false||__0==='false')?'none':''\"><t-t>logout.button</t-t></span></button>", "style": ":host{display:inline-block;height:100%;font-family:'Segoe UI',system-ui,Roboto,sans-serif;}.lo{appearance:none;display:inline-flex;align-items:center;justify-content:center;gap:8px;height:100%;width:100%;padding:6px 16px;margin:0;box-sizing:border-box;cursor:pointer;border-radius:999px;background:color-mix(in srgb,var(--ui-text,#fff) 7%,transparent);border:1px solid var(--ui-border,#3b4250);color:var(--ui-text,#e2e6ec);font-size:13px;font-weight:600;letter-spacing:.3px;white-space:nowrap;-webkit-backdrop-filter:var(--ui-backdrop,none);backdrop-filter:var(--ui-backdrop,none);}.lo svg{width:18px;height:18px;fill:currentColor;flex:none;display:block;}.lo:hover{background:color-mix(in srgb,var(--ui-error,#ef4d5e) 18%,transparent);border-color:color-mix(in srgb,var(--ui-error,#ef4d5e) 60%,transparent);color:var(--ui-error,#ef4d5e);}.lo:active{background:color-mix(in srgb,var(--ui-error,#ef4d5e) 30%,transparent);}.lo:focus-visible{outline:2px solid var(--accent,#2680eb);outline-offset:2px;}", "script": "export function init(instance) {\n try{ instance._bindingsRefresh && instance._bindingsRefresh(); }catch(e){}\n}\nexport function Logout(event, eventRaisingElement, shadowRoot, instance, parameters) {\n window.location.href = '/logout';\n}", "translations": {"az": {"logout": {"button": "Çıxış"}}, "ru": {"logout": {"button": "Выход"}}, "de": {"logout": {"button": "Abmelden"}}, "en": {"logout": {"button": "Logout"}}, "tr": {"logout": {"button": "Çıkış"}}}}