@collabdt/core 0.0.56 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -26
- package/dist/core/components/AppSidebarContent.d.ts +2 -1
- package/dist/core/components/AppSidebarContent.d.ts.map +1 -1
- package/dist/core/components/AppSidebarContent.js +10 -7
- package/dist/core/components/AppSidebarContent.js.map +1 -1
- package/dist/core/components/Toolbar.d.ts +7 -1
- package/dist/core/components/Toolbar.d.ts.map +1 -1
- package/dist/core/components/Toolbar.js +3 -3
- package/dist/core/components/Toolbar.js.map +1 -1
- package/dist/core/components/TopNavigationBar.d.ts +6 -1
- package/dist/core/components/TopNavigationBar.d.ts.map +1 -1
- package/dist/core/components/TopNavigationBar.js +2 -2
- package/dist/core/components/TopNavigationBar.js.map +1 -1
- package/dist/core/components/authentication/AuthPage.d.ts +2 -1
- package/dist/core/components/authentication/AuthPage.d.ts.map +1 -1
- package/dist/core/components/authentication/AuthPage.js +3 -5
- package/dist/core/components/authentication/AuthPage.js.map +1 -1
- package/dist/core/components/authentication/Signin.d.ts +2 -1
- package/dist/core/components/authentication/Signin.d.ts.map +1 -1
- package/dist/core/components/authentication/Signin.js +2 -2
- package/dist/core/components/authentication/Signin.js.map +1 -1
- package/dist/core/components/organizationConfig/src/organizationConfigContent.d.ts.map +1 -1
- package/dist/core/components/organizationConfig/src/organizationConfigContent.js +109 -36
- package/dist/core/components/organizationConfig/src/organizationConfigContent.js.map +1 -1
- package/dist/core/components/settings/index.d.ts +3 -1
- package/dist/core/components/settings/index.d.ts.map +1 -1
- package/dist/core/components/settings/index.js +2 -2
- package/dist/core/components/settings/index.js.map +1 -1
- package/dist/core/components/settings/src/AccountSettingsPanel.d.ts.map +1 -1
- package/dist/core/components/settings/src/AccountSettingsPanel.js +9 -2
- package/dist/core/components/settings/src/AccountSettingsPanel.js.map +1 -1
- package/dist/core/components/settings/src/OrganizationSettingsPanel.d.ts +5 -1
- package/dist/core/components/settings/src/OrganizationSettingsPanel.d.ts.map +1 -1
- package/dist/core/components/settings/src/OrganizationSettingsPanel.js +7 -5
- package/dist/core/components/settings/src/OrganizationSettingsPanel.js.map +1 -1
- package/dist/core/components/settings/src/SettingsContent.d.ts +2 -1
- package/dist/core/components/settings/src/SettingsContent.d.ts.map +1 -1
- package/dist/core/components/settings/src/SettingsContent.js +2 -2
- package/dist/core/components/settings/src/SettingsContent.js.map +1 -1
- package/dist/core/components/support/BugReportDialog.d.ts +3 -2
- package/dist/core/components/support/BugReportDialog.d.ts.map +1 -1
- package/dist/core/components/support/BugReportDialog.js +103 -25
- package/dist/core/components/support/BugReportDialog.js.map +1 -1
- package/dist/core/components/support/FeatureRequestDialog.d.ts +3 -1
- package/dist/core/components/support/FeatureRequestDialog.d.ts.map +1 -1
- package/dist/core/components/support/FeatureRequestDialog.js +39 -4
- package/dist/core/components/support/FeatureRequestDialog.js.map +1 -1
- package/dist/core/components/support/SupportMenu.d.ts.map +1 -1
- package/dist/core/components/support/SupportMenu.js +1 -4
- package/dist/core/components/support/SupportMenu.js.map +1 -1
- package/dist/core/components/ui/AnimatedBackground.d.ts +2 -1
- package/dist/core/components/ui/AnimatedBackground.d.ts.map +1 -1
- package/dist/core/components/ui/AnimatedBackground.js +2 -5
- package/dist/core/components/ui/AnimatedBackground.js.map +1 -1
- package/dist/core/components/ui/InfoSidebar/Container.d.ts +3 -1
- package/dist/core/components/ui/InfoSidebar/Container.d.ts.map +1 -1
- package/dist/core/components/ui/InfoSidebar/Container.js +4 -2
- package/dist/core/components/ui/InfoSidebar/Container.js.map +1 -1
- package/dist/core/components/ui/InfoSidebar/Header.d.ts +3 -2
- package/dist/core/components/ui/InfoSidebar/Header.d.ts.map +1 -1
- package/dist/core/components/ui/InfoSidebar/Header.js +5 -6
- package/dist/core/components/ui/InfoSidebar/Header.js.map +1 -1
- package/dist/core/components/ui/InfoSidebar/index.d.ts +7 -1
- package/dist/core/components/ui/InfoSidebar/index.d.ts.map +1 -1
- package/dist/core/components/ui/InfoSidebar/index.js +4 -4
- package/dist/core/components/ui/InfoSidebar/index.js.map +1 -1
- package/dist/core/components/ui/Sensors/CollapsibleSensorItem.d.ts +2 -1
- package/dist/core/components/ui/Sensors/CollapsibleSensorItem.d.ts.map +1 -1
- package/dist/core/components/ui/Sensors/CollapsibleSensorItem.js +3 -4
- package/dist/core/components/ui/Sensors/CollapsibleSensorItem.js.map +1 -1
- package/dist/core/components/ui/Sensors/SensorsSection.d.ts +3 -1
- package/dist/core/components/ui/Sensors/SensorsSection.d.ts.map +1 -1
- package/dist/core/components/ui/Sensors/SensorsSection.js +3 -1
- package/dist/core/components/ui/Sensors/SensorsSection.js.map +1 -1
- package/dist/core/components/ui/Sidebar.d.ts +8 -0
- package/dist/core/components/ui/Sidebar.d.ts.map +1 -1
- package/dist/core/components/ui/Sidebar.js +21 -7
- package/dist/core/components/ui/Sidebar.js.map +1 -1
- package/dist/core/components/ui/ToolbarButton.js +18 -1
- package/dist/core/components/ui/ToolbarButton.js.map +1 -1
- package/dist/core/components/viewers/Data/DataMenu.d.ts +5 -1
- package/dist/core/components/viewers/Data/DataMenu.d.ts.map +1 -1
- package/dist/core/components/viewers/Data/DataMenu.js +15 -4
- package/dist/core/components/viewers/Data/DataMenu.js.map +1 -1
- package/dist/core/components/viewers/Data/HeaderButtons.d.ts +3 -1
- package/dist/core/components/viewers/Data/HeaderButtons.d.ts.map +1 -1
- package/dist/core/components/viewers/Data/HeaderButtons.js +11 -14
- package/dist/core/components/viewers/Data/HeaderButtons.js.map +1 -1
- package/dist/core/components/viewers/Data/MoreOptions.d.ts.map +1 -1
- package/dist/core/components/viewers/Data/MoreOptions.js +14 -27
- package/dist/core/components/viewers/Data/MoreOptions.js.map +1 -1
- package/dist/core/components/viewers/Data/buildingDetails/AddBuilding.d.ts +3 -1
- package/dist/core/components/viewers/Data/buildingDetails/AddBuilding.d.ts.map +1 -1
- package/dist/core/components/viewers/Data/buildingDetails/AddBuilding.js +4 -2
- package/dist/core/components/viewers/Data/buildingDetails/AddBuilding.js.map +1 -1
- package/dist/core/components/viewers/Data/buildingDetails/FieldRenderer.d.ts.map +1 -1
- package/dist/core/components/viewers/Data/buildingDetails/FieldRenderer.js +13 -18
- package/dist/core/components/viewers/Data/buildingDetails/FieldRenderer.js.map +1 -1
- package/dist/core/components/viewers/Data/buildingDetails/GeocoderInput.d.ts +3 -1
- package/dist/core/components/viewers/Data/buildingDetails/GeocoderInput.d.ts.map +1 -1
- package/dist/core/components/viewers/Data/buildingDetails/GeocoderInput.js +3 -1
- package/dist/core/components/viewers/Data/buildingDetails/GeocoderInput.js.map +1 -1
- package/dist/core/components/viewers/Data/details/DetailHeader.d.ts +2 -1
- package/dist/core/components/viewers/Data/details/DetailHeader.d.ts.map +1 -1
- package/dist/core/components/viewers/Data/details/DetailHeader.js +3 -5
- package/dist/core/components/viewers/Data/details/DetailHeader.js.map +1 -1
- package/dist/core/components/viewers/Data/details/FieldValue.d.ts.map +1 -1
- package/dist/core/components/viewers/Data/details/FieldValue.js +13 -3
- package/dist/core/components/viewers/Data/details/FieldValue.js.map +1 -1
- package/dist/core/components/viewers/Data/siteDetails/AssociatedBuildings.d.ts +2 -0
- package/dist/core/components/viewers/Data/siteDetails/AssociatedBuildings.d.ts.map +1 -1
- package/dist/core/components/viewers/Data/siteDetails/AssociatedBuildings.js +84 -3
- package/dist/core/components/viewers/Data/siteDetails/AssociatedBuildings.js.map +1 -1
- package/dist/core/components/viewers/Data/siteDetails/SiteDetails.d.ts.map +1 -1
- package/dist/core/components/viewers/Data/siteDetails/SiteDetails.js +23 -2
- package/dist/core/components/viewers/Data/siteDetails/SiteDetails.js.map +1 -1
- package/dist/core/components/viewers/Viewer.d.ts +7 -1
- package/dist/core/components/viewers/Viewer.d.ts.map +1 -1
- package/dist/core/components/viewers/Viewer.js +6 -6
- package/dist/core/components/viewers/Viewer.js.map +1 -1
- package/dist/core/components/viewers/bim/BimToolbar.d.ts +3 -1
- package/dist/core/components/viewers/bim/BimToolbar.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/BimToolbar.js +2 -2
- package/dist/core/components/viewers/bim/BimToolbar.js.map +1 -1
- package/dist/core/components/viewers/bim/src/BimSidebar/src/SensorsTab/index.d.ts +3 -1
- 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/index.d.ts +5 -1
- package/dist/core/components/viewers/bim/src/BimSidebar/src/index.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/BimSidebar/src/index.js +3 -2
- package/dist/core/components/viewers/bim/src/BimSidebar/src/index.js.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/AddToBim/index.d.ts +3 -1
- 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 +2 -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/useSensorMarkers.d.ts +1 -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 +3 -5
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useSensorMarkers.js.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/bimToolbar.d.ts +3 -1
- package/dist/core/components/viewers/bim/src/tools/bimToolbar.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/bimToolbar.js +4 -2
- package/dist/core/components/viewers/bim/src/tools/bimToolbar.js.map +1 -1
- package/dist/core/components/viewers/map/MapViewer.d.ts +3 -1
- 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/RowActions.d.ts +2 -1
- package/dist/core/components/viewers/map/datasets/RowActions.d.ts.map +1 -1
- package/dist/core/components/viewers/map/datasets/RowActions.js +5 -6
- package/dist/core/components/viewers/map/datasets/RowActions.js.map +1 -1
- package/dist/core/components/viewers/map/datasets/index.d.ts +5 -1
- package/dist/core/components/viewers/map/datasets/index.d.ts.map +1 -1
- package/dist/core/components/viewers/map/datasets/index.js +15 -16
- package/dist/core/components/viewers/map/datasets/index.js.map +1 -1
- package/dist/core/components/viewers/map/src/Geocoder.d.ts +3 -1
- package/dist/core/components/viewers/map/src/Geocoder.d.ts.map +1 -1
- package/dist/core/components/viewers/map/src/Geocoder.js +5 -1
- package/dist/core/components/viewers/map/src/Geocoder.js.map +1 -1
- package/dist/core/components/viewers/map/src/MapLayers/index.d.ts +6 -1
- package/dist/core/components/viewers/map/src/MapLayers/index.d.ts.map +1 -1
- package/dist/core/components/viewers/map/src/MapLayers/index.js +5 -3
- package/dist/core/components/viewers/map/src/MapLayers/index.js.map +1 -1
- package/dist/core/components/viewers/map/src/MapLayers/src/CountryLayer/index.d.ts +5 -1
- package/dist/core/components/viewers/map/src/MapLayers/src/CountryLayer/index.d.ts.map +1 -1
- package/dist/core/components/viewers/map/src/MapLayers/src/CountryLayer/index.js +6 -10
- package/dist/core/components/viewers/map/src/MapLayers/src/CountryLayer/index.js.map +1 -1
- package/dist/core/components/viewers/map/src/MapLayers/src/SensorsLayer/index.d.ts +3 -1
- 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 +4 -6
- package/dist/core/components/viewers/map/src/MapLayers/src/SensorsLayer/index.js.map +1 -1
- package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/SiteContextMenu.d.ts +19 -0
- package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/SiteContextMenu.d.ts.map +1 -0
- package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/SiteContextMenu.js +163 -0
- package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/SiteContextMenu.js.map +1 -0
- package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/SiteLayer.d.ts +3 -0
- package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/SiteLayer.d.ts.map +1 -0
- package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/SiteLayer.js +310 -0
- package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/SiteLayer.js.map +1 -0
- package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/siteGeometry.d.ts +30 -0
- package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/siteGeometry.d.ts.map +1 -0
- package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/siteGeometry.js +122 -0
- package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/siteGeometry.js.map +1 -0
- package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/useShowSitesOnMap.d.ts +13 -0
- package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/useShowSitesOnMap.d.ts.map +1 -0
- package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/useShowSitesOnMap.js +58 -0
- package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/useShowSitesOnMap.js.map +1 -0
- package/dist/core/components/viewers/map/src/MapSidebar/index.d.ts +6 -1
- package/dist/core/components/viewers/map/src/MapSidebar/index.d.ts.map +1 -1
- package/dist/core/components/viewers/map/src/MapSidebar/index.js +5 -4
- package/dist/core/components/viewers/map/src/MapSidebar/index.js.map +1 -1
- package/dist/core/components/viewers/map/src/MapSidebar/src/LayersTab/index.d.ts +5 -1
- package/dist/core/components/viewers/map/src/MapSidebar/src/LayersTab/index.d.ts.map +1 -1
- package/dist/core/components/viewers/map/src/MapSidebar/src/LayersTab/index.js +5 -8
- package/dist/core/components/viewers/map/src/MapSidebar/src/LayersTab/index.js.map +1 -1
- package/dist/core/components/viewers/map/src/MapSidebar/src/SensorsTab/index.d.ts +3 -1
- 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/MapSidebar/src/SettingsTab/index.d.ts +3 -1
- package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/index.d.ts.map +1 -1
- package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/index.js +2 -2
- package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/index.js.map +1 -1
- package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/src/LocationSettings.d.ts +3 -1
- package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/src/LocationSettings.d.ts.map +1 -1
- package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/src/LocationSettings.js +4 -7
- package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/src/LocationSettings.js.map +1 -1
- package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/src/TerrainLevel.d.ts.map +1 -1
- package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/src/TerrainLevel.js +8 -8
- package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/src/TerrainLevel.js.map +1 -1
- package/dist/core/components/viewers/map/src/tools/AddTools/AddSite/AssociateBuildingsDialog.d.ts +18 -0
- package/dist/core/components/viewers/map/src/tools/AddTools/AddSite/AssociateBuildingsDialog.d.ts.map +1 -0
- package/dist/core/components/viewers/map/src/tools/AddTools/AddSite/AssociateBuildingsDialog.js +102 -0
- package/dist/core/components/viewers/map/src/tools/AddTools/AddSite/AssociateBuildingsDialog.js.map +1 -0
- package/dist/core/components/viewers/map/src/tools/AddTools/AddSite/SiteAdder.d.ts.map +1 -1
- package/dist/core/components/viewers/map/src/tools/AddTools/AddSite/SiteAdder.js +243 -176
- package/dist/core/components/viewers/map/src/tools/AddTools/AddSite/SiteAdder.js.map +1 -1
- package/dist/core/components/viewers/map/src/tools/AddTools/AddSite/persistSite.d.ts +24 -0
- package/dist/core/components/viewers/map/src/tools/AddTools/AddSite/persistSite.d.ts.map +1 -0
- package/dist/core/components/viewers/map/src/tools/AddTools/AddSite/persistSite.js +46 -0
- package/dist/core/components/viewers/map/src/tools/AddTools/AddSite/persistSite.js.map +1 -0
- package/dist/core/components/viewers/map/src/tools/AddTools/AddToMap.d.ts +8 -1
- package/dist/core/components/viewers/map/src/tools/AddTools/AddToMap.d.ts.map +1 -1
- package/dist/core/components/viewers/map/src/tools/AddTools/AddToMap.js +8 -3
- package/dist/core/components/viewers/map/src/tools/AddTools/AddToMap.js.map +1 -1
- package/dist/core/components/viewers/map/src/tools/DatasetMapTool.d.ts +11 -1
- package/dist/core/components/viewers/map/src/tools/DatasetMapTool.d.ts.map +1 -1
- package/dist/core/components/viewers/map/src/tools/DatasetMapTool.js +5 -3
- package/dist/core/components/viewers/map/src/tools/DatasetMapTool.js.map +1 -1
- package/dist/core/components/viewers/map/src/tools/mapTools.d.ts +10 -1
- package/dist/core/components/viewers/map/src/tools/mapTools.d.ts.map +1 -1
- package/dist/core/components/viewers/map/src/tools/mapTools.js +5 -3
- package/dist/core/components/viewers/map/src/tools/mapTools.js.map +1 -1
- package/dist/core/components/viewers/map/utils/MapEventManager/MapClickManager.d.ts +1 -0
- package/dist/core/components/viewers/map/utils/MapEventManager/MapClickManager.d.ts.map +1 -1
- package/dist/core/components/viewers/map/utils/MapEventManager/MapClickManager.js +1 -0
- package/dist/core/components/viewers/map/utils/MapEventManager/MapClickManager.js.map +1 -1
- package/dist/core/components/viewers/map/utils/geocoding/config.d.ts +14 -5
- package/dist/core/components/viewers/map/utils/geocoding/config.d.ts.map +1 -1
- package/dist/core/components/viewers/map/utils/geocoding/config.js +22 -11
- package/dist/core/components/viewers/map/utils/geocoding/config.js.map +1 -1
- package/dist/core/components/viewers/map/utils/geocoding/index.d.ts.map +1 -1
- package/dist/core/components/viewers/map/utils/geocoding/index.js +2 -2
- package/dist/core/components/viewers/map/utils/geocoding/index.js.map +1 -1
- package/dist/core/components/viewers/map/utils/geocoding/osm.d.ts.map +1 -1
- package/dist/core/components/viewers/map/utils/geocoding/osm.js +5 -4
- package/dist/core/components/viewers/map/utils/geocoding/osm.js.map +1 -1
- package/dist/core/components/viewers/map/utils/geocoding/pelias.d.ts.map +1 -1
- package/dist/core/components/viewers/map/utils/geocoding/pelias.js +7 -5
- package/dist/core/components/viewers/map/utils/geocoding/pelias.js.map +1 -1
- package/dist/core/components/viewers/pointcloud/PointCloudViewer.d.ts +3 -1
- package/dist/core/components/viewers/pointcloud/PointCloudViewer.d.ts.map +1 -1
- package/dist/core/components/viewers/pointcloud/PointCloudViewer.js +11 -14
- package/dist/core/components/viewers/pointcloud/PointCloudViewer.js.map +1 -1
- package/dist/core/components/viewers/pointcloud/src/PointCloudLoadingState/index.d.ts +3 -1
- package/dist/core/components/viewers/pointcloud/src/PointCloudLoadingState/index.d.ts.map +1 -1
- package/dist/core/components/viewers/pointcloud/src/PointCloudLoadingState/index.js +37 -52
- package/dist/core/components/viewers/pointcloud/src/PointCloudLoadingState/index.js.map +1 -1
- package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudManagementTable.d.ts +3 -1
- package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudManagementTable.d.ts.map +1 -1
- package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudManagementTable.js +5 -3
- package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudManagementTable.js.map +1 -1
- package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudTable.d.ts +2 -1
- package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudTable.d.ts.map +1 -1
- package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudTable.js +5 -6
- package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudTable.js.map +1 -1
- package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudUploadPanel.d.ts +2 -1
- package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudUploadPanel.d.ts.map +1 -1
- package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudUploadPanel.js +15 -9
- package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudUploadPanel.js.map +1 -1
- package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/index.d.ts +5 -1
- package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/index.d.ts.map +1 -1
- package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/index.js +3 -2
- package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/index.js.map +1 -1
- package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/index.d.ts +3 -1
- package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/index.d.ts.map +1 -1
- package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/index.js +2 -2
- package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/index.js.map +1 -1
- package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/src/PointCloudSection.d.ts +2 -1
- package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/src/PointCloudSection.d.ts.map +1 -1
- package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/src/PointCloudSection.js +12 -23
- package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/src/PointCloudSection.js.map +1 -1
- package/dist/core/hooks/sites/createSiteHooks.d.ts.map +1 -1
- package/dist/core/hooks/sites/createSiteHooks.js +0 -1
- package/dist/core/hooks/sites/createSiteHooks.js.map +1 -1
- package/dist/core/hooks/useCaptureScreenshot.d.ts +2 -0
- package/dist/core/hooks/useCaptureScreenshot.d.ts.map +1 -0
- package/dist/core/hooks/useCaptureScreenshot.js +110 -0
- package/dist/core/hooks/useCaptureScreenshot.js.map +1 -0
- package/dist/core/hooks/useGeocodingRuntimeConfig.d.ts +3 -0
- package/dist/core/hooks/useGeocodingRuntimeConfig.d.ts.map +1 -0
- package/dist/core/hooks/useGeocodingRuntimeConfig.js +17 -0
- package/dist/core/hooks/useGeocodingRuntimeConfig.js.map +1 -0
- package/dist/core/store/AppConfig/context.d.ts +5 -0
- package/dist/core/store/AppConfig/context.d.ts.map +1 -1
- package/dist/core/store/AppConfig/context.js.map +1 -1
- package/dist/core/store/CombineProviders.d.ts +6 -1
- package/dist/core/store/CombineProviders.d.ts.map +1 -1
- package/dist/core/store/CombineProviders.js +6 -3
- package/dist/core/store/CombineProviders.js.map +1 -1
- package/dist/core/store/MapSites/context.d.ts +16 -0
- package/dist/core/store/MapSites/context.d.ts.map +1 -0
- package/dist/core/store/MapSites/context.js +29 -0
- package/dist/core/store/MapSites/context.js.map +1 -0
- package/dist/core/store/MapSites/reducer.d.ts +52 -0
- package/dist/core/store/MapSites/reducer.d.ts.map +1 -0
- package/dist/core/store/MapSites/reducer.js +70 -0
- package/dist/core/store/MapSites/reducer.js.map +1 -0
- package/dist/core/store/index.d.ts +1 -0
- package/dist/core/store/index.d.ts.map +1 -1
- package/dist/core/store/index.js +1 -0
- package/dist/core/store/index.js.map +1 -1
- package/dist/core/types/tools.d.ts +2 -1
- package/dist/core/types/tools.d.ts.map +1 -1
- package/dist/core/utils/imageUtils.d.ts.map +1 -1
- package/dist/core/utils/imageUtils.js +2 -1
- package/dist/core/utils/imageUtils.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/core/components/viewers/Data/DataMenu.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\n// Dependencies\r\nimport * as React from 'react'\r\nimport { toast } from 'sonner'\r\nimport { useTranslations } from 'next-intl'\r\nimport { handleApiError } from '../../../utils/errorHandler'\r\n\r\n// Utils\r\nimport { useViewerData } from './utils/useViewerData'\r\nimport { VIEWER_CONFIG } from './utils/viewerConfig'\r\n\r\nimport type { Building, Site, User, Infrastructure } from '../../../types/dbTypes'\r\nimport type { FilterState } from '../../../types/global'\r\n\r\n// Custom hooks\r\nimport { useBuildings, useCreateBuilding } from '../../../hooks/buildings/buildings'\r\nimport { useCreateSite, useSites } from '../../../hooks/sites/sites'\r\nimport { useFiles } from '../../../hooks/files/files'\r\nimport { useUsers } from '../../../hooks/users/users'\r\n\r\n// Context\r\nimport { useMenusContext } from '../../../store'\r\nimport { useBuildingsContext } from '../../../store'\r\nimport { useFilesContext } from '../../../store'\r\n\r\n// Types\r\nimport type { FileRow } from '../../../types/files'\r\nimport {\r\n Breadcrumb,\r\n BreadcrumbItem,\r\n BreadcrumbLink,\r\n BreadcrumbList,\r\n BreadcrumbPage,\r\n BreadcrumbSeparator,\r\n} from '../../ui/Breadcrumb'\r\nimport { Button, Checkbox, DataTable, Input, Separator } from '../../ui/'\r\n\r\nimport type { BuildingDetailsRef } from './buildingDetails/BuildingDetails'\r\nimport type { SiteDetailsRef } from './siteDetails/SiteDetails'\r\nimport type { InfrastructureDetailsRef } from './infrastructureDetails/InfrastructureDetails'\r\n\r\nimport BuildingDetails from './buildingDetails/BuildingDetails'\r\nimport { FileDetails } from './files/FileDetails'\r\n\r\n// Custom Components\r\nimport DetailActions from './details/DetailActions'\r\nimport DetailHeader from './details/DetailHeader'\r\nimport FilterButtons from './FilterButtons'\r\nimport HeaderButtons from './HeaderButtons'\r\nimport MoreOptions from './MoreOptions'\r\nimport SiteDetails from './siteDetails/SiteDetails'\r\nimport UserDetails from './userDetails/UserDetails'\r\n\r\n// Data\r\nimport { useColumns, useUserColumns } from './utils/Columns'\r\nimport { useBuildingHeaders, useInfrastructureHeaders, useSiteHeaders } from './utils/Headers'\r\nimport { DataTypes, DataTypesNames, ViewerNames } from '../../../types'\r\nimport { useSession } from 'next-auth/react'\r\nimport InfrastructureDetails from './infrastructureDetails/InfrastructureDetails'\r\nimport { useCreateInfrastructure, useInfrastructures } from '../../../hooks/infrastructures/infrastructures'\r\n\r\ntype DataMenuProps = {\r\n currentViewer: ViewerNames\r\n height?: string\r\n hideFrame?: boolean\r\n hideTitle?: boolean\r\n hideActions?: boolean\r\n}\r\n\r\nexport function DataMenu({ currentViewer, height, hideTitle, hideActions, hideFrame }: DataMenuProps) {\r\n // Translations\r\n const t = useTranslations('DataMenu')\r\n\r\n // View state\r\n const { view, setView } = useMenusContext()\r\n const { selectedItem, setSelectedItem } = useMenusContext()\r\n const { selectedSite, setSelectedSite } = useMenusContext()\r\n const { selectedInfrastructure, setSelectedInfrastructure } = useMenusContext()\r\n const { selectedFile, setSelectedFile } = useMenusContext()\r\n const { selectedUser, setSelectedUser } = useMenusContext()\r\n const { state: fileState } = useFilesContext()\r\n const { currentFile } = fileState.files\r\n\r\n // Search / filter state\r\n const [searchTerm, setSearchTerm] = React.useState('')\r\n const [activeFilters, setActiveFilters] = React.useState<FilterState[]>([])\r\n const [filters, setFilters] = React.useState([\r\n { id: 1, field: '', fieldType: null, operator: null, value: null, secondValue: null },\r\n ])\r\n\r\n const [dataType, setDataType] = React.useState<DataTypes>(DataTypesNames.building)\r\n const [editing, setEditing] = React.useState(false)\r\n const [activeChanges, setActiveChanges] = React.useState(false)\r\n\r\n // Tab headers\r\n const buildingHeaders = useBuildingHeaders()\r\n const siteHeaders = useSiteHeaders()\r\n const infrastructureHeaders = useInfrastructureHeaders()\r\n\r\n const buildingTabOptions = buildingHeaders.map(section => ({\r\n key: section.title.toLowerCase().replaceAll(/\\s/g, '-'),\r\n label: section.title,\r\n }))\r\n const siteTabOptions = siteHeaders.map(section => ({\r\n key: section.title.toLowerCase().replaceAll(/\\s/g, '-'),\r\n label: section.title,\r\n }))\r\n const infrastructureTabOptions = infrastructureHeaders.map(section => ({\r\n key: section.title.toLowerCase().replaceAll(/\\s/g, '-'),\r\n label: section.title,\r\n }))\r\n\r\n const [activeBuildingTab, setActiveBuildingTab] = React.useState(buildingTabOptions[0]?.key || '')\r\n const [activeSiteTab, setActiveSiteTab] = React.useState(siteTabOptions[0]?.key || '')\r\n const [activeInfrastructureTab, setActiveInfrastructureTab] = React.useState(infrastructureTabOptions[0]?.key || '')\r\n\r\n // Reset active tab only when selected item ID changes\r\n const prevBuildingId = React.useRef<number | undefined>(undefined)\r\n const prevInfrastructureId = React.useRef<number | undefined>(undefined)\r\n\r\n React.useEffect(() => {\r\n if (currentViewer === ViewerNames.buildings && selectedItem?.id !== prevBuildingId.current) {\r\n setActiveBuildingTab(buildingTabOptions[0]?.key || '')\r\n prevBuildingId.current = selectedItem?.id\r\n }\r\n if (currentViewer === ViewerNames.infrastructure && selectedInfrastructure?.id !== prevInfrastructureId.current) {\r\n setActiveInfrastructureTab(infrastructureTabOptions[0]?.key || '')\r\n prevInfrastructureId.current = selectedInfrastructure?.id\r\n }\r\n }, [selectedItem?.id, selectedInfrastructure?.id, currentViewer])\r\n\r\n const [newItemName, setNewItemName] = React.useState('')\r\n\r\n // Compare state\r\n const {\r\n compareItems,\r\n setCompareItems,\r\n comparing,\r\n setComparing,\r\n addItemToCompare,\r\n removeItemFromCompare,\r\n } = useBuildingsContext()\r\n\r\n // Sync dataType with current viewer\r\n React.useEffect(() => {\r\n setDataType(DataTypesNames[currentViewer])\r\n }, [currentViewer])\r\n\r\n // Reset compare state when viewer changes\r\n React.useEffect(() => {\r\n setComparing(false)\r\n setCompareItems([])\r\n }, [currentViewer, setComparing, setCompareItems])\r\n\r\n // Data fetching\r\n const { buildings, isLoading: buildingsLoading, isError: buildingsError } = useBuildings()\r\n const { sites, isLoading: sitesLoading, isError: sitesError } = useSites()\r\n const { infrastructures, isLoading: infrastructuresLoading, isError: infrastructuresError } = useInfrastructures()\r\n const { files, isLoading: filesLoading, isError: filesError } = useFiles()\r\n const { users, isLoading: usersLoading, isError: usersError } = useUsers()\r\n\r\n const { createError: createSiteError } = useCreateSite()\r\n const { createError: createBuildingError } = useCreateBuilding()\r\n const { createError: createInfrastructureError } = useCreateInfrastructure()\r\n\r\n React.useEffect(() => {\r\n handleApiError(buildingsError)\r\n handleApiError(sitesError)\r\n handleApiError(filesError)\r\n handleApiError(infrastructuresError)\r\n handleApiError(usersError)\r\n handleApiError(createSiteError)\r\n handleApiError(createBuildingError)\r\n handleApiError(createInfrastructureError)\r\n }, [buildingsError, sitesError, infrastructuresError, filesError, usersError, createSiteError, createBuildingError, createInfrastructureError])\r\n\r\n const tableColumns = useColumns(buildings || [])\r\n const userColumns = useUserColumns()\r\n\r\n const { user } = useSession().data\r\n\r\n // Viewer config — resolves icon and i18n title key\r\n const viewerConfig = VIEWER_CONFIG[currentViewer]\r\n const headerTitle = t(viewerConfig.titleKey)\r\n const MenuIcon = viewerConfig.icon\r\n\r\n // Derived data, filtered data, and filter options — all per-viewer logic lives in this hook\r\n const { data, filteredData, filtersOptions, isLoading } = useViewerData({\r\n currentViewer,\r\n buildings,\r\n sites,\r\n infrastructures,\r\n files,\r\n users,\r\n loadingFlags: {\r\n buildings: buildingsLoading,\r\n sites: sitesLoading,\r\n infrastructures: infrastructuresLoading,\r\n files: filesLoading,\r\n users: usersLoading,\r\n },\r\n searchTerm,\r\n activeFilters,\r\n filters,\r\n userEmail: user?.email || '',\r\n })\r\n\r\n const openedCurrentFileIdRef = React.useRef<number | null>(null)\r\n\r\n React.useEffect(() => {\r\n if (currentViewer !== ViewerNames.files || !currentFile) return\r\n if (openedCurrentFileIdRef.current === currentFile.id) return\r\n\r\n const fileRow = data.find((item): item is FileRow => String(item.id) === String(currentFile.id))\r\n if (!fileRow) return\r\n\r\n openedCurrentFileIdRef.current = currentFile.id\r\n setSelectedFile(fileRow)\r\n setView('detail')\r\n }, [currentViewer, currentFile, data, setSelectedFile, setView])\r\n\r\n // Breadcrumb title — derives the detail page label from whichever item is selected\r\n const breadcrumbTitle = React.useMemo(() => {\r\n if (selectedItem) return selectedItem.buildingName || selectedItem.buildingAddress\r\n if (selectedSite) return selectedSite.siteName || selectedSite.siteAddress\r\n if (selectedInfrastructure) return selectedInfrastructure.infrastructureName || selectedInfrastructure.infrastructureType\r\n if (selectedFile) return selectedFile.name\r\n if (selectedUser) return selectedUser.name\r\n if (currentViewer === ViewerNames.extensions) return 'Extension Details'\r\n return undefined\r\n }, [selectedItem, selectedSite, selectedInfrastructure, selectedFile, selectedUser, currentViewer])\r\n\r\n // Row click handlers — consolidated into one function\r\n\r\n const handleRowClick = (item: Building | Site | Infrastructure | FileRow | User) => {\r\n // Files and users don't participate in compare mode\r\n if (comparing && 'id' in item) {\r\n const id = String(item.id)\r\n const isChecked = compareItems.some(i => i.id === id)\r\n if (isChecked) {\r\n removeItemFromCompare(id)\r\n } else {\r\n addItemToCompare({ ...item, id })\r\n }\r\n return\r\n }\r\n\r\n // Navigate to detail view, setting the correct selected item per viewer\r\n switch (currentViewer) {\r\n case ViewerNames.buildings:\r\n setSelectedItem(item as Building)\r\n break\r\n case ViewerNames.sites:\r\n setSelectedSite(item as Site)\r\n break\r\n case ViewerNames.infrastructure:\r\n setSelectedInfrastructure(item as Infrastructure)\r\n break\r\n case ViewerNames.files:\r\n setSelectedFile(item as FileRow)\r\n break\r\n case ViewerNames.users:\r\n setSelectedUser(item as User)\r\n break\r\n }\r\n setView('detail')\r\n }\r\n\r\nconst handleBackToTable = () => {\r\n setView('table')\r\n setSelectedItem(null)\r\n setSelectedSite(null)\r\n setSelectedInfrastructure(null)\r\n setSelectedFile(null)\r\n setSelectedUser(null)\r\n setEditing(false)\r\n setActiveChanges(false)\r\n }\r\n\r\n // Refs for imperative save on child detail components\r\n\r\n const buildingDetailsRef = React.useRef<BuildingDetailsRef>(null)\r\n const siteDetailsRef = React.useRef<SiteDetailsRef>(null)\r\n const infrastructureDetailsRef = React.useRef<InfrastructureDetailsRef>(null)\r\n const fileDetailsRef = React.useRef(null)\r\n const userDetailsRef = React.useRef(null)\r\n\r\n // Save / create handlers — consolidated into one function\r\n\r\n const handleSaveChanges = async () => {\r\n switch (currentViewer) {\r\n case ViewerNames.buildings:\r\n await buildingDetailsRef.current?.saveChanges()\r\n break\r\n case ViewerNames.sites:\r\n await siteDetailsRef.current?.saveChanges()\r\n break\r\n case ViewerNames.infrastructure:\r\n await infrastructureDetailsRef.current?.saveChanges()\r\n break\r\n case ViewerNames.files:\r\n await fileDetailsRef.current?.saveChanges()\r\n break\r\n case ViewerNames.users:\r\n await userDetailsRef.current?.saveChanges()\r\n break\r\n }\r\n }\r\n\r\n /**\r\n * Handles creation of a new entity (id < 0).\r\n * Calls saveChanges on the appropriate ref, then shows a toast.\r\n * Pass successKey as undefined for viewers that show their own success toast (e.g. buildings).\r\n */\r\n const handleCreate = async (\r\n ref: React.RefObject<{ saveChanges: () => Promise<void> }>,\r\n toastKeys: { successKey?: string; errorKey: string },\r\n ) => {\r\n try {\r\n await ref.current?.saveChanges()\r\n setActiveChanges(false)\r\n if (toastKeys.successKey) toast.success(t(toastKeys.successKey))\r\n } catch (error) {\r\n if (error?.status !== 401) toast.error(t(toastKeys.errorKey))\r\n }\r\n }\r\n\r\n // Dispatches to the right ref + toast keys based on which new item is selected\r\n const handleCreateNewItem = async () => {\r\n if (selectedSite && selectedSite.id < 0) {\r\n await handleCreate(siteDetailsRef, {\r\n successKey: 'toastSuccessCreateSite',\r\n errorKey: 'toastFailCreateSite',\r\n })\r\n } else if (selectedItem && selectedItem.id < 0) {\r\n await handleCreate(buildingDetailsRef, {\r\n // Building details shows its own success toast\r\n errorKey: 'toastFailCreateBuilding',\r\n })\r\n } else if (selectedInfrastructure && selectedInfrastructure.id < 0) {\r\n await handleCreate(infrastructureDetailsRef, {\r\n successKey: 'toastSuccessCreateInfrastructure',\r\n errorKey: 'toastFailCreateInfrastructure',\r\n })\r\n } else {\r\n // Users and existing items — standard save\r\n await handleSaveChanges()\r\n }\r\n }\r\n\r\n // Derived UI helpers\r\n\r\n const isNewItem = !!(\r\n (selectedSite && selectedSite.id < 0)\r\n || (selectedItem && selectedItem.id < 0)\r\n || (selectedInfrastructure && selectedInfrastructure.id < 0)\r\n )\r\n\r\n // Render\r\n\r\n return (\r\n <div className={`${hideFrame ? '' : 'sm:p-2'} overflow-hidden ${hideFrame ? '' : 'bg-[#fafafa]'} ${height ? height : 'h-full'}`}>\r\n <div className={`${hideFrame ? '' : 'bg-background rounded-xl shadow'} h-full min-h-0`}>\r\n <div className=\"flex flex-col h-full min-h-0\">\r\n\r\n {/* Breadcrumb Navigation */}\r\n <div className=\"\">\r\n <div className=\"flex flex-row gap-2 justify-start items-center px-3 py-4 relative\">\r\n <Breadcrumb className=\"px-3\">\r\n <BreadcrumbList>\r\n <BreadcrumbItem>\r\n {view === 'table'\r\n ? <BreadcrumbPage>{headerTitle}</BreadcrumbPage>\r\n : (\r\n <BreadcrumbLink onClick={handleBackToTable} className=\"cursor-pointer\">\r\n {headerTitle}\r\n </BreadcrumbLink>\r\n )}\r\n </BreadcrumbItem>\r\n\r\n {view === 'detail' && (\r\n <>\r\n <BreadcrumbSeparator />\r\n <BreadcrumbItem>\r\n <BreadcrumbPage>{breadcrumbTitle}</BreadcrumbPage>\r\n </BreadcrumbItem>\r\n </>\r\n )}\r\n </BreadcrumbList>\r\n </Breadcrumb>\r\n </div>\r\n\r\n {/* Header content based on view */}\r\n {view === 'table' ? (\r\n <>\r\n {/* Title Row */}\r\n {!hideTitle && (\r\n <div className=\"flex flex-row justify-between items-center px-6 py-6\">\r\n <div className=\"flex flex-col gap-1.5\">\r\n <div className=\"flex items-center gap-2\">\r\n <MenuIcon className=\"h-8 w-8\" />\r\n <h1 className=\"text-2xl text-foreground\">{headerTitle}</h1>\r\n </div>\r\n {comparing && (\r\n <h2 className=\"text-sm text-muted-foreground font-normal\">\r\n Choose up to 3 {headerTitle.toLowerCase()} to compare.\r\n </h2>\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Search & Filter & Actions Row */}\r\n <div className={`flex ${hideTitle ? 'justify-between' : 'justify-end'} items-center px-6 py-4 gap-4`}>\r\n <div className={hideTitle ? 'w-64' : 'w-96'}>\r\n <Input\r\n placeholder={`${t('searchPlaceholder')} ${headerTitle}...`}\r\n value={searchTerm}\r\n onChange={e => setSearchTerm(e.target.value)}\r\n />\r\n </div>\r\n\r\n <div className=\"flex gap-2\">\r\n <FilterButtons\r\n currentViewer={currentViewer}\r\n filters={filters}\r\n activeFilters={activeFilters}\r\n filterFields={filtersOptions}\r\n data={data}\r\n setFilters={setFilters}\r\n setActiveFilters={setActiveFilters}\r\n />\r\n <HeaderButtons\r\n headerTitle={headerTitle}\r\n currentViewer={currentViewer}\r\n compareItems={compareItems}\r\n setCompareItems={setCompareItems}\r\n comparing={comparing}\r\n setComparing={setComparing}\r\n newItemName={newItemName}\r\n setNewItemName={setNewItemName}\r\n filteredData={\r\n currentViewer === ViewerNames.buildings\r\n || currentViewer === ViewerNames.sites\r\n || currentViewer === ViewerNames.infrastructure\r\n ? filteredData\r\n : undefined\r\n }\r\n users={currentViewer === ViewerNames.users ? users : undefined}\r\n />\r\n </div>\r\n </div>\r\n\r\n <Separator />\r\n </>\r\n ) : (\r\n // Detail View Header\r\n <div className=\"flex justify-between items-center px-6 py-6\">\r\n <DetailHeader\r\n selectedItem={selectedItem}\r\n selectedSite={selectedSite}\r\n selectedInfrastructure={selectedInfrastructure}\r\n selectedFile={selectedFile}\r\n selectedUser={selectedUser}\r\n />\r\n\r\n <DetailActions\r\n editing={editing}\r\n activeChanges={activeChanges}\r\n currentViewer={currentViewer}\r\n selectedItem={selectedItem}\r\n selectedSite={selectedSite}\r\n selectedInfrastructure={selectedInfrastructure}\r\n selectedFile={selectedFile}\r\n selectedUser={selectedUser}\r\n activeBuildingTab={activeBuildingTab}\r\n activeSiteTab={activeSiteTab}\r\n onSave={async () => {\r\n await handleCreateNewItem()\r\n setEditing(false)\r\n }}\r\n onEdit={() => {\r\n setEditing(true)\r\n if (isNewItem) setActiveChanges(true)\r\n }}\r\n onCancel={() => {\r\n setEditing(false)\r\n if (isNewItem) handleBackToTable()\r\n }}\r\n onDeleteUser={() => {\r\n setSelectedUser(null)\r\n setView('table')\r\n }}\r\n setView={setView}\r\n />\r\n </div>\r\n )}\r\n\r\n {/* Detail view separator */}\r\n {view === 'detail' && <Separator />}\r\n </div>\r\n\r\n {/* Scrollable Content Area */}\r\n <div className=\"flex-1 overflow-hidden\">\r\n {view === 'table' ? (\r\n <div className=\"h-full flex flex-col md:p-6 overflow-auto\">\r\n <DataTable\r\n columns={currentViewer === ViewerNames.users ? userColumns : tableColumns}\r\n data={filteredData}\r\n onRowClick={handleRowClick}\r\n currentViewer={currentViewer}\r\n isLoading={isLoading}\r\n leadingCell={comparing\r\n ? ({ dataset }) => {\r\n const item = dataset\r\n const isChecked = compareItems.some(i => i?.id === String(item?.id))\r\n const maxReached = compareItems.length >= 3 && !isChecked\r\n\r\n return (\r\n <Button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n className=\"transition-opacity duration-200 hover:bg-transparent\"\r\n onClick={(e) => {\r\n e.stopPropagation()\r\n if (isChecked) {\r\n removeItemFromCompare?.(String(item.id))\r\n } else {\r\n addItemToCompare?.({ ...item, id: String(item.id) })\r\n }\r\n }}\r\n >\r\n <Checkbox\r\n checked={isChecked}\r\n disabled={maxReached}\r\n className={`opacity-70 hover:opacity-100 data-[state=checked]:opacity-100 ${maxReached && '!cursor-default'}`}\r\n />\r\n </Button>\r\n )\r\n }\r\n : undefined}\r\n trailingCell={({ row }) => (\r\n <div onClick={e => e.stopPropagation()}>\r\n <MoreOptions\r\n row={row.original}\r\n dataType={dataType}\r\n hideViewOnMap={currentViewer === ViewerNames.users}\r\n setView={setView}\r\n onDeleteUser={() => setSelectedUser(null)}\r\n />\r\n </div>\r\n )}\r\n />\r\n </div>\r\n ) : (\r\n <div className=\"h-full overflow-auto\">\r\n {selectedFile\r\n ? (\r\n <FileDetails\r\n selectedFile={selectedFile}\r\n buildings={buildings || []}\r\n editing={editing}\r\n setEditing={setEditing}\r\n setActiveChanges={setActiveChanges}\r\n ref={fileDetailsRef}\r\n />\r\n )\r\n : currentViewer === ViewerNames.buildings\r\n ? (\r\n <BuildingDetails\r\n selectedItem={selectedItem}\r\n setSelectedItem={setSelectedItem}\r\n editing={editing}\r\n setEditing={setEditing}\r\n setActiveChanges={setActiveChanges}\r\n buildings={buildings || []}\r\n ref={buildingDetailsRef}\r\n activeTab={activeBuildingTab}\r\n setActiveTab={setActiveBuildingTab}\r\n />\r\n )\r\n : currentViewer === ViewerNames.sites\r\n ? (\r\n <SiteDetails\r\n selectedSite={selectedSite}\r\n setSelectedSite={setSelectedSite}\r\n editing={editing}\r\n setEditing={setEditing}\r\n setActiveChanges={setActiveChanges}\r\n sites={sites || []}\r\n ref={siteDetailsRef}\r\n activeTab={activeSiteTab}\r\n setActiveTab={setActiveSiteTab}\r\n />\r\n )\r\n : currentViewer === ViewerNames.infrastructure\r\n ? (\r\n <InfrastructureDetails\r\n selectedInfrastructure={selectedInfrastructure}\r\n setSelectedInfrastructure={setSelectedInfrastructure}\r\n editing={editing}\r\n setEditing={setEditing}\r\n setActiveChanges={setActiveChanges}\r\n infrastructures={infrastructures || []}\r\n ref={infrastructureDetailsRef}\r\n activeTab={activeInfrastructureTab}\r\n setActiveTab={setActiveInfrastructureTab}\r\n />\r\n )\r\n : currentViewer === ViewerNames.users\r\n ? (\r\n <UserDetails\r\n selectedUser={selectedUser}\r\n setSelectedUser={setSelectedUser}\r\n editing={editing}\r\n setEditing={setEditing}\r\n setActiveChanges={setActiveChanges}\r\n users={users || []}\r\n ref={userDetailsRef}\r\n hideTitle={hideTitle}\r\n />\r\n )\r\n : null}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n )\r\n}"],"mappings":"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","names":["_a","_b","_c"]}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/core/components/viewers/Data/DataMenu.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\n// Dependencies\r\nimport * as React from 'react'\r\nimport { toast } from 'sonner'\r\nimport { useTranslations } from 'next-intl'\r\nimport { handleApiError } from '../../../utils/errorHandler'\r\n\r\n// Utils\r\nimport { useViewerData } from './utils/useViewerData'\r\nimport { VIEWER_CONFIG } from './utils/viewerConfig'\r\n\r\nimport type { Building, Site, User, Infrastructure, Organization } from '../../../types/dbTypes'\r\nimport type { FilterState } from '../../../types/global'\r\n\r\n// Custom hooks\r\nimport { useBuildings, useCreateBuilding } from '../../../hooks/buildings/buildings'\r\nimport { useCreateSite, useSites } from '../../../hooks/sites/sites'\r\nimport { useFiles } from '../../../hooks/files/files'\r\nimport { useUsers } from '../../../hooks/users/users'\r\n\r\n// Context\r\nimport { useMenusContext } from '../../../store'\r\nimport { useBuildingsContext } from '../../../store'\r\nimport { useFilesContext } from '../../../store'\r\n\r\n// Types\r\nimport type { FileRow } from '../../../types/files'\r\nimport {\r\n Breadcrumb,\r\n BreadcrumbItem,\r\n BreadcrumbLink,\r\n BreadcrumbList,\r\n BreadcrumbPage,\r\n BreadcrumbSeparator,\r\n} from '../../ui/Breadcrumb'\r\nimport { Button, Checkbox, DataTable, Input, Separator } from '../../ui/'\r\n\r\nimport type { BuildingDetailsRef } from './buildingDetails/BuildingDetails'\r\nimport type { SiteDetailsRef } from './siteDetails/SiteDetails'\r\nimport type { InfrastructureDetailsRef } from './infrastructureDetails/InfrastructureDetails'\r\n\r\nimport BuildingDetails from './buildingDetails/BuildingDetails'\r\nimport { FileDetails } from './files/FileDetails'\r\n\r\n// Custom Components\r\nimport DetailActions from './details/DetailActions'\r\nimport DetailHeader from './details/DetailHeader'\r\nimport FilterButtons from './FilterButtons'\r\nimport HeaderButtons from './HeaderButtons'\r\nimport MoreOptions from './MoreOptions'\r\nimport SiteDetails from './siteDetails/SiteDetails'\r\nimport UserDetails from './userDetails/UserDetails'\r\n\r\n// Data\r\nimport { useColumns, useUserColumns } from './utils/Columns'\r\nimport { useBuildingHeaders, useInfrastructureHeaders, useSiteHeaders } from './utils/Headers'\r\nimport { DataTypes, DataTypesNames, ViewerNames } from '../../../types'\r\nimport { useSession } from 'next-auth/react'\r\nimport InfrastructureDetails from './infrastructureDetails/InfrastructureDetails'\r\nimport { useCreateInfrastructure, useInfrastructures } from '../../../hooks/infrastructures/infrastructures'\r\n\r\ntype DataMenuProps = {\r\n currentViewer: ViewerNames\r\n height?: string\r\n hideFrame?: boolean\r\n hideTitle?: boolean\r\n hideActions?: boolean\r\n organization?: Organization\r\n geocodeEarthApiKey?: string\r\n geocoderUrl?: string\r\n}\r\n\r\nexport function DataMenu({ currentViewer, height, hideTitle, hideActions, hideFrame, organization, geocodeEarthApiKey, geocoderUrl }: DataMenuProps) {\r\n // Translations\r\n const t = useTranslations('DataMenu')\r\n\r\n // View state\r\n const { view, setView } = useMenusContext()\r\n const { selectedItem, setSelectedItem } = useMenusContext()\r\n const { selectedSite, setSelectedSite } = useMenusContext()\r\n const { selectedInfrastructure, setSelectedInfrastructure } = useMenusContext()\r\n const { selectedFile, setSelectedFile } = useMenusContext()\r\n const { selectedUser, setSelectedUser } = useMenusContext()\r\n const { state: fileState } = useFilesContext()\r\n const { currentFile } = fileState.files\r\n\r\n // Search / filter state\r\n const [searchTerm, setSearchTerm] = React.useState('')\r\n const [activeFilters, setActiveFilters] = React.useState<FilterState[]>([])\r\n const [filters, setFilters] = React.useState([\r\n { id: 1, field: '', fieldType: null, operator: null, value: null, secondValue: null },\r\n ])\r\n\r\n const [dataType, setDataType] = React.useState<DataTypes>(DataTypesNames.building)\r\n const [editing, setEditing] = React.useState(false)\r\n const [activeChanges, setActiveChanges] = React.useState(false)\r\n\r\n // Tab headers\r\n const buildingHeaders = useBuildingHeaders()\r\n const siteHeaders = useSiteHeaders()\r\n const infrastructureHeaders = useInfrastructureHeaders()\r\n\r\n const buildingTabOptions = buildingHeaders.map(section => ({\r\n key: section.title.toLowerCase().replaceAll(/\\s/g, '-'),\r\n label: section.title,\r\n }))\r\n const siteTabOptions = siteHeaders.map(section => ({\r\n key: section.title.toLowerCase().replaceAll(/\\s/g, '-'),\r\n label: section.title,\r\n }))\r\n const infrastructureTabOptions = infrastructureHeaders.map(section => ({\r\n key: section.title.toLowerCase().replaceAll(/\\s/g, '-'),\r\n label: section.title,\r\n }))\r\n\r\n const [activeBuildingTab, setActiveBuildingTab] = React.useState(buildingTabOptions[0]?.key || '')\r\n const [activeSiteTab, setActiveSiteTab] = React.useState(siteTabOptions[0]?.key || '')\r\n const [activeInfrastructureTab, setActiveInfrastructureTab] = React.useState(infrastructureTabOptions[0]?.key || '')\r\n\r\n // Reset active tab only when selected item ID changes\r\n const prevBuildingId = React.useRef<number | undefined>(undefined)\r\n const prevInfrastructureId = React.useRef<number | undefined>(undefined)\r\n\r\n React.useEffect(() => {\r\n if (currentViewer === ViewerNames.buildings && selectedItem?.id !== prevBuildingId.current) {\r\n setActiveBuildingTab(buildingTabOptions[0]?.key || '')\r\n prevBuildingId.current = selectedItem?.id\r\n }\r\n if (currentViewer === ViewerNames.infrastructure && selectedInfrastructure?.id !== prevInfrastructureId.current) {\r\n setActiveInfrastructureTab(infrastructureTabOptions[0]?.key || '')\r\n prevInfrastructureId.current = selectedInfrastructure?.id\r\n }\r\n }, [selectedItem?.id, selectedInfrastructure?.id, currentViewer])\r\n\r\n const [newItemName, setNewItemName] = React.useState('')\r\n\r\n // Compare state\r\n const {\r\n compareItems,\r\n setCompareItems,\r\n comparing,\r\n setComparing,\r\n addItemToCompare,\r\n removeItemFromCompare,\r\n } = useBuildingsContext()\r\n\r\n // Sync dataType with current viewer. ViewerNames are plural ('sites',\r\n // 'buildings', …) while DataTypes are singular ('site', 'building', …), so a\r\n // direct index returns undefined for most viewers — map explicitly.\r\n React.useEffect(() => {\r\n const viewerToDataType: Partial<Record<string, DataTypes>> = {\r\n [ViewerNames.buildings]: DataTypesNames.building,\r\n [ViewerNames.sites]: DataTypesNames.site,\r\n [ViewerNames.infrastructure]: DataTypesNames.infrastructure,\r\n [ViewerNames.files]: DataTypesNames.file,\r\n [ViewerNames.users]: DataTypesNames.user,\r\n }\r\n setDataType(viewerToDataType[currentViewer] ?? DataTypesNames.building)\r\n }, [currentViewer])\r\n\r\n // Reset compare state when viewer changes\r\n React.useEffect(() => {\r\n setComparing(false)\r\n setCompareItems([])\r\n }, [currentViewer, setComparing, setCompareItems])\r\n\r\n // Data fetching\r\n const { buildings, isLoading: buildingsLoading, isError: buildingsError } = useBuildings()\r\n const { sites, isLoading: sitesLoading, isError: sitesError } = useSites()\r\n const { infrastructures, isLoading: infrastructuresLoading, isError: infrastructuresError } = useInfrastructures()\r\n const { files, isLoading: filesLoading, isError: filesError } = useFiles()\r\n const { users, isLoading: usersLoading, isError: usersError } = useUsers()\r\n\r\n const { createError: createSiteError } = useCreateSite()\r\n const { createError: createBuildingError } = useCreateBuilding()\r\n const { createError: createInfrastructureError } = useCreateInfrastructure()\r\n\r\n React.useEffect(() => {\r\n handleApiError(buildingsError)\r\n handleApiError(sitesError)\r\n handleApiError(filesError)\r\n handleApiError(infrastructuresError)\r\n handleApiError(usersError)\r\n handleApiError(createSiteError)\r\n handleApiError(createBuildingError)\r\n handleApiError(createInfrastructureError)\r\n }, [buildingsError, sitesError, infrastructuresError, filesError, usersError, createSiteError, createBuildingError, createInfrastructureError])\r\n\r\n const tableColumns = useColumns(buildings || [])\r\n const userColumns = useUserColumns()\r\n\r\n const { user } = useSession().data\r\n\r\n // Viewer config — resolves icon and i18n title key\r\n const viewerConfig = VIEWER_CONFIG[currentViewer]\r\n const headerTitle = t(viewerConfig.titleKey)\r\n const MenuIcon = viewerConfig.icon\r\n\r\n // Derived data, filtered data, and filter options — all per-viewer logic lives in this hook\r\n const { data, filteredData, filtersOptions, isLoading } = useViewerData({\r\n currentViewer,\r\n buildings,\r\n sites,\r\n infrastructures,\r\n files,\r\n users,\r\n loadingFlags: {\r\n buildings: buildingsLoading,\r\n sites: sitesLoading,\r\n infrastructures: infrastructuresLoading,\r\n files: filesLoading,\r\n users: usersLoading,\r\n },\r\n searchTerm,\r\n activeFilters,\r\n filters,\r\n userEmail: user?.email || '',\r\n })\r\n\r\n const openedCurrentFileIdRef = React.useRef<number | null>(null)\r\n\r\n React.useEffect(() => {\r\n if (currentViewer !== ViewerNames.files || !currentFile) return\r\n if (openedCurrentFileIdRef.current === currentFile.id) return\r\n\r\n const fileRow = data.find((item): item is FileRow => String(item.id) === String(currentFile.id))\r\n if (!fileRow) return\r\n\r\n openedCurrentFileIdRef.current = currentFile.id\r\n setSelectedFile(fileRow)\r\n setView('detail')\r\n }, [currentViewer, currentFile, data, setSelectedFile, setView])\r\n\r\n // Breadcrumb title — derives the detail page label from whichever item is selected\r\n const breadcrumbTitle = React.useMemo(() => {\r\n if (selectedItem) return selectedItem.buildingName || selectedItem.buildingAddress\r\n if (selectedSite) return selectedSite.siteName || selectedSite.siteAddress\r\n if (selectedInfrastructure) return selectedInfrastructure.infrastructureName || selectedInfrastructure.infrastructureType\r\n if (selectedFile) return selectedFile.name\r\n if (selectedUser) return selectedUser.name\r\n if (currentViewer === ViewerNames.extensions) return 'Extension Details'\r\n return undefined\r\n }, [selectedItem, selectedSite, selectedInfrastructure, selectedFile, selectedUser, currentViewer])\r\n\r\n // Row click handlers — consolidated into one function\r\n\r\n const handleRowClick = (item: Building | Site | Infrastructure | FileRow | User) => {\r\n // Files and users don't participate in compare mode\r\n if (comparing && 'id' in item) {\r\n const id = String(item.id)\r\n const isChecked = compareItems.some(i => i.id === id)\r\n if (isChecked) {\r\n removeItemFromCompare(id)\r\n } else {\r\n addItemToCompare({ ...item, id })\r\n }\r\n return\r\n }\r\n\r\n // Navigate to detail view, setting the correct selected item per viewer\r\n switch (currentViewer) {\r\n case ViewerNames.buildings:\r\n setSelectedItem(item as Building)\r\n break\r\n case ViewerNames.sites:\r\n setSelectedSite(item as Site)\r\n break\r\n case ViewerNames.infrastructure:\r\n setSelectedInfrastructure(item as Infrastructure)\r\n break\r\n case ViewerNames.files:\r\n setSelectedFile(item as FileRow)\r\n break\r\n case ViewerNames.users:\r\n setSelectedUser(item as User)\r\n break\r\n }\r\n setView('detail')\r\n }\r\n\r\nconst handleBackToTable = () => {\r\n setView('table')\r\n setSelectedItem(null)\r\n setSelectedSite(null)\r\n setSelectedInfrastructure(null)\r\n setSelectedFile(null)\r\n setSelectedUser(null)\r\n setEditing(false)\r\n setActiveChanges(false)\r\n }\r\n\r\n // Refs for imperative save on child detail components\r\n\r\n const buildingDetailsRef = React.useRef<BuildingDetailsRef>(null)\r\n const siteDetailsRef = React.useRef<SiteDetailsRef>(null)\r\n const infrastructureDetailsRef = React.useRef<InfrastructureDetailsRef>(null)\r\n const fileDetailsRef = React.useRef(null)\r\n const userDetailsRef = React.useRef(null)\r\n\r\n // Save / create handlers — consolidated into one function\r\n\r\n const handleSaveChanges = async () => {\r\n switch (currentViewer) {\r\n case ViewerNames.buildings:\r\n await buildingDetailsRef.current?.saveChanges()\r\n break\r\n case ViewerNames.sites:\r\n await siteDetailsRef.current?.saveChanges()\r\n break\r\n case ViewerNames.infrastructure:\r\n await infrastructureDetailsRef.current?.saveChanges()\r\n break\r\n case ViewerNames.files:\r\n await fileDetailsRef.current?.saveChanges()\r\n break\r\n case ViewerNames.users:\r\n await userDetailsRef.current?.saveChanges()\r\n break\r\n }\r\n }\r\n\r\n /**\r\n * Handles creation of a new entity (id < 0).\r\n * Calls saveChanges on the appropriate ref, then shows a toast.\r\n * Pass successKey as undefined for viewers that show their own success toast (e.g. buildings).\r\n */\r\n const handleCreate = async (\r\n ref: React.RefObject<{ saveChanges: () => Promise<void> }>,\r\n toastKeys: { successKey?: string; errorKey: string },\r\n ) => {\r\n try {\r\n await ref.current?.saveChanges()\r\n setActiveChanges(false)\r\n if (toastKeys.successKey) toast.success(t(toastKeys.successKey))\r\n } catch (error) {\r\n if (error?.status !== 401) toast.error(t(toastKeys.errorKey))\r\n }\r\n }\r\n\r\n // Dispatches to the right ref + toast keys based on which new item is selected\r\n const handleCreateNewItem = async () => {\r\n if (selectedSite && selectedSite.id < 0) {\r\n await handleCreate(siteDetailsRef, {\r\n successKey: 'toastSuccessCreateSite',\r\n errorKey: 'toastFailCreateSite',\r\n })\r\n } else if (selectedItem && selectedItem.id < 0) {\r\n await handleCreate(buildingDetailsRef, {\r\n // Building details shows its own success toast\r\n errorKey: 'toastFailCreateBuilding',\r\n })\r\n } else if (selectedInfrastructure && selectedInfrastructure.id < 0) {\r\n await handleCreate(infrastructureDetailsRef, {\r\n successKey: 'toastSuccessCreateInfrastructure',\r\n errorKey: 'toastFailCreateInfrastructure',\r\n })\r\n } else {\r\n // Users and existing items — standard save\r\n await handleSaveChanges()\r\n }\r\n }\r\n\r\n // Derived UI helpers\r\n\r\n const isNewItem = !!(\r\n (selectedSite && selectedSite.id < 0)\r\n || (selectedItem && selectedItem.id < 0)\r\n || (selectedInfrastructure && selectedInfrastructure.id < 0)\r\n )\r\n\r\n // Render\r\n\r\n return (\r\n <div className={`${hideFrame ? '' : 'sm:p-2'} overflow-hidden ${hideFrame ? '' : 'bg-[#fafafa]'} ${height ? height : 'h-full'}`}>\r\n <div className={`${hideFrame ? '' : 'bg-background rounded-xl shadow'} h-full min-h-0`}>\r\n <div className=\"flex flex-col h-full min-h-0\">\r\n\r\n {/* Breadcrumb Navigation */}\r\n <div className=\"\">\r\n <div className=\"flex flex-row gap-2 justify-start items-center px-3 py-4 relative\">\r\n <Breadcrumb className=\"px-3\">\r\n <BreadcrumbList>\r\n <BreadcrumbItem>\r\n {view === 'table'\r\n ? <BreadcrumbPage>{headerTitle}</BreadcrumbPage>\r\n : (\r\n <BreadcrumbLink onClick={handleBackToTable} className=\"cursor-pointer\">\r\n {headerTitle}\r\n </BreadcrumbLink>\r\n )}\r\n </BreadcrumbItem>\r\n\r\n {view === 'detail' && (\r\n <>\r\n <BreadcrumbSeparator />\r\n <BreadcrumbItem>\r\n <BreadcrumbPage>{breadcrumbTitle}</BreadcrumbPage>\r\n </BreadcrumbItem>\r\n </>\r\n )}\r\n </BreadcrumbList>\r\n </Breadcrumb>\r\n </div>\r\n\r\n {/* Header content based on view */}\r\n {view === 'table' ? (\r\n <>\r\n {/* Title Row */}\r\n {!hideTitle && (\r\n <div className=\"flex flex-row justify-between items-center px-6 py-6\">\r\n <div className=\"flex flex-col gap-1.5\">\r\n <div className=\"flex items-center gap-2\">\r\n <MenuIcon className=\"h-8 w-8\" />\r\n <h1 className=\"text-2xl text-foreground\">{headerTitle}</h1>\r\n </div>\r\n {comparing && (\r\n <h2 className=\"text-sm text-muted-foreground font-normal\">\r\n Choose up to 3 {headerTitle.toLowerCase()} to compare.\r\n </h2>\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Search & Filter & Actions Row */}\r\n <div className={`flex ${hideTitle ? 'justify-between' : 'justify-end'} items-center px-6 py-4 gap-4`}>\r\n <div className={hideTitle ? 'w-64' : 'w-96'}>\r\n <Input\r\n placeholder={`${t('searchPlaceholder')} ${headerTitle}...`}\r\n value={searchTerm}\r\n onChange={e => setSearchTerm(e.target.value)}\r\n />\r\n </div>\r\n\r\n <div className=\"flex gap-2\">\r\n <FilterButtons\r\n currentViewer={currentViewer}\r\n filters={filters}\r\n activeFilters={activeFilters}\r\n filterFields={filtersOptions}\r\n data={data}\r\n setFilters={setFilters}\r\n setActiveFilters={setActiveFilters}\r\n />\r\n <HeaderButtons\r\n headerTitle={headerTitle}\r\n currentViewer={currentViewer}\r\n compareItems={compareItems}\r\n setCompareItems={setCompareItems}\r\n comparing={comparing}\r\n setComparing={setComparing}\r\n newItemName={newItemName}\r\n setNewItemName={setNewItemName}\r\n filteredData={\r\n currentViewer === ViewerNames.buildings\r\n || currentViewer === ViewerNames.sites\r\n || currentViewer === ViewerNames.infrastructure\r\n ? filteredData\r\n : undefined\r\n }\r\n users={currentViewer === ViewerNames.users ? users : undefined}\r\n geocodeEarthApiKey={geocodeEarthApiKey}\r\n geocoderUrl={geocoderUrl}\r\n />\r\n </div>\r\n </div>\r\n\r\n <Separator />\r\n </>\r\n ) : (\r\n // Detail View Header\r\n <div className=\"flex justify-between items-center px-6 py-6\">\r\n <DetailHeader\r\n selectedItem={selectedItem}\r\n selectedSite={selectedSite}\r\n selectedInfrastructure={selectedInfrastructure}\r\n selectedFile={selectedFile}\r\n selectedUser={selectedUser}\r\n countryCode={organization?.country}\r\n />\r\n\r\n <DetailActions\r\n editing={editing}\r\n activeChanges={activeChanges}\r\n currentViewer={currentViewer}\r\n selectedItem={selectedItem}\r\n selectedSite={selectedSite}\r\n selectedInfrastructure={selectedInfrastructure}\r\n selectedFile={selectedFile}\r\n selectedUser={selectedUser}\r\n activeBuildingTab={activeBuildingTab}\r\n activeSiteTab={activeSiteTab}\r\n onSave={async () => {\r\n await handleCreateNewItem()\r\n setEditing(false)\r\n }}\r\n onEdit={() => {\r\n setEditing(true)\r\n if (isNewItem) setActiveChanges(true)\r\n }}\r\n onCancel={() => {\r\n setEditing(false)\r\n if (isNewItem) handleBackToTable()\r\n }}\r\n onDeleteUser={() => {\r\n setSelectedUser(null)\r\n setView('table')\r\n }}\r\n setView={setView}\r\n />\r\n </div>\r\n )}\r\n\r\n {/* Detail view separator */}\r\n {view === 'detail' && <Separator />}\r\n </div>\r\n\r\n {/* Scrollable Content Area */}\r\n <div className=\"flex-1 overflow-hidden\">\r\n {view === 'table' ? (\r\n <div className=\"h-full flex flex-col md:p-6 overflow-auto\">\r\n <DataTable\r\n columns={currentViewer === ViewerNames.users ? userColumns : tableColumns}\r\n data={filteredData}\r\n onRowClick={handleRowClick}\r\n currentViewer={currentViewer}\r\n isLoading={isLoading}\r\n leadingCell={comparing\r\n ? ({ dataset }) => {\r\n const item = dataset\r\n const isChecked = compareItems.some(i => i?.id === String(item?.id))\r\n const maxReached = compareItems.length >= 3 && !isChecked\r\n\r\n return (\r\n <Button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n className=\"transition-opacity duration-200 hover:bg-transparent\"\r\n onClick={(e) => {\r\n e.stopPropagation()\r\n if (isChecked) {\r\n removeItemFromCompare?.(String(item.id))\r\n } else {\r\n addItemToCompare?.({ ...item, id: String(item.id) })\r\n }\r\n }}\r\n >\r\n <Checkbox\r\n checked={isChecked}\r\n disabled={maxReached}\r\n className={`opacity-70 hover:opacity-100 data-[state=checked]:opacity-100 ${maxReached && '!cursor-default'}`}\r\n />\r\n </Button>\r\n )\r\n }\r\n : undefined}\r\n trailingCell={({ row }) => (\r\n <div onClick={e => e.stopPropagation()}>\r\n <MoreOptions\r\n row={row.original}\r\n dataType={dataType}\r\n hideViewOnMap={currentViewer === ViewerNames.users}\r\n setView={setView}\r\n onDeleteUser={() => setSelectedUser(null)}\r\n />\r\n </div>\r\n )}\r\n />\r\n </div>\r\n ) : (\r\n <div className=\"h-full overflow-auto\">\r\n {selectedFile\r\n ? (\r\n <FileDetails\r\n selectedFile={selectedFile}\r\n buildings={buildings || []}\r\n editing={editing}\r\n setEditing={setEditing}\r\n setActiveChanges={setActiveChanges}\r\n ref={fileDetailsRef}\r\n />\r\n )\r\n : currentViewer === ViewerNames.buildings\r\n ? (\r\n <BuildingDetails\r\n selectedItem={selectedItem}\r\n setSelectedItem={setSelectedItem}\r\n editing={editing}\r\n setEditing={setEditing}\r\n setActiveChanges={setActiveChanges}\r\n buildings={buildings || []}\r\n ref={buildingDetailsRef}\r\n activeTab={activeBuildingTab}\r\n setActiveTab={setActiveBuildingTab}\r\n />\r\n )\r\n : currentViewer === ViewerNames.sites\r\n ? (\r\n <SiteDetails\r\n selectedSite={selectedSite}\r\n setSelectedSite={setSelectedSite}\r\n editing={editing}\r\n setEditing={setEditing}\r\n setActiveChanges={setActiveChanges}\r\n sites={sites || []}\r\n ref={siteDetailsRef}\r\n activeTab={activeSiteTab}\r\n setActiveTab={setActiveSiteTab}\r\n />\r\n )\r\n : currentViewer === ViewerNames.infrastructure\r\n ? (\r\n <InfrastructureDetails\r\n selectedInfrastructure={selectedInfrastructure}\r\n setSelectedInfrastructure={setSelectedInfrastructure}\r\n editing={editing}\r\n setEditing={setEditing}\r\n setActiveChanges={setActiveChanges}\r\n infrastructures={infrastructures || []}\r\n ref={infrastructureDetailsRef}\r\n activeTab={activeInfrastructureTab}\r\n setActiveTab={setActiveInfrastructureTab}\r\n />\r\n )\r\n : currentViewer === ViewerNames.users\r\n ? (\r\n <UserDetails\r\n selectedUser={selectedUser}\r\n setSelectedUser={setSelectedUser}\r\n editing={editing}\r\n setEditing={setEditing}\r\n setActiveChanges={setActiveChanges}\r\n users={users || []}\r\n ref={userDetailsRef}\r\n hideTitle={hideTitle}\r\n />\r\n )\r\n : null}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n )\r\n}"],"mappings":"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","names":["_a","_b","_c"]}
|
|
@@ -12,7 +12,9 @@ type HeaderButtonsProps = {
|
|
|
12
12
|
setNewItemName: React.Dispatch<React.SetStateAction<string>>;
|
|
13
13
|
filteredData?: Array<Building | Site>;
|
|
14
14
|
users?: User[];
|
|
15
|
+
geocodeEarthApiKey?: string;
|
|
16
|
+
geocoderUrl?: string;
|
|
15
17
|
};
|
|
16
|
-
export default function HeaderButtons({ headerTitle, currentViewer, compareItems, setCompareItems, comparing, setComparing, newItemName, setNewItemName, filteredData, users, }: HeaderButtonsProps): React.JSX.Element;
|
|
18
|
+
export default function HeaderButtons({ headerTitle, currentViewer, compareItems, setCompareItems, comparing, setComparing, newItemName, setNewItemName, filteredData, users, geocodeEarthApiKey, geocoderUrl, }: HeaderButtonsProps): React.JSX.Element;
|
|
17
19
|
export {};
|
|
18
20
|
//# sourceMappingURL=HeaderButtons.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HeaderButtons.d.ts","sourceRoot":"","sources":["../../../../../src/core/components/viewers/Data/HeaderButtons.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAM9B,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAA;AAGlE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAmBjD,KAAK,kBAAkB,GAAG;IACxB,WAAW,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,WAAW,EAAE,CAAA;IAC3B,eAAe,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,WAAW,EAAE,CAAC,CAAC,CAAA;IACrE,SAAS,EAAE,OAAO,CAAA;IAClB,YAAY,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAA;IAC3D,WAAW,EAAE,MAAM,CAAA;IACnB,cAAc,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAA;IAC5D,YAAY,CAAC,EAAE,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAA;IACrC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAA;
|
|
1
|
+
{"version":3,"file":"HeaderButtons.d.ts","sourceRoot":"","sources":["../../../../../src/core/components/viewers/Data/HeaderButtons.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAM9B,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAA;AAGlE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAmBjD,KAAK,kBAAkB,GAAG;IACxB,WAAW,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,WAAW,EAAE,CAAA;IAC3B,eAAe,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,WAAW,EAAE,CAAC,CAAC,CAAA;IACrE,SAAS,EAAE,OAAO,CAAA;IAClB,YAAY,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAA;IAC3D,WAAW,EAAE,MAAM,CAAA;IACnB,cAAc,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAA;IAC5D,YAAY,CAAC,EAAE,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAA;IACrC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAA;IACd,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,EACpC,WAAW,EACX,aAAa,EACb,YAAY,EACZ,eAAe,EACf,SAAS,EACT,YAAY,EACZ,WAAW,EACX,cAAc,EACd,YAAY,EACZ,KAAK,EACL,kBAAkB,EAClB,WAAW,GACZ,EAAE,kBAAkB,qBAuOpB"}
|
|
@@ -25,8 +25,8 @@ import { useTranslations } from "next-intl";
|
|
|
25
25
|
import { usePermissions } from "../../../store";
|
|
26
26
|
import { DatasetsContext, MapContext, MenusContext } from "../../../store";
|
|
27
27
|
import { Button } from "../../../components/ui/Button";
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
28
|
+
import { fitBuildingsBounds } from "../map/utils/fitBuildingsBounds";
|
|
29
|
+
import { useShowSitesOnMap } from "../map/src/MapLayers/src/SiteLayer/useShowSitesOnMap";
|
|
30
30
|
import AddBuilding from "./buildingDetails/AddBuilding";
|
|
31
31
|
import DatatableFileAdder from "./files/DatatableFileAdder";
|
|
32
32
|
import AddSite from "./siteDetails/AddSite";
|
|
@@ -47,7 +47,9 @@ function HeaderButtons({
|
|
|
47
47
|
newItemName,
|
|
48
48
|
setNewItemName,
|
|
49
49
|
filteredData,
|
|
50
|
-
users
|
|
50
|
+
users,
|
|
51
|
+
geocodeEarthApiKey,
|
|
52
|
+
geocoderUrl
|
|
51
53
|
}) {
|
|
52
54
|
const t = useTranslations("HeaderButtons");
|
|
53
55
|
const { ability } = usePermissions();
|
|
@@ -60,6 +62,7 @@ function HeaderButtons({
|
|
|
60
62
|
const [addBuildingOpen, setAddBuildingOpen] = React.useState(false);
|
|
61
63
|
const [addUserOpen, setAddUserOpen] = React.useState(false);
|
|
62
64
|
const { map } = mapState.map;
|
|
65
|
+
const showSitesOnMap = useShowSitesOnMap();
|
|
63
66
|
const firstBuilding = compareItems[0];
|
|
64
67
|
const coordinates = firstBuilding ? "buildingLongitude" in firstBuilding && "buildingLatitude" in firstBuilding ? [firstBuilding.buildingLongitude, firstBuilding.buildingLatitude] : "coordinates" in firstBuilding : void 0;
|
|
65
68
|
const handleViewOnMap = () => {
|
|
@@ -99,18 +102,10 @@ function HeaderButtons({
|
|
|
99
102
|
});
|
|
100
103
|
fitBuildingsBounds(validBuildings, map);
|
|
101
104
|
} else if (currentViewer === "sites") {
|
|
102
|
-
const validSites = filteredData.filter(
|
|
103
|
-
(item) => item.siteLongitude != null && item.siteLatitude != null
|
|
104
|
-
);
|
|
105
|
+
const validSites = (filteredData != null ? filteredData : []).filter((item) => !!(item == null ? void 0 : item.id));
|
|
105
106
|
if (validSites.length === 0)
|
|
106
107
|
return;
|
|
107
|
-
|
|
108
|
-
const dataset = createSitesDataset(validSites, name);
|
|
109
|
-
datasetDispatch({
|
|
110
|
-
type: "ADD_DATASET_TO_MAP",
|
|
111
|
-
payload: { dataset }
|
|
112
|
-
});
|
|
113
|
-
fitSitesBounds(validSites, map);
|
|
108
|
+
await showSitesOnMap(validSites, { switchViewer: false });
|
|
114
109
|
} else if (currentViewer === "infrastructure") {
|
|
115
110
|
}
|
|
116
111
|
};
|
|
@@ -161,7 +156,9 @@ function HeaderButtons({
|
|
|
161
156
|
newBuildingFields,
|
|
162
157
|
setNewBuildingFields,
|
|
163
158
|
open: addBuildingOpen,
|
|
164
|
-
onOpenChange: setAddBuildingOpen
|
|
159
|
+
onOpenChange: setAddBuildingOpen,
|
|
160
|
+
geocodeEarthApiKey,
|
|
161
|
+
geocoderUrl
|
|
165
162
|
}
|
|
166
163
|
),
|
|
167
164
|
/* @__PURE__ */ jsx(BuildingMoreOptions, { buildings: filteredData, variant: "outline" })
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/core/components/viewers/Data/HeaderButtons.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\n// Icons\r\nimport * as LR from 'lucide-react'\r\n// Dependencies\r\nimport * as React from 'react'\r\nimport { useTranslations } from 'next-intl'\r\nimport { usePermissions } from '../../../store'\r\n\r\n// Utils\r\nimport type { Dataset } from '../../../types/datasetTypes'\r\nimport type { Building, Site, User } from '../../../types/dbTypes'\r\n\r\nimport { DatasetsContext, MapContext, MenusContext } from '../../../store'\r\nimport type { CompareItem } from '../../../store'\r\n\r\n// Shadcn Components\r\nimport { Button } from '../../../components/ui/Button'\r\nimport { createSitesDataset } from '../map/src/MapLayers/src/SiteLayer'\r\nimport { fitBuildingsBounds, fitSitesBounds } from '../map/utils/fitBuildingsBounds'\r\nimport AddBuilding from './buildingDetails/AddBuilding'\r\n// File Adder\r\nimport DatatableFileAdder from './files/DatatableFileAdder'\r\n// Custom Components\r\nimport AddSite from './siteDetails/AddSite'\r\nimport CompareDialog from '../map/src/compare/CompareDialog'\r\nimport UserMoreOptions from './userDetails/UserMoreOptions'\r\nimport AddUser from './userDetails/AddUser'\r\nimport BuildingMoreOptions from './buildingDetails/BuildingsMoreOptions'\r\nimport { ViewerNames } from '../../../types/'\r\nimport AddInfrastructure from './infrastructureDetails/AddInfrastructure'\r\nimport { createBuildingsDataset } from '../map/src/MapLayers/src/BuildingLayers/src/databaseBuildings'\r\n\r\ntype HeaderButtonsProps = {\r\n headerTitle: string\r\n currentViewer: string\r\n compareItems: CompareItem[]\r\n setCompareItems?: React.Dispatch<React.SetStateAction<CompareItem[]>>\r\n comparing: boolean\r\n setComparing: React.Dispatch<React.SetStateAction<boolean>>\r\n newItemName: string\r\n setNewItemName: React.Dispatch<React.SetStateAction<string>>\r\n filteredData?: Array<Building | Site>\r\n users?: User[]\r\n}\r\n\r\nexport default function HeaderButtons({\r\n headerTitle,\r\n currentViewer,\r\n compareItems,\r\n setCompareItems,\r\n comparing,\r\n setComparing,\r\n newItemName,\r\n setNewItemName,\r\n filteredData,\r\n users,\r\n}: HeaderButtonsProps) {\r\n // Translations\r\n const t = useTranslations('HeaderButtons')\r\n\r\n // Permissions\r\n const { ability } = usePermissions()\r\n\r\n const { state: mapState } = React.useContext(MapContext)\r\n const { dispatch: datasetDispatch } = React.useContext(DatasetsContext)\r\n const { dispatch: menusDispatch } = React.useContext(MenusContext)\r\n const [newBuildingFields, setNewBuildingFields] = React.useState({})\r\n const [newInfrastructureFields, setNewInfrastructureFields] = React.useState({})\r\n const [addInfrastructureOpen, setAddInfrastructureOpen] = React.useState(false)\r\n const [addBuildingOpen, setAddBuildingOpen] = React.useState(false)\r\n const [addUserOpen, setAddUserOpen] = React.useState(false)\r\n\r\n const { map } = mapState.map\r\n const firstBuilding = compareItems[0]\r\n\r\n const coordinates = firstBuilding\r\n ? (('buildingLongitude' in firstBuilding && 'buildingLatitude' in firstBuilding)\r\n ? [firstBuilding.buildingLongitude, firstBuilding.buildingLatitude]\r\n : ('coordinates' in firstBuilding))\r\n : undefined\r\n\r\n const handleViewOnMap = () => {\r\n // set the current viewer to map\r\n menusDispatch({\r\n type: 'SET_VIEWER',\r\n payload: { currentViewer: ViewerNames.map },\r\n })\r\n }\r\n\r\n const handleViewAllOnMap = async () => {\r\n if (filteredData.length === 0)\r\n return\r\n\r\n // Switch to map view\r\n menusDispatch({\r\n type: 'SET_VIEWER',\r\n payload: { currentViewer: ViewerNames.map },\r\n })\r\n\r\n if (currentViewer === 'buildings') {\r\n // Filter buildings with valid coordinates\r\n const validBuildings = filteredData.filter(\r\n (item): item is Building => {\r\n const b = item as Building\r\n const lon = b.buildingLongitude\r\n const lat = b.buildingLatitude\r\n if (lon == null || lat == null) return false\r\n\r\n // Rough North America bounding box\r\n const minLat = 5\r\n const maxLat = 85\r\n const minLon = -170\r\n const maxLon = -10\r\n\r\n return Number.isFinite(lat)\r\n && Number.isFinite(lon)\r\n && lat >= minLat\r\n && lat <= maxLat\r\n && lon >= minLon\r\n && lon <= maxLon\r\n }\r\n )\r\n\r\n if (validBuildings.length === 0)\r\n return\r\n\r\n const name = 'Database Buildings'\r\n\r\n const dataset: Dataset = createBuildingsDataset(validBuildings, name)\r\n\r\n // Add buildings as a dataset to the map state\r\n datasetDispatch({\r\n type: 'ADD_DATASET_TO_MAP',\r\n payload: { dataset },\r\n })\r\n\r\n fitBuildingsBounds(validBuildings, map)\r\n }\r\n\r\n else if (currentViewer === 'sites') {\r\n // Filter sites with valid coordinates\r\n const validSites = filteredData.filter(\r\n (item): item is Site =>\r\n (item as Site).siteLongitude != null && (item as Site).siteLatitude != null\r\n )\r\n\r\n if (validSites.length === 0)\r\n return\r\n\r\n const name = 'Database Sites'\r\n\r\n const dataset: Dataset = createSitesDataset(validSites, name)\r\n\r\n // Add buildings as a dataset to the map state\r\n datasetDispatch({\r\n type: 'ADD_DATASET_TO_MAP',\r\n payload: { dataset },\r\n })\r\n\r\n fitSitesBounds(validSites, map)\r\n }\r\n\r\n else if (currentViewer === 'infrastructure') {\r\n // Filter infrastructure with valid coordinates\r\n }\r\n\r\n\r\n }\r\n\r\n const handleAddBuilding = (building: Building) => {\r\n if (setCompareItems) {\r\n const compareItem: CompareItem = {\r\n ...building,\r\n id: String(building.id),\r\n }\r\n setCompareItems([...compareItems, compareItem])\r\n }\r\n }\r\n\r\n const toggleOpen = () => {\r\n setComparing(false)\r\n // Clear compareItems when exiting compare mode for proper cleanup\r\n if (setCompareItems) {\r\n setCompareItems([])\r\n }\r\n }\r\n\r\n return (\r\n <div className=\"flex flex-row gap-2.5\">\r\n {comparing\r\n ? (\r\n <Button\r\n variant=\"outline\"\r\n onClick={() => {\r\n setComparing(false)\r\n // Clear compareItems for proper cleanup when canceling\r\n if (setCompareItems) {\r\n setCompareItems([])\r\n }\r\n }}\r\n disabled={currentViewer === 'buildings' && !ability.can('read', 'Building') || currentViewer === 'sites' && !ability.can('read', 'Site')}\r\n >\r\n {t('cancelButton')}\r\n </Button>\r\n )\r\n : currentViewer === 'files'\r\n ? (\r\n <DatatableFileAdder />\r\n )\r\n : currentViewer === 'buildings'\r\n ? (\r\n <>\r\n <Button\r\n variant=\"default\"\r\n onClick={() => setAddBuildingOpen(true)}\r\n disabled={!ability.can('create', 'Building')}\r\n >\r\n <LR.CirclePlus />\r\n {t('addBuilding')}\r\n </Button>\r\n <AddBuilding\r\n newBuildingFields={newBuildingFields}\r\n setNewBuildingFields={setNewBuildingFields}\r\n open={addBuildingOpen}\r\n onOpenChange={setAddBuildingOpen}\r\n />\r\n <BuildingMoreOptions buildings={filteredData as Building[]} variant=\"outline\" />\r\n </>\r\n )\r\n : currentViewer === 'sites'\r\n ? (\r\n <AddSite\r\n newItemName={newItemName}\r\n setNewItemName={setNewItemName}\r\n />\r\n )\r\n : currentViewer === 'infrastructure'\r\n ? (\r\n <AddInfrastructure\r\n newInfrastructureFields={newInfrastructureFields}\r\n setNewInfrastructureFields={setNewInfrastructureFields}\r\n open={addInfrastructureOpen}\r\n onOpenChange={setAddInfrastructureOpen}\r\n />\r\n )\r\n : currentViewer === 'users'\r\n ? (\r\n <>\r\n <Button\r\n variant=\"default\"\r\n onClick={() => setAddUserOpen(true)}\r\n disabled={!ability.can('create', 'User')}\r\n >\r\n <LR.CirclePlus />\r\n {t('addUser')}\r\n </Button>\r\n <AddUser open={addUserOpen} onOpenChange={setAddUserOpen} />\r\n <UserMoreOptions users={users} variant=\"outline\" />\r\n </>\r\n )\r\n : null}\r\n\r\n {/* Compare Button/Dialog */}\r\n {comparing\r\n ? (\r\n <CompareDialog\r\n toggleOpen={toggleOpen}\r\n compareItems={compareItems}\r\n setCompareItems={setCompareItems || (() => {})}\r\n handleAddBuilding={handleAddBuilding}\r\n />\r\n )\r\n : (\r\n <Button\r\n variant=\"secondary\"\r\n className={`max-sm:hidden ${(currentViewer === ViewerNames.files || currentViewer === ViewerNames.extensions || currentViewer === ViewerNames.users) ? 'hidden' : ''}`}\r\n onClick={() => setComparing(true)}\r\n >\r\n <LR.GitCompare />\r\n {t('compare')}\r\n {' '}\r\n {headerTitle}\r\n </Button>\r\n )}\r\n {(currentViewer === 'buildings' || currentViewer === 'sites') && filteredData && (\r\n <Button\r\n variant=\"outline\"\r\n onClick={handleViewAllOnMap}\r\n disabled={filteredData.length === 0 || currentViewer === 'buildings' &&!ability.can('read', 'Building') || currentViewer === 'sites' && !ability.can('read', 'Site')}\r\n >\r\n <LR.Map className=\"\" />\r\n {t('viewButton')}\r\n </Button>\r\n )}\r\n </div>\r\n )\r\n}"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/core/components/viewers/Data/HeaderButtons.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\n// Icons\r\nimport * as LR from 'lucide-react'\r\n// Dependencies\r\nimport * as React from 'react'\r\nimport { useTranslations } from 'next-intl'\r\nimport { usePermissions } from '../../../store'\r\n\r\n// Utils\r\nimport type { Dataset } from '../../../types/datasetTypes'\r\nimport type { Building, Site, User } from '../../../types/dbTypes'\r\n\r\nimport { DatasetsContext, MapContext, MenusContext } from '../../../store'\r\nimport type { CompareItem } from '../../../store'\r\n\r\n// Shadcn Components\r\nimport { Button } from '../../../components/ui/Button'\r\nimport { fitBuildingsBounds } from '../map/utils/fitBuildingsBounds'\r\nimport { useShowSitesOnMap } from '../map/src/MapLayers/src/SiteLayer/useShowSitesOnMap'\r\nimport AddBuilding from './buildingDetails/AddBuilding'\r\n// File Adder\r\nimport DatatableFileAdder from './files/DatatableFileAdder'\r\n// Custom Components\r\nimport AddSite from './siteDetails/AddSite'\r\nimport CompareDialog from '../map/src/compare/CompareDialog'\r\nimport UserMoreOptions from './userDetails/UserMoreOptions'\r\nimport AddUser from './userDetails/AddUser'\r\nimport BuildingMoreOptions from './buildingDetails/BuildingsMoreOptions'\r\nimport { ViewerNames } from '../../../types/'\r\nimport AddInfrastructure from './infrastructureDetails/AddInfrastructure'\r\nimport { createBuildingsDataset } from '../map/src/MapLayers/src/BuildingLayers/src/databaseBuildings'\r\n\r\ntype HeaderButtonsProps = {\r\n headerTitle: string\r\n currentViewer: string\r\n compareItems: CompareItem[]\r\n setCompareItems?: React.Dispatch<React.SetStateAction<CompareItem[]>>\r\n comparing: boolean\r\n setComparing: React.Dispatch<React.SetStateAction<boolean>>\r\n newItemName: string\r\n setNewItemName: React.Dispatch<React.SetStateAction<string>>\r\n filteredData?: Array<Building | Site>\r\n users?: User[]\r\n geocodeEarthApiKey?: string\r\n geocoderUrl?: string\r\n}\r\n\r\nexport default function HeaderButtons({\r\n headerTitle,\r\n currentViewer,\r\n compareItems,\r\n setCompareItems,\r\n comparing,\r\n setComparing,\r\n newItemName,\r\n setNewItemName,\r\n filteredData,\r\n users,\r\n geocodeEarthApiKey,\r\n geocoderUrl,\r\n}: HeaderButtonsProps) {\r\n // Translations\r\n const t = useTranslations('HeaderButtons')\r\n\r\n // Permissions\r\n const { ability } = usePermissions()\r\n\r\n const { state: mapState } = React.useContext(MapContext)\r\n const { dispatch: datasetDispatch } = React.useContext(DatasetsContext)\r\n const { dispatch: menusDispatch } = React.useContext(MenusContext)\r\n const [newBuildingFields, setNewBuildingFields] = React.useState({})\r\n const [newInfrastructureFields, setNewInfrastructureFields] = React.useState({})\r\n const [addInfrastructureOpen, setAddInfrastructureOpen] = React.useState(false)\r\n const [addBuildingOpen, setAddBuildingOpen] = React.useState(false)\r\n const [addUserOpen, setAddUserOpen] = React.useState(false)\r\n\r\n const { map } = mapState.map\r\n const showSitesOnMap = useShowSitesOnMap()\r\n const firstBuilding = compareItems[0]\r\n\r\n const coordinates = firstBuilding\r\n ? (('buildingLongitude' in firstBuilding && 'buildingLatitude' in firstBuilding)\r\n ? [firstBuilding.buildingLongitude, firstBuilding.buildingLatitude]\r\n : ('coordinates' in firstBuilding))\r\n : undefined\r\n\r\n const handleViewOnMap = () => {\r\n // set the current viewer to map\r\n menusDispatch({\r\n type: 'SET_VIEWER',\r\n payload: { currentViewer: ViewerNames.map },\r\n })\r\n }\r\n\r\n const handleViewAllOnMap = async () => {\r\n if (filteredData.length === 0)\r\n return\r\n\r\n // Switch to map view\r\n menusDispatch({\r\n type: 'SET_VIEWER',\r\n payload: { currentViewer: ViewerNames.map },\r\n })\r\n\r\n if (currentViewer === 'buildings') {\r\n // Filter buildings with valid coordinates\r\n const validBuildings = filteredData.filter(\r\n (item): item is Building => {\r\n const b = item as Building\r\n const lon = b.buildingLongitude\r\n const lat = b.buildingLatitude\r\n if (lon == null || lat == null) return false\r\n\r\n // Rough North America bounding box\r\n const minLat = 5\r\n const maxLat = 85\r\n const minLon = -170\r\n const maxLon = -10\r\n\r\n return Number.isFinite(lat)\r\n && Number.isFinite(lon)\r\n && lat >= minLat\r\n && lat <= maxLat\r\n && lon >= minLon\r\n && lon <= maxLon\r\n }\r\n )\r\n\r\n if (validBuildings.length === 0)\r\n return\r\n\r\n const name = 'Database Buildings'\r\n\r\n const dataset: Dataset = createBuildingsDataset(validBuildings, name)\r\n\r\n // Add buildings as a dataset to the map state\r\n datasetDispatch({\r\n type: 'ADD_DATASET_TO_MAP',\r\n payload: { dataset },\r\n })\r\n\r\n fitBuildingsBounds(validBuildings, map)\r\n }\r\n\r\n else if (currentViewer === 'sites') {\r\n const validSites = (filteredData ?? []).filter((item): item is Site => !!(item as Site)?.id)\r\n\r\n if (validSites.length === 0)\r\n return\r\n\r\n // Render each site's saved GeoJSON boundary (not just a point marker).\r\n // Viewer was already switched to the map above.\r\n await showSitesOnMap(validSites, { switchViewer: false })\r\n }\r\n\r\n else if (currentViewer === 'infrastructure') {\r\n // Filter infrastructure with valid coordinates\r\n }\r\n\r\n\r\n }\r\n\r\n const handleAddBuilding = (building: Building) => {\r\n if (setCompareItems) {\r\n const compareItem: CompareItem = {\r\n ...building,\r\n id: String(building.id),\r\n }\r\n setCompareItems([...compareItems, compareItem])\r\n }\r\n }\r\n\r\n const toggleOpen = () => {\r\n setComparing(false)\r\n // Clear compareItems when exiting compare mode for proper cleanup\r\n if (setCompareItems) {\r\n setCompareItems([])\r\n }\r\n }\r\n\r\n return (\r\n <div className=\"flex flex-row gap-2.5\">\r\n {comparing\r\n ? (\r\n <Button\r\n variant=\"outline\"\r\n onClick={() => {\r\n setComparing(false)\r\n // Clear compareItems for proper cleanup when canceling\r\n if (setCompareItems) {\r\n setCompareItems([])\r\n }\r\n }}\r\n disabled={currentViewer === 'buildings' && !ability.can('read', 'Building') || currentViewer === 'sites' && !ability.can('read', 'Site')}\r\n >\r\n {t('cancelButton')}\r\n </Button>\r\n )\r\n : currentViewer === 'files'\r\n ? (\r\n <DatatableFileAdder />\r\n )\r\n : currentViewer === 'buildings'\r\n ? (\r\n <>\r\n <Button\r\n variant=\"default\"\r\n onClick={() => setAddBuildingOpen(true)}\r\n disabled={!ability.can('create', 'Building')}\r\n >\r\n <LR.CirclePlus />\r\n {t('addBuilding')}\r\n </Button>\r\n <AddBuilding\r\n newBuildingFields={newBuildingFields}\r\n setNewBuildingFields={setNewBuildingFields}\r\n open={addBuildingOpen}\r\n onOpenChange={setAddBuildingOpen}\r\n geocodeEarthApiKey={geocodeEarthApiKey}\r\n geocoderUrl={geocoderUrl}\r\n />\r\n <BuildingMoreOptions buildings={filteredData as Building[]} variant=\"outline\" />\r\n </>\r\n )\r\n : currentViewer === 'sites'\r\n ? (\r\n <AddSite\r\n newItemName={newItemName}\r\n setNewItemName={setNewItemName}\r\n />\r\n )\r\n : currentViewer === 'infrastructure'\r\n ? (\r\n <AddInfrastructure\r\n newInfrastructureFields={newInfrastructureFields}\r\n setNewInfrastructureFields={setNewInfrastructureFields}\r\n open={addInfrastructureOpen}\r\n onOpenChange={setAddInfrastructureOpen}\r\n />\r\n )\r\n : currentViewer === 'users'\r\n ? (\r\n <>\r\n <Button\r\n variant=\"default\"\r\n onClick={() => setAddUserOpen(true)}\r\n disabled={!ability.can('create', 'User')}\r\n >\r\n <LR.CirclePlus />\r\n {t('addUser')}\r\n </Button>\r\n <AddUser open={addUserOpen} onOpenChange={setAddUserOpen} />\r\n <UserMoreOptions users={users} variant=\"outline\" />\r\n </>\r\n )\r\n : null}\r\n\r\n {/* Compare Button/Dialog */}\r\n {comparing\r\n ? (\r\n <CompareDialog\r\n toggleOpen={toggleOpen}\r\n compareItems={compareItems}\r\n setCompareItems={setCompareItems || (() => {})}\r\n handleAddBuilding={handleAddBuilding}\r\n />\r\n )\r\n : (\r\n <Button\r\n variant=\"secondary\"\r\n className={`max-sm:hidden ${(currentViewer === ViewerNames.files || currentViewer === ViewerNames.extensions || currentViewer === ViewerNames.users) ? 'hidden' : ''}`}\r\n onClick={() => setComparing(true)}\r\n >\r\n <LR.GitCompare />\r\n {t('compare')}\r\n {' '}\r\n {headerTitle}\r\n </Button>\r\n )}\r\n {(currentViewer === 'buildings' || currentViewer === 'sites') && filteredData && (\r\n <Button\r\n variant=\"outline\"\r\n onClick={handleViewAllOnMap}\r\n disabled={filteredData.length === 0 || currentViewer === 'buildings' &&!ability.can('read', 'Building') || currentViewer === 'sites' && !ability.can('read', 'Site')}\r\n >\r\n <LR.Map className=\"\" />\r\n {t('viewButton')}\r\n </Button>\r\n )}\r\n </div>\r\n )\r\n}"],"mappings":"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","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MoreOptions.d.ts","sourceRoot":"","sources":["../../../../../src/core/components/viewers/Data/MoreOptions.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"MoreOptions.d.ts","sourceRoot":"","sources":["../../../../../src/core/components/viewers/Data/MoreOptions.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAA;AAyBlE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AAInD,OAAO,EAAE,SAAS,EAAe,MAAM,iBAAiB,CAAA;AAKxD,UAAU,gBAAgB;IACxB,GAAG,EAAE,QAAQ,GAAG,IAAI,GAAG,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC9C,QAAQ,EAAE,SAAS,CAAA;IACnB,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,CAAA;IACzC,OAAO,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAA;IAClE,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAA;CAC1B;AAED,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,aAAqB,EAAE,YAAY,EAAE,EAAE,gBAAgB,qBAiL7H"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import * as React from "react";
|
|
4
|
-
import { BuildingsContext, DatasetsContext, MapContext, MenusContext } from "../../../store";
|
|
4
|
+
import { BuildingsContext, DatasetsContext, MapContext, MenusContext, useMapSitesContext } from "../../../store";
|
|
5
|
+
import { useShowSitesOnMap } from "../map/src/MapLayers/src/SiteLayer/useShowSitesOnMap";
|
|
5
6
|
import { usePermissions } from "../../../store";
|
|
6
7
|
import {
|
|
7
8
|
DropdownMenu,
|
|
@@ -20,7 +21,6 @@ import {
|
|
|
20
21
|
} from "lucide-react";
|
|
21
22
|
import ExportData from "../../../components/ui/ExportData";
|
|
22
23
|
import FileMoreOptions from "./files/FileMoreOptions";
|
|
23
|
-
import { MarkerManager } from "../map/utils/MarkerManager";
|
|
24
24
|
import { createBuildingsDataset } from "../map/src/MapLayers/src/BuildingLayers/src/databaseBuildings";
|
|
25
25
|
import ConfirmDialog from "../../../components/ConfirmDialog";
|
|
26
26
|
import { ViewerNames } from "../../../types/";
|
|
@@ -33,6 +33,8 @@ function MoreOptions({ row, dataType, variant, setView, hideViewOnMap = false, o
|
|
|
33
33
|
const { dispatch: menusDispatch } = React.useContext(MenusContext);
|
|
34
34
|
const { dispatch: datasetDispatch } = React.useContext(DatasetsContext);
|
|
35
35
|
const { dispatch: buildingsDispatch } = React.useContext(BuildingsContext);
|
|
36
|
+
const { dispatch: mapSitesDispatch } = useMapSitesContext();
|
|
37
|
+
const showSitesOnMap = useShowSitesOnMap();
|
|
36
38
|
const [isConfirmDialogOpen, setIsConfirmDialogOpen] = React.useState(false);
|
|
37
39
|
const { map } = mapState.map;
|
|
38
40
|
const siteId = dataType === "site" && row && "id" in row ? row.id : void 0;
|
|
@@ -44,6 +46,7 @@ function MoreOptions({ row, dataType, variant, setView, hideViewOnMap = false, o
|
|
|
44
46
|
if (!siteId) return;
|
|
45
47
|
try {
|
|
46
48
|
await deleteSite(siteId);
|
|
49
|
+
mapSitesDispatch({ type: "HIDE_SITE", payload: { id: Number(siteId) } });
|
|
47
50
|
toast.success("Site deleted successfully");
|
|
48
51
|
setIsConfirmDialogOpen(false);
|
|
49
52
|
setView("table");
|
|
@@ -65,35 +68,19 @@ function MoreOptions({ row, dataType, variant, setView, hideViewOnMap = false, o
|
|
|
65
68
|
toast.error(t("userDeleteFailed"));
|
|
66
69
|
}
|
|
67
70
|
};
|
|
68
|
-
const handleViewOnMap = (row2) => {
|
|
69
|
-
|
|
71
|
+
const handleViewOnMap = async (row2) => {
|
|
72
|
+
if (dataType === "site" && "id" in row2 && row2.id) {
|
|
73
|
+
await showSitesOnMap([row2]);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
70
76
|
if (dataType === "building" && "buildingLatitude" in row2 && "buildingLongitude" in row2 && typeof row2.buildingLatitude === "number" && typeof row2.buildingLongitude === "number") {
|
|
71
77
|
const building = row2;
|
|
72
|
-
coordinates = [building.buildingLongitude, building.buildingLatitude];
|
|
78
|
+
const coordinates = [building.buildingLongitude, building.buildingLatitude];
|
|
73
79
|
const name = building.buildingName || building.buildingAddress || "Unnamed Building";
|
|
74
80
|
const dataset = createBuildingsDataset([building], name);
|
|
75
|
-
datasetDispatch({
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
});
|
|
79
|
-
} else if (dataType === "site" && "siteLatitude" in row2 && "siteLongitude" in row2 && typeof row2.siteLatitude === "number" && typeof row2.siteLongitude === "number") {
|
|
80
|
-
coordinates = [row2.siteLongitude, row2.siteLatitude];
|
|
81
|
-
} else {
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
menusDispatch({
|
|
85
|
-
type: "SET_VIEWER",
|
|
86
|
-
payload: { currentViewer: ViewerNames.map }
|
|
87
|
-
});
|
|
88
|
-
const markerManager = new MarkerManager();
|
|
89
|
-
if (coordinates) {
|
|
90
|
-
map.flyTo({
|
|
91
|
-
center: coordinates,
|
|
92
|
-
zoom: 18,
|
|
93
|
-
duration: 1e3
|
|
94
|
-
});
|
|
95
|
-
} else {
|
|
96
|
-
console.warn("No coordinates available for the selected row.");
|
|
81
|
+
datasetDispatch({ type: "ADD_DATASET_TO_MAP", payload: { dataset } });
|
|
82
|
+
menusDispatch({ type: "SET_VIEWER", payload: { currentViewer: ViewerNames.map } });
|
|
83
|
+
if (map) map.flyTo({ center: coordinates, zoom: 18, duration: 1e3 });
|
|
97
84
|
}
|
|
98
85
|
};
|
|
99
86
|
const handleViewBIM = (row2) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/core/components/viewers/Data/MoreOptions.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\n// Dependencies\r\nimport * as React from 'react'\r\nimport { BuildingsContext, DatasetsContext, MapContext, MenusContext } from '../../../store'\r\n\r\nimport type { Building, Site, User } from '../../../types/dbTypes'\r\nimport { usePermissions } from '../../../store'\r\n\r\n// Shadcn Components\r\nimport {\r\n DropdownMenu,\r\n DropdownMenuContent,\r\n DropdownMenuItem,\r\n DropdownMenuTrigger,\r\n} from '../../../components/ui/DropdownMenu'\r\nimport { Button, LoadingSpinner } from '../../../components/ui/'\r\nimport { useTranslations } from 'next-intl'\r\nimport { toast } from 'sonner'\r\n\r\n// Icons\r\nimport {\r\n MoreHorizontal,\r\n Map,\r\n Box,\r\n Trash2,\r\n} from 'lucide-react'\r\n\r\n// Custom Components\r\nimport ExportData from '../../../components/ui/ExportData'\r\nimport FileMoreOptions from './files/FileMoreOptions'\r\nimport type { FileRow } from '../../../types/files'\r\nimport { MarkerManager } from '../map/utils/MarkerManager'\r\nimport { createBuildingsDataset } from '../map/src/MapLayers/src/BuildingLayers/src/databaseBuildings'\r\nimport type { Dataset } from '../../../types/datasetTypes'\r\nimport ConfirmDialog from '../../../components/ConfirmDialog'\r\nimport { DataTypes, ViewerNames } from '../../../types/'\r\nimport { useDeleteSite } from '../../../hooks/sites/sites'\r\nimport { useUser } from '../../../hooks/users/users'\r\n \r\n\r\ninterface MoreOptionsProps {\r\n row: Building | Site | FileRow | Partial<User>\r\n dataType: DataTypes\r\n variant?: 'ghost' | 'outline' | 'default'\r\n setView?: React.Dispatch<React.SetStateAction<'table' | 'detail'>>\r\n hideViewOnMap?: boolean\r\n onDeleteUser?: () => void\r\n}\r\n\r\nexport default function MoreOptions({ row, dataType, variant, setView, hideViewOnMap = false, onDeleteUser }: MoreOptionsProps) {\r\n // Translations\r\n const t = useTranslations('MoreOptions')\r\n // Permissions\r\n const { ability } = usePermissions()\r\n\r\n const { state: mapState } = React.useContext(MapContext)\r\n const { dispatch: menusDispatch } = React.useContext(MenusContext)\r\n const { dispatch: datasetDispatch } = React.useContext(DatasetsContext)\r\n const { dispatch: buildingsDispatch } = React.useContext(BuildingsContext)\r\n\r\n // States\r\n const [isConfirmDialogOpen, setIsConfirmDialogOpen] = React.useState(false)\r\n\r\n const { map } = mapState.map\r\n\r\n const siteId = dataType === 'site' && row && 'id' in row ? row.id : undefined\r\n const { deleteSite, isMutating: isDeleting } = useDeleteSite(siteId)\r\n\r\n const userId = dataType === 'user' && row && 'id' in row && Number(row.id) > 0 ? String(row.id) : undefined\r\n const { deleteUser, isDeleting: isDeletingUser } = useUser(userId || '')\r\n\r\n const handleDeleteSite = async (e: React.MouseEvent) => {\r\n e.stopPropagation()\r\n if (!siteId) return\r\n try {\r\n await deleteSite(siteId)\r\n toast.success(\"Site deleted successfully\")\r\n setIsConfirmDialogOpen(false)\r\n setView('table')\r\n } catch (err) {\r\n toast.error(\"Error deleting site\")\r\n }\r\n }\r\n\r\n const handleDeleteUser = async (e: React.MouseEvent) => {\r\n e.stopPropagation()\r\n if (!userId) return\r\n try {\r\n await deleteUser()\r\n toast.success(t('userDeleted'))\r\n setIsConfirmDialogOpen(false)\r\n setView('table')\r\n onDeleteUser?.()\r\n } catch (err) {\r\n console.error('Error deleting user:', err)\r\n toast.error(t('userDeleteFailed'))\r\n }\r\n }\r\n\r\n const handleViewOnMap = (row: Building | Site | FileRow | Partial<User>) => {\r\n let coordinates: [number, number]\r\n if (\r\n dataType === 'building'\r\n && 'buildingLatitude' in row\r\n && 'buildingLongitude' in row\r\n && typeof row.buildingLatitude === 'number'\r\n && typeof row.buildingLongitude === 'number'\r\n ) {\r\n const building = row as Building\r\n coordinates = [building.buildingLongitude, building.buildingLatitude]\r\n const name = building.buildingName || building.buildingAddress || 'Unnamed Building'\r\n\r\n // Create a dataset for the building\r\n const dataset: Dataset = createBuildingsDataset([building], name)\r\n\r\n // Add buildings as a dataset to the map state\r\n datasetDispatch({\r\n type: 'ADD_DATASET_TO_MAP',\r\n payload: { dataset },\r\n })\r\n }\r\n else if (\r\n dataType === 'site'\r\n && 'siteLatitude' in row\r\n && 'siteLongitude' in row\r\n && typeof row.siteLatitude === 'number'\r\n && typeof row.siteLongitude === 'number'\r\n ) {\r\n coordinates = [row.siteLongitude, row.siteLatitude]\r\n }\r\n else {\r\n // console.log('No coordinates available for the selected row.')\r\n return\r\n }\r\n\r\n // set the current viewer to map\r\n menusDispatch({\r\n type: 'SET_VIEWER',\r\n payload: { currentViewer: ViewerNames.map },\r\n })\r\n // Fly to location on the map WIP\r\n const markerManager = new MarkerManager()\r\n\r\n if (coordinates) {\r\n // markerManager.create(coordinates, map)\r\n map.flyTo({\r\n center: coordinates,\r\n zoom: 18,\r\n duration: 1000,\r\n })\r\n }\r\n else {\r\n console.warn('No coordinates available for the selected row.')\r\n }\r\n }\r\n const handleViewBIM = (row: Building | Site | FileRow | Partial<User>) => {\r\n const building = row as Building\r\n buildingsDispatch({\r\n \"type\": \"SET-CURRENT-BUILDING\",\r\n \"payload\": { building },\r\n });\r\n // set the current viewer to map\r\n menusDispatch({\r\n type: 'SET_VIEWER',\r\n payload: { currentViewer: ViewerNames.bim },\r\n })\r\n\r\n }\r\n\r\n if (dataType == 'file') {\r\n const fileRow = row as FileRow\r\n return (<FileMoreOptions file={fileRow} />)\r\n }\r\n\r\n return (\r\n <>\r\n <DropdownMenu>\r\n <DropdownMenuTrigger asChild>\r\n <Button\r\n variant={variant ? variant : 'ghost'}\r\n className=\"dropdown-menu-trigger\"\r\n onClick={e => e.stopPropagation()}\r\n size=\"icon\"\r\n >\r\n <MoreHorizontal />\r\n <span className=\"sr-only\">Open menu</span>\r\n </Button>\r\n </DropdownMenuTrigger>\r\n <DropdownMenuContent align=\"end\">\r\n {!hideViewOnMap && (\r\n <DropdownMenuItem\r\n onClick={() => handleViewOnMap(row)}\r\n disabled={dataType == 'building' && !ability.can('read', 'Building') || dataType == 'site' && !ability.can('read', 'Site')}\r\n >\r\n <Map />\r\n {t('viewMap')}\r\n </DropdownMenuItem>\r\n )}\r\n {dataType === 'building' && (\r\n <DropdownMenuItem\r\n onClick={() => handleViewBIM(row)}\r\n disabled={dataType == 'building' && !ability.can('read', 'Building')}\r\n >\r\n <Box />\r\n {t('viewBIM')}\r\n </DropdownMenuItem>\r\n )}\r\n <ExportData\r\n data={\r\n dataType === 'building'\r\n ? [row as Building]\r\n : (dataType === 'site'\r\n ? [row as Site]\r\n : [row as FileRow])\r\n }\r\n variant=\"ghost\"\r\n type={dataType}\r\n className=\"px-2 py-1.5 font-normal\"\r\n />\r\n {dataType === 'site' && (\r\n <DropdownMenuItem\r\n onClick={() => setIsConfirmDialogOpen(true)}\r\n disabled={dataType == 'site' && !ability.can('update', 'Site') ||isDeleting}\r\n >\r\n <Trash2 />\r\n {t('deleteSite')}\r\n {isDeleting && <LoadingSpinner />}\r\n </DropdownMenuItem>\r\n )}\r\n {dataType === 'user' && ability.can('delete', 'User') &&(\r\n <DropdownMenuItem\r\n onClick={() => setIsConfirmDialogOpen(true)}\r\n >\r\n <Trash2 />\r\n {t('deleteUser')}\r\n {isDeletingUser && <LoadingSpinner />}\r\n </DropdownMenuItem>\r\n )}\r\n </DropdownMenuContent>\r\n </DropdownMenu>\r\n {/* Confirm Dialog */}\r\n <ConfirmDialog\r\n isOpen={isConfirmDialogOpen}\r\n isDeleting={dataType === 'site' ? isDeleting : isDeletingUser}\r\n onOpenChange={setIsConfirmDialogOpen}\r\n handleConfirm={dataType === 'site' ? handleDeleteSite : handleDeleteUser}\r\n itemName={dataType === 'site' ? (row as Site).siteName : dataType === 'user' ? (row as User).name : undefined}\r\n dataType={dataType === 'site' ? 'site' : dataType === 'user' ? 'user' : undefined}\r\n />\r\n </>\r\n )\r\n}\r\n"],"mappings":"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","names":["row"]}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/core/components/viewers/Data/MoreOptions.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\n// Dependencies\r\nimport * as React from 'react'\r\nimport { BuildingsContext, DatasetsContext, MapContext, MenusContext, useMapSitesContext } from '../../../store'\r\nimport { useShowSitesOnMap } from '../map/src/MapLayers/src/SiteLayer/useShowSitesOnMap'\r\n\r\nimport type { Building, Site, User } from '../../../types/dbTypes'\r\nimport { usePermissions } from '../../../store'\r\n\r\n// Shadcn Components\r\nimport {\r\n DropdownMenu,\r\n DropdownMenuContent,\r\n DropdownMenuItem,\r\n DropdownMenuTrigger,\r\n} from '../../../components/ui/DropdownMenu'\r\nimport { Button, LoadingSpinner } from '../../../components/ui/'\r\nimport { useTranslations } from 'next-intl'\r\nimport { toast } from 'sonner'\r\n\r\n// Icons\r\nimport {\r\n MoreHorizontal,\r\n Map,\r\n Box,\r\n Trash2,\r\n} from 'lucide-react'\r\n\r\n// Custom Components\r\nimport ExportData from '../../../components/ui/ExportData'\r\nimport FileMoreOptions from './files/FileMoreOptions'\r\nimport type { FileRow } from '../../../types/files'\r\nimport { createBuildingsDataset } from '../map/src/MapLayers/src/BuildingLayers/src/databaseBuildings'\r\nimport type { Dataset } from '../../../types/datasetTypes'\r\nimport ConfirmDialog from '../../../components/ConfirmDialog'\r\nimport { DataTypes, ViewerNames } from '../../../types/'\r\nimport { useDeleteSite } from '../../../hooks/sites/sites'\r\nimport { useUser } from '../../../hooks/users/users'\r\n \r\n\r\ninterface MoreOptionsProps {\r\n row: Building | Site | FileRow | Partial<User>\r\n dataType: DataTypes\r\n variant?: 'ghost' | 'outline' | 'default'\r\n setView?: React.Dispatch<React.SetStateAction<'table' | 'detail'>>\r\n hideViewOnMap?: boolean\r\n onDeleteUser?: () => void\r\n}\r\n\r\nexport default function MoreOptions({ row, dataType, variant, setView, hideViewOnMap = false, onDeleteUser }: MoreOptionsProps) {\r\n // Translations\r\n const t = useTranslations('MoreOptions')\r\n // Permissions\r\n const { ability } = usePermissions()\r\n\r\n const { state: mapState } = React.useContext(MapContext)\r\n const { dispatch: menusDispatch } = React.useContext(MenusContext)\r\n const { dispatch: datasetDispatch } = React.useContext(DatasetsContext)\r\n const { dispatch: buildingsDispatch } = React.useContext(BuildingsContext)\r\n const { dispatch: mapSitesDispatch } = useMapSitesContext()\r\n const showSitesOnMap = useShowSitesOnMap()\r\n\r\n // States\r\n const [isConfirmDialogOpen, setIsConfirmDialogOpen] = React.useState(false)\r\n\r\n const { map } = mapState.map\r\n\r\n const siteId = dataType === 'site' && row && 'id' in row ? row.id : undefined\r\n const { deleteSite, isMutating: isDeleting } = useDeleteSite(siteId)\r\n\r\n const userId = dataType === 'user' && row && 'id' in row && Number(row.id) > 0 ? String(row.id) : undefined\r\n const { deleteUser, isDeleting: isDeletingUser } = useUser(userId || '')\r\n\r\n const handleDeleteSite = async (e: React.MouseEvent) => {\r\n e.stopPropagation()\r\n if (!siteId) return\r\n try {\r\n await deleteSite(siteId)\r\n // Remove the polygon from the map if it is currently shown, so it doesn't\r\n // linger as an un-backed \"ghost\" that still opens the context menu.\r\n mapSitesDispatch({ type: 'HIDE_SITE', payload: { id: Number(siteId) } })\r\n toast.success(\"Site deleted successfully\")\r\n setIsConfirmDialogOpen(false)\r\n setView('table')\r\n } catch (err) {\r\n toast.error(\"Error deleting site\")\r\n }\r\n }\r\n\r\n const handleDeleteUser = async (e: React.MouseEvent) => {\r\n e.stopPropagation()\r\n if (!userId) return\r\n try {\r\n await deleteUser()\r\n toast.success(t('userDeleted'))\r\n setIsConfirmDialogOpen(false)\r\n setView('table')\r\n onDeleteUser?.()\r\n } catch (err) {\r\n console.error('Error deleting user:', err)\r\n toast.error(t('userDeleteFailed'))\r\n }\r\n }\r\n\r\n const handleViewOnMap = async (row: Building | Site | FileRow | Partial<User>) => {\r\n // Sites: switch to the map and render the saved polygon boundary (falls\r\n // back to the site's point if it has no drawn boundary yet).\r\n if (dataType === 'site' && 'id' in row && row.id) {\r\n await showSitesOnMap([row as Site])\r\n return\r\n }\r\n\r\n // Buildings: add as a dataset and fly to it.\r\n if (\r\n dataType === 'building'\r\n && 'buildingLatitude' in row\r\n && 'buildingLongitude' in row\r\n && typeof row.buildingLatitude === 'number'\r\n && typeof row.buildingLongitude === 'number'\r\n ) {\r\n const building = row as Building\r\n const coordinates: [number, number] = [building.buildingLongitude, building.buildingLatitude]\r\n const name = building.buildingName || building.buildingAddress || 'Unnamed Building'\r\n const dataset: Dataset = createBuildingsDataset([building], name)\r\n datasetDispatch({ type: 'ADD_DATASET_TO_MAP', payload: { dataset } })\r\n menusDispatch({ type: 'SET_VIEWER', payload: { currentViewer: ViewerNames.map } })\r\n if (map) map.flyTo({ center: coordinates, zoom: 18, duration: 1000 })\r\n }\r\n }\r\n\r\n const handleViewBIM = (row: Building | Site | FileRow | Partial<User>) => {\r\n const building = row as Building\r\n buildingsDispatch({\r\n \"type\": \"SET-CURRENT-BUILDING\",\r\n \"payload\": { building },\r\n });\r\n // set the current viewer to map\r\n menusDispatch({\r\n type: 'SET_VIEWER',\r\n payload: { currentViewer: ViewerNames.bim },\r\n })\r\n\r\n }\r\n\r\n if (dataType == 'file') {\r\n const fileRow = row as FileRow\r\n return (<FileMoreOptions file={fileRow} />)\r\n }\r\n\r\n return (\r\n <>\r\n <DropdownMenu>\r\n <DropdownMenuTrigger asChild>\r\n <Button\r\n variant={variant ? variant : 'ghost'}\r\n className=\"dropdown-menu-trigger\"\r\n onClick={e => e.stopPropagation()}\r\n size=\"icon\"\r\n >\r\n <MoreHorizontal />\r\n <span className=\"sr-only\">Open menu</span>\r\n </Button>\r\n </DropdownMenuTrigger>\r\n <DropdownMenuContent align=\"end\">\r\n {!hideViewOnMap && (\r\n <DropdownMenuItem\r\n onClick={() => handleViewOnMap(row)}\r\n disabled={dataType == 'building' && !ability.can('read', 'Building') || dataType == 'site' && !ability.can('read', 'Site')}\r\n >\r\n <Map />\r\n {t('viewMap')}\r\n </DropdownMenuItem>\r\n )}\r\n {dataType === 'building' && (\r\n <DropdownMenuItem\r\n onClick={() => handleViewBIM(row)}\r\n disabled={dataType == 'building' && !ability.can('read', 'Building')}\r\n >\r\n <Box />\r\n {t('viewBIM')}\r\n </DropdownMenuItem>\r\n )}\r\n <ExportData\r\n data={\r\n dataType === 'building'\r\n ? [row as Building]\r\n : (dataType === 'site'\r\n ? [row as Site]\r\n : [row as FileRow])\r\n }\r\n variant=\"ghost\"\r\n type={dataType}\r\n className=\"px-2 py-1.5 font-normal\"\r\n />\r\n {dataType === 'site' && (\r\n <DropdownMenuItem\r\n onClick={() => setIsConfirmDialogOpen(true)}\r\n disabled={dataType == 'site' && !ability.can('update', 'Site') ||isDeleting}\r\n >\r\n <Trash2 />\r\n {t('deleteSite')}\r\n {isDeleting && <LoadingSpinner />}\r\n </DropdownMenuItem>\r\n )}\r\n {dataType === 'user' && ability.can('delete', 'User') &&(\r\n <DropdownMenuItem\r\n onClick={() => setIsConfirmDialogOpen(true)}\r\n >\r\n <Trash2 />\r\n {t('deleteUser')}\r\n {isDeletingUser && <LoadingSpinner />}\r\n </DropdownMenuItem>\r\n )}\r\n </DropdownMenuContent>\r\n </DropdownMenu>\r\n {/* Confirm Dialog */}\r\n <ConfirmDialog\r\n isOpen={isConfirmDialogOpen}\r\n isDeleting={dataType === 'site' ? isDeleting : isDeletingUser}\r\n onOpenChange={setIsConfirmDialogOpen}\r\n handleConfirm={dataType === 'site' ? handleDeleteSite : handleDeleteUser}\r\n itemName={dataType === 'site' ? (row as Site).siteName : dataType === 'user' ? (row as User).name : undefined}\r\n dataType={dataType === 'site' ? 'site' : dataType === 'user' ? 'user' : undefined}\r\n />\r\n </>\r\n )\r\n}\r\n"],"mappings":"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","names":["row"]}
|
|
@@ -4,7 +4,9 @@ interface AddBuildingProps {
|
|
|
4
4
|
setNewBuildingFields: (fields: any) => void;
|
|
5
5
|
open: boolean;
|
|
6
6
|
onOpenChange: (open: boolean) => void;
|
|
7
|
+
geocodeEarthApiKey?: string;
|
|
8
|
+
geocoderUrl?: string;
|
|
7
9
|
}
|
|
8
|
-
export default function AddBuilding({ newBuildingFields, setNewBuildingFields, open, onOpenChange, }: AddBuildingProps): React.JSX.Element;
|
|
10
|
+
export default function AddBuilding({ newBuildingFields, setNewBuildingFields, open, onOpenChange, geocodeEarthApiKey, geocoderUrl, }: AddBuildingProps): React.JSX.Element;
|
|
9
11
|
export {};
|
|
10
12
|
//# sourceMappingURL=AddBuilding.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AddBuilding.d.ts","sourceRoot":"","sources":["../../../../../../src/core/components/viewers/Data/buildingDetails/AddBuilding.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAgB/B,UAAU,gBAAgB;IACxB,iBAAiB,EAAE,GAAG,CAAA;IACtB,oBAAoB,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAA;IAC3C,IAAI,EAAE,OAAO,CAAA;IACb,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;
|
|
1
|
+
{"version":3,"file":"AddBuilding.d.ts","sourceRoot":"","sources":["../../../../../../src/core/components/viewers/Data/buildingDetails/AddBuilding.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAgB/B,UAAU,gBAAgB;IACxB,iBAAiB,EAAE,GAAG,CAAA;IACtB,oBAAoB,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAA;IAC3C,IAAI,EAAE,OAAO,CAAA;IACb,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAClC,iBAAiB,EACjB,oBAAoB,EACpB,IAAI,EACJ,YAAY,EACZ,kBAAkB,EAClB,WAAW,GACZ,EAAE,gBAAgB,qBAyDlB"}
|
|
@@ -27,7 +27,9 @@ function AddBuilding({
|
|
|
27
27
|
newBuildingFields,
|
|
28
28
|
setNewBuildingFields,
|
|
29
29
|
open,
|
|
30
|
-
onOpenChange
|
|
30
|
+
onOpenChange,
|
|
31
|
+
geocodeEarthApiKey,
|
|
32
|
+
geocoderUrl
|
|
31
33
|
}) {
|
|
32
34
|
var _a;
|
|
33
35
|
const t = useTranslations("AddBuilding");
|
|
@@ -59,7 +61,7 @@ function AddBuilding({
|
|
|
59
61
|
children: [
|
|
60
62
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
61
63
|
/* @__PURE__ */ jsx("div", { className: "text-sm font-medium text-foreground", children: t("label") }),
|
|
62
|
-
/* @__PURE__ */ jsx(GeocoderInput, { onSelect: handleGeocoderSelect }),
|
|
64
|
+
/* @__PURE__ */ jsx(GeocoderInput, { onSelect: handleGeocoderSelect, geocodeEarthApiKey, geocoderUrl }),
|
|
63
65
|
newBuildingFields.buildingAddress && /* @__PURE__ */ jsxs("div", { className: "text-xs text-muted-foreground mt-1", children: [
|
|
64
66
|
t("label2"),
|
|
65
67
|
" ",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../src/core/components/viewers/Data/buildingDetails/AddBuilding.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 React from \"react\";\r\nimport { useMenusContext } from '../../../../store'\r\nimport { toast } from 'sonner'\r\nimport { useTranslations } from 'next-intl'\r\n\r\n// Shadcn components\r\nimport { AddItemDialog } from '../../../ui/AddItemDialog'\r\nimport { Button } from '../../../ui/Button'\r\n\r\n// Icons\r\nimport * as LR from 'lucide-react'\r\n\r\n// Custom components\r\nimport GeocoderInput from './GeocoderInput'\r\nimport { DropdownMenuItem } from '@radix-ui/react-dropdown-menu'\r\n\r\ninterface AddBuildingProps {\r\n newBuildingFields: any\r\n setNewBuildingFields: (fields: any) => void\r\n open: boolean\r\n onOpenChange: (open: boolean) => void\r\n}\r\n\r\nexport default function AddBuilding({\r\n newBuildingFields,\r\n setNewBuildingFields,\r\n open,\r\n onOpenChange,\r\n}: AddBuildingProps) {\r\n // Translations\r\n const t = useTranslations('AddBuilding')\r\n\r\n const { setSelectedItem, setView } = useMenusContext()\r\n\r\n const handleGeocoderSelect = (fields) => {\r\n setNewBuildingFields(fields)\r\n }\r\n\r\n const handleGetStarted = () => {\r\n if (!newBuildingFields.buildingAddress?.trim()) {\r\n toast.error(t('toastErr'))\r\n return\r\n }\r\n\r\n const blankBuilding = {\r\n id: -1,\r\n ...newBuildingFields,\r\n }\r\n\r\n setSelectedItem(blankBuilding as any)\r\n setView('detail')\r\n onOpenChange(false)\r\n }\r\n\r\n return (\r\n <AddItemDialog\r\n open={open}\r\n onOpenChange={onOpenChange}\r\n title={t('title')}\r\n description={t('description')}\r\n icon={LR.Building2}\r\n >\r\n <div className=\"flex flex-col gap-2\">\r\n <div className=\"text-sm font-medium text-foreground\">{t('label')}</div>\r\n <GeocoderInput onSelect={handleGeocoderSelect} />\r\n {newBuildingFields.buildingAddress && (\r\n <div className=\"text-xs text-muted-foreground mt-1\">\r\n {t('label2')}\r\n {' '}\r\n {newBuildingFields.buildingAddress}\r\n </div>\r\n )}\r\n </div>\r\n <div className=\"w-full flex justify-end\">\r\n <Button\r\n variant=\"secondary\"\r\n className=\"w-fit\"\r\n onClick={handleGetStarted}\r\n disabled={!newBuildingFields.buildingAddress?.trim()}\r\n >\r\n {t('submit')}\r\n </Button>\r\n </div>\r\n </AddItemDialog>\r\n )\r\n}"],"mappings":";;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/core/components/viewers/Data/buildingDetails/AddBuilding.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 React from \"react\";\r\nimport { useMenusContext } from '../../../../store'\r\nimport { toast } from 'sonner'\r\nimport { useTranslations } from 'next-intl'\r\n\r\n// Shadcn components\r\nimport { AddItemDialog } from '../../../ui/AddItemDialog'\r\nimport { Button } from '../../../ui/Button'\r\n\r\n// Icons\r\nimport * as LR from 'lucide-react'\r\n\r\n// Custom components\r\nimport GeocoderInput from './GeocoderInput'\r\nimport { DropdownMenuItem } from '@radix-ui/react-dropdown-menu'\r\n\r\ninterface AddBuildingProps {\r\n newBuildingFields: any\r\n setNewBuildingFields: (fields: any) => void\r\n open: boolean\r\n onOpenChange: (open: boolean) => void\r\n geocodeEarthApiKey?: string\r\n geocoderUrl?: string\r\n}\r\n\r\nexport default function AddBuilding({\r\n newBuildingFields,\r\n setNewBuildingFields,\r\n open,\r\n onOpenChange,\r\n geocodeEarthApiKey,\r\n geocoderUrl,\r\n}: AddBuildingProps) {\r\n // Translations\r\n const t = useTranslations('AddBuilding')\r\n\r\n const { setSelectedItem, setView } = useMenusContext()\r\n\r\n const handleGeocoderSelect = (fields) => {\r\n setNewBuildingFields(fields)\r\n }\r\n\r\n const handleGetStarted = () => {\r\n if (!newBuildingFields.buildingAddress?.trim()) {\r\n toast.error(t('toastErr'))\r\n return\r\n }\r\n\r\n const blankBuilding = {\r\n id: -1,\r\n ...newBuildingFields,\r\n }\r\n\r\n setSelectedItem(blankBuilding as any)\r\n setView('detail')\r\n onOpenChange(false)\r\n }\r\n\r\n return (\r\n <AddItemDialog\r\n open={open}\r\n onOpenChange={onOpenChange}\r\n title={t('title')}\r\n description={t('description')}\r\n icon={LR.Building2}\r\n >\r\n <div className=\"flex flex-col gap-2\">\r\n <div className=\"text-sm font-medium text-foreground\">{t('label')}</div>\r\n <GeocoderInput onSelect={handleGeocoderSelect} geocodeEarthApiKey={geocodeEarthApiKey} geocoderUrl={geocoderUrl} />\r\n {newBuildingFields.buildingAddress && (\r\n <div className=\"text-xs text-muted-foreground mt-1\">\r\n {t('label2')}\r\n {' '}\r\n {newBuildingFields.buildingAddress}\r\n </div>\r\n )}\r\n </div>\r\n <div className=\"w-full flex justify-end\">\r\n <Button\r\n variant=\"secondary\"\r\n className=\"w-fit\"\r\n onClick={handleGetStarted}\r\n disabled={!newBuildingFields.buildingAddress?.trim()}\r\n >\r\n {t('submit')}\r\n </Button>\r\n </div>\r\n </AddItemDialog>\r\n )\r\n}"],"mappings":";;;;;;;;;;;;;;;;;AAwEQ,cAGE,YAHF;AAlER,SAAS,uBAAuB;AAChC,SAAS,aAAa;AACtB,SAAS,uBAAuB;AAGhC,SAAS,qBAAqB;AAC9B,SAAS,cAAc;AAGvB,YAAY,QAAQ;AAGpB,OAAO,mBAAmB;AAYX,SAAR,YAA6B;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAqB;AArCrB;AAuCE,QAAM,IAAI,gBAAgB,aAAa;AAEvC,QAAM,EAAE,iBAAiB,QAAQ,IAAI,gBAAgB;AAErD,QAAM,uBAAuB,CAAC,WAAW;AACvC,yBAAqB,MAAM;AAAA,EAC7B;AAEA,QAAM,mBAAmB,MAAM;AA/CjC,QAAAA;AAgDI,QAAI,GAACA,MAAA,kBAAkB,oBAAlB,gBAAAA,IAAmC,SAAQ;AAC9C,YAAM,MAAM,EAAE,UAAU,CAAC;AACzB;AAAA,IACF;AAEA,UAAM,gBAAgB;AAAA,MACpB,IAAI;AAAA,OACD;AAGL,oBAAgB,aAAoB;AACpC,YAAQ,QAAQ;AAChB,iBAAa,KAAK;AAAA,EACpB;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,OAAO,EAAE,OAAO;AAAA,MAChB,aAAa,EAAE,aAAa;AAAA,MAC5B,MAAM,GAAG;AAAA,MAET;AAAA,6BAAC,SAAI,WAAU,uBACb;AAAA,8BAAC,SAAI,WAAU,uCAAuC,YAAE,OAAO,GAAE;AAAA,UACjE,oBAAC,iBAAc,UAAU,sBAAsB,oBAAwC,aAA0B;AAAA,UAChH,kBAAkB,mBACjB,qBAAC,SAAI,WAAU,sCACZ;AAAA,cAAE,QAAQ;AAAA,YACV;AAAA,YACA,kBAAkB;AAAA,aACrB;AAAA,WAEJ;AAAA,QACA,oBAAC,SAAI,WAAU,2BACb;AAAA,UAAC;AAAA;AAAA,YACC,SAAQ;AAAA,YACR,WAAU;AAAA,YACV,SAAS;AAAA,YACT,UAAU,GAAC,uBAAkB,oBAAlB,mBAAmC;AAAA,YAE7C,YAAE,QAAQ;AAAA;AAAA,QACb,GACF;AAAA;AAAA;AAAA,EACF;AAEJ;","names":["_a"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FieldRenderer.d.ts","sourceRoot":"","sources":["../../../../../../src/core/components/viewers/Data/buildingDetails/FieldRenderer.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,MAAM,OAAO,CAAA;AAwCzB,eAAO,MAAM,gBAAgB,gHAOnB,CAAA;AAEV,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,GAAG,CAAA;IACV,iBAAiB,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,CAAA;IACzD,eAAe,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAA;IAC9C,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAA;IAC1C,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAA;IAC3C,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAA;IAC3C,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAA;IAC7C,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAA;IAChD,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAA;IACjD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;CAC9C;AAED,QAAA,MAAM,aAAa,GAAI,6KAapB,kBAAkB,
|
|
1
|
+
{"version":3,"file":"FieldRenderer.d.ts","sourceRoot":"","sources":["../../../../../../src/core/components/viewers/Data/buildingDetails/FieldRenderer.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,MAAM,OAAO,CAAA;AAwCzB,eAAO,MAAM,gBAAgB,gHAOnB,CAAA;AAEV,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,GAAG,CAAA;IACV,iBAAiB,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,CAAA;IACzD,eAAe,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAA;IAC9C,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAA;IAC1C,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAA;IAC3C,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAA;IAC3C,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAA;IAC7C,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAA;IAChD,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAA;IACjD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;CAC9C;AAED,QAAA,MAAM,aAAa,GAAI,6KAapB,kBAAkB,sBAknBpB,CAAA;AAED,eAAe,aAAa,CAAA"}
|