@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
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import * as LR from "lucide-react";
|
|
5
|
+
import { useTranslations } from "next-intl";
|
|
6
|
+
import { Input } from "../../../../../../ui/Input";
|
|
7
|
+
import ConfirmDialog from "../../../../../../ConfirmDialog";
|
|
8
|
+
const SiteContextMenu = ({
|
|
9
|
+
x,
|
|
10
|
+
y,
|
|
11
|
+
site,
|
|
12
|
+
isEditing,
|
|
13
|
+
canUpdate,
|
|
14
|
+
canDelete,
|
|
15
|
+
canRead,
|
|
16
|
+
onClose,
|
|
17
|
+
onRename,
|
|
18
|
+
onToggleEdit,
|
|
19
|
+
onHide,
|
|
20
|
+
onInfo,
|
|
21
|
+
onDelete
|
|
22
|
+
}) => {
|
|
23
|
+
const t = useTranslations("SiteContextMenu");
|
|
24
|
+
const tf = React.useCallback(
|
|
25
|
+
(key, fallback) => t.has(key) ? t(key) : fallback,
|
|
26
|
+
[t]
|
|
27
|
+
);
|
|
28
|
+
const ref = React.useRef(null);
|
|
29
|
+
const [name, setName] = React.useState(site.name);
|
|
30
|
+
const [isDeleteOpen, setIsDeleteOpen] = React.useState(false);
|
|
31
|
+
const [isDeleting, setIsDeleting] = React.useState(false);
|
|
32
|
+
React.useEffect(() => {
|
|
33
|
+
setName(site.name);
|
|
34
|
+
}, [site.id, site.name]);
|
|
35
|
+
React.useEffect(() => {
|
|
36
|
+
const onPointerDown = (e) => {
|
|
37
|
+
if (isDeleteOpen || isEditing) return;
|
|
38
|
+
if (ref.current && !ref.current.contains(e.target)) onClose();
|
|
39
|
+
};
|
|
40
|
+
const onKey = (e) => {
|
|
41
|
+
if (isDeleteOpen || isEditing) return;
|
|
42
|
+
if (e.key === "Escape") onClose();
|
|
43
|
+
};
|
|
44
|
+
document.addEventListener("mousedown", onPointerDown);
|
|
45
|
+
document.addEventListener("keydown", onKey);
|
|
46
|
+
return () => {
|
|
47
|
+
document.removeEventListener("mousedown", onPointerDown);
|
|
48
|
+
document.removeEventListener("keydown", onKey);
|
|
49
|
+
};
|
|
50
|
+
}, [isDeleteOpen, isEditing, onClose]);
|
|
51
|
+
const commitName = () => {
|
|
52
|
+
const trimmed = name.trim();
|
|
53
|
+
if (trimmed && trimmed !== site.name) onRename(trimmed);
|
|
54
|
+
};
|
|
55
|
+
const handleConfirmDelete = async (e) => {
|
|
56
|
+
e.preventDefault();
|
|
57
|
+
setIsDeleting(true);
|
|
58
|
+
try {
|
|
59
|
+
await onDelete();
|
|
60
|
+
} finally {
|
|
61
|
+
setIsDeleting(false);
|
|
62
|
+
setIsDeleteOpen(false);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
return /* @__PURE__ */ jsxs(
|
|
66
|
+
"div",
|
|
67
|
+
{
|
|
68
|
+
ref,
|
|
69
|
+
className: "fixed z-50 w-56 rounded-md border bg-popover text-popover-foreground shadow-md p-1",
|
|
70
|
+
style: { left: x, top: y },
|
|
71
|
+
onClick: (e) => e.stopPropagation(),
|
|
72
|
+
children: [
|
|
73
|
+
/* @__PURE__ */ jsx("div", { className: "px-2 pt-1.5 pb-2", children: /* @__PURE__ */ jsx(
|
|
74
|
+
Input,
|
|
75
|
+
{
|
|
76
|
+
value: name,
|
|
77
|
+
disabled: !canUpdate,
|
|
78
|
+
onChange: (e) => setName(e.target.value),
|
|
79
|
+
onBlur: commitName,
|
|
80
|
+
onKeyDown: (e) => {
|
|
81
|
+
if (e.key === "Enter") {
|
|
82
|
+
e.preventDefault();
|
|
83
|
+
commitName();
|
|
84
|
+
e.target.blur();
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
placeholder: tf("namePlaceholder", "Site name"),
|
|
88
|
+
className: "h-8 text-sm"
|
|
89
|
+
}
|
|
90
|
+
) }),
|
|
91
|
+
/* @__PURE__ */ jsx("div", { className: "h-px bg-border my-1" }),
|
|
92
|
+
/* @__PURE__ */ jsxs(
|
|
93
|
+
"button",
|
|
94
|
+
{
|
|
95
|
+
type: "button",
|
|
96
|
+
onClick: onToggleEdit,
|
|
97
|
+
disabled: !canUpdate,
|
|
98
|
+
className: "flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-sm hover:bg-accent disabled:opacity-50 disabled:pointer-events-none",
|
|
99
|
+
children: [
|
|
100
|
+
isEditing ? /* @__PURE__ */ jsx(LR.Check, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx(LR.PencilRuler, { className: "h-4 w-4" }),
|
|
101
|
+
isEditing ? tf("doneEditing", "Done editing shape") : tf("editShape", "Edit shape")
|
|
102
|
+
]
|
|
103
|
+
}
|
|
104
|
+
),
|
|
105
|
+
/* @__PURE__ */ jsxs(
|
|
106
|
+
"button",
|
|
107
|
+
{
|
|
108
|
+
type: "button",
|
|
109
|
+
onClick: onHide,
|
|
110
|
+
disabled: !canRead,
|
|
111
|
+
className: "flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-sm hover:bg-accent disabled:opacity-50 disabled:pointer-events-none",
|
|
112
|
+
children: [
|
|
113
|
+
/* @__PURE__ */ jsx(LR.EyeOff, { className: "h-4 w-4" }),
|
|
114
|
+
tf("hide", "Hide")
|
|
115
|
+
]
|
|
116
|
+
}
|
|
117
|
+
),
|
|
118
|
+
/* @__PURE__ */ jsxs(
|
|
119
|
+
"button",
|
|
120
|
+
{
|
|
121
|
+
type: "button",
|
|
122
|
+
onClick: onInfo,
|
|
123
|
+
disabled: !canRead,
|
|
124
|
+
className: "flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-sm hover:bg-accent disabled:opacity-50 disabled:pointer-events-none",
|
|
125
|
+
children: [
|
|
126
|
+
/* @__PURE__ */ jsx(LR.Info, { className: "h-4 w-4" }),
|
|
127
|
+
tf("info", "Site details")
|
|
128
|
+
]
|
|
129
|
+
}
|
|
130
|
+
),
|
|
131
|
+
/* @__PURE__ */ jsx("div", { className: "h-px bg-border my-1" }),
|
|
132
|
+
/* @__PURE__ */ jsxs(
|
|
133
|
+
"button",
|
|
134
|
+
{
|
|
135
|
+
type: "button",
|
|
136
|
+
onClick: () => setIsDeleteOpen(true),
|
|
137
|
+
disabled: !canDelete,
|
|
138
|
+
className: "flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-sm text-destructive hover:bg-accent disabled:opacity-50 disabled:pointer-events-none",
|
|
139
|
+
children: [
|
|
140
|
+
/* @__PURE__ */ jsx(LR.Trash2, { className: "h-4 w-4" }),
|
|
141
|
+
tf("delete", "Delete site")
|
|
142
|
+
]
|
|
143
|
+
}
|
|
144
|
+
),
|
|
145
|
+
/* @__PURE__ */ jsx(
|
|
146
|
+
ConfirmDialog,
|
|
147
|
+
{
|
|
148
|
+
isOpen: isDeleteOpen,
|
|
149
|
+
isDeleting,
|
|
150
|
+
onOpenChange: setIsDeleteOpen,
|
|
151
|
+
handleConfirm: handleConfirmDelete,
|
|
152
|
+
itemName: site.name,
|
|
153
|
+
dataType: tf("siteDataType", "site")
|
|
154
|
+
}
|
|
155
|
+
)
|
|
156
|
+
]
|
|
157
|
+
}
|
|
158
|
+
);
|
|
159
|
+
};
|
|
160
|
+
export {
|
|
161
|
+
SiteContextMenu
|
|
162
|
+
};
|
|
163
|
+
//# sourceMappingURL=SiteContextMenu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../../src/core/components/viewers/map/src/MapLayers/src/SiteLayer/SiteContextMenu.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 * as LR from 'lucide-react'\r\nimport { useTranslations } from 'next-intl'\r\nimport { Input } from '../../../../../../ui/Input'\r\nimport { Button } from '../../../../../../ui/Button'\r\nimport ConfirmDialog from '../../../../../../ConfirmDialog'\r\nimport type { ShownSite } from '../../../../../../../store/MapSites/reducer'\r\n\r\nexport interface SiteContextMenuProps {\r\n x: number\r\n y: number\r\n site: ShownSite\r\n isEditing: boolean\r\n canUpdate: boolean\r\n canDelete: boolean\r\n canRead: boolean\r\n onClose: () => void\r\n onRename: (name: string) => void\r\n onToggleEdit: () => void\r\n onHide: () => void\r\n onInfo: () => void\r\n onDelete: () => void | Promise<void>\r\n}\r\n\r\nexport const SiteContextMenu: React.FC<SiteContextMenuProps> = ({\r\n x, y, site, isEditing, canUpdate, canDelete, canRead,\r\n onClose, onRename, onToggleEdit, onHide, onInfo, onDelete,\r\n}) => {\r\n const t = useTranslations('SiteContextMenu')\r\n // Translate with an English fallback so the menu is usable before the host\r\n // app's message catalog is updated (mirrors SiteAdder's approach).\r\n const tf = React.useCallback(\r\n (key: string, fallback: string) => (t.has(key) ? t(key) : fallback),\r\n [t],\r\n )\r\n\r\n const ref = React.useRef<HTMLDivElement>(null)\r\n const [name, setName] = React.useState(site.name)\r\n const [isDeleteOpen, setIsDeleteOpen] = React.useState(false)\r\n const [isDeleting, setIsDeleting] = React.useState(false)\r\n\r\n React.useEffect(() => { setName(site.name) }, [site.id, site.name])\r\n\r\n // Close on outside click / Escape, unless the delete confirmation is open or\r\n // the user is editing the polygon (dragging a vertex is an \"outside\" click).\r\n React.useEffect(() => {\r\n const onPointerDown = (e: MouseEvent) => {\r\n if (isDeleteOpen || isEditing) return\r\n if (ref.current && !ref.current.contains(e.target as Node)) onClose()\r\n }\r\n const onKey = (e: KeyboardEvent) => {\r\n if (isDeleteOpen || isEditing) return\r\n if (e.key === 'Escape') onClose()\r\n }\r\n document.addEventListener('mousedown', onPointerDown)\r\n document.addEventListener('keydown', onKey)\r\n return () => {\r\n document.removeEventListener('mousedown', onPointerDown)\r\n document.removeEventListener('keydown', onKey)\r\n }\r\n }, [isDeleteOpen, isEditing, onClose])\r\n\r\n const commitName = () => {\r\n const trimmed = name.trim()\r\n if (trimmed && trimmed !== site.name) onRename(trimmed)\r\n }\r\n\r\n const handleConfirmDelete = async (e: React.MouseEvent) => {\r\n e.preventDefault()\r\n setIsDeleting(true)\r\n try {\r\n await onDelete()\r\n }\r\n finally {\r\n setIsDeleting(false)\r\n setIsDeleteOpen(false)\r\n }\r\n }\r\n\r\n return (\r\n <div\r\n ref={ref}\r\n className=\"fixed z-50 w-56 rounded-md border bg-popover text-popover-foreground shadow-md p-1\"\r\n style={{ left: x, top: y }}\r\n onClick={e => e.stopPropagation()}\r\n >\r\n {/* Editable site name */}\r\n <div className=\"px-2 pt-1.5 pb-2\">\r\n <Input\r\n value={name}\r\n disabled={!canUpdate}\r\n onChange={e => setName(e.target.value)}\r\n onBlur={commitName}\r\n onKeyDown={(e) => {\r\n if (e.key === 'Enter') { e.preventDefault(); commitName(); (e.target as HTMLInputElement).blur() }\r\n }}\r\n placeholder={tf('namePlaceholder', 'Site name')}\r\n className=\"h-8 text-sm\"\r\n />\r\n </div>\r\n\r\n <div className=\"h-px bg-border my-1\" />\r\n\r\n <button\r\n type=\"button\"\r\n onClick={onToggleEdit}\r\n disabled={!canUpdate}\r\n className=\"flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-sm hover:bg-accent disabled:opacity-50 disabled:pointer-events-none\"\r\n >\r\n {isEditing\r\n ? <LR.Check className=\"h-4 w-4\" />\r\n : <LR.PencilRuler className=\"h-4 w-4\" />}\r\n {isEditing ? tf('doneEditing', 'Done editing shape') : tf('editShape', 'Edit shape')}\r\n </button>\r\n\r\n <button\r\n type=\"button\"\r\n onClick={onHide}\r\n disabled={!canRead}\r\n className=\"flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-sm hover:bg-accent disabled:opacity-50 disabled:pointer-events-none\"\r\n >\r\n <LR.EyeOff className=\"h-4 w-4\" />\r\n {tf('hide', 'Hide')}\r\n </button>\r\n\r\n <button\r\n type=\"button\"\r\n onClick={onInfo}\r\n disabled={!canRead}\r\n className=\"flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-sm hover:bg-accent disabled:opacity-50 disabled:pointer-events-none\"\r\n >\r\n <LR.Info className=\"h-4 w-4\" />\r\n {tf('info', 'Site details')}\r\n </button>\r\n\r\n <div className=\"h-px bg-border my-1\" />\r\n\r\n <button\r\n type=\"button\"\r\n onClick={() => setIsDeleteOpen(true)}\r\n disabled={!canDelete}\r\n className=\"flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-sm text-destructive hover:bg-accent disabled:opacity-50 disabled:pointer-events-none\"\r\n >\r\n <LR.Trash2 className=\"h-4 w-4\" />\r\n {tf('delete', 'Delete site')}\r\n </button>\r\n\r\n <ConfirmDialog\r\n isOpen={isDeleteOpen}\r\n isDeleting={isDeleting}\r\n onOpenChange={setIsDeleteOpen}\r\n handleConfirm={handleConfirmDelete}\r\n itemName={site.name}\r\n dataType={tf('siteDataType', 'site')}\r\n />\r\n </div>\r\n )\r\n}\r\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SiteLayer.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/core/components/viewers/map/src/MapLayers/src/SiteLayer/SiteLayer.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AA8D9B,eAAO,MAAM,SAAS,yBA+QrB,CAAA"}
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
6
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
7
|
+
var __spreadValues = (a, b) => {
|
|
8
|
+
for (var prop in b || (b = {}))
|
|
9
|
+
if (__hasOwnProp.call(b, prop))
|
|
10
|
+
__defNormalProp(a, prop, b[prop]);
|
|
11
|
+
if (__getOwnPropSymbols)
|
|
12
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
13
|
+
if (__propIsEnum.call(b, prop))
|
|
14
|
+
__defNormalProp(a, prop, b[prop]);
|
|
15
|
+
}
|
|
16
|
+
return a;
|
|
17
|
+
};
|
|
18
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
19
|
+
import * as React from "react";
|
|
20
|
+
import { Source, Layer, Marker } from "react-map-gl/maplibre";
|
|
21
|
+
import { toast } from "sonner";
|
|
22
|
+
import {
|
|
23
|
+
MapContext,
|
|
24
|
+
usePermissions,
|
|
25
|
+
useMenusContext,
|
|
26
|
+
useMapSitesContext
|
|
27
|
+
} from "../../../../../../../store";
|
|
28
|
+
import { MapLayerClickPriority } from "../../../../utils/MapEventManager/MapClickManager";
|
|
29
|
+
import { ViewerNames } from "../../../../../../../types/dbTypes";
|
|
30
|
+
import { useSite, useDeleteSite } from "../../../../../../../hooks/sites/sites";
|
|
31
|
+
import { useDeleteFile } from "../../../../../../../hooks/files/files";
|
|
32
|
+
import { polygonCentroid, uploadGeoJsonToAsset, pointToSegmentDistance } from "./siteGeometry";
|
|
33
|
+
import { SiteContextMenu } from "./SiteContextMenu";
|
|
34
|
+
const SITE_FILL_ID = "site-fill";
|
|
35
|
+
const SITE_OUTLINE_ID = "site-outline";
|
|
36
|
+
const SITE_LABEL_ID = "site-label";
|
|
37
|
+
const VERTEX_HIT_PX = 12;
|
|
38
|
+
const EDGE_HIT_PX = 8;
|
|
39
|
+
const MIN_RING_POINTS = 3;
|
|
40
|
+
const fillLayer = {
|
|
41
|
+
id: SITE_FILL_ID,
|
|
42
|
+
type: "fill",
|
|
43
|
+
paint: { "fill-color": "#3b82f6", "fill-opacity": 0.35 },
|
|
44
|
+
filter: ["==", ["get", "type"], "site"]
|
|
45
|
+
};
|
|
46
|
+
const outlineLayer = {
|
|
47
|
+
id: SITE_OUTLINE_ID,
|
|
48
|
+
type: "line",
|
|
49
|
+
layout: { "line-cap": "round", "line-join": "round" },
|
|
50
|
+
paint: { "line-color": "#1c4587", "line-width": 2 },
|
|
51
|
+
filter: ["==", ["get", "type"], "site"]
|
|
52
|
+
};
|
|
53
|
+
const labelLayer = {
|
|
54
|
+
id: SITE_LABEL_ID,
|
|
55
|
+
type: "symbol",
|
|
56
|
+
layout: {
|
|
57
|
+
"text-field": ["get", "name"],
|
|
58
|
+
"text-font": ["Inter"],
|
|
59
|
+
"text-size": 16,
|
|
60
|
+
"text-anchor": "center",
|
|
61
|
+
"text-allow-overlap": false
|
|
62
|
+
},
|
|
63
|
+
paint: {
|
|
64
|
+
"text-color": "#ffffff",
|
|
65
|
+
"text-halo-color": "#000000",
|
|
66
|
+
"text-halo-width": 1.5
|
|
67
|
+
},
|
|
68
|
+
filter: ["==", ["get", "type"], "site-label"]
|
|
69
|
+
};
|
|
70
|
+
const SiteLayer = () => {
|
|
71
|
+
var _a, _b, _c, _d;
|
|
72
|
+
const { state: mapState } = React.useContext(MapContext);
|
|
73
|
+
const { map, mapClickManager } = mapState.map;
|
|
74
|
+
const { state: mapSitesState, dispatch } = useMapSitesContext();
|
|
75
|
+
const { sites, editingSiteId } = mapSitesState.mapSites;
|
|
76
|
+
const { ability } = usePermissions();
|
|
77
|
+
const canUpdate = ability.can("update", "Site");
|
|
78
|
+
const canDelete = ability.can("delete", "Site");
|
|
79
|
+
const canRead = ability.can("read", "Site");
|
|
80
|
+
const { dispatch: menusDispatch, setSelectedSite, setView } = useMenusContext();
|
|
81
|
+
const [menu, setMenu] = React.useState(null);
|
|
82
|
+
const activeSiteId = (_b = (_a = menu == null ? void 0 : menu.siteId) != null ? _a : editingSiteId) != null ? _b : null;
|
|
83
|
+
const { updateSite } = useSite(activeSiteId ? String(activeSiteId) : "");
|
|
84
|
+
const { deleteSite } = useDeleteSite(activeSiteId != null ? activeSiteId : void 0);
|
|
85
|
+
const { deleteFile } = useDeleteFile(void 0, activeSiteId != null ? activeSiteId : void 0);
|
|
86
|
+
const menuSite = menu ? (_c = sites.find((s) => s.id === menu.siteId)) != null ? _c : null : null;
|
|
87
|
+
const sitesRef = React.useRef(sites);
|
|
88
|
+
sitesRef.current = sites;
|
|
89
|
+
const editingSiteIdRef = React.useRef(editingSiteId);
|
|
90
|
+
editingSiteIdRef.current = editingSiteId;
|
|
91
|
+
const featureCollection = React.useMemo(() => {
|
|
92
|
+
const features = [];
|
|
93
|
+
for (const s of sites) {
|
|
94
|
+
if (s.ring.length < 3) continue;
|
|
95
|
+
features.push({
|
|
96
|
+
type: "Feature",
|
|
97
|
+
geometry: { type: "Polygon", coordinates: [[...s.ring, s.ring[0]]] },
|
|
98
|
+
properties: { type: "site", siteId: s.id, name: s.name }
|
|
99
|
+
});
|
|
100
|
+
features.push({
|
|
101
|
+
type: "Feature",
|
|
102
|
+
geometry: { type: "Point", coordinates: polygonCentroid(s.ring) },
|
|
103
|
+
properties: { type: "site-label", siteId: s.id, name: s.name }
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
return { type: "FeatureCollection", features };
|
|
107
|
+
}, [sites]);
|
|
108
|
+
React.useEffect(() => {
|
|
109
|
+
if (!map || !mapClickManager) return;
|
|
110
|
+
const handleSiteClick = (e, features) => {
|
|
111
|
+
var _a2, _b2, _c2;
|
|
112
|
+
if (editingSiteIdRef.current != null) return;
|
|
113
|
+
const feature = features == null ? void 0 : features[0];
|
|
114
|
+
const siteId = Number((_a2 = feature == null ? void 0 : feature.properties) == null ? void 0 : _a2.siteId);
|
|
115
|
+
if (!siteId || Number.isNaN(siteId)) return;
|
|
116
|
+
const native = e.originalEvent;
|
|
117
|
+
setMenu({
|
|
118
|
+
x: (_b2 = native == null ? void 0 : native.clientX) != null ? _b2 : e.point.x,
|
|
119
|
+
y: (_c2 = native == null ? void 0 : native.clientY) != null ? _c2 : e.point.y,
|
|
120
|
+
siteId
|
|
121
|
+
});
|
|
122
|
+
};
|
|
123
|
+
const onEnter = () => {
|
|
124
|
+
map.getCanvas().style.cursor = "pointer";
|
|
125
|
+
};
|
|
126
|
+
const onLeave = () => {
|
|
127
|
+
map.getCanvas().style.cursor = "";
|
|
128
|
+
};
|
|
129
|
+
mapClickManager.register(SITE_FILL_ID, MapLayerClickPriority.SiteLayerClickPriority, handleSiteClick);
|
|
130
|
+
map.on("mouseenter", SITE_FILL_ID, onEnter);
|
|
131
|
+
map.on("mouseleave", SITE_FILL_ID, onLeave);
|
|
132
|
+
return () => {
|
|
133
|
+
mapClickManager.unregister(SITE_FILL_ID);
|
|
134
|
+
map.off("mouseenter", SITE_FILL_ID, onEnter);
|
|
135
|
+
map.off("mouseleave", SITE_FILL_ID, onLeave);
|
|
136
|
+
};
|
|
137
|
+
}, [map, mapClickManager]);
|
|
138
|
+
const updateVertex = (index, lng, lat) => {
|
|
139
|
+
if (editingSiteId == null) return;
|
|
140
|
+
const s = sites.find((x) => x.id === editingSiteId);
|
|
141
|
+
if (!s) return;
|
|
142
|
+
const ring = s.ring.map((p, i) => i === index ? [lng, lat] : p);
|
|
143
|
+
dispatch({ type: "UPDATE_SITE_RING", payload: { id: editingSiteId, ring } });
|
|
144
|
+
};
|
|
145
|
+
const deleteVertex = (index) => {
|
|
146
|
+
if (editingSiteId == null) return;
|
|
147
|
+
const s = sites.find((x) => x.id === editingSiteId);
|
|
148
|
+
if (!s) return;
|
|
149
|
+
if (s.ring.length <= MIN_RING_POINTS) {
|
|
150
|
+
toast.warning("A site needs at least 3 points.");
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
const ring = s.ring.filter((_, i) => i !== index);
|
|
154
|
+
dispatch({ type: "UPDATE_SITE_RING", payload: { id: editingSiteId, ring } });
|
|
155
|
+
};
|
|
156
|
+
React.useEffect(() => {
|
|
157
|
+
if (!map || editingSiteId == null) return;
|
|
158
|
+
const onEditClick = (e) => {
|
|
159
|
+
const site = sitesRef.current.find((s) => s.id === editingSiteId);
|
|
160
|
+
const ring = site == null ? void 0 : site.ring;
|
|
161
|
+
if (!ring || ring.length < 2) return;
|
|
162
|
+
const click = e.point;
|
|
163
|
+
for (const v of ring) {
|
|
164
|
+
const vp = map.project(v);
|
|
165
|
+
if (Math.hypot(vp.x - click.x, vp.y - click.y) <= VERTEX_HIT_PX) return;
|
|
166
|
+
}
|
|
167
|
+
let bestDist = Infinity;
|
|
168
|
+
let bestIdx = -1;
|
|
169
|
+
for (let i = 0; i < ring.length; i++) {
|
|
170
|
+
const a = map.project(ring[i]);
|
|
171
|
+
const b = map.project(ring[(i + 1) % ring.length]);
|
|
172
|
+
const d = pointToSegmentDistance(click.x, click.y, a.x, a.y, b.x, b.y);
|
|
173
|
+
if (d < bestDist) {
|
|
174
|
+
bestDist = d;
|
|
175
|
+
bestIdx = i;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
if (bestIdx >= 0 && bestDist <= EDGE_HIT_PX) {
|
|
179
|
+
const next = [...ring];
|
|
180
|
+
next.splice(bestIdx + 1, 0, [e.lngLat.lng, e.lngLat.lat]);
|
|
181
|
+
dispatch({ type: "UPDATE_SITE_RING", payload: { id: editingSiteId, ring: next } });
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
map.doubleClickZoom.disable();
|
|
185
|
+
map.on("click", onEditClick);
|
|
186
|
+
return () => {
|
|
187
|
+
map.off("click", onEditClick);
|
|
188
|
+
map.doubleClickZoom.enable();
|
|
189
|
+
};
|
|
190
|
+
}, [map, editingSiteId, dispatch]);
|
|
191
|
+
const handleRename = async (name) => {
|
|
192
|
+
if (!menu) return;
|
|
193
|
+
dispatch({ type: "UPDATE_SITE_NAME", payload: { id: menu.siteId, name } });
|
|
194
|
+
try {
|
|
195
|
+
await updateSite({ siteName: name });
|
|
196
|
+
} catch (e) {
|
|
197
|
+
toast.error("Failed to rename the site.");
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
const handleToggleEdit = async () => {
|
|
201
|
+
if (editingSiteId === activeSiteId && activeSiteId != null) {
|
|
202
|
+
const s = sites.find((x) => x.id === activeSiteId);
|
|
203
|
+
dispatch({ type: "SET_EDITING_SITE", payload: { id: null } });
|
|
204
|
+
if ((s == null ? void 0 : s.assetId) && s.ring.length >= 3) {
|
|
205
|
+
const toastId = toast.loading("Saving site shape\u2026");
|
|
206
|
+
try {
|
|
207
|
+
await uploadGeoJsonToAsset(s.assetId, s.ring, s.name);
|
|
208
|
+
const c = polygonCentroid(s.ring);
|
|
209
|
+
await updateSite({ siteLongitude: c[0], siteLatitude: c[1] });
|
|
210
|
+
toast.success("Site shape saved.", { id: toastId });
|
|
211
|
+
} catch (e) {
|
|
212
|
+
toast.error("Failed to save the site shape.", { id: toastId });
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
} else {
|
|
216
|
+
dispatch({ type: "SET_EDITING_SITE", payload: { id: activeSiteId } });
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
const handleHide = () => {
|
|
220
|
+
if (!menu) return;
|
|
221
|
+
dispatch({ type: "HIDE_SITE", payload: { id: menu.siteId } });
|
|
222
|
+
setMenu(null);
|
|
223
|
+
};
|
|
224
|
+
const handleInfo = () => {
|
|
225
|
+
if (!menu) return;
|
|
226
|
+
const s = sites.find((x) => x.id === menu.siteId);
|
|
227
|
+
setSelectedSite({ id: menu.siteId, siteName: s == null ? void 0 : s.name });
|
|
228
|
+
setView("detail");
|
|
229
|
+
menusDispatch({ type: "SET_VIEWER", payload: { currentViewer: ViewerNames.sites } });
|
|
230
|
+
setMenu(null);
|
|
231
|
+
};
|
|
232
|
+
const handleDelete = async () => {
|
|
233
|
+
if (!menu) return;
|
|
234
|
+
const id = menu.siteId;
|
|
235
|
+
const s = sites.find((x) => x.id === id);
|
|
236
|
+
try {
|
|
237
|
+
await deleteSite(id);
|
|
238
|
+
if (s == null ? void 0 : s.fileId) {
|
|
239
|
+
try {
|
|
240
|
+
await deleteFile(s.fileId);
|
|
241
|
+
} catch (e) {
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
dispatch({ type: "HIDE_SITE", payload: { id } });
|
|
245
|
+
setMenu(null);
|
|
246
|
+
toast.success("Site deleted.");
|
|
247
|
+
} catch (e) {
|
|
248
|
+
toast.error("Failed to delete the site.");
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
const editingSite = editingSiteId != null ? (_d = sites.find((s) => s.id === editingSiteId)) != null ? _d : null : null;
|
|
252
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
253
|
+
/* @__PURE__ */ jsxs(Source, { id: "sites-source", type: "geojson", data: featureCollection, children: [
|
|
254
|
+
/* @__PURE__ */ jsx(Layer, __spreadValues({}, fillLayer)),
|
|
255
|
+
/* @__PURE__ */ jsx(Layer, __spreadValues({}, outlineLayer)),
|
|
256
|
+
/* @__PURE__ */ jsx(Layer, __spreadValues({}, labelLayer))
|
|
257
|
+
] }),
|
|
258
|
+
editingSite == null ? void 0 : editingSite.ring.map((vertex, index) => /* @__PURE__ */ jsx(
|
|
259
|
+
Marker,
|
|
260
|
+
{
|
|
261
|
+
longitude: vertex[0],
|
|
262
|
+
latitude: vertex[1],
|
|
263
|
+
draggable: true,
|
|
264
|
+
onDrag: (e) => updateVertex(index, e.lngLat.lng, e.lngLat.lat),
|
|
265
|
+
children: /* @__PURE__ */ jsx(
|
|
266
|
+
"div",
|
|
267
|
+
{
|
|
268
|
+
title: "Drag to move \xB7 double-click to delete",
|
|
269
|
+
onDoubleClick: (ev) => {
|
|
270
|
+
ev.stopPropagation();
|
|
271
|
+
deleteVertex(index);
|
|
272
|
+
},
|
|
273
|
+
style: {
|
|
274
|
+
width: 14,
|
|
275
|
+
height: 14,
|
|
276
|
+
borderRadius: "50%",
|
|
277
|
+
background: "#22c55e",
|
|
278
|
+
border: "2px solid #ffffff",
|
|
279
|
+
boxShadow: "0 0 0 1px #15803d",
|
|
280
|
+
cursor: "grab"
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
)
|
|
284
|
+
},
|
|
285
|
+
`${editingSite.id}-vertex-${index}`
|
|
286
|
+
)),
|
|
287
|
+
menu && menuSite && /* @__PURE__ */ jsx(
|
|
288
|
+
SiteContextMenu,
|
|
289
|
+
{
|
|
290
|
+
x: menu.x,
|
|
291
|
+
y: menu.y,
|
|
292
|
+
site: menuSite,
|
|
293
|
+
isEditing: editingSiteId === menu.siteId,
|
|
294
|
+
canUpdate,
|
|
295
|
+
canDelete,
|
|
296
|
+
canRead,
|
|
297
|
+
onClose: () => setMenu(null),
|
|
298
|
+
onRename: handleRename,
|
|
299
|
+
onToggleEdit: handleToggleEdit,
|
|
300
|
+
onHide: handleHide,
|
|
301
|
+
onInfo: handleInfo,
|
|
302
|
+
onDelete: handleDelete
|
|
303
|
+
}
|
|
304
|
+
)
|
|
305
|
+
] });
|
|
306
|
+
};
|
|
307
|
+
export {
|
|
308
|
+
SiteLayer
|
|
309
|
+
};
|
|
310
|
+
//# sourceMappingURL=SiteLayer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../../src/core/components/viewers/map/src/MapLayers/src/SiteLayer/SiteLayer.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 { Source, Layer, Marker } from 'react-map-gl/maplibre'\r\nimport type { LayerProps } from 'react-map-gl/maplibre'\r\nimport type { MapGeoJSONFeature } from 'maplibre-gl'\r\nimport { toast } from 'sonner'\r\n\r\nimport {\r\n MapContext,\r\n usePermissions,\r\n useMenusContext,\r\n useMapSitesContext,\r\n} from '../../../../../../../store'\r\nimport { MapLayerClickPriority, type ClickCallback } from '../../../../utils/MapEventManager/MapClickManager'\r\nimport { ViewerNames, type Site } from '../../../../../../../types/dbTypes'\r\nimport { useSite, useDeleteSite } from '../../../../../../../hooks/sites/sites'\r\nimport { useDeleteFile } from '../../../../../../../hooks/files/files'\r\nimport { polygonCentroid, uploadGeoJsonToAsset, pointToSegmentDistance } from './siteGeometry'\r\nimport { SiteContextMenu } from './SiteContextMenu'\r\n\r\nconst SITE_FILL_ID = 'site-fill'\r\nconst SITE_OUTLINE_ID = 'site-outline'\r\nconst SITE_LABEL_ID = 'site-label'\r\n\r\n// How close (screen px) a click must be to count as \"on a vertex\" / \"on an edge\".\r\nconst VERTEX_HIT_PX = 12\r\nconst EDGE_HIT_PX = 8\r\n// A polygon needs at least 3 corners; deleting below that is blocked.\r\nconst MIN_RING_POINTS = 3\r\n\r\nconst fillLayer: LayerProps = {\r\n id: SITE_FILL_ID,\r\n type: 'fill',\r\n paint: { 'fill-color': '#3b82f6', 'fill-opacity': 0.35 },\r\n filter: ['==', ['get', 'type'], 'site'],\r\n}\r\n\r\nconst outlineLayer: LayerProps = {\r\n id: SITE_OUTLINE_ID,\r\n type: 'line',\r\n layout: { 'line-cap': 'round', 'line-join': 'round' },\r\n paint: { 'line-color': '#1c4587', 'line-width': 2 },\r\n filter: ['==', ['get', 'type'], 'site'],\r\n}\r\n\r\nconst labelLayer: LayerProps = {\r\n id: SITE_LABEL_ID,\r\n type: 'symbol',\r\n layout: {\r\n 'text-field': ['get', 'name'],\r\n 'text-font': ['Inter'],\r\n 'text-size': 16,\r\n 'text-anchor': 'center',\r\n 'text-allow-overlap': false,\r\n },\r\n paint: {\r\n 'text-color': '#ffffff',\r\n 'text-halo-color': '#000000',\r\n 'text-halo-width': 1.5,\r\n },\r\n filter: ['==', ['get', 'type'], 'site-label'],\r\n}\r\n\r\nexport const SiteLayer = () => {\r\n const { state: mapState } = React.useContext(MapContext)\r\n const { map, mapClickManager } = mapState.map\r\n const { state: mapSitesState, dispatch } = useMapSitesContext()\r\n const { sites, editingSiteId } = mapSitesState.mapSites\r\n\r\n const { ability } = usePermissions()\r\n const canUpdate = ability.can('update', 'Site')\r\n const canDelete = ability.can('delete', 'Site')\r\n const canRead = ability.can('read', 'Site')\r\n\r\n const { dispatch: menusDispatch, setSelectedSite, setView } = useMenusContext()\r\n\r\n const [menu, setMenu] = React.useState<{ x: number, y: number, siteId: number } | null>(null)\r\n\r\n // The site the user is currently acting on (menu open) or editing.\r\n const activeSiteId = menu?.siteId ?? editingSiteId ?? null\r\n const { updateSite } = useSite(activeSiteId ? String(activeSiteId) : '')\r\n const { deleteSite } = useDeleteSite(activeSiteId ?? undefined)\r\n const { deleteFile } = useDeleteFile(undefined, activeSiteId ?? undefined)\r\n\r\n const menuSite = menu ? sites.find(s => s.id === menu.siteId) ?? null : null\r\n\r\n // Live mirrors so the once-bound map click handlers read current values.\r\n const sitesRef = React.useRef(sites)\r\n sitesRef.current = sites\r\n const editingSiteIdRef = React.useRef(editingSiteId)\r\n editingSiteIdRef.current = editingSiteId\r\n\r\n // Build the rendered FeatureCollection: a polygon + a single centroid label\r\n // per shown site.\r\n const featureCollection = React.useMemo<GeoJSON.FeatureCollection>(() => {\r\n const features: GeoJSON.Feature[] = []\r\n for (const s of sites) {\r\n if (s.ring.length < 3) continue\r\n features.push({\r\n type: 'Feature',\r\n geometry: { type: 'Polygon', coordinates: [[...s.ring, s.ring[0]]] },\r\n properties: { type: 'site', siteId: s.id, name: s.name },\r\n })\r\n features.push({\r\n type: 'Feature',\r\n geometry: { type: 'Point', coordinates: polygonCentroid(s.ring) },\r\n properties: { type: 'site-label', siteId: s.id, name: s.name },\r\n })\r\n }\r\n return { type: 'FeatureCollection', features }\r\n }, [sites])\r\n\r\n // Lowest-priority click handler: opens the site menu only when no other\r\n // interactive layer was hit at the click point.\r\n React.useEffect(() => {\r\n if (!map || !mapClickManager) return\r\n\r\n const handleSiteClick: ClickCallback = (e, features: MapGeoJSONFeature[]) => {\r\n // While editing a shape, fill clicks are for adding vertices (see the\r\n // edit-click effect), not for (re)opening the menu.\r\n if (editingSiteIdRef.current != null) return\r\n const feature = features?.[0]\r\n const siteId = Number(feature?.properties?.siteId)\r\n if (!siteId || Number.isNaN(siteId)) return\r\n const native = e.originalEvent as MouseEvent | undefined\r\n setMenu({\r\n x: native?.clientX ?? e.point.x,\r\n y: native?.clientY ?? e.point.y,\r\n siteId,\r\n })\r\n }\r\n\r\n const onEnter = () => { map.getCanvas().style.cursor = 'pointer' }\r\n const onLeave = () => { map.getCanvas().style.cursor = '' }\r\n\r\n mapClickManager.register(SITE_FILL_ID, MapLayerClickPriority.SiteLayerClickPriority, handleSiteClick)\r\n map.on('mouseenter', SITE_FILL_ID, onEnter)\r\n map.on('mouseleave', SITE_FILL_ID, onLeave)\r\n\r\n return () => {\r\n mapClickManager.unregister(SITE_FILL_ID)\r\n map.off('mouseenter', SITE_FILL_ID, onEnter)\r\n map.off('mouseleave', SITE_FILL_ID, onLeave)\r\n }\r\n }, [map, mapClickManager])\r\n\r\n const updateVertex = (index: number, lng: number, lat: number) => {\r\n if (editingSiteId == null) return\r\n const s = sites.find(x => x.id === editingSiteId)\r\n if (!s) return\r\n const ring = s.ring.map((p, i) => (i === index ? [lng, lat] as [number, number] : p))\r\n dispatch({ type: 'UPDATE_SITE_RING', payload: { id: editingSiteId, ring } })\r\n }\r\n\r\n // Double-click a vertex to delete it (a polygon keeps at least 3 corners).\r\n const deleteVertex = (index: number) => {\r\n if (editingSiteId == null) return\r\n const s = sites.find(x => x.id === editingSiteId)\r\n if (!s) return\r\n if (s.ring.length <= MIN_RING_POINTS) {\r\n toast.warning('A site needs at least 3 points.')\r\n return\r\n }\r\n const ring = s.ring.filter((_, i) => i !== index)\r\n dispatch({ type: 'UPDATE_SITE_RING', payload: { id: editingSiteId, ring } })\r\n }\r\n\r\n // While editing, a click on an edge (not a vertex) inserts a new vertex there.\r\n React.useEffect(() => {\r\n if (!map || editingSiteId == null) return\r\n\r\n const onEditClick = (e: maplibregl.MapMouseEvent) => {\r\n const site = sitesRef.current.find(s => s.id === editingSiteId)\r\n const ring = site?.ring\r\n if (!ring || ring.length < 2) return\r\n\r\n const click = e.point\r\n // Ignore clicks on/near an existing vertex — those drag (or, on a\r\n // double-click, delete) via the markers.\r\n for (const v of ring) {\r\n const vp = map.project(v as [number, number])\r\n if (Math.hypot(vp.x - click.x, vp.y - click.y) <= VERTEX_HIT_PX) return\r\n }\r\n\r\n // Find the nearest edge segment in screen space.\r\n let bestDist = Infinity\r\n let bestIdx = -1\r\n for (let i = 0; i < ring.length; i++) {\r\n const a = map.project(ring[i] as [number, number])\r\n const b = map.project(ring[(i + 1) % ring.length] as [number, number])\r\n const d = pointToSegmentDistance(click.x, click.y, a.x, a.y, b.x, b.y)\r\n if (d < bestDist) { bestDist = d; bestIdx = i }\r\n }\r\n\r\n if (bestIdx >= 0 && bestDist <= EDGE_HIT_PX) {\r\n const next = [...ring]\r\n next.splice(bestIdx + 1, 0, [e.lngLat.lng, e.lngLat.lat])\r\n dispatch({ type: 'UPDATE_SITE_RING', payload: { id: editingSiteId, ring: next } })\r\n }\r\n }\r\n\r\n // Avoid the map zooming when a vertex is double-clicked to delete it.\r\n map.doubleClickZoom.disable()\r\n map.on('click', onEditClick)\r\n return () => {\r\n map.off('click', onEditClick)\r\n map.doubleClickZoom.enable()\r\n }\r\n }, [map, editingSiteId, dispatch])\r\n\r\n const handleRename = async (name: string) => {\r\n if (!menu) return\r\n dispatch({ type: 'UPDATE_SITE_NAME', payload: { id: menu.siteId, name } })\r\n try {\r\n await updateSite({ siteName: name })\r\n }\r\n catch {\r\n toast.error('Failed to rename the site.')\r\n }\r\n }\r\n\r\n const handleToggleEdit = async () => {\r\n if (editingSiteId === activeSiteId && activeSiteId != null) {\r\n // Finishing an edit: persist the new geometry + centroid.\r\n const s = sites.find(x => x.id === activeSiteId)\r\n dispatch({ type: 'SET_EDITING_SITE', payload: { id: null } })\r\n if (s?.assetId && s.ring.length >= 3) {\r\n const toastId = toast.loading('Saving site shape…')\r\n try {\r\n await uploadGeoJsonToAsset(s.assetId, s.ring, s.name)\r\n const c = polygonCentroid(s.ring)\r\n await updateSite({ siteLongitude: c[0], siteLatitude: c[1] })\r\n toast.success('Site shape saved.', { id: toastId })\r\n }\r\n catch {\r\n toast.error('Failed to save the site shape.', { id: toastId })\r\n }\r\n }\r\n }\r\n else {\r\n // Keep the menu open so the name can be edited alongside the vertices.\r\n dispatch({ type: 'SET_EDITING_SITE', payload: { id: activeSiteId } })\r\n }\r\n }\r\n\r\n const handleHide = () => {\r\n if (!menu) return\r\n dispatch({ type: 'HIDE_SITE', payload: { id: menu.siteId } })\r\n setMenu(null)\r\n }\r\n\r\n const handleInfo = () => {\r\n if (!menu) return\r\n const s = sites.find(x => x.id === menu.siteId)\r\n setSelectedSite({ id: menu.siteId, siteName: s?.name } as Site)\r\n setView('detail')\r\n menusDispatch({ type: 'SET_VIEWER', payload: { currentViewer: ViewerNames.sites } })\r\n setMenu(null)\r\n }\r\n\r\n const handleDelete = async () => {\r\n if (!menu) return\r\n const id = menu.siteId\r\n const s = sites.find(x => x.id === id)\r\n try {\r\n await deleteSite(id)\r\n if (s?.fileId) {\r\n try { await deleteFile(s.fileId) }\r\n catch { /* geometry file orphaned; site itself is gone */ }\r\n }\r\n dispatch({ type: 'HIDE_SITE', payload: { id } })\r\n setMenu(null)\r\n toast.success('Site deleted.')\r\n }\r\n catch {\r\n toast.error('Failed to delete the site.')\r\n }\r\n }\r\n\r\n const editingSite = editingSiteId != null ? sites.find(s => s.id === editingSiteId) ?? null : null\r\n\r\n return (\r\n <>\r\n <Source id=\"sites-source\" type=\"geojson\" data={featureCollection}>\r\n <Layer {...fillLayer} />\r\n <Layer {...outlineLayer} />\r\n <Layer {...labelLayer} />\r\n </Source>\r\n\r\n {/* Draggable vertex handles while editing a site's shape */}\r\n {editingSite?.ring.map((vertex, index) => (\r\n <Marker\r\n key={`${editingSite.id}-vertex-${index}`}\r\n longitude={vertex[0]}\r\n latitude={vertex[1]}\r\n draggable\r\n onDrag={(e: { lngLat: { lng: number, lat: number } }) =>\r\n updateVertex(index, e.lngLat.lng, e.lngLat.lat)}\r\n >\r\n <div\r\n title=\"Drag to move · double-click to delete\"\r\n onDoubleClick={(ev) => { ev.stopPropagation(); deleteVertex(index) }}\r\n style={{\r\n width: 14,\r\n height: 14,\r\n borderRadius: '50%',\r\n background: '#22c55e',\r\n border: '2px solid #ffffff',\r\n boxShadow: '0 0 0 1px #15803d',\r\n cursor: 'grab',\r\n }}\r\n />\r\n </Marker>\r\n ))}\r\n\r\n {menu && menuSite && (\r\n <SiteContextMenu\r\n x={menu.x}\r\n y={menu.y}\r\n site={menuSite}\r\n isEditing={editingSiteId === menu.siteId}\r\n canUpdate={canUpdate}\r\n canDelete={canDelete}\r\n canRead={canRead}\r\n onClose={() => setMenu(null)}\r\n onRename={handleRename}\r\n onToggleEdit={handleToggleEdit}\r\n onHide={handleHide}\r\n onInfo={handleInfo}\r\n onDelete={handleDelete}\r\n />\r\n )}\r\n </>\r\n )\r\n}\r\n"],"mappings":"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","names":["_a","_b","_c"]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export type Ring = [number, number][];
|
|
2
|
+
/** Area-weighted centroid of a polygon ring; used to place a single label. */
|
|
3
|
+
export declare const polygonCentroid: (pts: Ring) => [number, number];
|
|
4
|
+
/** Bounding box of a ring as [[minLng, minLat], [maxLng, maxLat]]. */
|
|
5
|
+
export declare const ringBounds: (ring: Ring) => [[number, number], [number, number]];
|
|
6
|
+
/** Shortest distance from point (px,py) to the segment (ax,ay)-(bx,by). */
|
|
7
|
+
export declare const pointToSegmentDistance: (px: number, py: number, ax: number, ay: number, bx: number, by: number) => number;
|
|
8
|
+
/** Build the GeoJSON FeatureCollection stored in minio for a site polygon. */
|
|
9
|
+
export declare const ringToFeatureCollection: (ring: Ring, name: string) => GeoJSON.FeatureCollection;
|
|
10
|
+
/**
|
|
11
|
+
* Return the items whose [lng, lat] point falls inside the polygon ring.
|
|
12
|
+
* The Turf polygon is built once, so this is cheap for many points.
|
|
13
|
+
*/
|
|
14
|
+
export declare const filterPointsInRing: <T>(ring: Ring, items: T[], getLngLat: (item: T) => [number, number] | null) => T[];
|
|
15
|
+
/**
|
|
16
|
+
* Extract the outer ring (open, no repeated closing point) from a stored
|
|
17
|
+
* GeoJSON value, accepting a FeatureCollection, Feature, or bare geometry.
|
|
18
|
+
*/
|
|
19
|
+
export declare const ringFromGeoJson: (geo: any) => Ring | null;
|
|
20
|
+
/**
|
|
21
|
+
* Load a site's saved boundary ring from minio (via its attached geometry
|
|
22
|
+
* file). Returns null if the site has no saved boundary or it can't be read.
|
|
23
|
+
*/
|
|
24
|
+
export declare const fetchSiteBoundaryRing: (siteId: number) => Promise<Ring | null>;
|
|
25
|
+
/**
|
|
26
|
+
* (Over)write a site's GeoJSON object in minio under the given asset key.
|
|
27
|
+
* Mirrors the presigned-upload flow used by FileAdder/DatasetAdder.
|
|
28
|
+
*/
|
|
29
|
+
export declare const uploadGeoJsonToAsset: (assetId: string, ring: Ring, name: string) => Promise<void>;
|
|
30
|
+
//# sourceMappingURL=siteGeometry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"siteGeometry.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/core/components/viewers/map/src/MapLayers/src/SiteLayer/siteGeometry.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAA;AAErC,8EAA8E;AAC9E,eAAO,MAAM,eAAe,GAAI,KAAK,IAAI,KAAG,CAAC,MAAM,EAAE,MAAM,CAgB1D,CAAA;AAED,sEAAsE;AACtE,eAAO,MAAM,UAAU,GAAI,MAAM,IAAI,KAAG,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAS1E,CAAA;AAED,2EAA2E;AAC3E,eAAO,MAAM,sBAAsB,GACjC,IAAI,MAAM,EAAE,IAAI,MAAM,EAAE,IAAI,MAAM,EAAE,IAAI,MAAM,EAAE,IAAI,MAAM,EAAE,IAAI,MAAM,KACrE,MAOF,CAAA;AAED,8EAA8E;AAC9E,eAAO,MAAM,uBAAuB,GAAI,MAAM,IAAI,EAAE,MAAM,MAAM,KAAG,OAAO,CAAC,iBASzE,CAAA;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAAI,CAAC,EAClC,MAAM,IAAI,EACV,OAAO,CAAC,EAAE,EACV,WAAW,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,KAC9C,CAAC,EAYH,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,GAAI,KAAK,GAAG,KAAG,IAAI,GAAG,IA0BjD,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB,GAAU,QAAQ,MAAM,KAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAe/E,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,oBAAoB,GAC/B,SAAS,MAAM,EACf,MAAM,IAAI,EACV,MAAM,MAAM,KACX,OAAO,CAAC,IAAI,CASd,CAAA"}
|