@collabdt/core 0.3.1 → 0.3.3

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 (300) hide show
  1. package/dist/core/components/authentication/ForgotPassword.d.ts.map +1 -1
  2. package/dist/core/components/authentication/ForgotPassword.js +0 -1
  3. package/dist/core/components/authentication/ForgotPassword.js.map +1 -1
  4. package/dist/core/components/ui/Comments/CollapsibleCommentItem.d.ts +12 -2
  5. package/dist/core/components/ui/Comments/CollapsibleCommentItem.d.ts.map +1 -1
  6. package/dist/core/components/ui/Comments/CollapsibleCommentItem.js +137 -139
  7. package/dist/core/components/ui/Comments/CollapsibleCommentItem.js.map +1 -1
  8. package/dist/core/components/ui/Comments/Comment.d.ts +18 -1
  9. package/dist/core/components/ui/Comments/Comment.d.ts.map +1 -1
  10. package/dist/core/components/ui/Comments/Comment.js +94 -23
  11. package/dist/core/components/ui/Comments/Comment.js.map +1 -1
  12. package/dist/core/components/ui/Comments/CommentActionButtons.d.ts +38 -0
  13. package/dist/core/components/ui/Comments/CommentActionButtons.d.ts.map +1 -0
  14. package/dist/core/components/ui/Comments/CommentActionButtons.js +134 -0
  15. package/dist/core/components/ui/Comments/CommentActionButtons.js.map +1 -0
  16. package/dist/core/components/ui/Comments/CommentInput.d.ts.map +1 -1
  17. package/dist/core/components/ui/Comments/CommentInput.js +5 -2
  18. package/dist/core/components/ui/Comments/CommentInput.js.map +1 -1
  19. package/dist/core/components/ui/Comments/CommentsSection.d.ts.map +1 -1
  20. package/dist/core/components/ui/Comments/CommentsSection.js +86 -42
  21. package/dist/core/components/ui/Comments/CommentsSection.js.map +1 -1
  22. package/dist/core/components/ui/Comments/commentUtils.d.ts.map +1 -1
  23. package/dist/core/components/ui/Comments/commentUtils.js +2 -1
  24. package/dist/core/components/ui/Comments/commentUtils.js.map +1 -1
  25. package/dist/core/components/ui/FilesManager/src/useFileUploadWithProgress.d.ts.map +1 -1
  26. package/dist/core/components/ui/FilesManager/src/useFileUploadWithProgress.js +0 -1
  27. package/dist/core/components/ui/FilesManager/src/useFileUploadWithProgress.js.map +1 -1
  28. package/dist/core/components/ui/InfoSidebar/Container.d.ts.map +1 -1
  29. package/dist/core/components/ui/InfoSidebar/Container.js +16 -12
  30. package/dist/core/components/ui/InfoSidebar/Container.js.map +1 -1
  31. package/dist/core/components/ui/Sensors/CollapsibleSensorItem.d.ts +1 -2
  32. package/dist/core/components/ui/Sensors/CollapsibleSensorItem.d.ts.map +1 -1
  33. package/dist/core/components/ui/Sensors/CollapsibleSensorItem.js +66 -94
  34. package/dist/core/components/ui/Sensors/CollapsibleSensorItem.js.map +1 -1
  35. package/dist/core/components/ui/Sensors/Sensor.d.ts +16 -3
  36. package/dist/core/components/ui/Sensors/Sensor.d.ts.map +1 -1
  37. package/dist/core/components/ui/Sensors/Sensor.js +76 -37
  38. package/dist/core/components/ui/Sensors/Sensor.js.map +1 -1
  39. package/dist/core/components/ui/Sensors/SensorChart.d.ts +12 -2
  40. package/dist/core/components/ui/Sensors/SensorChart.d.ts.map +1 -1
  41. package/dist/core/components/ui/Sensors/SensorChart.js +49 -12
  42. package/dist/core/components/ui/Sensors/SensorChart.js.map +1 -1
  43. package/dist/core/components/ui/Sensors/SensorDetailDialog.d.ts +9 -0
  44. package/dist/core/components/ui/Sensors/SensorDetailDialog.d.ts.map +1 -0
  45. package/dist/core/components/ui/Sensors/SensorDetailDialog.js +128 -0
  46. package/dist/core/components/ui/Sensors/SensorDetailDialog.js.map +1 -0
  47. package/dist/core/components/ui/Sensors/SensorInput.d.ts +6 -1
  48. package/dist/core/components/ui/Sensors/SensorInput.d.ts.map +1 -1
  49. package/dist/core/components/ui/Sensors/SensorInput.js +94 -9
  50. package/dist/core/components/ui/Sensors/SensorInput.js.map +1 -1
  51. package/dist/core/components/ui/Sensors/SensorTagsSection.d.ts +3 -1
  52. package/dist/core/components/ui/Sensors/SensorTagsSection.d.ts.map +1 -1
  53. package/dist/core/components/ui/Sensors/SensorTagsSection.js +4 -1
  54. package/dist/core/components/ui/Sensors/SensorTagsSection.js.map +1 -1
  55. package/dist/core/components/ui/Sensors/SensorsSection.d.ts +1 -3
  56. package/dist/core/components/ui/Sensors/SensorsSection.d.ts.map +1 -1
  57. package/dist/core/components/ui/Sensors/SensorsSection.js +33 -10
  58. package/dist/core/components/ui/Sensors/SensorsSection.js.map +1 -1
  59. package/dist/core/components/ui/Sensors/TimeZoneSelect.d.ts +7 -0
  60. package/dist/core/components/ui/Sensors/TimeZoneSelect.d.ts.map +1 -0
  61. package/dist/core/components/ui/Sensors/TimeZoneSelect.js +56 -0
  62. package/dist/core/components/ui/Sensors/TimeZoneSelect.js.map +1 -0
  63. package/dist/core/components/ui/Sensors/sensorData.d.ts +42 -0
  64. package/dist/core/components/ui/Sensors/sensorData.d.ts.map +1 -0
  65. package/dist/core/components/ui/Sensors/sensorData.js +118 -0
  66. package/dist/core/components/ui/Sensors/sensorData.js.map +1 -0
  67. package/dist/core/components/ui/Sensors/sensorRange.d.ts +24 -0
  68. package/dist/core/components/ui/Sensors/sensorRange.d.ts.map +1 -0
  69. package/dist/core/components/ui/Sensors/sensorRange.js +34 -0
  70. package/dist/core/components/ui/Sensors/sensorRange.js.map +1 -0
  71. package/dist/core/components/ui/Sensors/useSensorSeries.d.ts +15 -0
  72. package/dist/core/components/ui/Sensors/useSensorSeries.d.ts.map +1 -0
  73. package/dist/core/components/ui/Sensors/useSensorSeries.js +63 -0
  74. package/dist/core/components/ui/Sensors/useSensorSeries.js.map +1 -0
  75. package/dist/core/components/ui/Sidebar.d.ts.map +1 -1
  76. package/dist/core/components/ui/Sidebar.js +27 -4
  77. package/dist/core/components/ui/Sidebar.js.map +1 -1
  78. package/dist/core/components/ui/ToolbarButton.d.ts.map +1 -1
  79. package/dist/core/components/ui/ToolbarButton.js +0 -1
  80. package/dist/core/components/ui/ToolbarButton.js.map +1 -1
  81. package/dist/core/components/viewers/Data/advancedFilter/FiltersDialog.d.ts.map +1 -1
  82. package/dist/core/components/viewers/Data/advancedFilter/FiltersDialog.js +0 -2
  83. package/dist/core/components/viewers/Data/advancedFilter/FiltersDialog.js.map +1 -1
  84. package/dist/core/components/viewers/Data/details/EnergySourcesGrid.d.ts.map +1 -1
  85. package/dist/core/components/viewers/Data/details/EnergySourcesGrid.js +0 -10
  86. package/dist/core/components/viewers/Data/details/EnergySourcesGrid.js.map +1 -1
  87. package/dist/core/components/viewers/Data/files/DatatableFileAdder.d.ts.map +1 -1
  88. package/dist/core/components/viewers/Data/files/DatatableFileAdder.js +0 -1
  89. package/dist/core/components/viewers/Data/files/DatatableFileAdder.js.map +1 -1
  90. package/dist/core/components/viewers/Data/files/utils/fuzzySearch.d.ts.map +1 -1
  91. package/dist/core/components/viewers/Data/files/utils/fuzzySearch.js +0 -1
  92. package/dist/core/components/viewers/Data/files/utils/fuzzySearch.js.map +1 -1
  93. package/dist/core/components/viewers/Data/userDetails/UserMoreOptions.d.ts.map +1 -1
  94. package/dist/core/components/viewers/Data/userDetails/UserMoreOptions.js +0 -1
  95. package/dist/core/components/viewers/Data/userDetails/UserMoreOptions.js.map +1 -1
  96. package/dist/core/components/viewers/Data/utils/filterHelper.d.ts.map +1 -1
  97. package/dist/core/components/viewers/Data/utils/filterHelper.js +0 -2
  98. package/dist/core/components/viewers/Data/utils/filterHelper.js.map +1 -1
  99. package/dist/core/components/viewers/Viewer.js +1 -1
  100. package/dist/core/components/viewers/Viewer.js.map +1 -1
  101. package/dist/core/components/viewers/bim/src/BimSidebar/src/CommunicationTab/src/TopicsSection.d.ts.map +1 -1
  102. package/dist/core/components/viewers/bim/src/BimSidebar/src/CommunicationTab/src/TopicsSection.js +0 -3
  103. package/dist/core/components/viewers/bim/src/BimSidebar/src/CommunicationTab/src/TopicsSection.js.map +1 -1
  104. package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/FilesSection.d.ts.map +1 -1
  105. package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/FilesSection.js +1 -7
  106. package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/FilesSection.js.map +1 -1
  107. package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/ModelsSection.d.ts.map +1 -1
  108. package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/ModelsSection.js +1 -9
  109. package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/ModelsSection.js.map +1 -1
  110. package/dist/core/components/viewers/bim/src/BimSidebar/src/SensorsTab/index.d.ts +1 -3
  111. package/dist/core/components/viewers/bim/src/BimSidebar/src/SensorsTab/index.d.ts.map +1 -1
  112. package/dist/core/components/viewers/bim/src/BimSidebar/src/SensorsTab/index.js +2 -2
  113. package/dist/core/components/viewers/bim/src/BimSidebar/src/SensorsTab/index.js.map +1 -1
  114. package/dist/core/components/viewers/bim/src/BimSidebar/src/TabSelector.d.ts.map +1 -1
  115. package/dist/core/components/viewers/bim/src/BimSidebar/src/TabSelector.js +4 -3
  116. package/dist/core/components/viewers/bim/src/BimSidebar/src/TabSelector.js.map +1 -1
  117. package/dist/core/components/viewers/bim/src/BimSidebar/src/index.js +1 -1
  118. package/dist/core/components/viewers/bim/src/BimSidebar/src/index.js.map +1 -1
  119. package/dist/core/components/viewers/bim/src/ClippingPlane.d.ts.map +1 -1
  120. package/dist/core/components/viewers/bim/src/ClippingPlane.js +0 -1
  121. package/dist/core/components/viewers/bim/src/ClippingPlane.js.map +1 -1
  122. package/dist/core/components/viewers/bim/src/tools/AddToBim/index.d.ts +1 -2
  123. package/dist/core/components/viewers/bim/src/tools/AddToBim/index.d.ts.map +1 -1
  124. package/dist/core/components/viewers/bim/src/tools/AddToBim/index.js +25 -2
  125. package/dist/core/components/viewers/bim/src/tools/AddToBim/index.js.map +1 -1
  126. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimComment.d.ts +16 -10
  127. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimComment.d.ts.map +1 -1
  128. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimComment.js +26 -6
  129. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimComment.js.map +1 -1
  130. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimCommentCluster.d.ts +2 -0
  131. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimCommentCluster.d.ts.map +1 -0
  132. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimCommentCluster.js +5 -0
  133. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimCommentCluster.js.map +1 -0
  134. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimSensor.d.ts +8 -1
  135. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimSensor.d.ts.map +1 -1
  136. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimSensor.js +15 -3
  137. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimSensor.js.map +1 -1
  138. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/clusterMarkersByScreenSpace.d.ts +44 -0
  139. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/clusterMarkersByScreenSpace.d.ts.map +1 -0
  140. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/clusterMarkersByScreenSpace.js +77 -0
  141. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/clusterMarkersByScreenSpace.js.map +1 -0
  142. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/commentCameraUtils.d.ts +3 -0
  143. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/commentCameraUtils.d.ts.map +1 -0
  144. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/commentCameraUtils.js +5 -0
  145. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/commentCameraUtils.js.map +1 -0
  146. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/commentMarkerConfig.d.ts +33 -0
  147. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/commentMarkerConfig.d.ts.map +1 -0
  148. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/commentMarkerConfig.js +90 -0
  149. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/commentMarkerConfig.js.map +1 -0
  150. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/renderCSS2DMarkers.d.ts.map +1 -1
  151. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/renderCSS2DMarkers.js +2 -2
  152. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/renderCSS2DMarkers.js.map +1 -1
  153. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useCommentMarkers.d.ts +7 -1
  154. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useCommentMarkers.d.ts.map +1 -1
  155. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useCommentMarkers.js +50 -73
  156. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useCommentMarkers.js.map +1 -1
  157. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useSensorMarkers.d.ts +7 -1
  158. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useSensorMarkers.d.ts.map +1 -1
  159. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useSensorMarkers.js +39 -11
  160. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useSensorMarkers.js.map +1 -1
  161. package/dist/core/components/viewers/bim/src/tools/ClippingTool/ClippingTool.d.ts.map +1 -1
  162. package/dist/core/components/viewers/bim/src/tools/ClippingTool/ClippingTool.js +1 -5
  163. package/dist/core/components/viewers/bim/src/tools/ClippingTool/ClippingTool.js.map +1 -1
  164. package/dist/core/components/viewers/bim/src/tools/ExplodeByLevelTool.d.ts.map +1 -1
  165. package/dist/core/components/viewers/bim/src/tools/ExplodeByLevelTool.js +0 -1
  166. package/dist/core/components/viewers/bim/src/tools/ExplodeByLevelTool.js.map +1 -1
  167. package/dist/core/components/viewers/bim/src/tools/measureBimTool.d.ts.map +1 -1
  168. package/dist/core/components/viewers/bim/src/tools/measureBimTool.js +1 -2
  169. package/dist/core/components/viewers/bim/src/tools/measureBimTool.js.map +1 -1
  170. package/dist/core/components/viewers/map/MapViewer.d.ts +1 -2
  171. package/dist/core/components/viewers/map/MapViewer.d.ts.map +1 -1
  172. package/dist/core/components/viewers/map/MapViewer.js +2 -2
  173. package/dist/core/components/viewers/map/MapViewer.js.map +1 -1
  174. package/dist/core/components/viewers/map/datasets/src/arcGISDatasets.d.ts.map +1 -1
  175. package/dist/core/components/viewers/map/datasets/src/arcGISDatasets.js +11 -14
  176. package/dist/core/components/viewers/map/datasets/src/arcGISDatasets.js.map +1 -1
  177. package/dist/core/components/viewers/map/datasets/src/ckanDatasets.d.ts.map +1 -1
  178. package/dist/core/components/viewers/map/datasets/src/ckanDatasets.js +2 -5
  179. package/dist/core/components/viewers/map/datasets/src/ckanDatasets.js.map +1 -1
  180. package/dist/core/components/viewers/map/datasets/src/localDatasets.d.ts.map +1 -1
  181. package/dist/core/components/viewers/map/datasets/src/localDatasets.js +0 -3
  182. package/dist/core/components/viewers/map/datasets/src/localDatasets.js.map +1 -1
  183. package/dist/core/components/viewers/map/datasets/src/opendatasoftDatasets.d.ts.map +1 -1
  184. package/dist/core/components/viewers/map/datasets/src/opendatasoftDatasets.js +0 -11
  185. package/dist/core/components/viewers/map/datasets/src/opendatasoftDatasets.js.map +1 -1
  186. package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/DatabaseBuildingPopover/src/BuildingsTools.d.ts.map +1 -1
  187. package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/DatabaseBuildingPopover/src/BuildingsTools.js +0 -1
  188. package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/DatabaseBuildingPopover/src/BuildingsTools.js.map +1 -1
  189. package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/NonDatabaseBuildingPopover.d.ts.map +1 -1
  190. package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/NonDatabaseBuildingPopover.js +0 -1
  191. package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/NonDatabaseBuildingPopover.js.map +1 -1
  192. package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/OpenDataFeaturePopover.d.ts.map +1 -1
  193. package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/OpenDataFeaturePopover.js +0 -1
  194. package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/OpenDataFeaturePopover.js.map +1 -1
  195. package/dist/core/components/viewers/map/src/MapLayers/index.d.ts +1 -2
  196. package/dist/core/components/viewers/map/src/MapLayers/index.d.ts.map +1 -1
  197. package/dist/core/components/viewers/map/src/MapLayers/index.js +2 -2
  198. package/dist/core/components/viewers/map/src/MapLayers/index.js.map +1 -1
  199. package/dist/core/components/viewers/map/src/MapLayers/src/CommentLayer/index.d.ts.map +1 -1
  200. package/dist/core/components/viewers/map/src/MapLayers/src/CommentLayer/index.js +174 -53
  201. package/dist/core/components/viewers/map/src/MapLayers/src/CommentLayer/index.js.map +1 -1
  202. package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/components/MapFileManager.d.ts.map +1 -1
  203. package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/components/MapFileManager.js +2 -1
  204. package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/components/MapFileManager.js.map +1 -1
  205. package/dist/core/components/viewers/map/src/MapLayers/src/SensorsLayer/index.d.ts +1 -3
  206. package/dist/core/components/viewers/map/src/MapLayers/src/SensorsLayer/index.d.ts.map +1 -1
  207. package/dist/core/components/viewers/map/src/MapLayers/src/SensorsLayer/index.js +74 -42
  208. package/dist/core/components/viewers/map/src/MapLayers/src/SensorsLayer/index.js.map +1 -1
  209. package/dist/core/components/viewers/map/src/MapSidebar/TabSelector.d.ts.map +1 -1
  210. package/dist/core/components/viewers/map/src/MapSidebar/TabSelector.js +4 -3
  211. package/dist/core/components/viewers/map/src/MapSidebar/TabSelector.js.map +1 -1
  212. package/dist/core/components/viewers/map/src/MapSidebar/index.js +1 -1
  213. package/dist/core/components/viewers/map/src/MapSidebar/index.js.map +1 -1
  214. package/dist/core/components/viewers/map/src/MapSidebar/src/FileTab/src/FilesSection.d.ts.map +1 -1
  215. package/dist/core/components/viewers/map/src/MapSidebar/src/FileTab/src/FilesSection.js +0 -1
  216. package/dist/core/components/viewers/map/src/MapSidebar/src/FileTab/src/FilesSection.js.map +1 -1
  217. package/dist/core/components/viewers/map/src/MapSidebar/src/FileTab/src/ModelsSection.d.ts.map +1 -1
  218. package/dist/core/components/viewers/map/src/MapSidebar/src/FileTab/src/ModelsSection.js +1 -5
  219. package/dist/core/components/viewers/map/src/MapSidebar/src/FileTab/src/ModelsSection.js.map +1 -1
  220. package/dist/core/components/viewers/map/src/MapSidebar/src/SensorsTab/index.d.ts +1 -3
  221. package/dist/core/components/viewers/map/src/MapSidebar/src/SensorsTab/index.d.ts.map +1 -1
  222. package/dist/core/components/viewers/map/src/MapSidebar/src/SensorsTab/index.js +2 -2
  223. package/dist/core/components/viewers/map/src/MapSidebar/src/SensorsTab/index.js.map +1 -1
  224. package/dist/core/components/viewers/map/src/tools/AddTools/AddFile/utils/uploadToPresignedURLS.d.ts.map +1 -1
  225. package/dist/core/components/viewers/map/src/tools/AddTools/AddFile/utils/uploadToPresignedURLS.js +1 -3
  226. package/dist/core/components/viewers/map/src/tools/AddTools/AddFile/utils/uploadToPresignedURLS.js.map +1 -1
  227. package/dist/core/components/viewers/map/utils/MapEventManager/MapClickManager.d.ts.map +1 -1
  228. package/dist/core/components/viewers/map/utils/MapEventManager/MapClickManager.js +0 -1
  229. package/dist/core/components/viewers/map/utils/MapEventManager/MapClickManager.js.map +1 -1
  230. package/dist/core/components/viewers/map/utils/flyToEach.d.ts.map +1 -1
  231. package/dist/core/components/viewers/map/utils/flyToEach.js +0 -1
  232. package/dist/core/components/viewers/map/utils/flyToEach.js.map +1 -1
  233. package/dist/core/components/viewers/map/utils/getOsmIdbyCoordinates.d.ts.map +1 -1
  234. package/dist/core/components/viewers/map/utils/getOsmIdbyCoordinates.js +0 -2
  235. package/dist/core/components/viewers/map/utils/getOsmIdbyCoordinates.js.map +1 -1
  236. package/dist/core/components/viewers/shared/markers/BimMarkerCluster.d.ts +19 -0
  237. package/dist/core/components/viewers/shared/markers/BimMarkerCluster.d.ts.map +1 -0
  238. package/dist/core/components/viewers/shared/markers/BimMarkerCluster.js +108 -0
  239. package/dist/core/components/viewers/shared/markers/BimMarkerCluster.js.map +1 -0
  240. package/dist/core/components/viewers/shared/markers/computeMarkerLookAt.d.ts +24 -0
  241. package/dist/core/components/viewers/shared/markers/computeMarkerLookAt.d.ts.map +1 -0
  242. package/dist/core/components/viewers/shared/markers/computeMarkerLookAt.js +27 -0
  243. package/dist/core/components/viewers/shared/markers/computeMarkerLookAt.js.map +1 -0
  244. package/dist/core/components/viewers/shared/markers/types.d.ts +66 -0
  245. package/dist/core/components/viewers/shared/markers/types.d.ts.map +1 -0
  246. package/dist/core/components/viewers/shared/markers/types.js +1 -0
  247. package/dist/core/components/viewers/shared/markers/types.js.map +1 -0
  248. package/dist/core/components/viewers/shared/markers/useMarkerLayerBim.d.ts +22 -0
  249. package/dist/core/components/viewers/shared/markers/useMarkerLayerBim.d.ts.map +1 -0
  250. package/dist/core/components/viewers/shared/markers/useMarkerLayerBim.js +233 -0
  251. package/dist/core/components/viewers/shared/markers/useMarkerLayerBim.js.map +1 -0
  252. package/dist/core/hooks/comments/comments.d.ts +11 -0
  253. package/dist/core/hooks/comments/comments.d.ts.map +1 -1
  254. package/dist/core/hooks/comments/comments.js +3 -1
  255. package/dist/core/hooks/comments/comments.js.map +1 -1
  256. package/dist/core/hooks/comments/createCommentHooks.d.ts +11 -0
  257. package/dist/core/hooks/comments/createCommentHooks.d.ts.map +1 -1
  258. package/dist/core/hooks/comments/createCommentHooks.js +30 -1
  259. package/dist/core/hooks/comments/createCommentHooks.js.map +1 -1
  260. package/dist/core/hooks/files/files.d.ts.map +1 -1
  261. package/dist/core/hooks/files/files.js +0 -1
  262. package/dist/core/hooks/files/files.js.map +1 -1
  263. package/dist/core/hooks/ui/useResizableSidebarWidth.d.ts +30 -0
  264. package/dist/core/hooks/ui/useResizableSidebarWidth.d.ts.map +1 -0
  265. package/dist/core/hooks/ui/useResizableSidebarWidth.js +75 -0
  266. package/dist/core/hooks/ui/useResizableSidebarWidth.js.map +1 -0
  267. package/dist/core/i18n/messages/en.json +10 -1
  268. package/dist/core/i18n/messages/es.json +11 -2
  269. package/dist/core/i18n/messages/fr.json +11 -2
  270. package/dist/core/store/AppConfig/context.d.ts.map +1 -1
  271. package/dist/core/store/AppConfig/context.js +4 -1
  272. package/dist/core/store/AppConfig/context.js.map +1 -1
  273. package/dist/core/store/AppConfig/reducer.d.ts +10 -0
  274. package/dist/core/store/AppConfig/reducer.d.ts.map +1 -1
  275. package/dist/core/store/AppConfig/reducer.js +10 -0
  276. package/dist/core/store/AppConfig/reducer.js.map +1 -1
  277. package/dist/core/store/Datasets/reducer.d.ts.map +1 -1
  278. package/dist/core/store/Datasets/reducer.js +0 -2
  279. package/dist/core/store/Datasets/reducer.js.map +1 -1
  280. package/dist/core/store/Files/reducer.js +0 -1
  281. package/dist/core/store/Files/reducer.js.map +1 -1
  282. package/dist/core/store/Menus/context.d.ts.map +1 -1
  283. package/dist/core/store/Menus/context.js +8 -2
  284. package/dist/core/store/Menus/context.js.map +1 -1
  285. package/dist/core/store/Menus/reducer.d.ts +65 -1
  286. package/dist/core/store/Menus/reducer.d.ts.map +1 -1
  287. package/dist/core/store/Menus/reducer.js +39 -3
  288. package/dist/core/store/Menus/reducer.js.map +1 -1
  289. package/dist/core/utils/markerUtils.d.ts +10 -0
  290. package/dist/core/utils/markerUtils.d.ts.map +1 -1
  291. package/dist/core/utils/markerUtils.js +9 -1
  292. package/dist/core/utils/markerUtils.js.map +1 -1
  293. package/dist/core/utils/memcache.d.ts.map +1 -1
  294. package/dist/core/utils/memcache.js +0 -7
  295. package/dist/core/utils/memcache.js.map +1 -1
  296. package/dist/core/utils/timeUtils.d.ts +24 -1
  297. package/dist/core/utils/timeUtils.d.ts.map +1 -1
  298. package/dist/core/utils/timeUtils.js +52 -3
  299. package/dist/core/utils/timeUtils.js.map +1 -1
  300. package/package.json +4 -1
@@ -1 +1 @@
1
- {"version":3,"file":"SensorChart.d.ts","sourceRoot":"","sources":["../../../../../src/core/components/ui/Sensors/SensorChart.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAW9B,OAAO,EAIL,KAAK,WAAW,EACjB,MAAM,UAAU,CAAA;AAIjB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAExD,UAAU,gBAAgB;IACxB,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IAC7C,aAAa,EAAE,OAAO,CAAA;IACtB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,UAAU,CAAA;IACtB,eAAe,EAAE,MAAM,CAAA;IACvB,WAAW,EAAE,WAAW,CAAA;IACxB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;IACzB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,wBAAgB,WAAW,CAAC,EAC1B,UAAU,EACV,aAAa,EACb,UAAU,EACV,UAAU,EACV,eAAe,EACf,WAAW,EACX,IAAW,EACX,WAA2B,EAC3B,WAA+B,EAC/B,UAAgC,EAChC,mBAAwC,EACxC,cAA8B,EAC9B,QAAQ,EACR,QAAQ,EACR,QAAQ,GACT,EAAE,gBAAgB,qBAiGlB"}
1
+ {"version":3,"file":"SensorChart.d.ts","sourceRoot":"","sources":["../../../../../src/core/components/ui/Sensors/SensorChart.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAW9B,OAAO,EAIL,KAAK,WAAW,EACjB,MAAM,UAAU,CAAA;AAIjB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAExD,UAAU,gBAAgB;IACxB,UAAU,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IAC1C,aAAa,EAAE,OAAO,CAAA;IACtB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,UAAU,CAAA;IACtB,eAAe,EAAE,MAAM,CAAA;IACvB,WAAW,EAAE,WAAW,CAAA;IACxB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;IACzB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;CAC5E;AAED,wBAAgB,WAAW,CAAC,EAC1B,UAAU,EACV,aAAa,EACb,UAAU,EACV,UAAU,EACV,eAAe,EACf,WAAW,EACX,IAAW,EACX,WAA2B,EAC3B,WAA+B,EAC/B,UAAgC,EAChC,mBAAwC,EACxC,cAA8B,EAC9B,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,IAAI,EACJ,WAAW,EACX,QAA2B,EAC3B,SAAiB,EACjB,eAAe,EACf,aAAa,EACb,aAAa,GACd,EAAE,gBAAgB,qBAkIlB"}
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import * as LR from "lucide-react";
4
- import { Area, AreaChart, CartesianGrid, XAxis } from "recharts";
5
- import { formatDuration } from "../../../utils/timeUtils";
4
+ import { Area, AreaChart, Brush, CartesianGrid, XAxis } from "recharts";
5
+ import { detectTimeZone, formatInZone, formatDuration } from "../../../utils/timeUtils";
6
6
  import {
7
7
  Card,
8
8
  CardContent,
@@ -31,7 +31,14 @@ function SensorChart({
31
31
  dataPointsText = "Data Points",
32
32
  minColor,
33
33
  midColor,
34
- maxColor
34
+ maxColor,
35
+ unit,
36
+ valueLabels,
37
+ timeZone = detectTimeZone(),
38
+ showBrush = false,
39
+ brushStartIndex,
40
+ brushEndIndex,
41
+ onBrushChange
35
42
  }) {
36
43
  const { maxColour, midColour, minColour } = sensorType || { name: "Unknown", icon: "Radio" };
37
44
  const finalMin = minColor || minColour || defaultPalette.min;
@@ -44,6 +51,10 @@ function SensorChart({
44
51
  };
45
52
  const currentSize = sizeClasses[size];
46
53
  const gradientId = `gradient-${sensorName.replace(/\s+/g, "-").toLowerCase()}`;
54
+ const axisOpts = { hour: "2-digit", minute: "2-digit", hourCycle: "h23" };
55
+ const fullOpts = { month: "short", day: "2-digit", hour: "2-digit", minute: "2-digit", hourCycle: "h23" };
56
+ const formatAxis = (value) => formatInZone(Number(value), timeZone, axisOpts);
57
+ const formatFull = (value) => formatInZone(Number(value), timeZone, fullOpts);
47
58
  return /* @__PURE__ */ jsxs(Card, { children: [
48
59
  /* @__PURE__ */ jsx(CardHeader, { children: /* @__PURE__ */ jsx(CardTitle, { className: currentSize.titleSize, children: sensorTitle }) }),
49
60
  /* @__PURE__ */ jsx(CardContent, { children: isLoadingData ? /* @__PURE__ */ jsxs("div", { className: `flex items-center justify-center ${currentSize.height} text-muted-foreground`, children: [
@@ -65,24 +76,37 @@ function SensorChart({
65
76
  /* @__PURE__ */ jsx(
66
77
  XAxis,
67
78
  {
68
- dataKey: "time",
79
+ dataKey: "t",
80
+ type: "number",
81
+ scale: "time",
82
+ domain: ["dataMin", "dataMax"],
69
83
  tickLine: false,
70
84
  axisLine: false,
71
85
  tickMargin: 8,
72
86
  interval: "preserveStartEnd",
73
- tickFormatter: (value) => {
74
- if (value.endsWith(":00:00") || value.endsWith(":00")) {
75
- return value.substring(0, value.lastIndexOf(":"));
76
- }
77
- return "";
78
- }
87
+ tickFormatter: formatAxis
79
88
  }
80
89
  ),
81
90
  /* @__PURE__ */ jsx(
82
91
  ChartTooltip,
83
92
  {
84
93
  cursor: false,
85
- content: /* @__PURE__ */ jsx(ChartTooltipContent, { indicator: "line" })
94
+ content: /* @__PURE__ */ jsx(
95
+ ChartTooltipContent,
96
+ {
97
+ indicator: "dot",
98
+ labelFormatter: (_label, payload) => {
99
+ var _a, _b;
100
+ const t = (_b = (_a = payload == null ? void 0 : payload[0]) == null ? void 0 : _a.payload) == null ? void 0 : _b.t;
101
+ return t != null ? formatFull(t) : "";
102
+ },
103
+ formatter: unit || valueLabels ? (value) => {
104
+ const label = valueLabels == null ? void 0 : valueLabels[value];
105
+ if (label) return label;
106
+ return unit ? `${value} ${unit}` : String(value);
107
+ } : void 0
108
+ }
109
+ )
86
110
  }
87
111
  ),
88
112
  /* @__PURE__ */ jsx(
@@ -95,6 +119,18 @@ function SensorChart({
95
119
  strokeWidth: 1,
96
120
  fillOpacity: 1
97
121
  }
122
+ ),
123
+ showBrush && sensorData.length > 1 && /* @__PURE__ */ jsx(
124
+ Brush,
125
+ {
126
+ dataKey: "t",
127
+ height: 26,
128
+ travellerWidth: 8,
129
+ startIndex: brushStartIndex,
130
+ endIndex: brushEndIndex,
131
+ tickFormatter: (value) => formatAxis(Number(value)),
132
+ onChange: (range) => onBrushChange == null ? void 0 : onBrushChange(range)
133
+ }
98
134
  )
99
135
  ]
100
136
  }
@@ -110,7 +146,8 @@ function SensorChart({
110
146
  /* @__PURE__ */ jsx(LR.Database, { className: "h-4 w-4" }),
111
147
  sensorData.length,
112
148
  " ",
113
- dataPointsText
149
+ dataPointsText,
150
+ unit ? ` \xB7 ${unit}` : ""
114
151
  ] })
115
152
  ] }) }) })
116
153
  ] });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/core/components/ui/Sensors/SensorChart.tsx"],"sourcesContent":["'use client'\r\n\r\n// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\nimport * as LR from 'lucide-react'\r\nimport * as React from 'react'\r\nimport { Area, AreaChart, CartesianGrid, XAxis } from 'recharts'\r\n\r\nimport { formatDuration } from '../../../utils/timeUtils'\r\nimport {\r\n Card,\r\n CardContent,\r\n CardFooter,\r\n CardHeader,\r\n CardTitle,\r\n} from '../Card'\r\nimport {\r\n ChartContainer,\r\n ChartTooltip,\r\n ChartTooltipContent,\r\n type ChartConfig,\r\n} from '../chart'\r\n\r\nimport { defaultPalette } from './sensorUtils'\r\n\r\nimport type { SensorType } from '../../../types/dbTypes'\r\n\r\ninterface SensorChartProps {\r\n sensorData: { time: string; value: number }[]\r\n isLoadingData: boolean\r\n sensorName: string\r\n sensorType: SensorType\r\n updateFrequency: number\r\n chartConfig: ChartConfig\r\n size?: 'sm' | 'md' | 'lg'\r\n sensorTitle?: string\r\n loadingText?: string\r\n noDataText?: string\r\n updateFrequencyText?: string\r\n dataPointsText?: string\r\n minColor?: string\r\n midColor?: string\r\n maxColor?: string\r\n}\r\n\r\nexport function SensorChart({\r\n sensorData,\r\n isLoadingData,\r\n sensorName,\r\n sensorType,\r\n updateFrequency,\r\n chartConfig,\r\n size = 'md',\r\n sensorTitle = 'Sensor Data',\r\n loadingText = 'Loading data...',\r\n noDataText = 'No data available',\r\n updateFrequencyText = 'Update Frequency',\r\n dataPointsText = 'Data Points',\r\n minColor,\r\n midColor,\r\n maxColor,\r\n}: SensorChartProps) {\r\n\r\n const { maxColour, midColour, minColour } = sensorType || { name: 'Unknown', icon: 'Radio' }\r\n\r\n const finalMin = minColor || minColour || defaultPalette.min\r\n const finalMid = midColor || midColour || defaultPalette.mid\r\n const finalMax = maxColor || maxColour || defaultPalette.max\r\n\r\n\r\n\r\n const sizeClasses = {\r\n sm: { height: 'h-[150px]', titleSize: 'text-sm', descSize: 'text-xs', footerSize: 'text-xs' },\r\n md: { height: 'h-[200px]', titleSize: 'text-base', descSize: 'text-sm', footerSize: 'text-sm' },\r\n lg: { height: 'h-[300px]', titleSize: 'text-lg', descSize: 'text-base', footerSize: 'text-sm' }\r\n }\r\n\r\n const currentSize = sizeClasses[size]\r\n const gradientId = `gradient-${sensorName.replace(/\\s+/g, '-').toLowerCase()}`\r\n\r\n return (\r\n <Card>\r\n <CardHeader>\r\n <CardTitle className={currentSize.titleSize}>{sensorTitle}</CardTitle>\r\n </CardHeader>\r\n <CardContent>\r\n {isLoadingData ? (\r\n <div className={`flex items-center justify-center ${currentSize.height} text-muted-foreground`}>\r\n <LR.Loader2 className=\"h-6 w-6 animate-spin mr-2\" />\r\n {loadingText}\r\n </div>\r\n ) : sensorData.length === 0 ? (\r\n <div className={`flex items-center justify-center ${currentSize.height} text-muted-foreground`}>\r\n {noDataText}\r\n </div>\r\n ) : (\r\n <ChartContainer config={chartConfig}>\r\n <AreaChart\r\n accessibilityLayer\r\n data={sensorData}\r\n margin={{ left: 12, right: 12, top: 10 }}\r\n >\r\n <defs>\r\n <linearGradient id={gradientId} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\r\n <stop offset=\"5%\" stopColor={finalMax} stopOpacity={0.8} />\r\n <stop offset=\"50%\" stopColor={finalMid} stopOpacity={0.5} />\r\n <stop offset=\"95%\" stopColor={finalMin} stopOpacity={0.2} />\r\n </linearGradient>\r\n </defs>\r\n\r\n <CartesianGrid vertical={false} strokeDasharray=\"3 3\" opacity={0.4} />\r\n <XAxis\r\n dataKey=\"time\"\r\n tickLine={false}\r\n axisLine={false}\r\n tickMargin={8}\r\n interval=\"preserveStartEnd\"\r\n tickFormatter={(value) => {\r\n if (value.endsWith(':00:00') || value.endsWith(':00')) {\r\n return value.substring(0, value.lastIndexOf(':'))\r\n }\r\n return ''\r\n }}\r\n />\r\n <ChartTooltip\r\n cursor={false}\r\n content={<ChartTooltipContent indicator=\"line\" />}\r\n />\r\n <Area\r\n dataKey=\"value\"\r\n type=\"natural\"\r\n fill={`url(#${gradientId})`}\r\n stroke={finalMax}\r\n strokeWidth={1}\r\n fillOpacity={1}\r\n />\r\n </AreaChart>\r\n </ChartContainer>\r\n )}\r\n </CardContent>\r\n <CardFooter>\r\n <div className={`flex w-full items-start gap-2 ${currentSize.footerSize}`}>\r\n <div className=\"grid gap-2\">\r\n <div className=\"flex items-center gap-2 leading-none text-muted-foreground\">\r\n <LR.Timer className=\"h-4 w-4\" />\r\n {updateFrequencyText} {formatDuration(updateFrequency)}\r\n </div>\r\n {sensorData.length > 0 && (\r\n <div className=\"flex items-center gap-2 leading-none text-muted-foreground\">\r\n <LR.Database className=\"h-4 w-4\" />\r\n {sensorData.length} {dataPointsText}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n </CardFooter>\r\n </Card>\r\n )\r\n}"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../../src/core/components/ui/Sensors/SensorChart.tsx"],"sourcesContent":["'use client'\r\n\r\n// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\nimport * as LR from 'lucide-react'\r\nimport * as React from 'react'\r\nimport { Area, AreaChart, Brush, CartesianGrid, XAxis } from 'recharts'\r\n\r\nimport { detectTimeZone, formatInZone, formatDuration } from '../../../utils/timeUtils'\r\nimport {\r\n Card,\r\n CardContent,\r\n CardFooter,\r\n CardHeader,\r\n CardTitle,\r\n} from '../Card'\r\nimport {\r\n ChartContainer,\r\n ChartTooltip,\r\n ChartTooltipContent,\r\n type ChartConfig,\r\n} from '../chart'\r\n\r\nimport { defaultPalette } from './sensorUtils'\r\n\r\nimport type { SensorType } from '../../../types/dbTypes'\r\n\r\ninterface SensorChartProps {\r\n sensorData: { t: number; value: number }[]\r\n isLoadingData: boolean\r\n sensorName: string\r\n sensorType: SensorType\r\n updateFrequency: number\r\n chartConfig: ChartConfig\r\n size?: 'sm' | 'md' | 'lg'\r\n sensorTitle?: string\r\n loadingText?: string\r\n noDataText?: string\r\n updateFrequencyText?: string\r\n dataPointsText?: string\r\n minColor?: string\r\n midColor?: string\r\n maxColor?: string\r\n unit?: string\r\n valueLabels?: Record<number, string>\r\n timeZone?: string\r\n showBrush?: boolean\r\n brushStartIndex?: number\r\n brushEndIndex?: number\r\n onBrushChange?: (range: { startIndex?: number; endIndex?: number }) => void\r\n}\r\n\r\nexport function SensorChart({\r\n sensorData,\r\n isLoadingData,\r\n sensorName,\r\n sensorType,\r\n updateFrequency,\r\n chartConfig,\r\n size = 'md',\r\n sensorTitle = 'Sensor Data',\r\n loadingText = 'Loading data...',\r\n noDataText = 'No data available',\r\n updateFrequencyText = 'Update Frequency',\r\n dataPointsText = 'Data Points',\r\n minColor,\r\n midColor,\r\n maxColor,\r\n unit,\r\n valueLabels,\r\n timeZone = detectTimeZone(),\r\n showBrush = false,\r\n brushStartIndex,\r\n brushEndIndex,\r\n onBrushChange,\r\n}: SensorChartProps) {\r\n\r\n const { maxColour, midColour, minColour } = sensorType || { name: 'Unknown', icon: 'Radio' }\r\n\r\n const finalMin = minColor || minColour || defaultPalette.min\r\n const finalMid = midColor || midColour || defaultPalette.mid\r\n const finalMax = maxColor || maxColour || defaultPalette.max\r\n\r\n const sizeClasses = {\r\n sm: { height: 'h-[150px]', titleSize: 'text-sm', descSize: 'text-xs', footerSize: 'text-xs' },\r\n md: { height: 'h-[200px]', titleSize: 'text-base', descSize: 'text-sm', footerSize: 'text-sm' },\r\n lg: { height: 'h-[300px]', titleSize: 'text-lg', descSize: 'text-base', footerSize: 'text-sm' }\r\n }\r\n\r\n const currentSize = sizeClasses[size]\r\n const gradientId = `gradient-${sensorName.replace(/\\s+/g, '-').toLowerCase()}`\r\n\r\n // All axis/tooltip time strings are formatted in the caller's chosen zone.\r\n const axisOpts: Intl.DateTimeFormatOptions = { hour: '2-digit', minute: '2-digit', hourCycle: 'h23' }\r\n const fullOpts: Intl.DateTimeFormatOptions = { month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit', hourCycle: 'h23' }\r\n const formatAxis = (value: number) => formatInZone(Number(value), timeZone, axisOpts)\r\n const formatFull = (value: number) => formatInZone(Number(value), timeZone, fullOpts)\r\n\r\n return (\r\n <Card>\r\n <CardHeader>\r\n <CardTitle className={currentSize.titleSize}>{sensorTitle}</CardTitle>\r\n </CardHeader>\r\n <CardContent>\r\n {isLoadingData ? (\r\n <div className={`flex items-center justify-center ${currentSize.height} text-muted-foreground`}>\r\n <LR.Loader2 className=\"h-6 w-6 animate-spin mr-2\" />\r\n {loadingText}\r\n </div>\r\n ) : sensorData.length === 0 ? (\r\n <div className={`flex items-center justify-center ${currentSize.height} text-muted-foreground`}>\r\n {noDataText}\r\n </div>\r\n ) : (\r\n <ChartContainer config={chartConfig}>\r\n <AreaChart\r\n accessibilityLayer\r\n data={sensorData}\r\n margin={{ left: 12, right: 12, top: 10 }}\r\n >\r\n <defs>\r\n <linearGradient id={gradientId} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\r\n <stop offset=\"5%\" stopColor={finalMax} stopOpacity={0.8} />\r\n <stop offset=\"50%\" stopColor={finalMid} stopOpacity={0.5} />\r\n <stop offset=\"95%\" stopColor={finalMin} stopOpacity={0.2} />\r\n </linearGradient>\r\n </defs>\r\n\r\n <CartesianGrid vertical={false} strokeDasharray=\"3 3\" opacity={0.4} />\r\n <XAxis\r\n dataKey=\"t\"\r\n type=\"number\"\r\n scale=\"time\"\r\n domain={['dataMin', 'dataMax']}\r\n tickLine={false}\r\n axisLine={false}\r\n tickMargin={8}\r\n interval=\"preserveStartEnd\"\r\n tickFormatter={formatAxis}\r\n />\r\n <ChartTooltip\r\n cursor={false}\r\n content={\r\n <ChartTooltipContent\r\n // \"dot\" (not \"line\") so the time label renders at the top of the tooltip:\r\n // with a single series + \"line\", ChartTooltipContent nests the label inside the\r\n // per-item row, which the unit/category formatter branch then skips.\r\n indicator=\"dot\"\r\n labelFormatter={(_label, payload) => {\r\n const t = (payload?.[0]?.payload as { t?: number } | undefined)?.t\r\n return t != null ? formatFull(t) : ''\r\n }}\r\n formatter={\r\n unit || valueLabels\r\n ? (value: unknown) => {\r\n const label = valueLabels?.[value as number]\r\n if (label) return label\r\n return unit ? `${value} ${unit}` : String(value)\r\n }\r\n : undefined\r\n }\r\n />\r\n }\r\n />\r\n <Area\r\n dataKey=\"value\"\r\n type=\"natural\"\r\n fill={`url(#${gradientId})`}\r\n stroke={finalMax}\r\n strokeWidth={1}\r\n fillOpacity={1}\r\n />\r\n {showBrush && sensorData.length > 1 && (\r\n <Brush\r\n dataKey=\"t\"\r\n height={26}\r\n travellerWidth={8}\r\n startIndex={brushStartIndex}\r\n endIndex={brushEndIndex}\r\n tickFormatter={(value) => formatAxis(Number(value))}\r\n onChange={(range) => onBrushChange?.(range as { startIndex?: number; endIndex?: number })}\r\n />\r\n )}\r\n </AreaChart>\r\n </ChartContainer>\r\n )}\r\n </CardContent>\r\n <CardFooter>\r\n <div className={`flex w-full items-start gap-2 ${currentSize.footerSize}`}>\r\n <div className=\"grid gap-2\">\r\n <div className=\"flex items-center gap-2 leading-none text-muted-foreground\">\r\n <LR.Timer className=\"h-4 w-4\" />\r\n {updateFrequencyText} {formatDuration(updateFrequency)}\r\n </div>\r\n {sensorData.length > 0 && (\r\n <div className=\"flex items-center gap-2 leading-none text-muted-foreground\">\r\n <LR.Database className=\"h-4 w-4\" />\r\n {sensorData.length} {dataPointsText}{unit ? ` · ${unit}` : ''}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n </CardFooter>\r\n </Card>\r\n )\r\n}\r\n"],"mappings":"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","names":[]}
@@ -0,0 +1,9 @@
1
+ import * as React from 'react';
2
+ import type { Sensor, SensorType } from '../../../types/dbTypes';
3
+ export declare function SensorDetailDialog({ open, onOpenChange, sensor, sensorType, }: {
4
+ open: boolean;
5
+ onOpenChange: (open: boolean) => void;
6
+ sensor: Sensor;
7
+ sensorType?: SensorType;
8
+ }): React.ReactElement;
9
+ //# sourceMappingURL=SensorDetailDialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SensorDetailDialog.d.ts","sourceRoot":"","sources":["../../../../../src/core/components/ui/Sensors/SensorDetailDialog.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAa9B,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAyDhE,wBAAgB,kBAAkB,CAAC,EACjC,IAAI,EACJ,YAAY,EACZ,MAAM,EACN,UAAU,GACX,EAAE;IACD,IAAI,EAAE,OAAO,CAAA;IACb,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,UAAU,CAAA;CACxB,GAAG,KAAK,CAAC,YAAY,CAsErB"}
@@ -0,0 +1,128 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { Radio } from "lucide-react";
4
+ import * as React from "react";
5
+ import { AppConfigContext } from "../../../store";
6
+ import { formatInZone } from "../../../utils/timeUtils";
7
+ import { AddItemDialog } from "../AddItemDialog";
8
+ import { Button } from "../Button";
9
+ import { indicesForBounds, rangeBounds } from "./sensorRange";
10
+ import { SensorChart } from "./SensorChart";
11
+ import { useSensorSeries } from "./useSensorSeries";
12
+ const PRESETS = [
13
+ { key: "all", label: "All" },
14
+ { key: "day", label: "Last day" },
15
+ { key: "hour", label: "Last hour" },
16
+ { key: "custom", label: "Custom" }
17
+ ];
18
+ function MetaRow({ label, children }) {
19
+ if (children == null || children === "") return null;
20
+ return /* @__PURE__ */ jsxs("div", { className: "flex justify-between gap-4 py-1 text-sm", children: [
21
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: label }),
22
+ /* @__PURE__ */ jsx("span", { className: "text-right font-medium break-all", children })
23
+ ] });
24
+ }
25
+ function MetaLink({ href }) {
26
+ if (!href) return null;
27
+ return /* @__PURE__ */ jsx("a", { href, target: "_blank", rel: "noopener noreferrer", className: "text-primary underline", children: href });
28
+ }
29
+ function MetadataSection({ meta, timeZone }) {
30
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
31
+ if (!meta || Object.keys(meta).length === 0) {
32
+ return /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "No metadata available." });
33
+ }
34
+ const phenomenon = (_a = meta.phenomenonTime) == null ? void 0 : _a.split("/").map((iso) => formatInZone(Date.parse(iso), timeZone, { dateStyle: "medium", timeStyle: "short" })).join(" \u2192 ");
35
+ return /* @__PURE__ */ jsxs("div", { className: "divide-y", children: [
36
+ /* @__PURE__ */ jsx(MetaRow, { label: "Datastream", children: meta.name }),
37
+ /* @__PURE__ */ jsx(MetaRow, { label: "Description", children: meta.description }),
38
+ /* @__PURE__ */ jsx(MetaRow, { label: "Observation type", children: meta.observationType }),
39
+ /* @__PURE__ */ jsx(MetaRow, { label: "Observed property", children: (_b = meta.observedProperty) == null ? void 0 : _b.name }),
40
+ /* @__PURE__ */ jsx(MetaRow, { label: "Property definition", children: /* @__PURE__ */ jsx(MetaLink, { href: (_c = meta.observedProperty) == null ? void 0 : _c.definition }) }),
41
+ /* @__PURE__ */ jsx(MetaRow, { label: "Unit", children: meta.unit ? `${(_d = meta.unit.name) != null ? _d : ""} ${meta.unit.symbol ? `(${meta.unit.symbol})` : ""}`.trim() : void 0 }),
42
+ /* @__PURE__ */ jsx(MetaRow, { label: "Unit definition", children: /* @__PURE__ */ jsx(MetaLink, { href: (_e = meta.unit) == null ? void 0 : _e.definition }) }),
43
+ /* @__PURE__ */ jsx(MetaRow, { label: "Phenomenon time", children: phenomenon }),
44
+ /* @__PURE__ */ jsx(MetaRow, { label: "Observations", children: meta.observationCount }),
45
+ /* @__PURE__ */ jsx(MetaRow, { label: "Generator", children: (_f = meta.properties) == null ? void 0 : _f.generator }),
46
+ /* @__PURE__ */ jsx(MetaRow, { label: "Seed", children: (_g = meta.properties) == null ? void 0 : _g.seed }),
47
+ /* @__PURE__ */ jsx(MetaRow, { label: "Frequency (ms)", children: (_h = meta.properties) == null ? void 0 : _h.frequency }),
48
+ /* @__PURE__ */ jsx(MetaRow, { label: "Sensor metadata", children: /* @__PURE__ */ jsx(MetaLink, { href: (_i = meta.sensor) == null ? void 0 : _i.metadata }) }),
49
+ /* @__PURE__ */ jsx(MetaRow, { label: "Self link", children: /* @__PURE__ */ jsx(MetaLink, { href: meta.selfLink }) })
50
+ ] });
51
+ }
52
+ function SensorDetailDialog({
53
+ open,
54
+ onOpenChange,
55
+ sensor,
56
+ sensorType
57
+ }) {
58
+ var _a, _b;
59
+ const { state } = React.useContext(AppConfigContext);
60
+ const timeZone = state.appConfig.displayTimeZone;
61
+ const { points, unit, valueLabels, meta, isLoading } = useSensorSeries(
62
+ (_a = sensor.url) != null ? _a : "",
63
+ sensor.dataFormat,
64
+ sensor.updateFrequency,
65
+ { enabled: open }
66
+ );
67
+ const [preset, setPreset] = React.useState("all");
68
+ const [brush, setBrush] = React.useState({});
69
+ React.useEffect(() => {
70
+ if (preset === "custom") return;
71
+ const bounds = rangeBounds(preset, points);
72
+ setBrush(indicesForBounds(points, bounds));
73
+ }, [preset, points]);
74
+ const chartConfig = { value: { label: (_b = sensorType == null ? void 0 : sensorType.name) != null ? _b : "Value", color: "hsl(var(--chart-1))" } };
75
+ return /* @__PURE__ */ jsx(
76
+ AddItemDialog,
77
+ {
78
+ open,
79
+ onOpenChange,
80
+ title: sensor.name,
81
+ icon: Radio,
82
+ contentClassName: "max-w-3xl max-h-[90vh] overflow-y-auto",
83
+ children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
84
+ /* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center gap-1", children: PRESETS.map((p) => /* @__PURE__ */ jsx(
85
+ Button,
86
+ {
87
+ type: "button",
88
+ size: "sm",
89
+ variant: preset === p.key ? "default" : "outline",
90
+ onClick: () => setPreset(p.key),
91
+ children: p.label
92
+ },
93
+ p.key
94
+ )) }),
95
+ /* @__PURE__ */ jsx(
96
+ SensorChart,
97
+ {
98
+ sensorData: points,
99
+ isLoadingData: isLoading,
100
+ sensorName: sensor.name,
101
+ sensorType,
102
+ updateFrequency: sensor.updateFrequency,
103
+ chartConfig,
104
+ size: "lg",
105
+ unit,
106
+ valueLabels,
107
+ timeZone,
108
+ showBrush: true,
109
+ brushStartIndex: brush.startIndex,
110
+ brushEndIndex: brush.endIndex,
111
+ onBrushChange: (range) => {
112
+ setPreset("custom");
113
+ setBrush(range);
114
+ }
115
+ }
116
+ ),
117
+ /* @__PURE__ */ jsxs("div", { children: [
118
+ /* @__PURE__ */ jsx("h4", { className: "mb-2 text-sm font-semibold", children: "Metadata" }),
119
+ /* @__PURE__ */ jsx(MetadataSection, { meta, timeZone })
120
+ ] })
121
+ ] })
122
+ }
123
+ );
124
+ }
125
+ export {
126
+ SensorDetailDialog
127
+ };
128
+ //# sourceMappingURL=SensorDetailDialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/core/components/ui/Sensors/SensorDetailDialog.tsx"],"sourcesContent":["'use client'\r\n\r\n// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\nimport { Radio } from 'lucide-react'\r\nimport * as React from 'react'\r\n\r\nimport { AppConfigContext } from '../../../store'\r\nimport { formatInZone } from '../../../utils/timeUtils'\r\nimport { AddItemDialog } from '../AddItemDialog'\r\nimport { Button } from '../Button'\r\n\r\nimport { indicesForBounds, rangeBounds, type RangePreset } from './sensorRange'\r\nimport { SensorChart } from './SensorChart'\r\n// TimeZoneSelect is intentionally not rendered for now (kept as a standalone component).\r\nimport { useSensorSeries } from './useSensorSeries'\r\n\r\nimport type { SensorSeriesMeta } from './sensorData'\r\nimport type { Sensor, SensorType } from '../../../types/dbTypes'\r\nimport type { ChartConfig } from '../chart'\r\n\r\nconst PRESETS: { key: RangePreset; label: string }[] = [\r\n { key: 'all', label: 'All' },\r\n { key: 'day', label: 'Last day' },\r\n { key: 'hour', label: 'Last hour' },\r\n { key: 'custom', label: 'Custom' },\r\n]\r\n\r\nfunction MetaRow({ label, children }: { label: string; children: React.ReactNode }) {\r\n if (children == null || children === '') return null\r\n return (\r\n <div className=\"flex justify-between gap-4 py-1 text-sm\">\r\n <span className=\"text-muted-foreground\">{label}</span>\r\n <span className=\"text-right font-medium break-all\">{children}</span>\r\n </div>\r\n )\r\n}\r\n\r\nfunction MetaLink({ href }: { href?: string }) {\r\n if (!href) return null\r\n return (\r\n <a href={href} target=\"_blank\" rel=\"noopener noreferrer\" className=\"text-primary underline\">\r\n {href}\r\n </a>\r\n )\r\n}\r\n\r\nfunction MetadataSection({ meta, timeZone }: { meta?: SensorSeriesMeta; timeZone: string }) {\r\n if (!meta || Object.keys(meta).length === 0) {\r\n return <p className=\"text-sm text-muted-foreground\">No metadata available.</p>\r\n }\r\n const phenomenon = meta.phenomenonTime\r\n ?.split('/')\r\n .map(iso => formatInZone(Date.parse(iso), timeZone, { dateStyle: 'medium', timeStyle: 'short' }))\r\n .join(' → ')\r\n return (\r\n <div className=\"divide-y\">\r\n <MetaRow label=\"Datastream\">{meta.name}</MetaRow>\r\n <MetaRow label=\"Description\">{meta.description}</MetaRow>\r\n <MetaRow label=\"Observation type\">{meta.observationType}</MetaRow>\r\n <MetaRow label=\"Observed property\">{meta.observedProperty?.name}</MetaRow>\r\n <MetaRow label=\"Property definition\"><MetaLink href={meta.observedProperty?.definition} /></MetaRow>\r\n <MetaRow label=\"Unit\">{meta.unit ? `${meta.unit.name ?? ''} ${meta.unit.symbol ? `(${meta.unit.symbol})` : ''}`.trim() : undefined}</MetaRow>\r\n <MetaRow label=\"Unit definition\"><MetaLink href={meta.unit?.definition} /></MetaRow>\r\n <MetaRow label=\"Phenomenon time\">{phenomenon}</MetaRow>\r\n <MetaRow label=\"Observations\">{meta.observationCount}</MetaRow>\r\n <MetaRow label=\"Generator\">{meta.properties?.generator as React.ReactNode}</MetaRow>\r\n <MetaRow label=\"Seed\">{meta.properties?.seed as React.ReactNode}</MetaRow>\r\n <MetaRow label=\"Frequency (ms)\">{meta.properties?.frequency as React.ReactNode}</MetaRow>\r\n <MetaRow label=\"Sensor metadata\"><MetaLink href={meta.sensor?.metadata} /></MetaRow>\r\n <MetaRow label=\"Self link\"><MetaLink href={meta.selfLink} /></MetaRow>\r\n </div>\r\n )\r\n}\r\n\r\nexport function SensorDetailDialog({\r\n open,\r\n onOpenChange,\r\n sensor,\r\n sensorType,\r\n}: {\r\n open: boolean\r\n onOpenChange: (open: boolean) => void\r\n sensor: Sensor\r\n sensorType?: SensorType\r\n}): React.ReactElement {\r\n const { state } = React.useContext(AppConfigContext)\r\n const timeZone = state.appConfig.displayTimeZone\r\n\r\n const { points, unit, valueLabels, meta, isLoading } = useSensorSeries(\r\n sensor.url ?? '',\r\n sensor.dataFormat,\r\n sensor.updateFrequency,\r\n { enabled: open },\r\n )\r\n\r\n const [preset, setPreset] = React.useState<RangePreset>('all')\r\n const [brush, setBrush] = React.useState<{ startIndex?: number; endIndex?: number }>({})\r\n\r\n // When a preset is picked (not custom), derive brush indices from its bounds.\r\n React.useEffect(() => {\r\n if (preset === 'custom') return\r\n const bounds = rangeBounds(preset, points)\r\n setBrush(indicesForBounds(points, bounds))\r\n }, [preset, points])\r\n\r\n const chartConfig: ChartConfig = { value: { label: sensorType?.name ?? 'Value', color: 'hsl(var(--chart-1))' } }\r\n\r\n return (\r\n <AddItemDialog\r\n open={open}\r\n onOpenChange={onOpenChange}\r\n title={sensor.name}\r\n icon={Radio}\r\n contentClassName=\"max-w-3xl max-h-[90vh] overflow-y-auto\"\r\n >\r\n <div className=\"space-y-4\">\r\n <div className=\"flex flex-wrap items-center gap-1\">\r\n {PRESETS.map(p => (\r\n <Button\r\n key={p.key}\r\n type=\"button\"\r\n size=\"sm\"\r\n variant={preset === p.key ? 'default' : 'outline'}\r\n onClick={() => setPreset(p.key)}\r\n >\r\n {p.label}\r\n </Button>\r\n ))}\r\n </div>\r\n\r\n <SensorChart\r\n sensorData={points}\r\n isLoadingData={isLoading}\r\n sensorName={sensor.name}\r\n sensorType={sensorType as SensorType}\r\n updateFrequency={sensor.updateFrequency}\r\n chartConfig={chartConfig}\r\n size=\"lg\"\r\n unit={unit}\r\n valueLabels={valueLabels}\r\n timeZone={timeZone}\r\n showBrush\r\n brushStartIndex={brush.startIndex}\r\n brushEndIndex={brush.endIndex}\r\n onBrushChange={range => { setPreset('custom'); setBrush(range) }}\r\n />\r\n\r\n <div>\r\n <h4 className=\"mb-2 text-sm font-semibold\">Metadata</h4>\r\n <MetadataSection meta={meta} timeZone={timeZone} />\r\n </div>\r\n </div>\r\n </AddItemDialog>\r\n )\r\n}\r\n"],"mappings":"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","names":[]}
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { ViewerNames } from '../../../types/dbTypes';
3
+ import type { Sensor } from '../../../types/dbTypes';
3
4
  export type SensorInputLayout = 'inline' | 'dialog';
4
5
  export type BimSensorPlacementContext = {
5
6
  world: any;
@@ -23,6 +24,10 @@ export type SensorInputProps = {
23
24
  onCancel?: () => void;
24
25
  bim?: BimSensorPlacementContext;
25
26
  isOpen?: boolean;
27
+ /** When provided, the dialog becomes a single-sensor EDIT form (no multi-add, no placement). */
28
+ editSensor?: Sensor;
29
+ /** Called after a successful edit save (in addition to onCancel). */
30
+ onSaved?: () => void;
26
31
  };
27
- export declare function SensorInput({ viewer, layout, onCancel, bim, isOpen, }: SensorInputProps): React.JSX.Element;
32
+ export declare function SensorInput({ viewer, layout, onCancel, bim, isOpen, editSensor, onSaved, }: SensorInputProps): React.JSX.Element;
28
33
  //# sourceMappingURL=SensorInput.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SensorInput.d.ts","sourceRoot":"","sources":["../../../../../src/core/components/ui/Sensors/SensorInput.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAK9B,OAAO,EAAE,WAAW,EAAoB,MAAM,wBAAwB,CAAA;AAuBtE,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAEnD,MAAM,MAAM,yBAAyB,GAAG;IACtC,KAAK,EAAE,GAAG,CAAA;IACV,OAAO,EAAE,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,GAAG,CAAC;QAAC,GAAG,EAAE,GAAG,CAAA;KAAE,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA;IACtE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;IACpC,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,MAAM,CAAA;IAC5E,mBAAmB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;CAC3C,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,WAAW,CAAA;IACnB,MAAM,CAAC,EAAE,iBAAiB,CAAA;IAC1B,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,GAAG,CAAC,EAAE,yBAAyB,CAAA;IAC/B,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB,CAAA;AAYD,wBAAgB,WAAW,CAAC,EAC1B,MAAM,EACN,MAAiB,EACjB,QAAQ,EACR,GAAG,EACH,MAAc,GACf,EAAE,gBAAgB,qBAmdlB"}
1
+ {"version":3,"file":"SensorInput.d.ts","sourceRoot":"","sources":["../../../../../src/core/components/ui/Sensors/SensorInput.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAK9B,OAAO,EAAE,WAAW,EAAoB,MAAM,wBAAwB,CAAA;AAoBtE,OAAO,KAAK,EAAE,MAAM,EAAC,MAAM,wBAAwB,CAAC;AAIpD,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAEnD,MAAM,MAAM,yBAAyB,GAAG;IACtC,KAAK,EAAE,GAAG,CAAA;IACV,OAAO,EAAE,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,GAAG,CAAC;QAAC,GAAG,EAAE,GAAG,CAAA;KAAE,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA;IACtE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;IACpC,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,MAAM,CAAA;IAC5E,mBAAmB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;CAC3C,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,WAAW,CAAA;IACnB,MAAM,CAAC,EAAE,iBAAiB,CAAA;IAC1B,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,GAAG,CAAC,EAAE,yBAAyB,CAAA;IAC/B,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,gGAAgG;IAChG,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CACrB,CAAA;AAwCD,wBAAgB,WAAW,CAAC,EAC1B,MAAM,EACN,MAAiB,EACjB,QAAQ,EACR,GAAG,EACH,MAAc,EACd,UAAU,EACV,OAAO,GACR,EAAE,gBAAgB,qBA2hBlB"}
@@ -23,7 +23,7 @@ import { Radio } from "lucide-react";
23
23
  import { useSession } from "next-auth/react";
24
24
  import { useTranslations } from "next-intl";
25
25
  import * as React from "react";
26
- import { useCreateSensor } from "../../../hooks/sensors/sensors";
26
+ import { useCreateSensor, useSensor } from "../../../hooks/sensors/sensors";
27
27
  import { useSensorTypes } from "../../../hooks/sensorTypes/sensorTypes";
28
28
  import { AppConfigContext, MapContext, BuildingsContext, MenusContext, ToolsContext } from "../../../store";
29
29
  import { ViewerNames, SensorDataFormat } from "../../../types/dbTypes";
@@ -42,16 +42,42 @@ import {
42
42
  } from "../Select";
43
43
  import { Separator } from "../Separator";
44
44
  import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "../Tooltip";
45
+ import { parseSensorSeries } from "./sensorData";
45
46
  import { SensorTagsSection } from "./SensorTagsSection";
47
+ function splitUpdateFrequencyMs(updateFrequencyMs) {
48
+ const sortedDesc = [...frequencyUnits].sort((a, b) => b.value - a.value);
49
+ for (const unit of sortedDesc) {
50
+ if (unit.value > 0 && updateFrequencyMs % unit.value === 0) {
51
+ return { updateFrequency: updateFrequencyMs / unit.value, updateFrequencyUnit: unit.value };
52
+ }
53
+ }
54
+ return { updateFrequency: updateFrequencyMs, updateFrequencyUnit: 1 };
55
+ }
56
+ function sensorFormFromEditSensor(editSensor) {
57
+ var _a, _b, _c, _d;
58
+ const { updateFrequency, updateFrequencyUnit } = splitUpdateFrequencyMs(editSensor.updateFrequency);
59
+ return {
60
+ typeId: (_a = editSensor.typeId) != null ? _a : -1,
61
+ name: editSensor.name,
62
+ data: (_c = (_b = editSensor.url) != null ? _b : editSensor.data) != null ? _c : "",
63
+ dataFormat: editSensor.dataFormat,
64
+ updateFrequency,
65
+ updateFrequencyUnit,
66
+ tags: (_d = editSensor.tags) != null ? _d : []
67
+ };
68
+ }
46
69
  function SensorInput({
47
70
  viewer,
48
71
  layout = "dialog",
49
72
  onCancel,
50
73
  bim,
51
- isOpen = false
74
+ isOpen = false,
75
+ editSensor,
76
+ onSaved
52
77
  }) {
53
- var _a, _b, _c, _d, _e;
78
+ var _a, _b, _c, _d, _e, _f;
54
79
  const t = useTranslations("SensorInput");
80
+ const tf = React.useCallback((key, fallback) => t.has(key) ? t(key) : fallback, [t]);
55
81
  const session = useSession();
56
82
  const user = (_a = session.data) == null ? void 0 : _a.user;
57
83
  const organizationId = user == null ? void 0 : user.organizationId;
@@ -64,7 +90,7 @@ function SensorInput({
64
90
  const { state: menusState, dispatch: menusDispatch } = React.useContext(MenusContext);
65
91
  const { currentSensorTypeId } = menusState.menus;
66
92
  const [sensors, setSensors] = React.useState([
67
- {
93
+ editSensor ? sensorFormFromEditSensor(editSensor) : {
68
94
  typeId: currentSensorTypeId != null ? currentSensorTypeId : -1,
69
95
  name: "",
70
96
  data: "",
@@ -76,10 +102,38 @@ function SensorInput({
76
102
  ]);
77
103
  const [currentSensorIndex, setCurrentSensorIndex] = React.useState(0);
78
104
  const [isPlacing, setIsPlacing] = React.useState(false);
105
+ const [preview, setPreview] = React.useState({});
106
+ const checkDataUrl = React.useCallback(async (index, url, dataFormat) => {
107
+ if (!url.trim()) {
108
+ setPreview((prev) => {
109
+ const next = __spreadValues({}, prev);
110
+ delete next[index];
111
+ return next;
112
+ });
113
+ return;
114
+ }
115
+ try {
116
+ const res = await fetch(url);
117
+ if (!res.ok) {
118
+ setPreview((prev) => __spreadProps(__spreadValues({}, prev), { [index]: { ok: false, text: t("previewError") } }));
119
+ return;
120
+ }
121
+ const raw = await res.text();
122
+ const { points, unit } = parseSensorSeries(raw, dataFormat);
123
+ if (points.length === 0) {
124
+ setPreview((prev) => __spreadProps(__spreadValues({}, prev), { [index]: { ok: false, text: t("previewNoData") } }));
125
+ return;
126
+ }
127
+ const unitText = unit ? ` \xB7 ${unit}` : "";
128
+ setPreview((prev) => __spreadProps(__spreadValues({}, prev), { [index]: { ok: true, text: `${points.length} ${t("previewPoints")}${unitText}` } }));
129
+ } catch (e) {
130
+ setPreview((prev) => __spreadProps(__spreadValues({}, prev), { [index]: { ok: false, text: t("previewError") } }));
131
+ }
132
+ }, [t]);
79
133
  React.useEffect(() => {
80
134
  if (!isOpen) return;
81
135
  setSensors([
82
- {
136
+ editSensor ? sensorFormFromEditSensor(editSensor) : {
83
137
  typeId: currentSensorTypeId != null ? currentSensorTypeId : -1,
84
138
  name: "",
85
139
  data: "",
@@ -90,8 +144,10 @@ function SensorInput({
90
144
  }
91
145
  ]);
92
146
  setCurrentSensorIndex(0);
93
- }, [isOpen]);
147
+ setPreview({});
148
+ }, [isOpen, editSensor]);
94
149
  const { createSensor } = useCreateSensor();
150
+ const { updateSensor: updateSensorMutation } = useSensor((_f = editSensor == null ? void 0 : editSensor.id) != null ? _f : null);
95
151
  const setCursor = React.useCallback(
96
152
  (cursor) => {
97
153
  var _a2, _b2, _c2;
@@ -122,6 +178,7 @@ function SensorInput({
122
178
  }
123
179
  ]);
124
180
  setCurrentSensorIndex(0);
181
+ setPreview({});
125
182
  setCursor("");
126
183
  menusDispatch({ type: "SET_CURRENT_SENSOR_TYPE_ID", payload: { currentSensorTypeId: null } });
127
184
  }, [setCursor, currentSensorTypeId]);
@@ -140,8 +197,25 @@ function SensorInput({
140
197
  reset();
141
198
  onCancel == null ? void 0 : onCancel();
142
199
  };
200
+ const onSaveEdit = async () => {
201
+ if (!editSensor) return;
202
+ const form = sensors[0];
203
+ const partial = {
204
+ typeId: form.typeId,
205
+ name: form.name,
206
+ data: form.data,
207
+ dataFormat: form.dataFormat,
208
+ url: form.data,
209
+ updateFrequency: form.updateFrequency * form.updateFrequencyUnit,
210
+ tags: form.tags
211
+ };
212
+ await updateSensorMutation(partial);
213
+ onSaved == null ? void 0 : onSaved();
214
+ onCancel == null ? void 0 : onCancel();
215
+ };
143
216
  React.useEffect(() => {
144
217
  var _a2, _b2;
218
+ if (editSensor) return;
145
219
  if (!isPlacing) return;
146
220
  if (viewer === ViewerNames.map) {
147
221
  const map = (_b2 = (_a2 = mapContext == null ? void 0 : mapContext.state) == null ? void 0 : _a2.map) == null ? void 0 : _b2.map;
@@ -252,6 +326,7 @@ function SensorInput({
252
326
  }, [
253
327
  appConfigState,
254
328
  bim,
329
+ editSensor,
255
330
  isPlacing,
256
331
  mapContext,
257
332
  viewer,
@@ -299,7 +374,6 @@ function SensorInput({
299
374
  );
300
375
  };
301
376
  const onPlaceSensor = (index) => {
302
- console.log("[SensorInput] onPlaceSensor called, index:", index);
303
377
  const sensor = sensors[index];
304
378
  if (!sensor.name.trim() || !sensor.data.trim()) {
305
379
  return;
@@ -350,9 +424,11 @@ function SensorInput({
350
424
  type: "text",
351
425
  value: sensor.data,
352
426
  onChange: (e) => updateSensor(index, "data", e.target.value),
427
+ onBlur: (e) => checkDataUrl(index, e.target.value, sensor.dataFormat),
353
428
  placeholder: t("dataUrlPlaceholder")
354
429
  }
355
- )
430
+ ),
431
+ preview[index] && /* @__PURE__ */ jsx("p", { className: cn("text-xs", preview[index].ok ? "text-muted-foreground" : "text-destructive"), children: preview[index].text })
356
432
  ] }),
357
433
  /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
358
434
  /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
@@ -410,7 +486,16 @@ function SensorInput({
410
486
  }
411
487
  )
412
488
  ] }),
413
- /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [
489
+ editSensor ? /* @__PURE__ */ jsx(
490
+ Button,
491
+ {
492
+ type: "button",
493
+ onClick: onSaveEdit,
494
+ disabled: !sensor.name.trim() || !sensor.data.trim(),
495
+ className: "w-full",
496
+ children: tf("save", "Save")
497
+ }
498
+ ) : /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [
414
499
  /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
415
500
  Button,
416
501
  {