@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,20 +1,24 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
3
|
-
import { format } from "date-fns";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
3
|
import * as LR from "lucide-react";
|
|
5
4
|
import { useSession } from "next-auth/react";
|
|
6
5
|
import { useTranslations } from "next-intl";
|
|
7
6
|
import * as React from "react";
|
|
8
7
|
import { useCoreHooks } from "../../../hooks/provider";
|
|
9
8
|
import { useUser } from "../../../hooks/users/users";
|
|
9
|
+
import { AppConfigContext } from "../../../store";
|
|
10
|
+
import { formatInZone } from "../../../utils/timeUtils";
|
|
10
11
|
import { cn } from "../../../utils/utils";
|
|
11
12
|
import { Avatar } from "../Avatar";
|
|
12
13
|
import { Badge } from "../Badge";
|
|
13
14
|
import { Button } from "../Button";
|
|
15
|
+
import { CommentActionButtons } from "../Comments/CommentActionButtons";
|
|
14
16
|
import { UserAvatar } from "../UserAvatar";
|
|
15
17
|
import { SensorChart } from "./SensorChart";
|
|
18
|
+
import { SensorDetailDialog } from "./SensorDetailDialog";
|
|
16
19
|
import { SensorTagsSection } from "./SensorTagsSection";
|
|
17
20
|
import { resolveLucideIcon } from "./sensorUtils";
|
|
21
|
+
import { useSensorSeries } from "./useSensorSeries";
|
|
18
22
|
function CollapsibleSensorItem({
|
|
19
23
|
sensor,
|
|
20
24
|
sensorType,
|
|
@@ -22,17 +26,18 @@ function CollapsibleSensorItem({
|
|
|
22
26
|
depth = 0,
|
|
23
27
|
isVisible = true,
|
|
24
28
|
onMouseEnter,
|
|
25
|
-
onMouseLeave
|
|
26
|
-
minioBaseUrl
|
|
29
|
+
onMouseLeave
|
|
27
30
|
}) {
|
|
28
|
-
var _a, _b, _c, _d;
|
|
31
|
+
var _a, _b, _c, _d, _e;
|
|
29
32
|
const t = useTranslations("SensorsSection");
|
|
30
33
|
const [isExpanded, setIsExpanded] = React.useState(false);
|
|
31
|
-
const
|
|
32
|
-
const
|
|
34
|
+
const { state: appConfigState } = React.useContext(AppConfigContext);
|
|
35
|
+
const timeZone = appConfigState.appConfig.displayTimeZone;
|
|
36
|
+
const [detailOpen, setDetailOpen] = React.useState(false);
|
|
37
|
+
const [tagAddNonce, setTagAddNonce] = React.useState(0);
|
|
38
|
+
const { points: sensorData, unit, valueLabels, isLoading: isLoadingData } = useSensorSeries((_a = sensor.url) != null ? _a : "", sensor.dataFormat, sensor.updateFrequency, { enabled: isExpanded });
|
|
33
39
|
const prevVisibleRef = React.useRef(isVisible);
|
|
34
|
-
const
|
|
35
|
-
const typeName = (_a = sensorType == null ? void 0 : sensorType.name.replace(/_/g, " ")) != null ? _a : "Unknown";
|
|
40
|
+
const typeName = (_b = sensorType == null ? void 0 : sensorType.name.replace(/_/g, " ")) != null ? _b : "Unknown";
|
|
36
41
|
const SensorIcon = resolveLucideIcon(sensorType == null ? void 0 : sensorType.icon);
|
|
37
42
|
React.useEffect(() => {
|
|
38
43
|
const prevVisible = prevVisibleRef.current;
|
|
@@ -41,42 +46,16 @@ function CollapsibleSensorItem({
|
|
|
41
46
|
}
|
|
42
47
|
prevVisibleRef.current = isVisible;
|
|
43
48
|
}, [isVisible]);
|
|
44
|
-
React.useEffect(() => {
|
|
45
|
-
const fetchCSVData = async () => {
|
|
46
|
-
setIsLoadingData(true);
|
|
47
|
-
try {
|
|
48
|
-
const response = await fetch(dataPath);
|
|
49
|
-
const csvText = await response.text();
|
|
50
|
-
const lines = csvText.trim().split("\n");
|
|
51
|
-
const parsed = lines.map((line) => {
|
|
52
|
-
const [time, valueStr] = line.split(",");
|
|
53
|
-
return {
|
|
54
|
-
time: time.trim(),
|
|
55
|
-
value: parseFloat(valueStr.trim())
|
|
56
|
-
};
|
|
57
|
-
}).filter((item) => !isNaN(item.value));
|
|
58
|
-
setSensorData(parsed);
|
|
59
|
-
} catch (error) {
|
|
60
|
-
console.error("Error fetching sensor data:", error);
|
|
61
|
-
setSensorData([]);
|
|
62
|
-
} finally {
|
|
63
|
-
setIsLoadingData(false);
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
if (isExpanded) {
|
|
67
|
-
fetchCSVData();
|
|
68
|
-
}
|
|
69
|
-
}, [dataPath, isExpanded]);
|
|
70
49
|
const chartConfig = {
|
|
71
50
|
value: {
|
|
72
51
|
label: typeName,
|
|
73
52
|
color: "hsl(var(--chart-1))"
|
|
74
53
|
}
|
|
75
54
|
};
|
|
76
|
-
const user = (
|
|
55
|
+
const user = (_c = useSession().data) == null ? void 0 : _c.user;
|
|
77
56
|
const indentClass = depth > 0 ? `ml-${Math.min(depth * 4, 12)}` : "";
|
|
78
57
|
const { user: author } = useUser(String(sensor.authorId));
|
|
79
|
-
const authorName = (
|
|
58
|
+
const authorName = (_d = author == null ? void 0 : author.name) != null ? _d : "Unknown User";
|
|
80
59
|
const { sensor: sensorHooks } = useCoreHooks();
|
|
81
60
|
const { updateSensor } = sensorHooks.useSensor(sensor.id);
|
|
82
61
|
const handleAddTag = async (tag) => {
|
|
@@ -100,65 +79,39 @@ function CollapsibleSensorItem({
|
|
|
100
79
|
onMouseEnter,
|
|
101
80
|
onMouseLeave,
|
|
102
81
|
children: [
|
|
103
|
-
/* @__PURE__ */
|
|
104
|
-
/* @__PURE__ */
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
/* @__PURE__ */ jsx("
|
|
128
|
-
|
|
129
|
-
sensor.updatedAt !== sensor.createdAt && /* @__PURE__ */ jsx(Badge, { variant: "outline", className: "text-xs", children: t("edited") })
|
|
130
|
-
] }) })
|
|
131
|
-
] }),
|
|
132
|
-
onAction && /* @__PURE__ */ jsx("div", { className: cn("flex items-center gap-0 flex-shrink-0", !isVisible && "opacity-70"), children: (user == null ? void 0 : user.id) === String(sensor.authorId) && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
133
|
-
/* @__PURE__ */ jsx(
|
|
134
|
-
Button,
|
|
135
|
-
{
|
|
136
|
-
variant: "ghost",
|
|
137
|
-
size: "icon",
|
|
138
|
-
className: "h-8 w-8 p-0",
|
|
139
|
-
onClick: () => onAction("edit", sensor.id),
|
|
140
|
-
title: t("editSensor"),
|
|
141
|
-
children: /* @__PURE__ */ jsx(LR.Pencil, { className: "h-4 w-4" })
|
|
142
|
-
}
|
|
143
|
-
),
|
|
144
|
-
/* @__PURE__ */ jsx(
|
|
145
|
-
Button,
|
|
146
|
-
{
|
|
147
|
-
variant: "ghost",
|
|
148
|
-
size: "icon",
|
|
149
|
-
className: "h-8 w-8 p-0",
|
|
150
|
-
onClick: () => onAction("delete", sensor.id),
|
|
151
|
-
title: t("deleteSensor"),
|
|
152
|
-
children: /* @__PURE__ */ jsx(LR.Trash2, { className: "h-4 w-4" })
|
|
153
|
-
}
|
|
154
|
-
)
|
|
82
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-start justify-between p-3 hover:bg-accent/50 transition-colors", children: /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3 flex-1 min-w-0", children: [
|
|
83
|
+
/* @__PURE__ */ jsx(
|
|
84
|
+
Button,
|
|
85
|
+
{
|
|
86
|
+
variant: "ghost",
|
|
87
|
+
size: "sm",
|
|
88
|
+
className: cn("h-6 w-6 p-0 mt-1", !isVisible && "opacity-70"),
|
|
89
|
+
onClick: () => setIsExpanded(!isExpanded),
|
|
90
|
+
children: /* @__PURE__ */ jsx(
|
|
91
|
+
LR.ChevronRight,
|
|
92
|
+
{
|
|
93
|
+
className: cn(
|
|
94
|
+
"h-4 w-4 transition-transform",
|
|
95
|
+
isExpanded && "rotate-90"
|
|
96
|
+
)
|
|
97
|
+
}
|
|
98
|
+
)
|
|
99
|
+
}
|
|
100
|
+
),
|
|
101
|
+
/* @__PURE__ */ jsx("div", { className: cn(
|
|
102
|
+
"h-8 w-8 mt-1 rounded-full bg-primary flex items-center justify-center flex-shrink-0",
|
|
103
|
+
!isVisible && "opacity-70 grayscale"
|
|
104
|
+
), children: /* @__PURE__ */ jsx(SensorIcon, { className: cn("h-4 w-4 text-primary-foreground", !isVisible && "opacity-70") }) }),
|
|
105
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
106
|
+
/* @__PURE__ */ jsx("span", { className: cn("text-sm font-medium", isVisible ? "text-foreground" : "text-muted-foreground"), children: sensor.name }),
|
|
107
|
+
sensor.updatedAt !== sensor.createdAt && /* @__PURE__ */ jsx(Badge, { variant: "outline", className: "text-xs", children: t("edited") })
|
|
155
108
|
] }) })
|
|
156
|
-
] }),
|
|
109
|
+
] }) }),
|
|
157
110
|
isExpanded && /* @__PURE__ */ jsxs("div", { className: "border-t bg-muted/30", children: [
|
|
158
111
|
/* @__PURE__ */ jsxs("div", { className: "p-4 space-y-4", children: [
|
|
159
112
|
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
160
113
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
161
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children:
|
|
114
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: formatInZone(new Date(sensor.createdAt).getTime(), timeZone, { dateStyle: "medium", timeStyle: "short" }) }),
|
|
162
115
|
/* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "text-xs", children: typeName })
|
|
163
116
|
] }),
|
|
164
117
|
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2 text-sm", children: [
|
|
@@ -185,16 +138,20 @@ function CollapsibleSensorItem({
|
|
|
185
138
|
sensorName: sensor.name,
|
|
186
139
|
sensorType,
|
|
187
140
|
updateFrequency: sensor.updateFrequency,
|
|
188
|
-
chartConfig
|
|
141
|
+
chartConfig,
|
|
142
|
+
unit,
|
|
143
|
+
valueLabels,
|
|
144
|
+
timeZone
|
|
189
145
|
}
|
|
190
146
|
)
|
|
191
147
|
] }),
|
|
192
148
|
/* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
|
|
193
149
|
SensorTagsSection,
|
|
194
150
|
{
|
|
195
|
-
tags: (
|
|
151
|
+
tags: (_e = sensor.tags) != null ? _e : [],
|
|
196
152
|
onAdd: handleAddTag,
|
|
197
153
|
onDelete: handleDeleteTag,
|
|
154
|
+
openAddSignal: tagAddNonce,
|
|
198
155
|
translations: {
|
|
199
156
|
addTag: t("addTag"),
|
|
200
157
|
removeTag: t("removeTag"),
|
|
@@ -203,7 +160,22 @@ function CollapsibleSensorItem({
|
|
|
203
160
|
}
|
|
204
161
|
}
|
|
205
162
|
) })
|
|
206
|
-
] })
|
|
163
|
+
] }),
|
|
164
|
+
/* @__PURE__ */ jsx("div", { className: cn("flex items-center justify-end gap-0 border-t px-2 py-1", !isVisible && "opacity-70"), children: /* @__PURE__ */ jsx(
|
|
165
|
+
CommentActionButtons,
|
|
166
|
+
{
|
|
167
|
+
onExpand: () => setDetailOpen(true),
|
|
168
|
+
onTag: () => {
|
|
169
|
+
setIsExpanded(true);
|
|
170
|
+
setTagAddNonce((n) => n + 1);
|
|
171
|
+
},
|
|
172
|
+
onEdit: onAction && (user == null ? void 0 : user.id) === String(sensor.authorId) ? () => onAction("edit", sensor.id) : void 0,
|
|
173
|
+
onDelete: onAction && (user == null ? void 0 : user.id) === String(sensor.authorId) ? () => onAction("delete", sensor.id) : void 0,
|
|
174
|
+
buttonClassName: "h-8 w-8",
|
|
175
|
+
labels: { expand: t("expandSensor"), tag: t("addTag"), edit: t("editSensor"), delete: t("deleteSensor") }
|
|
176
|
+
}
|
|
177
|
+
) }),
|
|
178
|
+
/* @__PURE__ */ jsx(SensorDetailDialog, { open: detailOpen, onOpenChange: setDetailOpen, sensor, sensorType })
|
|
207
179
|
]
|
|
208
180
|
}
|
|
209
181
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/core/components/ui/Sensors/CollapsibleSensorItem.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 { format } from 'date-fns'\r\nimport * as LR from 'lucide-react'\r\nimport { useSession } from 'next-auth/react'\r\nimport { useTranslations } from 'next-intl'\r\nimport * as React from 'react'\r\n\r\nimport { useCoreHooks } from '../../../hooks/provider'\r\nimport { useUser } from '../../../hooks/users/users'\r\nimport { cn } from '../../../utils/utils'\r\nimport { Avatar, AvatarFallback } from '../Avatar'\r\nimport { Badge } from '../Badge'\r\nimport { Button } from '../Button'\r\nimport { UserAvatar } from '../UserAvatar'\r\n\r\nimport { SensorChart } from './SensorChart'\r\nimport { SensorTagsSection } from './SensorTagsSection'\r\nimport { resolveLucideIcon } from './sensorUtils'\r\n\r\nimport type { Sensor, SensorType } from '../../../types/dbTypes'\r\nimport type { ChartConfig } from '../chart'\r\n\r\ntype SensorAction = 'view' | 'edit' | 'delete' | 'reply'\r\n\r\ninterface CollapsibleSensorItemProps {\r\n sensor: Sensor\r\n sensorType: SensorType\r\n onAction?: (action: SensorAction, id: number) => void\r\n depth?: number\r\n isVisible?: boolean\r\n onMouseEnter?: () => void\r\n onMouseLeave?: () => void\r\n minioBaseUrl?: string\r\n}\r\n\r\nexport function CollapsibleSensorItem({\r\n sensor,\r\n sensorType,\r\n onAction,\r\n depth = 0,\r\n isVisible = true,\r\n onMouseEnter,\r\n onMouseLeave,\r\n minioBaseUrl\r\n}: CollapsibleSensorItemProps) {\r\n const t = useTranslations('SensorsSection')\r\n const [isExpanded, setIsExpanded] = React.useState(false)\r\n const [sensorData, setSensorData] = React.useState<{ time: string; value: number }[]>([])\r\n const [isLoadingData, setIsLoadingData] = React.useState(false)\r\n const prevVisibleRef = React.useRef(isVisible)\r\n\r\n //const { state: { runtimeConfig: { minioUrl } } } = useAppConfigContext()\r\n\r\n //const dataPath = `${minioUrl ?? ''}/sensors/${sensor.url}`\r\n const dataPath = minioBaseUrl\r\n ? `${minioBaseUrl}/sensors/${sensor.url}`\r\n : ''\r\n const typeName = sensorType?.name.replace(/_/g, ' ') ?? 'Unknown'\r\n\r\n const SensorIcon = resolveLucideIcon(sensorType?.icon)\r\n\r\n // Auto-collapse when visibility turns off\r\n React.useEffect(() => {\r\n const prevVisible = prevVisibleRef.current\r\n\r\n if (prevVisible && !isVisible) {\r\n // Just turned invisible - collapse\r\n setIsExpanded(false)\r\n }\r\n\r\n prevVisibleRef.current = isVisible\r\n }, [isVisible])\r\n\r\n // Fetch and parse CSV data\r\n React.useEffect(() => {\r\n const fetchCSVData = async () => {\r\n setIsLoadingData(true)\r\n try {\r\n const response = await fetch(dataPath)\r\n const csvText = await response.text()\r\n\r\n // Parse CSV: format is \"time,value\" (e.g., \"0:00:00,7.4\")\r\n const lines = csvText.trim().split('\\n')\r\n const parsed = lines.map(line => {\r\n const [time, valueStr] = line.split(',')\r\n return {\r\n time: time.trim(),\r\n value: parseFloat(valueStr.trim())\r\n }\r\n }).filter(item => !isNaN(item.value)) // Filter out any invalid entries\r\n\r\n setSensorData(parsed)\r\n } catch (error) {\r\n console.error('Error fetching sensor data:', error)\r\n // Fallback to empty array on error\r\n setSensorData([])\r\n } finally {\r\n setIsLoadingData(false)\r\n }\r\n }\r\n\r\n if (isExpanded) {\r\n fetchCSVData()\r\n }\r\n }, [dataPath, isExpanded])\r\n\r\n const chartConfig = {\r\n value: {\r\n label: typeName,\r\n color: \"hsl(var(--chart-1))\",\r\n },\r\n } satisfies ChartConfig\r\n\r\n const user = useSession().data?.user\r\n\r\n const indentClass = depth > 0 ? `ml-${Math.min(depth * 4, 12)}` : ''\r\n\r\n const { user: author } = useUser(String(sensor.authorId))\r\n const authorName: string | undefined = author?.name ?? 'Unknown User'\r\n\r\n const { sensor: sensorHooks } = useCoreHooks()\r\n const { updateSensor } = sensorHooks.useSensor(sensor.id)\r\n\r\n const handleAddTag = async (tag: string) => {\r\n const currentTags = sensor.tags ?? []\r\n await updateSensor({ tags: [...currentTags, tag] })\r\n }\r\n\r\n const handleDeleteTag = async (tag: string) => {\r\n const currentTags = sensor.tags ?? []\r\n await updateSensor({ tags: currentTags.filter(t => t !== tag) })\r\n }\r\n\r\n return (\r\n <div\r\n className={cn(\r\n \"border rounded-md overflow-hidden transition-opacity\",\r\n indentClass,\r\n !isVisible && \"opacity-70\"\r\n )}\r\n onMouseEnter={onMouseEnter}\r\n onMouseLeave={onMouseLeave}\r\n >\r\n {/* Sensor Header */}\r\n <div className=\"flex items-start justify-between p-3 hover:bg-accent/50 transition-colors\">\r\n <div className=\"flex items-start gap-3 flex-1 min-w-0\">\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n className={cn(\"h-6 w-6 p-0 mt-1\", !isVisible && \"opacity-70\")}\r\n onClick={() => setIsExpanded(!isExpanded)}\r\n >\r\n <LR.ChevronRight\r\n className={cn(\r\n \"h-4 w-4 transition-transform\",\r\n isExpanded && \"rotate-90\"\r\n )}\r\n />\r\n </Button>\r\n\r\n <div className={cn(\r\n \"h-8 w-8 mt-1 rounded-full bg-primary flex items-center justify-center flex-shrink-0\",\r\n !isVisible && \"opacity-70 grayscale\"\r\n )}>\r\n <SensorIcon className={cn(\"h-4 w-4 text-primary-foreground\", !isVisible && \"opacity-70\")} />\r\n </div>\r\n\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"flex items-center gap-2\">\r\n <span className={cn(\"text-sm font-medium\", isVisible ? \"text-foreground\" : \"text-muted-foreground\")}>\r\n {sensor.name}\r\n </span>\r\n {sensor.updatedAt !== sensor.createdAt && (\r\n <Badge variant=\"outline\" className=\"text-xs\">\r\n {t('edited')}\r\n </Badge>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Action Buttons */}\r\n {onAction && (\r\n <div className={cn(\"flex items-center gap-0 flex-shrink-0\", !isVisible && \"opacity-70\")}>\r\n {user?.id === String(sensor.authorId) && (\r\n <>\r\n <Button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n className=\"h-8 w-8 p-0\"\r\n onClick={() => onAction('edit', sensor.id)}\r\n title={t('editSensor')}\r\n >\r\n <LR.Pencil className=\"h-4 w-4\" />\r\n </Button>\r\n <Button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n className=\"h-8 w-8 p-0\"\r\n onClick={() => onAction('delete', sensor.id)}\r\n title={t('deleteSensor')}\r\n >\r\n <LR.Trash2 className=\"h-4 w-4\" />\r\n </Button>\r\n </>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Expanded Content */ }\r\n {\r\n isExpanded && (\r\n <div className=\"border-t bg-muted/30\">\r\n <div className=\"p-4 space-y-4\">\r\n {/* Sensor Information */}\r\n <div className=\"space-y-2\">\r\n <div className=\"flex items-center justify-between\">\r\n <span className=\"text-xs text-muted-foreground\">\r\n {format(new Date(sensor.createdAt), 'PPp')}\r\n </span>\r\n <Badge variant=\"secondary\" className=\"text-xs\">\r\n {typeName}\r\n </Badge>\r\n </div>\r\n\r\n <div className=\"grid grid-cols-2 gap-2 text-sm\">\r\n <div>\r\n <span className=\"text-muted-foreground\">Name:</span>\r\n <span className=\"ml-2 font-medium\">{sensor.name}</span>\r\n </div>\r\n <div>\r\n <span className=\"text-muted-foreground\">Format:</span>\r\n <span className=\"ml-2 font-medium\">{sensor.dataFormat}</span>\r\n </div>\r\n </div>\r\n\r\n {/* Author Information */}\r\n <div className=\"flex items-center gap-2 pt-2\">\r\n <span className=\"text-muted-foreground text-sm\">Author:</span>\r\n <Avatar className=\"h-5 w-5 rounded-full overflow-hidden\">\r\n <UserAvatar imageFileId={author?.imageFileId} name={authorName} />\r\n </Avatar>\r\n <span className=\"text-sm font-medium\">{authorName}</span>\r\n </div>\r\n </div>\r\n\r\n {/* Sensor Data Chart */}\r\n <SensorChart\r\n sensorData={sensorData}\r\n isLoadingData={isLoadingData}\r\n sensorName={sensor.name}\r\n sensorType={sensorType}\r\n updateFrequency={sensor.updateFrequency}\r\n chartConfig={chartConfig}\r\n />\r\n </div>\r\n <div>\r\n <SensorTagsSection\r\n tags={sensor.tags ?? []}\r\n onAdd={handleAddTag}\r\n onDelete={handleDeleteTag}\r\n translations={{\r\n addTag: t('addTag'),\r\n removeTag: t('removeTag'),\r\n cancel: t('cancel'),\r\n newTagPlaceholder: t('newTagPlaceholder'),\r\n }}\r\n />\r\n </div>\r\n\r\n </div>\r\n )\r\n }\r\n </div >\r\n )\r\n}\r\n"],"mappings":"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","names":["_a","t"]}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/core/components/ui/Sensors/CollapsibleSensorItem.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 { useSession } from 'next-auth/react'\r\nimport { useTranslations } from 'next-intl'\r\nimport * as React from 'react'\r\n\r\nimport { useCoreHooks } from '../../../hooks/provider'\r\nimport { useUser } from '../../../hooks/users/users'\r\nimport { AppConfigContext } from '../../../store'\r\nimport { formatInZone } from '../../../utils/timeUtils'\r\nimport { cn } from '../../../utils/utils'\r\nimport { Avatar, AvatarFallback } from '../Avatar'\r\nimport { Badge } from '../Badge'\r\nimport { Button } from '../Button'\r\nimport { CommentActionButtons } from '../Comments/CommentActionButtons'\r\nimport { UserAvatar } from '../UserAvatar'\r\n\r\nimport { SensorChart } from './SensorChart'\r\nimport { SensorDetailDialog } from './SensorDetailDialog'\r\nimport { SensorTagsSection } from './SensorTagsSection'\r\nimport { resolveLucideIcon } from './sensorUtils'\r\nimport { useSensorSeries } from './useSensorSeries'\r\n\r\nimport type { Sensor, SensorType } from '../../../types/dbTypes'\r\nimport type { ChartConfig } from '../chart'\r\n\r\ntype SensorAction = 'view' | 'edit' | 'delete' | 'reply'\r\n\r\ninterface CollapsibleSensorItemProps {\r\n sensor: Sensor\r\n sensorType: SensorType\r\n onAction?: (action: SensorAction, id: number) => void\r\n depth?: number\r\n isVisible?: boolean\r\n onMouseEnter?: () => void\r\n onMouseLeave?: () => void\r\n}\r\n\r\nexport function CollapsibleSensorItem({\r\n sensor,\r\n sensorType,\r\n onAction,\r\n depth = 0,\r\n isVisible = true,\r\n onMouseEnter,\r\n onMouseLeave,\r\n}: CollapsibleSensorItemProps) {\r\n const t = useTranslations('SensorsSection')\r\n const [isExpanded, setIsExpanded] = React.useState(false)\r\n const { state: appConfigState } = React.useContext(AppConfigContext)\r\n const timeZone = appConfigState.appConfig.displayTimeZone\r\n const [detailOpen, setDetailOpen] = React.useState(false)\r\n const [tagAddNonce, setTagAddNonce] = React.useState(0)\r\n const { points: sensorData, unit, valueLabels, isLoading: isLoadingData } =\r\n useSensorSeries(sensor.url ?? '', sensor.dataFormat, sensor.updateFrequency, { enabled: isExpanded })\r\n const prevVisibleRef = React.useRef(isVisible)\r\n\r\n const typeName = sensorType?.name.replace(/_/g, ' ') ?? 'Unknown'\r\n\r\n const SensorIcon = resolveLucideIcon(sensorType?.icon)\r\n\r\n // Auto-collapse when visibility turns off\r\n React.useEffect(() => {\r\n const prevVisible = prevVisibleRef.current\r\n\r\n if (prevVisible && !isVisible) {\r\n // Just turned invisible - collapse\r\n setIsExpanded(false)\r\n }\r\n\r\n prevVisibleRef.current = isVisible\r\n }, [isVisible])\r\n\r\n const chartConfig = {\r\n value: {\r\n label: typeName,\r\n color: \"hsl(var(--chart-1))\",\r\n },\r\n } satisfies ChartConfig\r\n\r\n const user = useSession().data?.user\r\n\r\n const indentClass = depth > 0 ? `ml-${Math.min(depth * 4, 12)}` : ''\r\n\r\n const { user: author } = useUser(String(sensor.authorId))\r\n const authorName: string | undefined = author?.name ?? 'Unknown User'\r\n\r\n const { sensor: sensorHooks } = useCoreHooks()\r\n const { updateSensor } = sensorHooks.useSensor(sensor.id)\r\n\r\n const handleAddTag = async (tag: string) => {\r\n const currentTags = sensor.tags ?? []\r\n await updateSensor({ tags: [...currentTags, tag] })\r\n }\r\n\r\n const handleDeleteTag = async (tag: string) => {\r\n const currentTags = sensor.tags ?? []\r\n await updateSensor({ tags: currentTags.filter(t => t !== tag) })\r\n }\r\n\r\n return (\r\n <div\r\n className={cn(\r\n \"border rounded-md overflow-hidden transition-opacity\",\r\n indentClass,\r\n !isVisible && \"opacity-70\"\r\n )}\r\n onMouseEnter={onMouseEnter}\r\n onMouseLeave={onMouseLeave}\r\n >\r\n {/* Sensor Header */}\r\n <div className=\"flex items-start justify-between p-3 hover:bg-accent/50 transition-colors\">\r\n <div className=\"flex items-start gap-3 flex-1 min-w-0\">\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n className={cn(\"h-6 w-6 p-0 mt-1\", !isVisible && \"opacity-70\")}\r\n onClick={() => setIsExpanded(!isExpanded)}\r\n >\r\n <LR.ChevronRight\r\n className={cn(\r\n \"h-4 w-4 transition-transform\",\r\n isExpanded && \"rotate-90\"\r\n )}\r\n />\r\n </Button>\r\n\r\n <div className={cn(\r\n \"h-8 w-8 mt-1 rounded-full bg-primary flex items-center justify-center flex-shrink-0\",\r\n !isVisible && \"opacity-70 grayscale\"\r\n )}>\r\n <SensorIcon className={cn(\"h-4 w-4 text-primary-foreground\", !isVisible && \"opacity-70\")} />\r\n </div>\r\n\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"flex items-center gap-2\">\r\n <span className={cn(\"text-sm font-medium\", isVisible ? \"text-foreground\" : \"text-muted-foreground\")}>\r\n {sensor.name}\r\n </span>\r\n {sensor.updatedAt !== sensor.createdAt && (\r\n <Badge variant=\"outline\" className=\"text-xs\">\r\n {t('edited')}\r\n </Badge>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Expanded Content */ }\r\n {\r\n isExpanded && (\r\n <div className=\"border-t bg-muted/30\">\r\n <div className=\"p-4 space-y-4\">\r\n {/* Sensor Information */}\r\n <div className=\"space-y-2\">\r\n <div className=\"flex items-center justify-between\">\r\n <span className=\"text-xs text-muted-foreground\">\r\n {formatInZone(new Date(sensor.createdAt).getTime(), timeZone, { dateStyle: 'medium', timeStyle: 'short' })}\r\n </span>\r\n <Badge variant=\"secondary\" className=\"text-xs\">\r\n {typeName}\r\n </Badge>\r\n </div>\r\n\r\n <div className=\"grid grid-cols-2 gap-2 text-sm\">\r\n <div>\r\n <span className=\"text-muted-foreground\">Name:</span>\r\n <span className=\"ml-2 font-medium\">{sensor.name}</span>\r\n </div>\r\n <div>\r\n <span className=\"text-muted-foreground\">Format:</span>\r\n <span className=\"ml-2 font-medium\">{sensor.dataFormat}</span>\r\n </div>\r\n </div>\r\n\r\n {/* Author Information */}\r\n <div className=\"flex items-center gap-2 pt-2\">\r\n <span className=\"text-muted-foreground text-sm\">Author:</span>\r\n <Avatar className=\"h-5 w-5 rounded-full overflow-hidden\">\r\n <UserAvatar imageFileId={author?.imageFileId} name={authorName} />\r\n </Avatar>\r\n <span className=\"text-sm font-medium\">{authorName}</span>\r\n </div>\r\n </div>\r\n\r\n {/* Sensor Data Chart */}\r\n <SensorChart\r\n sensorData={sensorData}\r\n isLoadingData={isLoadingData}\r\n sensorName={sensor.name}\r\n sensorType={sensorType}\r\n updateFrequency={sensor.updateFrequency}\r\n chartConfig={chartConfig}\r\n unit={unit}\r\n valueLabels={valueLabels}\r\n timeZone={timeZone}\r\n />\r\n </div>\r\n <div>\r\n <SensorTagsSection\r\n tags={sensor.tags ?? []}\r\n onAdd={handleAddTag}\r\n onDelete={handleDeleteTag}\r\n openAddSignal={tagAddNonce}\r\n translations={{\r\n addTag: t('addTag'),\r\n removeTag: t('removeTag'),\r\n cancel: t('cancel'),\r\n newTagPlaceholder: t('newTagPlaceholder'),\r\n }}\r\n />\r\n </div>\r\n\r\n </div>\r\n )\r\n }\r\n {/* Card tools row (bottom), mirroring the comment card */}\r\n <div className={cn(\"flex items-center justify-end gap-0 border-t px-2 py-1\", !isVisible && \"opacity-70\")}>\r\n <CommentActionButtons\r\n onExpand={() => setDetailOpen(true)}\r\n onTag={() => { setIsExpanded(true); setTagAddNonce(n => n + 1) }}\r\n onEdit={onAction && user?.id === String(sensor.authorId) ? () => onAction('edit', sensor.id) : undefined}\r\n onDelete={onAction && user?.id === String(sensor.authorId) ? () => onAction('delete', sensor.id) : undefined}\r\n buttonClassName=\"h-8 w-8\"\r\n labels={{ expand: t('expandSensor'), tag: t('addTag'), edit: t('editSensor'), delete: t('deleteSensor') }}\r\n />\r\n </div>\r\n <SensorDetailDialog open={detailOpen} onOpenChange={setDetailOpen} sensor={sensor} sensorType={sensorType} />\r\n </div >\r\n )\r\n}\r\n"],"mappings":";AA2HY,cAgBA,YAhBA;AAtHZ,YAAY,QAAQ;AACpB,SAAS,kBAAkB;AAC3B,SAAS,uBAAuB;AAChC,YAAY,WAAW;AAEvB,SAAS,oBAAoB;AAC7B,SAAS,eAAe;AACxB,SAAS,wBAAwB;AACjC,SAAS,oBAAoB;AAC7B,SAAS,UAAU;AACnB,SAAS,cAA8B;AACvC,SAAS,aAAa;AACtB,SAAS,cAAc;AACvB,SAAS,4BAA4B;AACrC,SAAS,kBAAkB;AAE3B,SAAS,mBAAmB;AAC5B,SAAS,0BAA0B;AACnC,SAAS,yBAAyB;AAClC,SAAS,yBAAyB;AAClC,SAAS,uBAAuB;AAiBzB,SAAS,sBAAsB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ;AAAA,EACA;AACF,GAA+B;AAlD/B;AAmDE,QAAM,IAAI,gBAAgB,gBAAgB;AAC1C,QAAM,CAAC,YAAY,aAAa,IAAI,MAAM,SAAS,KAAK;AACxD,QAAM,EAAE,OAAO,eAAe,IAAI,MAAM,WAAW,gBAAgB;AACnE,QAAM,WAAW,eAAe,UAAU;AAC1C,QAAM,CAAC,YAAY,aAAa,IAAI,MAAM,SAAS,KAAK;AACxD,QAAM,CAAC,aAAa,cAAc,IAAI,MAAM,SAAS,CAAC;AACtD,QAAM,EAAE,QAAQ,YAAY,MAAM,aAAa,WAAW,cAAc,IACtE,iBAAgB,YAAO,QAAP,YAAc,IAAI,OAAO,YAAY,OAAO,iBAAiB,EAAE,SAAS,WAAW,CAAC;AACtG,QAAM,iBAAiB,MAAM,OAAO,SAAS;AAE7C,QAAM,YAAW,8CAAY,KAAK,QAAQ,MAAM,SAA/B,YAAuC;AAExD,QAAM,aAAa,kBAAkB,yCAAY,IAAI;AAGrD,QAAM,UAAU,MAAM;AACpB,UAAM,cAAc,eAAe;AAEnC,QAAI,eAAe,CAAC,WAAW;AAE7B,oBAAc,KAAK;AAAA,IACrB;AAEA,mBAAe,UAAU;AAAA,EAC3B,GAAG,CAAC,SAAS,CAAC;AAEd,QAAM,cAAc;AAAA,IAClB,OAAO;AAAA,MACL,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,QAAO,gBAAW,EAAE,SAAb,mBAAmB;AAEhC,QAAM,cAAc,QAAQ,IAAI,MAAM,KAAK,IAAI,QAAQ,GAAG,EAAE,CAAC,KAAK;AAElE,QAAM,EAAE,MAAM,OAAO,IAAI,QAAQ,OAAO,OAAO,QAAQ,CAAC;AACxD,QAAM,cAAiC,sCAAQ,SAAR,YAAgB;AAEvD,QAAM,EAAE,QAAQ,YAAY,IAAI,aAAa;AAC7C,QAAM,EAAE,aAAa,IAAI,YAAY,UAAU,OAAO,EAAE;AAExD,QAAM,eAAe,OAAO,QAAgB;AA9F9C,QAAAA;AA+FI,UAAM,eAAcA,MAAA,OAAO,SAAP,OAAAA,MAAe,CAAC;AACpC,UAAM,aAAa,EAAE,MAAM,CAAC,GAAG,aAAa,GAAG,EAAE,CAAC;AAAA,EACpD;AAEA,QAAM,kBAAkB,OAAO,QAAgB;AAnGjD,QAAAA;AAoGI,UAAM,eAAcA,MAAA,OAAO,SAAP,OAAAA,MAAe,CAAC;AACpC,UAAM,aAAa,EAAE,MAAM,YAAY,OAAO,CAAAC,OAAKA,OAAM,GAAG,EAAE,CAAC;AAAA,EACjE;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA,CAAC,aAAa;AAAA,MAChB;AAAA,MACA;AAAA,MACA;AAAA,MAGA;AAAA,4BAAC,SAAI,WAAU,6EACb,+BAAC,SAAI,WAAU,yCACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,WAAW,GAAG,oBAAoB,CAAC,aAAa,YAAY;AAAA,cAC5D,SAAS,MAAM,cAAc,CAAC,UAAU;AAAA,cAExC;AAAA,gBAAC,GAAG;AAAA,gBAAH;AAAA,kBACC,WAAW;AAAA,oBACT;AAAA,oBACA,cAAc;AAAA,kBAChB;AAAA;AAAA,cACF;AAAA;AAAA,UACF;AAAA,UAEA,oBAAC,SAAI,WAAW;AAAA,YACd;AAAA,YACA,CAAC,aAAa;AAAA,UAChB,GACE,8BAAC,cAAW,WAAW,GAAG,mCAAmC,CAAC,aAAa,YAAY,GAAG,GAC5F;AAAA,UAEA,oBAAC,SAAI,WAAU,kBACb,+BAAC,SAAI,WAAU,2BACX;AAAA,gCAAC,UAAK,WAAW,GAAG,uBAAuB,YAAY,oBAAoB,uBAAuB,GACjG,iBAAO,MACV;AAAA,YACC,OAAO,cAAc,OAAO,aAC3B,oBAAC,SAAM,SAAQ,WAAU,WAAU,WAChC,YAAE,QAAQ,GACb;AAAA,aAEJ,GACF;AAAA,WACF,GACJ;AAAA,QAIA,cACE,qBAAC,SAAI,WAAU,wBACb;AAAA,+BAAC,SAAI,WAAU,iBAEb;AAAA,iCAAC,SAAI,WAAU,aACb;AAAA,mCAAC,SAAI,WAAU,qCACb;AAAA,oCAAC,UAAK,WAAU,iCACb,uBAAa,IAAI,KAAK,OAAO,SAAS,EAAE,QAAQ,GAAG,UAAU,EAAE,WAAW,UAAU,WAAW,QAAQ,CAAC,GAC3G;AAAA,gBACA,oBAAC,SAAM,SAAQ,aAAY,WAAU,WAClC,oBACH;AAAA,iBACF;AAAA,cAEA,qBAAC,SAAI,WAAU,kCACb;AAAA,qCAAC,SACC;AAAA,sCAAC,UAAK,WAAU,yBAAwB,mBAAK;AAAA,kBAC7C,oBAAC,UAAK,WAAU,oBAAoB,iBAAO,MAAK;AAAA,mBAClD;AAAA,gBACA,qBAAC,SACC;AAAA,sCAAC,UAAK,WAAU,yBAAwB,qBAAO;AAAA,kBAC/C,oBAAC,UAAK,WAAU,oBAAoB,iBAAO,YAAW;AAAA,mBACxD;AAAA,iBACF;AAAA,cAGA,qBAAC,SAAI,WAAU,gCACb;AAAA,oCAAC,UAAK,WAAU,iCAAgC,qBAAO;AAAA,gBACvD,oBAAC,UAAO,WAAU,wCAChB,8BAAC,cAAW,aAAa,iCAAQ,aAAa,MAAM,YAAY,GAClE;AAAA,gBACA,oBAAC,UAAK,WAAU,uBAAuB,sBAAW;AAAA,iBACpD;AAAA,eACF;AAAA,YAGA;AAAA,cAAC;AAAA;AAAA,gBACC;AAAA,gBACA;AAAA,gBACA,YAAY,OAAO;AAAA,gBACnB;AAAA,gBACA,iBAAiB,OAAO;AAAA,gBACxB;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA;AAAA,YACF;AAAA,aACF;AAAA,UACA,oBAAC,SACG;AAAA,YAAC;AAAA;AAAA,cACC,OAAM,YAAO,SAAP,YAAe,CAAC;AAAA,cACtB,OAAO;AAAA,cACP,UAAU;AAAA,cACV,eAAe;AAAA,cACf,cAAc;AAAA,gBACZ,QAAQ,EAAE,QAAQ;AAAA,gBAClB,WAAW,EAAE,WAAW;AAAA,gBACxB,QAAQ,EAAE,QAAQ;AAAA,gBAClB,mBAAmB,EAAE,mBAAmB;AAAA,cAC1C;AAAA;AAAA,UACF,GACJ;AAAA,WAEF;AAAA,QAIA,oBAAC,SAAI,WAAW,GAAG,0DAA0D,CAAC,aAAa,YAAY,GACrG;AAAA,UAAC;AAAA;AAAA,YACC,UAAU,MAAM,cAAc,IAAI;AAAA,YAClC,OAAO,MAAM;AAAE,4BAAc,IAAI;AAAG,6BAAe,OAAK,IAAI,CAAC;AAAA,YAAE;AAAA,YAC/D,QAAQ,aAAY,6BAAM,QAAO,OAAO,OAAO,QAAQ,IAAI,MAAM,SAAS,QAAQ,OAAO,EAAE,IAAI;AAAA,YAC/F,UAAU,aAAY,6BAAM,QAAO,OAAO,OAAO,QAAQ,IAAI,MAAM,SAAS,UAAU,OAAO,EAAE,IAAI;AAAA,YACnG,iBAAgB;AAAA,YAChB,QAAQ,EAAE,QAAQ,EAAE,cAAc,GAAG,KAAK,EAAE,QAAQ,GAAG,MAAM,EAAE,YAAY,GAAG,QAAQ,EAAE,cAAc,EAAE;AAAA;AAAA,QAC1G,GACF;AAAA,QACA,oBAAC,sBAAmB,MAAM,YAAY,cAAc,eAAe,QAAgB,YAAwB;AAAA;AAAA;AAAA,EAC7G;AAEJ;","names":["_a","t"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { type CommentActionLabels } from '../Comments/CommentActionButtons';
|
|
3
3
|
import { type SensorTagsTranslations } from './SensorTagsSection';
|
|
4
|
-
import type { SensorType } from '../../../types/dbTypes';
|
|
4
|
+
import type { SensorDataFormat, SensorType } from '../../../types/dbTypes';
|
|
5
5
|
export type SensorProps = {
|
|
6
6
|
sensorName: string;
|
|
7
7
|
sensorType: SensorType;
|
|
@@ -18,10 +18,23 @@ export type SensorProps = {
|
|
|
18
18
|
createdAt: string | Date;
|
|
19
19
|
onRemove?: () => void;
|
|
20
20
|
onClose?: () => void;
|
|
21
|
+
/** Edit the sensor (used by the in-viewer BIM card action row). */
|
|
22
|
+
onEdit?: () => void;
|
|
23
|
+
/** Open the expandable detail view (wired into the shared action row). */
|
|
24
|
+
onExpand?: () => void;
|
|
25
|
+
/** Display timezone for the chart + created line. Defaults to the browser zone. */
|
|
26
|
+
timeZone?: string;
|
|
21
27
|
enableCollapse?: boolean;
|
|
22
28
|
defaultCollapsed?: boolean;
|
|
23
29
|
size?: 'sm' | 'md' | 'lg';
|
|
24
30
|
highlight?: boolean;
|
|
31
|
+
/** Double-clicked/zoomed sensor: reserved for the focus ring, mirrors Comment's `focused`. */
|
|
32
|
+
focused?: boolean;
|
|
33
|
+
/** Render the close/edit/delete action row (used by the in-viewer BIM card). */
|
|
34
|
+
showActions?: boolean;
|
|
35
|
+
canEdit?: boolean;
|
|
36
|
+
canDelete?: boolean;
|
|
37
|
+
actionLabels?: CommentActionLabels;
|
|
25
38
|
};
|
|
26
|
-
export default function Sensor({ sensorName, sensorType, dataUrl, dataFormat, updateFrequency, createdAt, onRemove, onClose, enableCollapse, defaultCollapsed, size, highlight, sensorId, tags, tagsVariant, tagsTranslations, onAddTag, onDeleteTag, }: SensorProps): React.JSX.Element;
|
|
39
|
+
export default function Sensor({ sensorName, sensorType, dataUrl, dataFormat, updateFrequency, createdAt, onRemove, onClose, onEdit, onExpand, enableCollapse, defaultCollapsed, size, highlight, focused, showActions, canEdit, canDelete, actionLabels, sensorId, tags, tagsVariant, tagsTranslations, onAddTag, onDeleteTag, timeZone, }: SensorProps): React.JSX.Element;
|
|
27
40
|
//# sourceMappingURL=Sensor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Sensor.d.ts","sourceRoot":"","sources":["../../../../../src/core/components/ui/Sensors/Sensor.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"Sensor.d.ts","sourceRoot":"","sources":["../../../../../src/core/components/ui/Sensors/Sensor.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAM9B,OAAO,EAAwB,KAAK,mBAAmB,EAAE,MAAM,kCAAkC,CAAA;AAGjG,OAAO,EAAqB,KAAK,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AAGpF,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAG3E,MAAM,MAAM,WAAW,GAAG;IACxB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,UAAU,CAAA;IACtB,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,gBAAgB,GAAG,GAAG,gBAAgB,EAAE,CAAA;IACpD,eAAe,EAAE,MAAM,CAAA;IACvB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,GAAG,WAAW,CAAA;IAClC,gBAAgB,CAAC,EAAE,sBAAsB,CAAA;IACzC,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACzC,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5C,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,mEAAmE;IACnE,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;IACnB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,mFAAmF;IACnF,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;IACzB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,8FAA8F;IAC9F,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,gFAAgF;IAChF,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,YAAY,CAAC,EAAE,mBAAmB,CAAA;CACnC,CAAA;AAED,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,EAC7B,UAAU,EACV,UAAU,EACV,OAAO,EACP,UAAU,EACV,eAAe,EACf,SAAS,EACT,QAAQ,EACR,OAAO,EACP,MAAM,EACN,QAAQ,EACR,cAAsB,EACtB,gBAAwB,EACxB,IAAW,EACX,SAAiB,EACjB,OAAe,EACf,WAAmB,EACnB,OAAc,EACd,SAAgB,EAChB,YAAY,EACZ,QAAQ,EACR,IAAS,EACT,WAAoB,EACpB,gBAAgB,EAChB,QAAQ,EACR,WAAW,EACX,QAA2B,GAC5B,EAAE,WAAW,qBAsMb"}
|
|
@@ -1,13 +1,33 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __defProps = Object.defineProperties;
|
|
4
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
5
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
8
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
9
|
+
var __spreadValues = (a, b) => {
|
|
10
|
+
for (var prop in b || (b = {}))
|
|
11
|
+
if (__hasOwnProp.call(b, prop))
|
|
12
|
+
__defNormalProp(a, prop, b[prop]);
|
|
13
|
+
if (__getOwnPropSymbols)
|
|
14
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
15
|
+
if (__propIsEnum.call(b, prop))
|
|
16
|
+
__defNormalProp(a, prop, b[prop]);
|
|
17
|
+
}
|
|
18
|
+
return a;
|
|
19
|
+
};
|
|
20
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
2
21
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
22
|
import * as LR from "lucide-react";
|
|
4
23
|
import * as React from "react";
|
|
5
|
-
import {
|
|
6
|
-
import { formatTimestamp } from "../../../utils/timeUtils";
|
|
24
|
+
import { formatTimestamp, detectTimeZone } from "../../../utils/timeUtils";
|
|
7
25
|
import { Button } from "../Button";
|
|
8
26
|
import { Card } from "../Card";
|
|
27
|
+
import { CommentActionButtons } from "../Comments/CommentActionButtons";
|
|
9
28
|
import { SensorChart } from "./SensorChart";
|
|
10
29
|
import { SensorTagsSection } from "./SensorTagsSection";
|
|
30
|
+
import { useSensorSeries } from "./useSensorSeries";
|
|
11
31
|
function Sensor({
|
|
12
32
|
sensorName,
|
|
13
33
|
sensorType,
|
|
@@ -17,51 +37,31 @@ function Sensor({
|
|
|
17
37
|
createdAt,
|
|
18
38
|
onRemove,
|
|
19
39
|
onClose,
|
|
40
|
+
onEdit,
|
|
41
|
+
onExpand,
|
|
20
42
|
enableCollapse = false,
|
|
21
43
|
defaultCollapsed = false,
|
|
22
44
|
size = "md",
|
|
23
45
|
highlight = false,
|
|
46
|
+
focused = false,
|
|
47
|
+
showActions = false,
|
|
48
|
+
canEdit = true,
|
|
49
|
+
canDelete = true,
|
|
50
|
+
actionLabels,
|
|
24
51
|
sensorId,
|
|
25
52
|
tags = [],
|
|
26
53
|
tagsVariant = "edit",
|
|
27
54
|
tagsTranslations,
|
|
28
55
|
onAddTag,
|
|
29
|
-
onDeleteTag
|
|
56
|
+
onDeleteTag,
|
|
57
|
+
timeZone = detectTimeZone()
|
|
30
58
|
}) {
|
|
31
|
-
var _a;
|
|
59
|
+
var _a, _b, _c;
|
|
32
60
|
const [isCollapsed, setIsCollapsed] = React.useState(defaultCollapsed);
|
|
33
|
-
const
|
|
34
|
-
const [isLoadingData, setIsLoadingData] = React.useState(false);
|
|
61
|
+
const { points: sensorData, unit, valueLabels, isLoading: isLoadingData } = useSensorSeries(dataUrl, dataFormat, updateFrequency, { enabled: !(enableCollapse && isCollapsed) });
|
|
35
62
|
const lastTap = React.useRef(0);
|
|
36
63
|
const sensorTypeNameFormatted = ((_a = sensorType == null ? void 0 : sensorType.name) == null ? void 0 : _a.replace(/_/g, " ")) || "Other";
|
|
37
64
|
const SensorIcon = LR[sensorType == null ? void 0 : sensorType.icon] || LR.Radio;
|
|
38
|
-
React.useEffect(() => {
|
|
39
|
-
const fetchData = async () => {
|
|
40
|
-
if (!dataUrl || dataFormat !== SensorDataFormat.Csv) {
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
setIsLoadingData(true);
|
|
44
|
-
try {
|
|
45
|
-
const response = await fetch(dataUrl);
|
|
46
|
-
const text = await response.text();
|
|
47
|
-
const lines = text.trim().split("\n");
|
|
48
|
-
const data = lines.map((line) => {
|
|
49
|
-
const [time, value] = line.split(",");
|
|
50
|
-
return {
|
|
51
|
-
time: time.trim(),
|
|
52
|
-
value: parseFloat(value)
|
|
53
|
-
};
|
|
54
|
-
});
|
|
55
|
-
setSensorData(data);
|
|
56
|
-
} catch (error) {
|
|
57
|
-
console.error("Failed to fetch sensor data:", error);
|
|
58
|
-
setSensorData([]);
|
|
59
|
-
} finally {
|
|
60
|
-
setIsLoadingData(false);
|
|
61
|
-
}
|
|
62
|
-
};
|
|
63
|
-
fetchData();
|
|
64
|
-
}, [dataUrl, dataFormat]);
|
|
65
65
|
const chartConfig = {
|
|
66
66
|
value: {
|
|
67
67
|
label: "Value",
|
|
@@ -120,6 +120,10 @@ function Sensor({
|
|
|
120
120
|
if (now - lastTap.current < 300) setIsCollapsed((v) => !v);
|
|
121
121
|
lastTap.current = now;
|
|
122
122
|
};
|
|
123
|
+
const handleClose = () => {
|
|
124
|
+
if (enableCollapse) setIsCollapsed(true);
|
|
125
|
+
else onClose == null ? void 0 : onClose();
|
|
126
|
+
};
|
|
123
127
|
if (enableCollapse && isCollapsed) {
|
|
124
128
|
return /* @__PURE__ */ jsx(
|
|
125
129
|
"div",
|
|
@@ -152,7 +156,26 @@ function Sensor({
|
|
|
152
156
|
/* @__PURE__ */ jsx("span", { className: `font-semibold ${currentSize.titleSize} text-foreground leading-none truncate`, children: sensorName }),
|
|
153
157
|
/* @__PURE__ */ jsx("span", { className: `${currentSize.subtitleSize} text-muted-foreground leading-none`, children: sensorTypeNameFormatted })
|
|
154
158
|
] }),
|
|
155
|
-
|
|
159
|
+
showActions && /* @__PURE__ */ jsx(
|
|
160
|
+
Button,
|
|
161
|
+
__spreadProps(__spreadValues({
|
|
162
|
+
type: "button",
|
|
163
|
+
variant: "ghost",
|
|
164
|
+
size: "icon",
|
|
165
|
+
title: (_b = actionLabels == null ? void 0 : actionLabels.close) != null ? _b : "Close",
|
|
166
|
+
"aria-label": (_c = actionLabels == null ? void 0 : actionLabels.close) != null ? _c : "Close",
|
|
167
|
+
className: `z-50 ${currentSize.buttonSize} shrink-0 -mr-1 -mt-1`
|
|
168
|
+
}, enableCollapse ? { onPointerDown: (e) => {
|
|
169
|
+
e.stopPropagation();
|
|
170
|
+
handleClose();
|
|
171
|
+
} } : { onClick: (e) => {
|
|
172
|
+
e.stopPropagation();
|
|
173
|
+
handleClose();
|
|
174
|
+
} }), {
|
|
175
|
+
children: /* @__PURE__ */ jsx(LR.X, { className: currentSize.buttonIconSize })
|
|
176
|
+
})
|
|
177
|
+
),
|
|
178
|
+
!showActions && onRemove && /* @__PURE__ */ jsx(
|
|
156
179
|
Button,
|
|
157
180
|
{
|
|
158
181
|
type: "button",
|
|
@@ -171,7 +194,7 @@ function Sensor({
|
|
|
171
194
|
] }),
|
|
172
195
|
/* @__PURE__ */ jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxs("span", { className: `${currentSize.metaSize} text-muted-foreground`, children: [
|
|
173
196
|
"Created ",
|
|
174
|
-
formatTimestamp(createdAt)
|
|
197
|
+
formatTimestamp(createdAt, timeZone)
|
|
175
198
|
] }) }),
|
|
176
199
|
/* @__PURE__ */ jsx(
|
|
177
200
|
SensorChart,
|
|
@@ -182,7 +205,10 @@ function Sensor({
|
|
|
182
205
|
sensorType,
|
|
183
206
|
updateFrequency,
|
|
184
207
|
chartConfig,
|
|
185
|
-
size
|
|
208
|
+
size,
|
|
209
|
+
unit,
|
|
210
|
+
valueLabels,
|
|
211
|
+
timeZone
|
|
186
212
|
}
|
|
187
213
|
),
|
|
188
214
|
/* @__PURE__ */ jsx(
|
|
@@ -194,7 +220,20 @@ function Sensor({
|
|
|
194
220
|
onDelete: onDeleteTag,
|
|
195
221
|
translations: tagsTranslations
|
|
196
222
|
}
|
|
197
|
-
)
|
|
223
|
+
),
|
|
224
|
+
showActions && (onEdit || onRemove || onExpand) && /* @__PURE__ */ jsx("div", { className: "mt-2 flex justify-end border-t pt-1", children: /* @__PURE__ */ jsx(
|
|
225
|
+
CommentActionButtons,
|
|
226
|
+
{
|
|
227
|
+
onExpand,
|
|
228
|
+
onEdit: canEdit ? onEdit : void 0,
|
|
229
|
+
onDelete: canDelete ? onRemove : void 0,
|
|
230
|
+
canEdit,
|
|
231
|
+
canDelete,
|
|
232
|
+
activateOnPointerDown: enableCollapse,
|
|
233
|
+
buttonClassName: "h-7 w-7",
|
|
234
|
+
labels: { edit: actionLabels == null ? void 0 : actionLabels.edit, delete: actionLabels == null ? void 0 : actionLabels.delete, close: actionLabels == null ? void 0 : actionLabels.close, expand: actionLabels == null ? void 0 : actionLabels.expand }
|
|
235
|
+
}
|
|
236
|
+
) })
|
|
198
237
|
] })
|
|
199
238
|
}
|
|
200
239
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/core/components/ui/Sensors/Sensor.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\n\r\nimport { SensorDataFormat } from '../../../types/dbTypes'\r\nimport { formatTimestamp } from '../../../utils/timeUtils'\r\nimport { Button } from '../Button'\r\nimport { Card } from '../Card'\r\n\r\nimport { SensorChart } from './SensorChart'\r\nimport { SensorTagsSection, type SensorTagsTranslations } from './SensorTagsSection'\r\n\r\nimport type { SensorType } from '../../../types/dbTypes';\r\nimport type { ChartConfig } from '../chart'\r\n\r\nexport type SensorProps = {\r\n sensorName: string\r\n sensorType: SensorType\r\n dataUrl: string\r\n dataFormat: SensorDataFormat | `${SensorDataFormat}`\r\n updateFrequency: number\r\n buildingId?: number\r\n sensorId?: number\r\n tags?: string[]\r\n tagsVariant?: 'edit' | 'read-only'\r\n tagsTranslations?: SensorTagsTranslations\r\n onAddTag?: (tag: string) => Promise<void>\r\n onDeleteTag?: (tag: string) => Promise<void>\r\n createdAt: string | Date\r\n onRemove?: () => void\r\n onClose?: () => void\r\n enableCollapse?: boolean\r\n defaultCollapsed?: boolean\r\n size?: 'sm' | 'md' | 'lg'\r\n highlight?: boolean\r\n}\r\n\r\nexport default function Sensor({\r\n sensorName,\r\n sensorType,\r\n dataUrl,\r\n dataFormat,\r\n updateFrequency,\r\n createdAt,\r\n onRemove,\r\n onClose,\r\n enableCollapse = false,\r\n defaultCollapsed = false,\r\n size = 'md',\r\n highlight = false,\r\n sensorId,\r\n tags = [],\r\n tagsVariant = 'edit',\r\n tagsTranslations,\r\n onAddTag,\r\n onDeleteTag,\r\n}: SensorProps) {\r\n const [isCollapsed, setIsCollapsed] = React.useState(defaultCollapsed)\r\n const [sensorData, setSensorData] = React.useState<{ time: string; value: number }[]>([])\r\n const [isLoadingData, setIsLoadingData] = React.useState(false)\r\n const lastTap = React.useRef(0)\r\n\r\n const sensorTypeNameFormatted = sensorType?.name?.replace(/_/g, ' ') || 'Other'\r\n const SensorIcon = LR[sensorType?.icon] || LR.Radio\r\n\r\n // Fetch sensor data\r\n React.useEffect(() => {\r\n const fetchData = async () => {\r\n if (!dataUrl || dataFormat !== SensorDataFormat.Csv) {\r\n return\r\n }\r\n\r\n setIsLoadingData(true)\r\n try {\r\n const response = await fetch(dataUrl)\r\n const text = await response.text()\r\n\r\n const lines = text.trim().split('\\n')\r\n const data = lines.map((line) => {\r\n const [time, value] = line.split(',')\r\n return {\r\n time: time.trim(),\r\n value: parseFloat(value),\r\n }\r\n })\r\n\r\n setSensorData(data)\r\n } catch (error) {\r\n console.error('Failed to fetch sensor data:', error)\r\n setSensorData([])\r\n } finally {\r\n setIsLoadingData(false)\r\n }\r\n }\r\n\r\n fetchData()\r\n }, [dataUrl, dataFormat])\r\n\r\n const chartConfig: ChartConfig = {\r\n value: {\r\n label: 'Value',\r\n color: 'hsl(var(--chart-1))',\r\n },\r\n }\r\n\r\n const sizeStyles = {\r\n sm: {\r\n cardWidth: 'w-[280px]',\r\n cardPadding: 'px-2 py-2',\r\n iconSize: 'h-7 w-7',\r\n iconInnerSize: 'h-4 w-4',\r\n titleSize: 'text-xs',\r\n subtitleSize: 'text-[10px]',\r\n metaSize: 'text-[10px]',\r\n buttonSize: 'h-6 w-6',\r\n buttonIconSize: 'h-3 w-3',\r\n gap: 'gap-2',\r\n collapsedIconSize: 'h-8 w-8',\r\n collapsedIconInnerSize: 'h-4 w-4',\r\n },\r\n md: {\r\n cardWidth: 'w-[410px]',\r\n cardPadding: 'px-3 py-2.5',\r\n iconSize: 'h-9 w-9',\r\n iconInnerSize: 'h-5 w-5',\r\n titleSize: 'text-sm',\r\n subtitleSize: 'text-xs',\r\n metaSize: 'text-xs',\r\n buttonSize: 'h-7 w-7',\r\n buttonIconSize: 'h-4 w-4',\r\n gap: 'gap-3',\r\n collapsedIconSize: 'h-9 w-9',\r\n collapsedIconInnerSize: 'h-5 w-5',\r\n },\r\n lg: {\r\n cardWidth: 'w-[500px]',\r\n cardPadding: 'px-4 py-3',\r\n iconSize: 'h-11 w-11',\r\n iconInnerSize: 'h-6 w-6',\r\n titleSize: 'text-base',\r\n subtitleSize: 'text-sm',\r\n metaSize: 'text-sm',\r\n buttonSize: 'h-8 w-8',\r\n buttonIconSize: 'h-5 w-5',\r\n gap: 'gap-4',\r\n collapsedIconSize: 'h-11 w-11',\r\n collapsedIconInnerSize: 'h-6 w-6',\r\n },\r\n }\r\n\r\n const currentSize = sizeStyles[size]\r\n\r\n const handlePointerDown = (e: React.PointerEvent) => {\r\n if (!enableCollapse) return\r\n e.stopPropagation()\r\n\r\n const now = performance.now()\r\n if (now - lastTap.current < 300) setIsCollapsed(v => !v)\r\n lastTap.current = now\r\n }\r\n\r\n if (enableCollapse && isCollapsed) {\r\n return (\r\n <div\r\n className={`${currentSize.collapsedIconSize} rounded-full shadow-md flex items-center justify-center flex-shrink-0 bg-primary pointer-events-auto`}\r\n onPointerDown={handlePointerDown}\r\n onDoubleClick={(e) => {\r\n e.stopPropagation()\r\n setIsCollapsed(v => !v)\r\n }}\r\n >\r\n <SensorIcon className={`${currentSize.collapsedIconInnerSize} text-primary-foreground cursor-pointer`} />\r\n </div>\r\n )\r\n }\r\n\r\n return (\r\n <div\r\n className=\"relative inline-block group pointer-events-auto\"\r\n title={enableCollapse ? 'Double click to collapse' : undefined}\r\n onPointerDown={handlePointerDown}\r\n onDoubleClick={(e) => {\r\n e.stopPropagation()\r\n if (enableCollapse) setIsCollapsed(v => !v)\r\n else onClose?.()\r\n }}\r\n >\r\n <Card className={`${currentSize.cardWidth} ${currentSize.cardPadding} shadow-md group-hover:shadow-lg transition-shadow duration-200`}>\r\n <div className={`flex items-start ${currentSize.gap}`}>\r\n <div className={`${currentSize.iconSize} rounded-full shadow-sm flex items-center justify-center select-none flex-shrink-0 bg-primary`}>\r\n <SensorIcon className={`${currentSize.iconInnerSize} text-primary-foreground`} />\r\n </div>\r\n\r\n <div className=\"flex-1 min-w-0 flex flex-col gap-1\">\r\n <span className={`font-semibold ${currentSize.titleSize} text-foreground leading-none truncate`}>\r\n {sensorName}\r\n </span>\r\n <span className={`${currentSize.subtitleSize} text-muted-foreground leading-none`}>\r\n {sensorTypeNameFormatted}\r\n </span>\r\n </div>\r\n\r\n {onRemove && (\r\n <Button\r\n type=\"button\"\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n title=\"Remove sensor\"\r\n className={`z-50 ${currentSize.buttonSize} shrink-0`}\r\n aria-label=\"Remove sensor\"\r\n onClick={(e) => {\r\n e.stopPropagation()\r\n onRemove()\r\n }}\r\n >\r\n <LR.Trash2 className={currentSize.buttonIconSize} />\r\n </Button>\r\n )}\r\n </div>\r\n\r\n <div className=\"mb-2\">\r\n <span className={`${currentSize.metaSize} text-muted-foreground`}>\r\n Created {formatTimestamp(createdAt)}\r\n </span>\r\n </div>\r\n\r\n <SensorChart\r\n sensorData={sensorData}\r\n isLoadingData={isLoadingData}\r\n sensorName={sensorName}\r\n sensorType={sensorType}\r\n updateFrequency={updateFrequency}\r\n chartConfig={chartConfig}\r\n size={size}\r\n />\r\n <SensorTagsSection\r\n tags={tags}\r\n variant={tagsVariant}\r\n onAdd={onAddTag}\r\n onDelete={onDeleteTag}\r\n translations={tagsTranslations}\r\n />\r\n </Card>\r\n </div>\r\n )\r\n}\r\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/core/components/ui/Sensors/Sensor.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\n\r\nimport { formatTimestamp, detectTimeZone } from '../../../utils/timeUtils'\r\nimport { Button } from '../Button'\r\nimport { Card } from '../Card'\r\n\r\nimport { CommentActionButtons, type CommentActionLabels } from '../Comments/CommentActionButtons'\r\n\r\nimport { SensorChart } from './SensorChart'\r\nimport { SensorTagsSection, type SensorTagsTranslations } from './SensorTagsSection'\r\nimport { useSensorSeries } from './useSensorSeries'\r\n\r\nimport type { SensorDataFormat, SensorType } from '../../../types/dbTypes';\r\nimport type { ChartConfig } from '../chart'\r\n\r\nexport type SensorProps = {\r\n sensorName: string\r\n sensorType: SensorType\r\n dataUrl: string\r\n dataFormat: SensorDataFormat | `${SensorDataFormat}`\r\n updateFrequency: number\r\n buildingId?: number\r\n sensorId?: number\r\n tags?: string[]\r\n tagsVariant?: 'edit' | 'read-only'\r\n tagsTranslations?: SensorTagsTranslations\r\n onAddTag?: (tag: string) => Promise<void>\r\n onDeleteTag?: (tag: string) => Promise<void>\r\n createdAt: string | Date\r\n onRemove?: () => void\r\n onClose?: () => void\r\n /** Edit the sensor (used by the in-viewer BIM card action row). */\r\n onEdit?: () => void\r\n /** Open the expandable detail view (wired into the shared action row). */\r\n onExpand?: () => void\r\n /** Display timezone for the chart + created line. Defaults to the browser zone. */\r\n timeZone?: string\r\n enableCollapse?: boolean\r\n defaultCollapsed?: boolean\r\n size?: 'sm' | 'md' | 'lg'\r\n highlight?: boolean\r\n /** Double-clicked/zoomed sensor: reserved for the focus ring, mirrors Comment's `focused`. */\r\n focused?: boolean\r\n /** Render the close/edit/delete action row (used by the in-viewer BIM card). */\r\n showActions?: boolean\r\n canEdit?: boolean\r\n canDelete?: boolean\r\n actionLabels?: CommentActionLabels\r\n}\r\n\r\nexport default function Sensor({\r\n sensorName,\r\n sensorType,\r\n dataUrl,\r\n dataFormat,\r\n updateFrequency,\r\n createdAt,\r\n onRemove,\r\n onClose,\r\n onEdit,\r\n onExpand,\r\n enableCollapse = false,\r\n defaultCollapsed = false,\r\n size = 'md',\r\n highlight = false,\r\n focused = false,\r\n showActions = false,\r\n canEdit = true,\r\n canDelete = true,\r\n actionLabels,\r\n sensorId,\r\n tags = [],\r\n tagsVariant = 'edit',\r\n tagsTranslations,\r\n onAddTag,\r\n onDeleteTag,\r\n timeZone = detectTimeZone(),\r\n}: SensorProps) {\r\n const [isCollapsed, setIsCollapsed] = React.useState(defaultCollapsed)\r\n const { points: sensorData, unit, valueLabels, isLoading: isLoadingData } =\r\n useSensorSeries(dataUrl, dataFormat, updateFrequency, { enabled: !(enableCollapse && isCollapsed) })\r\n const lastTap = React.useRef(0)\r\n\r\n const sensorTypeNameFormatted = sensorType?.name?.replace(/_/g, ' ') || 'Other'\r\n const SensorIcon = LR[sensorType?.icon] || LR.Radio\r\n\r\n const chartConfig: ChartConfig = {\r\n value: {\r\n label: 'Value',\r\n color: 'hsl(var(--chart-1))',\r\n },\r\n }\r\n\r\n const sizeStyles = {\r\n sm: {\r\n cardWidth: 'w-[280px]',\r\n cardPadding: 'px-2 py-2',\r\n iconSize: 'h-7 w-7',\r\n iconInnerSize: 'h-4 w-4',\r\n titleSize: 'text-xs',\r\n subtitleSize: 'text-[10px]',\r\n metaSize: 'text-[10px]',\r\n buttonSize: 'h-6 w-6',\r\n buttonIconSize: 'h-3 w-3',\r\n gap: 'gap-2',\r\n collapsedIconSize: 'h-8 w-8',\r\n collapsedIconInnerSize: 'h-4 w-4',\r\n },\r\n md: {\r\n cardWidth: 'w-[410px]',\r\n cardPadding: 'px-3 py-2.5',\r\n iconSize: 'h-9 w-9',\r\n iconInnerSize: 'h-5 w-5',\r\n titleSize: 'text-sm',\r\n subtitleSize: 'text-xs',\r\n metaSize: 'text-xs',\r\n buttonSize: 'h-7 w-7',\r\n buttonIconSize: 'h-4 w-4',\r\n gap: 'gap-3',\r\n collapsedIconSize: 'h-9 w-9',\r\n collapsedIconInnerSize: 'h-5 w-5',\r\n },\r\n lg: {\r\n cardWidth: 'w-[500px]',\r\n cardPadding: 'px-4 py-3',\r\n iconSize: 'h-11 w-11',\r\n iconInnerSize: 'h-6 w-6',\r\n titleSize: 'text-base',\r\n subtitleSize: 'text-sm',\r\n metaSize: 'text-sm',\r\n buttonSize: 'h-8 w-8',\r\n buttonIconSize: 'h-5 w-5',\r\n gap: 'gap-4',\r\n collapsedIconSize: 'h-11 w-11',\r\n collapsedIconInnerSize: 'h-6 w-6',\r\n },\r\n }\r\n\r\n const currentSize = sizeStyles[size]\r\n\r\n const handlePointerDown = (e: React.PointerEvent) => {\r\n if (!enableCollapse) return\r\n e.stopPropagation()\r\n\r\n const now = performance.now()\r\n if (now - lastTap.current < 300) setIsCollapsed(v => !v)\r\n lastTap.current = now\r\n }\r\n\r\n const handleClose = () => {\r\n if (enableCollapse) setIsCollapsed(true)\r\n else onClose?.()\r\n }\r\n\r\n if (enableCollapse && isCollapsed) {\r\n return (\r\n <div\r\n className={`${currentSize.collapsedIconSize} rounded-full shadow-md flex items-center justify-center flex-shrink-0 bg-primary pointer-events-auto`}\r\n onPointerDown={handlePointerDown}\r\n onDoubleClick={(e) => {\r\n e.stopPropagation()\r\n setIsCollapsed(v => !v)\r\n }}\r\n >\r\n <SensorIcon className={`${currentSize.collapsedIconInnerSize} text-primary-foreground cursor-pointer`} />\r\n </div>\r\n )\r\n }\r\n\r\n return (\r\n <div\r\n className=\"relative inline-block group pointer-events-auto\"\r\n title={enableCollapse ? 'Double click to collapse' : undefined}\r\n onPointerDown={handlePointerDown}\r\n onDoubleClick={(e) => {\r\n e.stopPropagation()\r\n if (enableCollapse) setIsCollapsed(v => !v)\r\n else onClose?.()\r\n }}\r\n >\r\n <Card className={`${currentSize.cardWidth} ${currentSize.cardPadding} shadow-md group-hover:shadow-lg transition-shadow duration-200`}>\r\n <div className={`flex items-start ${currentSize.gap}`}>\r\n <div className={`${currentSize.iconSize} rounded-full shadow-sm flex items-center justify-center select-none flex-shrink-0 bg-primary`}>\r\n <SensorIcon className={`${currentSize.iconInnerSize} text-primary-foreground`} />\r\n </div>\r\n\r\n <div className=\"flex-1 min-w-0 flex flex-col gap-1\">\r\n <span className={`font-semibold ${currentSize.titleSize} text-foreground leading-none truncate`}>\r\n {sensorName}\r\n </span>\r\n <span className={`${currentSize.subtitleSize} text-muted-foreground leading-none`}>\r\n {sensorTypeNameFormatted}\r\n </span>\r\n </div>\r\n\r\n {showActions && (\r\n <Button\r\n type=\"button\"\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n title={actionLabels?.close ?? 'Close'}\r\n aria-label={actionLabels?.close ?? 'Close'}\r\n className={`z-50 ${currentSize.buttonSize} shrink-0 -mr-1 -mt-1`}\r\n // In the CSS2D 3D card (enableCollapse) activate on pointerdown for reliability;\r\n // the map popup is normal DOM, so keep click for keyboard accessibility.\r\n {...(enableCollapse\r\n ? { onPointerDown: (e: React.PointerEvent) => { e.stopPropagation(); handleClose() } }\r\n : { onClick: (e: React.MouseEvent) => { e.stopPropagation(); handleClose() } })}\r\n >\r\n <LR.X className={currentSize.buttonIconSize} />\r\n </Button>\r\n )}\r\n\r\n {/* Map popup keeps the inline delete; the BIM card uses the action row below instead. */}\r\n {!showActions && onRemove && (\r\n <Button\r\n type=\"button\"\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n title=\"Remove sensor\"\r\n className={`z-50 ${currentSize.buttonSize} shrink-0`}\r\n aria-label=\"Remove sensor\"\r\n onClick={(e) => {\r\n e.stopPropagation()\r\n onRemove()\r\n }}\r\n >\r\n <LR.Trash2 className={currentSize.buttonIconSize} />\r\n </Button>\r\n )}\r\n </div>\r\n\r\n <div className=\"mb-2\">\r\n <span className={`${currentSize.metaSize} text-muted-foreground`}>\r\n Created {formatTimestamp(createdAt, timeZone)}\r\n </span>\r\n </div>\r\n\r\n <SensorChart\r\n sensorData={sensorData}\r\n isLoadingData={isLoadingData}\r\n sensorName={sensorName}\r\n sensorType={sensorType}\r\n updateFrequency={updateFrequency}\r\n chartConfig={chartConfig}\r\n size={size}\r\n unit={unit}\r\n valueLabels={valueLabels}\r\n timeZone={timeZone}\r\n />\r\n <SensorTagsSection\r\n tags={tags}\r\n variant={tagsVariant}\r\n onAdd={onAddTag}\r\n onDelete={onDeleteTag}\r\n translations={tagsTranslations}\r\n />\r\n\r\n {showActions && (onEdit || onRemove || onExpand) && (\r\n <div className=\"mt-2 flex justify-end border-t pt-1\">\r\n <CommentActionButtons\r\n onExpand={onExpand}\r\n onEdit={canEdit ? onEdit : undefined}\r\n onDelete={canDelete ? onRemove : undefined}\r\n canEdit={canEdit}\r\n canDelete={canDelete}\r\n activateOnPointerDown={enableCollapse}\r\n buttonClassName=\"h-7 w-7\"\r\n labels={{ edit: actionLabels?.edit, delete: actionLabels?.delete, close: actionLabels?.close, expand: actionLabels?.expand }}\r\n />\r\n </div>\r\n )}\r\n </Card>\r\n </div>\r\n )\r\n}\r\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AA0KQ,cAsBE,YAtBF;AArKR,YAAY,QAAQ;AACpB,YAAY,WAAW;AAEvB,SAAS,iBAAiB,sBAAsB;AAChD,SAAS,cAAc;AACvB,SAAS,YAAY;AAErB,SAAS,4BAAsD;AAE/D,SAAS,mBAAmB;AAC5B,SAAS,yBAAsD;AAC/D,SAAS,uBAAuB;AAwCjB,SAAR,OAAwB;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EACnB,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,cAAc;AAAA,EACd,UAAU;AAAA,EACV,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA,OAAO,CAAC;AAAA,EACR,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW,eAAe;AAC5B,GAAgB;AAnFhB;AAoFE,QAAM,CAAC,aAAa,cAAc,IAAI,MAAM,SAAS,gBAAgB;AACrE,QAAM,EAAE,QAAQ,YAAY,MAAM,aAAa,WAAW,cAAc,IACtE,gBAAgB,SAAS,YAAY,iBAAiB,EAAE,SAAS,EAAE,kBAAkB,aAAa,CAAC;AACrG,QAAM,UAAU,MAAM,OAAO,CAAC;AAE9B,QAAM,4BAA0B,8CAAY,SAAZ,mBAAkB,QAAQ,MAAM,SAAQ;AACxE,QAAM,aAAa,GAAG,yCAAY,IAAI,KAAK,GAAG;AAE9C,QAAM,cAA2B;AAAA,IAC/B,OAAO;AAAA,MACL,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,aAAa;AAAA,IACjB,IAAI;AAAA,MACF,WAAW;AAAA,MACX,aAAa;AAAA,MACb,UAAU;AAAA,MACV,eAAe;AAAA,MACf,WAAW;AAAA,MACX,cAAc;AAAA,MACd,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,KAAK;AAAA,MACL,mBAAmB;AAAA,MACnB,wBAAwB;AAAA,IAC1B;AAAA,IACA,IAAI;AAAA,MACF,WAAW;AAAA,MACX,aAAa;AAAA,MACb,UAAU;AAAA,MACV,eAAe;AAAA,MACf,WAAW;AAAA,MACX,cAAc;AAAA,MACd,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,KAAK;AAAA,MACL,mBAAmB;AAAA,MACnB,wBAAwB;AAAA,IAC1B;AAAA,IACA,IAAI;AAAA,MACF,WAAW;AAAA,MACX,aAAa;AAAA,MACb,UAAU;AAAA,MACV,eAAe;AAAA,MACf,WAAW;AAAA,MACX,cAAc;AAAA,MACd,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,KAAK;AAAA,MACL,mBAAmB;AAAA,MACnB,wBAAwB;AAAA,IAC1B;AAAA,EACF;AAEA,QAAM,cAAc,WAAW,IAAI;AAEnC,QAAM,oBAAoB,CAAC,MAA0B;AACnD,QAAI,CAAC,eAAgB;AACrB,MAAE,gBAAgB;AAElB,UAAM,MAAM,YAAY,IAAI;AAC5B,QAAI,MAAM,QAAQ,UAAU,IAAK,gBAAe,OAAK,CAAC,CAAC;AACvD,YAAQ,UAAU;AAAA,EACpB;AAEA,QAAM,cAAc,MAAM;AACxB,QAAI,eAAgB,gBAAe,IAAI;AAAA,QAClC;AAAA,EACP;AAEA,MAAI,kBAAkB,aAAa;AACjC,WACE;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,GAAG,YAAY,iBAAiB;AAAA,QAC3C,eAAe;AAAA,QACf,eAAe,CAAC,MAAM;AACpB,YAAE,gBAAgB;AAClB,yBAAe,OAAK,CAAC,CAAC;AAAA,QACxB;AAAA,QAEA,8BAAC,cAAW,WAAW,GAAG,YAAY,sBAAsB,2CAA2C;AAAA;AAAA,IACzG;AAAA,EAEJ;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO,iBAAiB,6BAA6B;AAAA,MACrD,eAAe;AAAA,MACf,eAAe,CAAC,MAAM;AACpB,UAAE,gBAAgB;AAClB,YAAI,eAAgB,gBAAe,OAAK,CAAC,CAAC;AAAA,YACrC;AAAA,MACP;AAAA,MAEA,+BAAC,QAAK,WAAW,GAAG,YAAY,SAAS,IAAI,YAAY,WAAW,mEAClE;AAAA,6BAAC,SAAI,WAAW,oBAAoB,YAAY,GAAG,IACjD;AAAA,8BAAC,SAAI,WAAW,GAAG,YAAY,QAAQ,iGACrC,8BAAC,cAAW,WAAW,GAAG,YAAY,aAAa,4BAA4B,GACjF;AAAA,UAEA,qBAAC,SAAI,WAAU,sCACb;AAAA,gCAAC,UAAK,WAAW,iBAAiB,YAAY,SAAS,0CACpD,sBACH;AAAA,YACA,oBAAC,UAAK,WAAW,GAAG,YAAY,YAAY,uCACzC,mCACH;AAAA,aACF;AAAA,UAEC,eACC;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,QAAO,kDAAc,UAAd,YAAuB;AAAA,cAC9B,eAAY,kDAAc,UAAd,YAAuB;AAAA,cACnC,WAAW,QAAQ,YAAY,UAAU;AAAA,eAGpC,iBACD,EAAE,eAAe,CAAC,MAA0B;AAAE,gBAAE,gBAAgB;AAAG,0BAAY;AAAA,YAAE,EAAE,IACnF,EAAE,SAAS,CAAC,MAAwB;AAAE,gBAAE,gBAAgB;AAAG,0BAAY;AAAA,YAAE,EAAE,IAXhF;AAAA,cAaC,8BAAC,GAAG,GAAH,EAAK,WAAW,YAAY,gBAAgB;AAAA;AAAA,UAC/C;AAAA,UAID,CAAC,eAAe,YACf;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,OAAM;AAAA,cACN,WAAW,QAAQ,YAAY,UAAU;AAAA,cACzC,cAAW;AAAA,cACX,SAAS,CAAC,MAAM;AACd,kBAAE,gBAAgB;AAClB,yBAAS;AAAA,cACX;AAAA,cAEA,8BAAC,GAAG,QAAH,EAAU,WAAW,YAAY,gBAAgB;AAAA;AAAA,UACpD;AAAA,WAEJ;AAAA,QAEA,oBAAC,SAAI,WAAU,QACb,+BAAC,UAAK,WAAW,GAAG,YAAY,QAAQ,0BAA0B;AAAA;AAAA,UACvD,gBAAgB,WAAW,QAAQ;AAAA,WAC9C,GACF;AAAA,QAEA;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA;AAAA,QACF;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA,SAAS;AAAA,YACT,OAAO;AAAA,YACP,UAAU;AAAA,YACV,cAAc;AAAA;AAAA,QAChB;AAAA,QAEC,gBAAgB,UAAU,YAAY,aACrC,oBAAC,SAAI,WAAU,uCACb;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA,QAAQ,UAAU,SAAS;AAAA,YAC3B,UAAU,YAAY,WAAW;AAAA,YACjC;AAAA,YACA;AAAA,YACA,uBAAuB;AAAA,YACvB,iBAAgB;AAAA,YAChB,QAAQ,EAAE,MAAM,6CAAc,MAAM,QAAQ,6CAAc,QAAQ,OAAO,6CAAc,OAAO,QAAQ,6CAAc,OAAO;AAAA;AAAA,QAC7H,GACF;AAAA,SAEJ;AAAA;AAAA,EACF;AAEJ;","names":[]}
|
|
@@ -3,7 +3,7 @@ import { type ChartConfig } from '../chart';
|
|
|
3
3
|
import type { SensorType } from '../../../types/dbTypes';
|
|
4
4
|
interface SensorChartProps {
|
|
5
5
|
sensorData: {
|
|
6
|
-
|
|
6
|
+
t: number;
|
|
7
7
|
value: number;
|
|
8
8
|
}[];
|
|
9
9
|
isLoadingData: boolean;
|
|
@@ -20,7 +20,17 @@ interface SensorChartProps {
|
|
|
20
20
|
minColor?: string;
|
|
21
21
|
midColor?: string;
|
|
22
22
|
maxColor?: string;
|
|
23
|
+
unit?: string;
|
|
24
|
+
valueLabels?: Record<number, string>;
|
|
25
|
+
timeZone?: string;
|
|
26
|
+
showBrush?: boolean;
|
|
27
|
+
brushStartIndex?: number;
|
|
28
|
+
brushEndIndex?: number;
|
|
29
|
+
onBrushChange?: (range: {
|
|
30
|
+
startIndex?: number;
|
|
31
|
+
endIndex?: number;
|
|
32
|
+
}) => void;
|
|
23
33
|
}
|
|
24
|
-
export declare function SensorChart({ sensorData, isLoadingData, sensorName, sensorType, updateFrequency, chartConfig, size, sensorTitle, loadingText, noDataText, updateFrequencyText, dataPointsText, minColor, midColor, maxColor, }: SensorChartProps): React.JSX.Element;
|
|
34
|
+
export declare function SensorChart({ sensorData, isLoadingData, sensorName, sensorType, updateFrequency, chartConfig, size, sensorTitle, loadingText, noDataText, updateFrequencyText, dataPointsText, minColor, midColor, maxColor, unit, valueLabels, timeZone, showBrush, brushStartIndex, brushEndIndex, onBrushChange, }: SensorChartProps): React.JSX.Element;
|
|
25
35
|
export {};
|
|
26
36
|
//# sourceMappingURL=SensorChart.d.ts.map
|