@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.
- package/dist/core/components/authentication/ForgotPassword.d.ts.map +1 -1
- package/dist/core/components/authentication/ForgotPassword.js +0 -1
- package/dist/core/components/authentication/ForgotPassword.js.map +1 -1
- package/dist/core/components/ui/Comments/CollapsibleCommentItem.d.ts +12 -2
- package/dist/core/components/ui/Comments/CollapsibleCommentItem.d.ts.map +1 -1
- package/dist/core/components/ui/Comments/CollapsibleCommentItem.js +137 -139
- package/dist/core/components/ui/Comments/CollapsibleCommentItem.js.map +1 -1
- package/dist/core/components/ui/Comments/Comment.d.ts +18 -1
- package/dist/core/components/ui/Comments/Comment.d.ts.map +1 -1
- package/dist/core/components/ui/Comments/Comment.js +94 -23
- package/dist/core/components/ui/Comments/Comment.js.map +1 -1
- package/dist/core/components/ui/Comments/CommentActionButtons.d.ts +38 -0
- package/dist/core/components/ui/Comments/CommentActionButtons.d.ts.map +1 -0
- package/dist/core/components/ui/Comments/CommentActionButtons.js +134 -0
- package/dist/core/components/ui/Comments/CommentActionButtons.js.map +1 -0
- package/dist/core/components/ui/Comments/CommentInput.d.ts.map +1 -1
- package/dist/core/components/ui/Comments/CommentInput.js +5 -2
- package/dist/core/components/ui/Comments/CommentInput.js.map +1 -1
- package/dist/core/components/ui/Comments/CommentsSection.d.ts.map +1 -1
- package/dist/core/components/ui/Comments/CommentsSection.js +86 -42
- package/dist/core/components/ui/Comments/CommentsSection.js.map +1 -1
- package/dist/core/components/ui/Comments/commentUtils.d.ts.map +1 -1
- package/dist/core/components/ui/Comments/commentUtils.js +2 -1
- package/dist/core/components/ui/Comments/commentUtils.js.map +1 -1
- package/dist/core/components/ui/FilesManager/src/useFileUploadWithProgress.d.ts.map +1 -1
- package/dist/core/components/ui/FilesManager/src/useFileUploadWithProgress.js +0 -1
- package/dist/core/components/ui/FilesManager/src/useFileUploadWithProgress.js.map +1 -1
- package/dist/core/components/ui/InfoSidebar/Container.d.ts.map +1 -1
- package/dist/core/components/ui/InfoSidebar/Container.js +16 -12
- package/dist/core/components/ui/InfoSidebar/Container.js.map +1 -1
- package/dist/core/components/ui/Sensors/CollapsibleSensorItem.d.ts +1 -2
- package/dist/core/components/ui/Sensors/CollapsibleSensorItem.d.ts.map +1 -1
- package/dist/core/components/ui/Sensors/CollapsibleSensorItem.js +66 -94
- package/dist/core/components/ui/Sensors/CollapsibleSensorItem.js.map +1 -1
- package/dist/core/components/ui/Sensors/Sensor.d.ts +16 -3
- package/dist/core/components/ui/Sensors/Sensor.d.ts.map +1 -1
- package/dist/core/components/ui/Sensors/Sensor.js +76 -37
- package/dist/core/components/ui/Sensors/Sensor.js.map +1 -1
- package/dist/core/components/ui/Sensors/SensorChart.d.ts +12 -2
- package/dist/core/components/ui/Sensors/SensorChart.d.ts.map +1 -1
- package/dist/core/components/ui/Sensors/SensorChart.js +49 -12
- package/dist/core/components/ui/Sensors/SensorChart.js.map +1 -1
- package/dist/core/components/ui/Sensors/SensorDetailDialog.d.ts +9 -0
- package/dist/core/components/ui/Sensors/SensorDetailDialog.d.ts.map +1 -0
- package/dist/core/components/ui/Sensors/SensorDetailDialog.js +128 -0
- package/dist/core/components/ui/Sensors/SensorDetailDialog.js.map +1 -0
- package/dist/core/components/ui/Sensors/SensorInput.d.ts +6 -1
- package/dist/core/components/ui/Sensors/SensorInput.d.ts.map +1 -1
- package/dist/core/components/ui/Sensors/SensorInput.js +94 -9
- package/dist/core/components/ui/Sensors/SensorInput.js.map +1 -1
- package/dist/core/components/ui/Sensors/SensorTagsSection.d.ts +3 -1
- package/dist/core/components/ui/Sensors/SensorTagsSection.d.ts.map +1 -1
- package/dist/core/components/ui/Sensors/SensorTagsSection.js +4 -1
- package/dist/core/components/ui/Sensors/SensorTagsSection.js.map +1 -1
- package/dist/core/components/ui/Sensors/SensorsSection.d.ts +1 -3
- package/dist/core/components/ui/Sensors/SensorsSection.d.ts.map +1 -1
- package/dist/core/components/ui/Sensors/SensorsSection.js +33 -10
- package/dist/core/components/ui/Sensors/SensorsSection.js.map +1 -1
- package/dist/core/components/ui/Sensors/TimeZoneSelect.d.ts +7 -0
- package/dist/core/components/ui/Sensors/TimeZoneSelect.d.ts.map +1 -0
- package/dist/core/components/ui/Sensors/TimeZoneSelect.js +56 -0
- package/dist/core/components/ui/Sensors/TimeZoneSelect.js.map +1 -0
- package/dist/core/components/ui/Sensors/sensorData.d.ts +42 -0
- package/dist/core/components/ui/Sensors/sensorData.d.ts.map +1 -0
- package/dist/core/components/ui/Sensors/sensorData.js +118 -0
- package/dist/core/components/ui/Sensors/sensorData.js.map +1 -0
- package/dist/core/components/ui/Sensors/sensorRange.d.ts +24 -0
- package/dist/core/components/ui/Sensors/sensorRange.d.ts.map +1 -0
- package/dist/core/components/ui/Sensors/sensorRange.js +34 -0
- package/dist/core/components/ui/Sensors/sensorRange.js.map +1 -0
- package/dist/core/components/ui/Sensors/useSensorSeries.d.ts +15 -0
- package/dist/core/components/ui/Sensors/useSensorSeries.d.ts.map +1 -0
- package/dist/core/components/ui/Sensors/useSensorSeries.js +63 -0
- package/dist/core/components/ui/Sensors/useSensorSeries.js.map +1 -0
- package/dist/core/components/ui/Sidebar.d.ts.map +1 -1
- package/dist/core/components/ui/Sidebar.js +27 -4
- package/dist/core/components/ui/Sidebar.js.map +1 -1
- package/dist/core/components/ui/ToolbarButton.d.ts.map +1 -1
- package/dist/core/components/ui/ToolbarButton.js +0 -1
- package/dist/core/components/ui/ToolbarButton.js.map +1 -1
- package/dist/core/components/viewers/Data/advancedFilter/FiltersDialog.d.ts.map +1 -1
- package/dist/core/components/viewers/Data/advancedFilter/FiltersDialog.js +0 -2
- package/dist/core/components/viewers/Data/advancedFilter/FiltersDialog.js.map +1 -1
- package/dist/core/components/viewers/Data/details/EnergySourcesGrid.d.ts.map +1 -1
- package/dist/core/components/viewers/Data/details/EnergySourcesGrid.js +0 -10
- package/dist/core/components/viewers/Data/details/EnergySourcesGrid.js.map +1 -1
- package/dist/core/components/viewers/Data/files/DatatableFileAdder.d.ts.map +1 -1
- package/dist/core/components/viewers/Data/files/DatatableFileAdder.js +0 -1
- package/dist/core/components/viewers/Data/files/DatatableFileAdder.js.map +1 -1
- package/dist/core/components/viewers/Data/files/utils/fuzzySearch.d.ts.map +1 -1
- package/dist/core/components/viewers/Data/files/utils/fuzzySearch.js +0 -1
- package/dist/core/components/viewers/Data/files/utils/fuzzySearch.js.map +1 -1
- package/dist/core/components/viewers/Data/userDetails/UserMoreOptions.d.ts.map +1 -1
- package/dist/core/components/viewers/Data/userDetails/UserMoreOptions.js +0 -1
- package/dist/core/components/viewers/Data/userDetails/UserMoreOptions.js.map +1 -1
- package/dist/core/components/viewers/Data/utils/filterHelper.d.ts.map +1 -1
- package/dist/core/components/viewers/Data/utils/filterHelper.js +0 -2
- package/dist/core/components/viewers/Data/utils/filterHelper.js.map +1 -1
- package/dist/core/components/viewers/Viewer.js +1 -1
- package/dist/core/components/viewers/Viewer.js.map +1 -1
- package/dist/core/components/viewers/bim/src/BimSidebar/src/CommunicationTab/src/TopicsSection.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/BimSidebar/src/CommunicationTab/src/TopicsSection.js +0 -3
- package/dist/core/components/viewers/bim/src/BimSidebar/src/CommunicationTab/src/TopicsSection.js.map +1 -1
- package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/FilesSection.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/FilesSection.js +1 -7
- package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/FilesSection.js.map +1 -1
- package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/ModelsSection.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/ModelsSection.js +1 -9
- package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/ModelsSection.js.map +1 -1
- package/dist/core/components/viewers/bim/src/BimSidebar/src/SensorsTab/index.d.ts +1 -3
- package/dist/core/components/viewers/bim/src/BimSidebar/src/SensorsTab/index.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/BimSidebar/src/SensorsTab/index.js +2 -2
- package/dist/core/components/viewers/bim/src/BimSidebar/src/SensorsTab/index.js.map +1 -1
- package/dist/core/components/viewers/bim/src/BimSidebar/src/TabSelector.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/BimSidebar/src/TabSelector.js +4 -3
- package/dist/core/components/viewers/bim/src/BimSidebar/src/TabSelector.js.map +1 -1
- package/dist/core/components/viewers/bim/src/BimSidebar/src/index.js +1 -1
- package/dist/core/components/viewers/bim/src/BimSidebar/src/index.js.map +1 -1
- package/dist/core/components/viewers/bim/src/ClippingPlane.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/ClippingPlane.js +0 -1
- package/dist/core/components/viewers/bim/src/ClippingPlane.js.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/AddToBim/index.d.ts +1 -2
- package/dist/core/components/viewers/bim/src/tools/AddToBim/index.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/AddToBim/index.js +25 -2
- package/dist/core/components/viewers/bim/src/tools/AddToBim/index.js.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimComment.d.ts +16 -10
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimComment.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimComment.js +26 -6
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimComment.js.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimCommentCluster.d.ts +2 -0
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimCommentCluster.d.ts.map +1 -0
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimCommentCluster.js +5 -0
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimCommentCluster.js.map +1 -0
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimSensor.d.ts +8 -1
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimSensor.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimSensor.js +15 -3
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimSensor.js.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/clusterMarkersByScreenSpace.d.ts +44 -0
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/clusterMarkersByScreenSpace.d.ts.map +1 -0
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/clusterMarkersByScreenSpace.js +77 -0
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/clusterMarkersByScreenSpace.js.map +1 -0
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/commentCameraUtils.d.ts +3 -0
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/commentCameraUtils.d.ts.map +1 -0
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/commentCameraUtils.js +5 -0
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/commentCameraUtils.js.map +1 -0
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/commentMarkerConfig.d.ts +33 -0
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/commentMarkerConfig.d.ts.map +1 -0
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/commentMarkerConfig.js +90 -0
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/commentMarkerConfig.js.map +1 -0
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/renderCSS2DMarkers.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/renderCSS2DMarkers.js +2 -2
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/renderCSS2DMarkers.js.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useCommentMarkers.d.ts +7 -1
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useCommentMarkers.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useCommentMarkers.js +50 -73
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useCommentMarkers.js.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useSensorMarkers.d.ts +7 -1
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useSensorMarkers.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useSensorMarkers.js +39 -11
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useSensorMarkers.js.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/ClippingTool/ClippingTool.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/ClippingTool/ClippingTool.js +1 -5
- package/dist/core/components/viewers/bim/src/tools/ClippingTool/ClippingTool.js.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/ExplodeByLevelTool.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/ExplodeByLevelTool.js +0 -1
- package/dist/core/components/viewers/bim/src/tools/ExplodeByLevelTool.js.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/measureBimTool.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/measureBimTool.js +1 -2
- package/dist/core/components/viewers/bim/src/tools/measureBimTool.js.map +1 -1
- package/dist/core/components/viewers/map/MapViewer.d.ts +1 -2
- package/dist/core/components/viewers/map/MapViewer.d.ts.map +1 -1
- package/dist/core/components/viewers/map/MapViewer.js +2 -2
- package/dist/core/components/viewers/map/MapViewer.js.map +1 -1
- package/dist/core/components/viewers/map/datasets/src/arcGISDatasets.d.ts.map +1 -1
- package/dist/core/components/viewers/map/datasets/src/arcGISDatasets.js +11 -14
- package/dist/core/components/viewers/map/datasets/src/arcGISDatasets.js.map +1 -1
- package/dist/core/components/viewers/map/datasets/src/ckanDatasets.d.ts.map +1 -1
- package/dist/core/components/viewers/map/datasets/src/ckanDatasets.js +2 -5
- package/dist/core/components/viewers/map/datasets/src/ckanDatasets.js.map +1 -1
- package/dist/core/components/viewers/map/datasets/src/localDatasets.d.ts.map +1 -1
- package/dist/core/components/viewers/map/datasets/src/localDatasets.js +0 -3
- package/dist/core/components/viewers/map/datasets/src/localDatasets.js.map +1 -1
- package/dist/core/components/viewers/map/datasets/src/opendatasoftDatasets.d.ts.map +1 -1
- package/dist/core/components/viewers/map/datasets/src/opendatasoftDatasets.js +0 -11
- package/dist/core/components/viewers/map/datasets/src/opendatasoftDatasets.js.map +1 -1
- package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/DatabaseBuildingPopover/src/BuildingsTools.d.ts.map +1 -1
- package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/DatabaseBuildingPopover/src/BuildingsTools.js +0 -1
- package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/DatabaseBuildingPopover/src/BuildingsTools.js.map +1 -1
- package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/NonDatabaseBuildingPopover.d.ts.map +1 -1
- package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/NonDatabaseBuildingPopover.js +0 -1
- package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/NonDatabaseBuildingPopover.js.map +1 -1
- package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/OpenDataFeaturePopover.d.ts.map +1 -1
- package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/OpenDataFeaturePopover.js +0 -1
- package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/OpenDataFeaturePopover.js.map +1 -1
- package/dist/core/components/viewers/map/src/MapLayers/index.d.ts +1 -2
- package/dist/core/components/viewers/map/src/MapLayers/index.d.ts.map +1 -1
- package/dist/core/components/viewers/map/src/MapLayers/index.js +2 -2
- package/dist/core/components/viewers/map/src/MapLayers/index.js.map +1 -1
- package/dist/core/components/viewers/map/src/MapLayers/src/CommentLayer/index.d.ts.map +1 -1
- package/dist/core/components/viewers/map/src/MapLayers/src/CommentLayer/index.js +174 -53
- package/dist/core/components/viewers/map/src/MapLayers/src/CommentLayer/index.js.map +1 -1
- package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/components/MapFileManager.d.ts.map +1 -1
- package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/components/MapFileManager.js +2 -1
- package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/components/MapFileManager.js.map +1 -1
- package/dist/core/components/viewers/map/src/MapLayers/src/SensorsLayer/index.d.ts +1 -3
- package/dist/core/components/viewers/map/src/MapLayers/src/SensorsLayer/index.d.ts.map +1 -1
- package/dist/core/components/viewers/map/src/MapLayers/src/SensorsLayer/index.js +74 -42
- package/dist/core/components/viewers/map/src/MapLayers/src/SensorsLayer/index.js.map +1 -1
- package/dist/core/components/viewers/map/src/MapSidebar/TabSelector.d.ts.map +1 -1
- package/dist/core/components/viewers/map/src/MapSidebar/TabSelector.js +4 -3
- package/dist/core/components/viewers/map/src/MapSidebar/TabSelector.js.map +1 -1
- package/dist/core/components/viewers/map/src/MapSidebar/index.js +1 -1
- package/dist/core/components/viewers/map/src/MapSidebar/index.js.map +1 -1
- package/dist/core/components/viewers/map/src/MapSidebar/src/FileTab/src/FilesSection.d.ts.map +1 -1
- package/dist/core/components/viewers/map/src/MapSidebar/src/FileTab/src/FilesSection.js +0 -1
- package/dist/core/components/viewers/map/src/MapSidebar/src/FileTab/src/FilesSection.js.map +1 -1
- package/dist/core/components/viewers/map/src/MapSidebar/src/FileTab/src/ModelsSection.d.ts.map +1 -1
- package/dist/core/components/viewers/map/src/MapSidebar/src/FileTab/src/ModelsSection.js +1 -5
- package/dist/core/components/viewers/map/src/MapSidebar/src/FileTab/src/ModelsSection.js.map +1 -1
- package/dist/core/components/viewers/map/src/MapSidebar/src/SensorsTab/index.d.ts +1 -3
- package/dist/core/components/viewers/map/src/MapSidebar/src/SensorsTab/index.d.ts.map +1 -1
- package/dist/core/components/viewers/map/src/MapSidebar/src/SensorsTab/index.js +2 -2
- package/dist/core/components/viewers/map/src/MapSidebar/src/SensorsTab/index.js.map +1 -1
- package/dist/core/components/viewers/map/src/tools/AddTools/AddFile/utils/uploadToPresignedURLS.d.ts.map +1 -1
- package/dist/core/components/viewers/map/src/tools/AddTools/AddFile/utils/uploadToPresignedURLS.js +1 -3
- package/dist/core/components/viewers/map/src/tools/AddTools/AddFile/utils/uploadToPresignedURLS.js.map +1 -1
- package/dist/core/components/viewers/map/utils/MapEventManager/MapClickManager.d.ts.map +1 -1
- package/dist/core/components/viewers/map/utils/MapEventManager/MapClickManager.js +0 -1
- package/dist/core/components/viewers/map/utils/MapEventManager/MapClickManager.js.map +1 -1
- package/dist/core/components/viewers/map/utils/flyToEach.d.ts.map +1 -1
- package/dist/core/components/viewers/map/utils/flyToEach.js +0 -1
- package/dist/core/components/viewers/map/utils/flyToEach.js.map +1 -1
- package/dist/core/components/viewers/map/utils/getOsmIdbyCoordinates.d.ts.map +1 -1
- package/dist/core/components/viewers/map/utils/getOsmIdbyCoordinates.js +0 -2
- package/dist/core/components/viewers/map/utils/getOsmIdbyCoordinates.js.map +1 -1
- package/dist/core/components/viewers/shared/markers/BimMarkerCluster.d.ts +19 -0
- package/dist/core/components/viewers/shared/markers/BimMarkerCluster.d.ts.map +1 -0
- package/dist/core/components/viewers/shared/markers/BimMarkerCluster.js +108 -0
- package/dist/core/components/viewers/shared/markers/BimMarkerCluster.js.map +1 -0
- package/dist/core/components/viewers/shared/markers/computeMarkerLookAt.d.ts +24 -0
- package/dist/core/components/viewers/shared/markers/computeMarkerLookAt.d.ts.map +1 -0
- package/dist/core/components/viewers/shared/markers/computeMarkerLookAt.js +27 -0
- package/dist/core/components/viewers/shared/markers/computeMarkerLookAt.js.map +1 -0
- package/dist/core/components/viewers/shared/markers/types.d.ts +66 -0
- package/dist/core/components/viewers/shared/markers/types.d.ts.map +1 -0
- package/dist/core/components/viewers/shared/markers/types.js +1 -0
- package/dist/core/components/viewers/shared/markers/types.js.map +1 -0
- package/dist/core/components/viewers/shared/markers/useMarkerLayerBim.d.ts +22 -0
- package/dist/core/components/viewers/shared/markers/useMarkerLayerBim.d.ts.map +1 -0
- package/dist/core/components/viewers/shared/markers/useMarkerLayerBim.js +233 -0
- package/dist/core/components/viewers/shared/markers/useMarkerLayerBim.js.map +1 -0
- package/dist/core/hooks/comments/comments.d.ts +11 -0
- package/dist/core/hooks/comments/comments.d.ts.map +1 -1
- package/dist/core/hooks/comments/comments.js +3 -1
- package/dist/core/hooks/comments/comments.js.map +1 -1
- package/dist/core/hooks/comments/createCommentHooks.d.ts +11 -0
- package/dist/core/hooks/comments/createCommentHooks.d.ts.map +1 -1
- package/dist/core/hooks/comments/createCommentHooks.js +30 -1
- package/dist/core/hooks/comments/createCommentHooks.js.map +1 -1
- package/dist/core/hooks/files/files.d.ts.map +1 -1
- package/dist/core/hooks/files/files.js +0 -1
- package/dist/core/hooks/files/files.js.map +1 -1
- package/dist/core/hooks/ui/useResizableSidebarWidth.d.ts +30 -0
- package/dist/core/hooks/ui/useResizableSidebarWidth.d.ts.map +1 -0
- package/dist/core/hooks/ui/useResizableSidebarWidth.js +75 -0
- package/dist/core/hooks/ui/useResizableSidebarWidth.js.map +1 -0
- package/dist/core/i18n/messages/en.json +10 -1
- package/dist/core/i18n/messages/es.json +11 -2
- package/dist/core/i18n/messages/fr.json +11 -2
- package/dist/core/store/AppConfig/context.d.ts.map +1 -1
- package/dist/core/store/AppConfig/context.js +4 -1
- package/dist/core/store/AppConfig/context.js.map +1 -1
- package/dist/core/store/AppConfig/reducer.d.ts +10 -0
- package/dist/core/store/AppConfig/reducer.d.ts.map +1 -1
- package/dist/core/store/AppConfig/reducer.js +10 -0
- package/dist/core/store/AppConfig/reducer.js.map +1 -1
- package/dist/core/store/Datasets/reducer.d.ts.map +1 -1
- package/dist/core/store/Datasets/reducer.js +0 -2
- package/dist/core/store/Datasets/reducer.js.map +1 -1
- package/dist/core/store/Files/reducer.js +0 -1
- package/dist/core/store/Files/reducer.js.map +1 -1
- package/dist/core/store/Menus/context.d.ts.map +1 -1
- package/dist/core/store/Menus/context.js +8 -2
- package/dist/core/store/Menus/context.js.map +1 -1
- package/dist/core/store/Menus/reducer.d.ts +65 -1
- package/dist/core/store/Menus/reducer.d.ts.map +1 -1
- package/dist/core/store/Menus/reducer.js +39 -3
- package/dist/core/store/Menus/reducer.js.map +1 -1
- package/dist/core/utils/markerUtils.d.ts +10 -0
- package/dist/core/utils/markerUtils.d.ts.map +1 -1
- package/dist/core/utils/markerUtils.js +9 -1
- package/dist/core/utils/markerUtils.js.map +1 -1
- package/dist/core/utils/memcache.d.ts.map +1 -1
- package/dist/core/utils/memcache.js +0 -7
- package/dist/core/utils/memcache.js.map +1 -1
- package/dist/core/utils/timeUtils.d.ts +24 -1
- package/dist/core/utils/timeUtils.d.ts.map +1 -1
- package/dist/core/utils/timeUtils.js +52 -3
- package/dist/core/utils/timeUtils.js.map +1 -1
- 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,
|
|
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: "
|
|
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:
|
|
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(
|
|
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;
|
|
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
|
-
|
|
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
|
-
|
|
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
|
{
|