@collabdt/core 0.0.42 → 0.0.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/components/Toolbar.d.ts.map +1 -1
- package/dist/core/components/Toolbar.js.map +1 -1
- package/dist/core/components/ToolbarBody.js.map +1 -1
- package/dist/core/components/TopNavigationBar.js.map +1 -1
- package/dist/core/components/authentication/ForgotPassword.js.map +1 -1
- package/dist/core/components/authentication/Signin.js.map +1 -1
- package/dist/core/components/authentication/Signup.js.map +1 -1
- package/dist/core/components/settings/src/OrganizationSkeleton.js.map +1 -1
- package/dist/core/components/settings/src/SettingsSkeleton.js.map +1 -1
- package/dist/core/components/ui/Comments/CollapsibleCommentItem.d.ts.map +1 -1
- package/dist/core/components/ui/Comments/CollapsibleCommentItem.js.map +1 -1
- package/dist/core/components/ui/Comments/CommentsSection.d.ts.map +1 -1
- package/dist/core/components/ui/Comments/CommentsSection.js.map +1 -1
- package/dist/core/components/ui/DataTable.d.ts.map +1 -1
- package/dist/core/components/ui/DataTable.js +7 -0
- package/dist/core/components/ui/DataTable.js.map +1 -1
- package/dist/core/components/ui/FilesManager/src/FileItemComponent.d.ts.map +1 -1
- package/dist/core/components/ui/FilesManager/src/FileItemComponent.js.map +1 -1
- package/dist/core/components/ui/FilesManager/src/FileMarker.d.ts +5 -2
- package/dist/core/components/ui/FilesManager/src/FileMarker.d.ts.map +1 -1
- package/dist/core/components/ui/FilesManager/src/FileMarker.js +84 -21
- package/dist/core/components/ui/FilesManager/src/FileMarker.js.map +1 -1
- package/dist/core/components/ui/FilesManager/src/convertIfcToFragmentsFile.d.ts.map +1 -1
- package/dist/core/components/ui/FilesManager/src/convertIfcToFragmentsFile.js.map +1 -1
- package/dist/core/components/ui/FilesManager/src/useFileUploadHandler.d.ts.map +1 -1
- package/dist/core/components/ui/FilesManager/src/useFileUploadHandler.js.map +1 -1
- package/dist/core/components/ui/Icons/IfcIcon.d.ts.map +1 -1
- package/dist/core/components/ui/Icons/IfcIcon.js.map +1 -1
- package/dist/core/components/ui/InfoSidebar/index.d.ts.map +1 -1
- package/dist/core/components/ui/InfoSidebar/index.js.map +1 -1
- package/dist/core/components/ui/Navbar.d.ts.map +1 -1
- package/dist/core/components/ui/Navbar.js.map +1 -1
- package/dist/core/components/ui/Sensors/CollapsibleSensorItem.d.ts.map +1 -1
- package/dist/core/components/ui/Sensors/CollapsibleSensorItem.js.map +1 -1
- package/dist/core/components/ui/Sensors/SensorTagsSection.d.ts.map +1 -1
- package/dist/core/components/ui/Sensors/SensorTagsSection.js.map +1 -1
- package/dist/core/components/ui/Sensors/SensorsSection.d.ts.map +1 -1
- package/dist/core/components/ui/Sensors/SensorsSection.js.map +1 -1
- package/dist/core/components/ui/ShareFeature/ShareToolSubmenu.d.ts.map +1 -1
- package/dist/core/components/ui/ShareFeature/ShareToolSubmenu.js.map +1 -1
- package/dist/core/components/viewers/Data/buildingDetails/GeocoderInput.js +2 -2
- package/dist/core/components/viewers/Data/buildingDetails/GeocoderInput.js.map +1 -1
- package/dist/core/components/viewers/Data/infrastructureDetails/FieldRenderer.d.ts.map +1 -1
- package/dist/core/components/viewers/Data/infrastructureDetails/FieldRenderer.js.map +1 -1
- package/dist/core/components/viewers/Data/siteDetails/AssociatedBuildings.js +2 -2
- package/dist/core/components/viewers/Data/siteDetails/AssociatedBuildings.js.map +1 -1
- package/dist/core/components/viewers/Viewer.d.ts.map +1 -1
- package/dist/core/components/viewers/Viewer.js +5 -1
- package/dist/core/components/viewers/Viewer.js.map +1 -1
- package/dist/core/components/viewers/bim/BimToolbar.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/BimToolbar.js.map +1 -1
- package/dist/core/components/viewers/bim/BimViewer.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/BimViewer.js +14 -5
- package/dist/core/components/viewers/bim/BimViewer.js.map +1 -1
- package/dist/core/components/viewers/bim/src/BimLoadingState/index.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/BimLoadingState/index.js +6 -0
- package/dist/core/components/viewers/bim/src/BimLoadingState/index.js.map +1 -1
- package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/FilesSection.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/FilesSection.js +168 -39
- package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/FilesSection.js.map +1 -1
- package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/ModelsSection.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/ModelsSection.js.map +1 -1
- package/dist/core/components/viewers/bim/src/BimSidebar/src/LayersTab/src/FloorplanSection.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/BimSidebar/src/LayersTab/src/FloorplanSection.js +1 -1
- package/dist/core/components/viewers/bim/src/BimSidebar/src/LayersTab/src/FloorplanSection.js.map +1 -1
- package/dist/core/components/viewers/bim/src/ClippingPlane.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/ClippingPlane.js.map +1 -1
- package/dist/core/components/viewers/bim/src/DXFLoader/index.d.ts +14 -37
- package/dist/core/components/viewers/bim/src/DXFLoader/index.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/DXFLoader/index.js +31 -318
- package/dist/core/components/viewers/bim/src/DXFLoader/index.js.map +1 -1
- package/dist/core/components/viewers/bim/src/FloorplanTool/index.d.ts +66 -7
- package/dist/core/components/viewers/bim/src/FloorplanTool/index.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/FloorplanTool/index.js +253 -21
- package/dist/core/components/viewers/bim/src/FloorplanTool/index.js.map +1 -1
- package/dist/core/components/viewers/bim/src/ModelManager/index.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/ModelManager/index.js +9 -0
- package/dist/core/components/viewers/bim/src/ModelManager/index.js.map +1 -1
- package/dist/core/components/viewers/bim/src/SimpleBimViewer.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/SimpleBimViewer.js.map +1 -1
- package/dist/core/components/viewers/bim/src/lib/TrueNorthPopover.d.ts +3 -2
- package/dist/core/components/viewers/bim/src/lib/TrueNorthPopover.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/lib/TrueNorthPopover.js.map +1 -1
- package/dist/core/components/viewers/bim/src/lib/useFriendlyIfcClassName.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/lib/useFriendlyIfcClassName.js +3 -4
- package/dist/core/components/viewers/bim/src/lib/useFriendlyIfcClassName.js.map +1 -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 +40 -18
- package/dist/core/components/viewers/bim/src/tools/AddToBim/index.js.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/AddDxf.d.ts +2 -5
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/AddDxf.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/AddDxf.js +45 -59
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/AddDxf.js.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/AddSensor.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/AddSensor.js.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimSensor.js +1 -0
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimSensor.js.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/FileHandler.d.ts +10 -1
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/FileHandler.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/FileHandler.js +25 -73
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/FileHandler.js.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/FileMarkerUtils.d.ts +7 -3
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/FileMarkerUtils.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/FileMarkerUtils.js +42 -78
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/FileMarkerUtils.js.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/Position3DCard.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/Position3DCard.js +52 -75
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/Position3DCard.js.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useFilePlacement.d.ts +15 -3
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useFilePlacement.d.ts.map +1 -1
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useFilePlacement.js +165 -105
- package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useFilePlacement.js.map +1 -1
- package/dist/core/components/viewers/index.d.ts.map +1 -1
- package/dist/core/components/viewers/index.js.map +1 -1
- package/dist/core/components/viewers/map/MapViewer.d.ts.map +1 -1
- package/dist/core/components/viewers/map/MapViewer.js +32 -8
- package/dist/core/components/viewers/map/MapViewer.js.map +1 -1
- package/dist/core/components/viewers/map/datasets/DatasetManager/index.d.ts.map +1 -1
- package/dist/core/components/viewers/map/datasets/DatasetManager/index.js +4 -3
- package/dist/core/components/viewers/map/datasets/DatasetManager/index.js.map +1 -1
- package/dist/core/components/viewers/map/datasets/RowActions.d.ts.map +1 -1
- package/dist/core/components/viewers/map/datasets/RowActions.js +148 -0
- package/dist/core/components/viewers/map/datasets/RowActions.js.map +1 -1
- package/dist/core/components/viewers/map/datasets/index.d.ts.map +1 -1
- package/dist/core/components/viewers/map/datasets/index.js +32 -15
- package/dist/core/components/viewers/map/datasets/index.js.map +1 -1
- package/dist/core/components/viewers/map/datasets/src/builtinLiveDatasets.d.ts +4 -0
- package/dist/core/components/viewers/map/datasets/src/builtinLiveDatasets.d.ts.map +1 -0
- package/dist/core/components/viewers/map/datasets/src/builtinLiveDatasets.js +43 -0
- package/dist/core/components/viewers/map/datasets/src/builtinLiveDatasets.js.map +1 -0
- package/dist/core/components/viewers/map/datasets/src/localDatasets.d.ts.map +1 -1
- package/dist/core/components/viewers/map/datasets/src/localDatasets.js +39 -3
- package/dist/core/components/viewers/map/datasets/src/localDatasets.js.map +1 -1
- package/dist/core/components/viewers/map/datasets/src/minioDatasets.d.ts +1 -1
- package/dist/core/components/viewers/map/datasets/src/minioDatasets.d.ts.map +1 -1
- package/dist/core/components/viewers/map/datasets/src/minioDatasets.js +2 -1
- package/dist/core/components/viewers/map/datasets/src/minioDatasets.js.map +1 -1
- package/dist/core/components/viewers/map/datasets/src/publishedTiles.d.ts +47 -0
- package/dist/core/components/viewers/map/datasets/src/publishedTiles.d.ts.map +1 -0
- package/dist/core/components/viewers/map/datasets/src/publishedTiles.js +114 -0
- package/dist/core/components/viewers/map/datasets/src/publishedTiles.js.map +1 -0
- package/dist/core/components/viewers/map/datasets/src/wmsTime.d.ts +49 -0
- package/dist/core/components/viewers/map/datasets/src/wmsTime.d.ts.map +1 -0
- package/dist/core/components/viewers/map/datasets/src/wmsTime.js +100 -0
- package/dist/core/components/viewers/map/datasets/src/wmsTime.js.map +1 -0
- package/dist/core/components/viewers/map/src/Geocoder.d.ts.map +1 -1
- package/dist/core/components/viewers/map/src/Geocoder.js +9 -9
- package/dist/core/components/viewers/map/src/Geocoder.js.map +1 -1
- package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/NonDatabaseBuildingPopover.d.ts.map +1 -1
- package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/NonDatabaseBuildingPopover.js +25 -43
- package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/NonDatabaseBuildingPopover.js.map +1 -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.map +1 -1
- package/dist/core/components/viewers/map/src/MapLayers/src/BimLayer/index.d.ts.map +1 -1
- package/dist/core/components/viewers/map/src/MapLayers/src/BimLayer/index.js +19 -2
- package/dist/core/components/viewers/map/src/MapLayers/src/BimLayer/index.js.map +1 -1
- package/dist/core/components/viewers/map/src/MapLayers/src/CountryLayer/countryLayerUtils.d.ts +9 -0
- package/dist/core/components/viewers/map/src/MapLayers/src/CountryLayer/countryLayerUtils.d.ts.map +1 -0
- package/dist/core/components/viewers/map/src/MapLayers/src/CountryLayer/countryLayerUtils.js +28 -0
- package/dist/core/components/viewers/map/src/MapLayers/src/CountryLayer/countryLayerUtils.js.map +1 -0
- 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 +1 -16
- package/dist/core/components/viewers/map/src/MapLayers/src/CountryLayer/index.js.map +1 -1
- package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/FileModelLayer/FileModelLayer.d.ts.map +1 -1
- package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/FileModelLayer/FileModelLayer.js.map +1 -1
- package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/utils/CustomModelLayer.d.ts.map +1 -1
- package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/utils/CustomModelLayer.js +31 -2
- package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/utils/CustomModelLayer.js.map +1 -1
- package/dist/core/components/viewers/map/src/MapLayers/src/OpenDataLayer/src/WmsTimeControl.d.ts +21 -0
- package/dist/core/components/viewers/map/src/MapLayers/src/OpenDataLayer/src/WmsTimeControl.d.ts.map +1 -0
- package/dist/core/components/viewers/map/src/MapLayers/src/OpenDataLayer/src/WmsTimeControl.js +111 -0
- package/dist/core/components/viewers/map/src/MapLayers/src/OpenDataLayer/src/WmsTimeControl.js.map +1 -0
- package/dist/core/components/viewers/map/src/MapLayers/src/OpenDataLayer/src/index.d.ts.map +1 -1
- package/dist/core/components/viewers/map/src/MapLayers/src/OpenDataLayer/src/index.js +77 -2
- package/dist/core/components/viewers/map/src/MapLayers/src/OpenDataLayer/src/index.js.map +1 -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.map +1 -1
- package/dist/core/components/viewers/map/src/MapSidebar/src/FileTab/src/FilesSection.d.ts.map +1 -1
- package/dist/core/components/viewers/map/src/MapSidebar/src/FileTab/src/FilesSection.js.map +1 -1
- package/dist/core/components/viewers/map/src/MapSidebar/src/FileTab/src/ModelsSection.d.ts.map +1 -1
- package/dist/core/components/viewers/map/src/MapSidebar/src/FileTab/src/ModelsSection.js.map +1 -1
- package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/src/MapProjection.d.ts.map +1 -1
- package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/src/MapProjection.js +19 -9
- package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/src/MapProjection.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 +10 -3
- package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/src/TerrainLevel.js.map +1 -1
- package/dist/core/components/viewers/map/utils/geocoder.d.ts +6 -2
- package/dist/core/components/viewers/map/utils/geocoder.d.ts.map +1 -1
- package/dist/core/components/viewers/map/utils/geocoder.js +10 -62
- package/dist/core/components/viewers/map/utils/geocoder.js.map +1 -1
- package/dist/core/components/viewers/map/utils/geocoding/adapters.d.ts +5 -0
- package/dist/core/components/viewers/map/utils/geocoding/adapters.d.ts.map +1 -0
- package/dist/core/components/viewers/map/utils/geocoding/adapters.js +192 -0
- package/dist/core/components/viewers/map/utils/geocoding/adapters.js.map +1 -0
- package/dist/core/components/viewers/map/utils/geocoding/config.d.ts +6 -0
- package/dist/core/components/viewers/map/utils/geocoding/config.d.ts.map +1 -0
- package/dist/core/components/viewers/map/utils/geocoding/config.js +14 -0
- package/dist/core/components/viewers/map/utils/geocoding/config.js.map +1 -0
- package/dist/core/components/viewers/map/utils/geocoding/index.d.ts +8 -0
- package/dist/core/components/viewers/map/utils/geocoding/index.d.ts.map +1 -0
- package/dist/core/components/viewers/map/utils/geocoding/index.js +44 -0
- package/dist/core/components/viewers/map/utils/geocoding/index.js.map +1 -0
- package/dist/core/components/viewers/map/utils/geocoding/osm.d.ts +6 -0
- package/dist/core/components/viewers/map/utils/geocoding/osm.d.ts.map +1 -0
- package/dist/core/components/viewers/map/utils/geocoding/osm.js +39 -0
- package/dist/core/components/viewers/map/utils/geocoding/osm.js.map +1 -0
- package/dist/core/components/viewers/map/utils/geocoding/pelias.d.ts +8 -0
- package/dist/core/components/viewers/map/utils/geocoding/pelias.d.ts.map +1 -0
- package/dist/core/components/viewers/map/utils/geocoding/pelias.js +35 -0
- package/dist/core/components/viewers/map/utils/geocoding/pelias.js.map +1 -0
- package/dist/core/components/viewers/pointcloud/PointCloudToolbar.d.ts.map +1 -1
- package/dist/core/components/viewers/pointcloud/PointCloudToolbar.js.map +1 -1
- package/dist/core/components/viewers/pointcloud/PointCloudViewer.js +1 -3
- package/dist/core/components/viewers/pointcloud/PointCloudViewer.js.map +1 -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 -3
- 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/FilesSection.d.ts.map +1 -1
- package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/src/FilesSection.js +8 -2
- package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/src/FilesSection.js.map +1 -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.map +1 -1
- package/dist/core/components/viewers/pointcloud/src/tools/PerformanceSettingsTools/NodeSizeSelectionTool.js +9 -9
- package/dist/core/components/viewers/pointcloud/src/tools/PerformanceSettingsTools/NodeSizeSelectionTool.js.map +1 -1
- package/dist/core/hooks/provider.js.map +1 -1
- package/dist/core/plugins/host/provider.d.ts.map +1 -1
- package/dist/core/plugins/host/provider.js.map +1 -1
- 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/BIM/context.d.ts.map +1 -1
- package/dist/core/store/BIM/context.js.map +1 -1
- package/dist/core/store/BIM/reducer.d.ts +0 -1
- package/dist/core/store/BIM/reducer.d.ts.map +1 -1
- package/dist/core/store/BIM/reducer.js +0 -4
- package/dist/core/store/BIM/reducer.js.map +1 -1
- package/dist/core/store/Buildings/context.d.ts.map +1 -1
- package/dist/core/store/Buildings/context.js.map +1 -1
- package/dist/core/store/Content/context.d.ts.map +1 -1
- package/dist/core/store/Content/context.js.map +1 -1
- package/dist/core/store/Datasets/context.d.ts.map +1 -1
- package/dist/core/store/Datasets/context.js +2 -1
- package/dist/core/store/Datasets/context.js.map +1 -1
- package/dist/core/store/Datasets/reducer.d.ts +2 -0
- package/dist/core/store/Datasets/reducer.d.ts.map +1 -1
- package/dist/core/store/Datasets/reducer.js +9 -4
- package/dist/core/store/Datasets/reducer.js.map +1 -1
- package/dist/core/store/Files/context.d.ts.map +1 -1
- package/dist/core/store/Files/context.js.map +1 -1
- package/dist/core/store/Map/context.d.ts.map +1 -1
- package/dist/core/store/Map/context.js.map +1 -1
- package/dist/core/store/Menus/context.d.ts.map +1 -1
- package/dist/core/store/Menus/context.js.map +1 -1
- package/dist/core/store/Permissions/context.d.ts.map +1 -1
- package/dist/core/store/Permissions/context.js.map +1 -1
- package/dist/core/store/PointCloud/context.d.ts.map +1 -1
- package/dist/core/store/PointCloud/context.js.map +1 -1
- package/dist/core/store/Tools/context.d.ts.map +1 -1
- package/dist/core/store/Tools/context.js.map +1 -1
- package/dist/core/types/datasetTypes.d.ts +8 -1
- package/dist/core/types/datasetTypes.d.ts.map +1 -1
- package/dist/core/types/dbTypes.d.ts +13 -13
- package/dist/core/types/dbTypes.d.ts.map +1 -1
- package/dist/core/types/dbTypes.js +13 -13
- package/dist/core/types/dbTypes.js.map +1 -1
- package/dist/core/types/index.d.ts +1 -1
- package/dist/core/types/index.d.ts.map +1 -1
- package/dist/core/types/index.js.map +1 -1
- package/dist/core/utils/imageUtils.js +1 -1
- package/dist/core/utils/imageUtils.js.map +1 -1
- package/package.json +4 -3
- package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudViewer-old.d.ts +0 -3
- package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudViewer-old.d.ts.map +0 -1
- package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudViewer-old.js +0 -173
- package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudViewer-old.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/core/components/viewers/Viewer.tsx"],"sourcesContent":["'use client'\r\n\r\n// Dependencies\r\nimport * as React from 'react'\r\nimport dynamic from 'next/dynamic'\r\nimport { useSearchParams, useRouter, usePathname } from 'next/navigation'\r\nimport { ViewerNames } from '../../types'\r\nimport { BuildingsContext, MenusContext } from '../../store'\r\nimport { MapViewer } from './map/MapViewer'\r\n// Audit Phase 1.F (F-2c): direct file import to bypass the ui barrel\r\n// (`src/core/components/ui/index.ts`), which re-exports `InfoSidebar` and\r\n// `useFileUploadHandler` and other heavy modules. Viewer.tsx is on the\r\n// eager map route, so any pull-through-the-barrel here lands in the\r\n// /[instance] First Load JS.\r\nimport { SidebarTrigger } from '../ui/Sidebar'\r\nimport { UserSettings } from '../settings'\r\nimport { Toolbar } from '../Toolbar'\r\nimport { switchLanguage } from '../../utils/utils'\r\nimport { Organization } from '../../types/dbTypes'\r\n\r\n// Audit Phase 1.A (F-1): code-split heavy viewers. BimViewer pulls in\r\n// ~456 KB gzipped of @thatopen/*; PointCloudViewer pulls in the Potree\r\n// loader stack. Both are loaded only when the user actually selects them,\r\n// so map-only sessions never pay their cost. MapViewer stays statically\r\n// imported because every user lands on it.\r\nconst BimViewer = dynamic(\r\n () => import('./bim/BimViewer').then(m => ({ default: m.BimViewer })),\r\n { ssr: false, loading: () => <ViewerLoadingFallback label=\"Loading BIM viewer…\" /> },\r\n)\r\nconst PointCloudViewer = dynamic(\r\n () => import('./pointcloud/PointCloudViewer').then(m => ({ default: m.PointCloudViewer })),\r\n { ssr: false, loading: () => <ViewerLoadingFallback label=\"Loading point cloud viewer…\" /> },\r\n)\r\n\r\n// Audit Phase 1.B (F-13): DataMenu transitively imports FilePreview which\r\n// imports BimViewer directly (not via the dynamic wrapper above) — so the\r\n// previous static import of DataMenu re-introduced @thatopen + three/webgpu\r\n// into the eager bundle. Now lazy alongside BimViewer / PointCloudViewer.\r\n// DataMenu is only rendered when the user picks viewer=buildings|sites|\r\n// files|land|infrastructure|extensions|users, so map-only sessions skip it.\r\nconst DataMenu = dynamic(\r\n () => import('./Data/DataMenu').then(m => ({ default: m.DataMenu })),\r\n { ssr: false, loading: () => <ViewerLoadingFallback label=\"Loading data…\" /> },\r\n)\r\n\r\nfunction ViewerLoadingFallback({ label }: { label: string }) {\r\n return (\r\n <div style={{ width: '100%', height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#888' }}>\r\n {label}\r\n </div>\r\n )\r\n}\r\n\r\ninterface ViewerProps {\r\n organization: Organization\r\n}\r\n\r\nexport function Viewer({ organization }: ViewerProps) {\r\n\r\n const searchParams = useSearchParams()\r\n const viewer = (searchParams.get('viewer') as ViewerNames) || ViewerNames.map\r\n\r\n const { dispatch: menusDispatch, state: menusState } = React.useContext(MenusContext)\r\n const { state: buildingState } = React.useContext(BuildingsContext)\r\n // const { dispatch: appConfigDispatch } = React.useContext(AppConfigContext)\r\n const { building } = buildingState.buildings\r\n const { currentViewer } = menusState.menus\r\n const router = useRouter()\r\n const pathname = usePathname()\r\n const [isMounted, setIsMounted] = React.useState(false)\r\n\r\n // Use a ref to track if we're currently updating -> prevent circular updates\r\n const isUpdatingRef = React.useRef(false)\r\n\r\n const { appContent } = organization\r\n\r\n // Check if viewer is valid based on appContent\r\n const isViewerValid = appContent.length === 0 || appContent.includes(viewer)\r\n \r\n // Use default viewer (map) if current viewer is not valid\r\n const validViewer = isViewerValid ? viewer : ViewerNames.map\r\n\r\n // Update URL if viewer was not available for the organization\r\n React.useEffect(() => {\r\n if (isMounted && !isViewerValid && viewer !== ViewerNames.map) {\r\n const newSearchParams = new URLSearchParams(searchParams.toString())\r\n newSearchParams.delete('viewer')\r\n if (building?.id) {\r\n newSearchParams.set('buildingId', String(building.id))\r\n }\r\n router.replace(`${pathname}?${newSearchParams.toString()}`, { scroll: false })\r\n }\r\n }, [isMounted, isViewerValid, viewer, searchParams, pathname, router, building?.id])\r\n\r\n // On first mount, respond to URL\r\n React.useEffect(() => {\r\n if (!isMounted) {\r\n menusDispatch({\r\n type: 'SET_VIEWER',\r\n payload: { currentViewer: validViewer },\r\n })\r\n setIsMounted(true)\r\n }\r\n }, [isMounted, validViewer, menusDispatch])\r\n\r\n React.useEffect(() => {\r\n if (!organization) return\r\n const defaultLanguage = organization.languages?.[0] || 'En'\r\n if (defaultLanguage) switchLanguage(defaultLanguage)\r\n }, [organization])\r\n\r\n // Handle context changes (from sidebar, HeaderButtons, etc.)\r\n React.useEffect(() => {\r\n if (!isMounted || !currentViewer || currentViewer === validViewer || isUpdatingRef.current) {\r\n return\r\n }\r\n\r\n isUpdatingRef.current = true\r\n\r\n // Create URLSearchParams to preserve existing search params\r\n\r\n const newSearchParams = new URLSearchParams(searchParams.toString())\r\n newSearchParams.set('viewer', currentViewer)\r\n if (building?.id) {\r\n newSearchParams.set('buildingId', String(building.id))\r\n }\r\n\r\n\r\n router.replace(`${pathname}?${newSearchParams.toString()}`, { scroll: false })\r\n\r\n // Reset the flag after a brief delay to allow the navigation to complete\r\n setTimeout(() => {\r\n isUpdatingRef.current = false\r\n }, 100)\r\n }, [currentViewer, isMounted, pathname, router, viewer, searchParams])\r\n\r\n // Handle URL changes (direct navigation)\r\n React.useEffect(() => {\r\n if (isMounted && currentViewer !== validViewer && !isUpdatingRef.current) {\r\n isUpdatingRef.current = true\r\n\r\n menusDispatch({\r\n type: 'SET_VIEWER',\r\n payload: { currentViewer: validViewer },\r\n })\r\n\r\n // Reset the flag after a brief delay\r\n setTimeout(() => {\r\n isUpdatingRef.current = false\r\n }, 100)\r\n }\r\n }, [validViewer, menusDispatch, isMounted, currentViewer])\r\n\r\n const selectedViewer = (\r\n <>\r\n {[ViewerNames.map, ViewerNames.bim, ViewerNames.pointcloud].includes(validViewer) && <SidebarTrigger />}\r\n <div style={{ height: '100%', width: '100%', position: 'relative' }}>\r\n <div style={{ display: validViewer === ViewerNames.map ? 'block' : 'none', width: '100%', height: '100%' }}>\r\n <MapViewer organization={organization} />\r\n </div>\r\n {validViewer === ViewerNames.bim && <BimViewer />}\r\n {validViewer === ViewerNames.pointcloud && <PointCloudViewer />}\r\n {[ViewerNames.buildings, ViewerNames.sites, ViewerNames.files, ViewerNames.land, ViewerNames.infrastructure, ViewerNames.extensions, ViewerNames.users].includes(validViewer) && (\r\n <DataMenu currentViewer={validViewer} />\r\n )}\r\n {[ViewerNames.settings].includes(validViewer) && (\r\n <UserSettings />\r\n )}\r\n </div>\r\n </>\r\n )\r\n\r\n return (\r\n <>\r\n {selectedViewer}\r\n <Toolbar viewer={validViewer} />\r\n </>\r\n )\r\n}"],"mappings":";AA2B+B,SA+H3B,UA/H2B,KAiIzB,YAjIyB;AAxB/B,YAAY,WAAW;AACvB,OAAO,aAAa;AACpB,SAAS,iBAAiB,WAAW,mBAAmB;AACxD,SAAS,mBAAmB;AAC5B,SAAS,kBAAkB,oBAAoB;AAC/C,SAAS,iBAAiB;AAM1B,SAAS,sBAAsB;AAC/B,SAAS,oBAAoB;AAC7B,SAAS,eAAe;AACxB,SAAS,sBAAsB;AAQ/B,MAAM,YAAY;AAAA,EAChB,MAAM,OAAO,iBAAiB,EAAE,KAAK,QAAM,EAAE,SAAS,EAAE,UAAU,EAAE;AAAA,EACpE,EAAE,KAAK,OAAO,SAAS,MAAM,oBAAC,yBAAsB,OAAM,4BAAsB,EAAG;AACrF;AACA,MAAM,mBAAmB;AAAA,EACvB,MAAM,OAAO,+BAA+B,EAAE,KAAK,QAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE;AAAA,EACzF,EAAE,KAAK,OAAO,SAAS,MAAM,oBAAC,yBAAsB,OAAM,oCAA8B,EAAG;AAC7F;AAQA,MAAM,WAAW;AAAA,EACf,MAAM,OAAO,iBAAiB,EAAE,KAAK,QAAM,EAAE,SAAS,EAAE,SAAS,EAAE;AAAA,EACnE,EAAE,KAAK,OAAO,SAAS,MAAM,oBAAC,yBAAsB,OAAM,sBAAgB,EAAG;AAC/E;AAEA,SAAS,sBAAsB,EAAE,MAAM,GAAsB;AAC3D,SACE,oBAAC,SAAI,OAAO,EAAE,OAAO,QAAQ,QAAQ,QAAQ,SAAS,QAAQ,YAAY,UAAU,gBAAgB,UAAU,OAAO,OAAO,GACzH,iBACH;AAEJ;AAMO,SAAS,OAAO,EAAE,aAAa,GAAgB;AAEpD,QAAM,eAAe,gBAAgB;AACrC,QAAM,SAAU,aAAa,IAAI,QAAQ,KAAqB,YAAY;AAE1E,QAAM,EAAE,UAAU,eAAe,OAAO,WAAW,IAAI,MAAM,WAAW,YAAY;AACpF,QAAM,EAAE,OAAO,cAAc,IAAI,MAAM,WAAW,gBAAgB;AAElE,QAAM,EAAE,SAAS,IAAI,cAAc;AACnC,QAAM,EAAE,cAAc,IAAI,WAAW;AACrC,QAAM,SAAS,UAAU;AACzB,QAAM,WAAW,YAAY;AAC7B,QAAM,CAAC,WAAW,YAAY,IAAI,MAAM,SAAS,KAAK;AAGtD,QAAM,gBAAgB,MAAM,OAAO,KAAK;AAEtC,QAAM,EAAE,WAAW,IAAI;AAGzB,QAAM,gBAAgB,WAAW,WAAW,KAAK,WAAW,SAAS,MAAM;AAG3E,QAAM,cAAc,gBAAgB,SAAS,YAAY;AAGzD,QAAM,UAAU,MAAM;AACpB,QAAI,aAAa,CAAC,iBAAiB,WAAW,YAAY,KAAK;AAC7D,YAAM,kBAAkB,IAAI,gBAAgB,aAAa,SAAS,CAAC;AACnE,sBAAgB,OAAO,QAAQ;AAC/B,UAAI,qCAAU,IAAI;AAChB,wBAAgB,IAAI,cAAc,OAAO,SAAS,EAAE,CAAC;AAAA,MACvD;AACA,aAAO,QAAQ,GAAG,QAAQ,IAAI,gBAAgB,SAAS,CAAC,IAAI,EAAE,QAAQ,MAAM,CAAC;AAAA,IAC/E;AAAA,EACF,GAAG,CAAC,WAAW,eAAe,QAAQ,cAAc,UAAU,QAAQ,qCAAU,EAAE,CAAC;AAGnF,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,WAAW;AACd,oBAAc;AAAA,QACZ,MAAM;AAAA,QACN,SAAS,EAAE,eAAe,YAAY;AAAA,MACxC,CAAC;AACD,mBAAa,IAAI;AAAA,IACnB;AAAA,EACF,GAAG,CAAC,WAAW,aAAa,aAAa,CAAC;AAE1C,QAAM,UAAU,MAAM;AAzGxB;AA0GI,QAAI,CAAC,aAAc;AACnB,UAAM,oBAAmB,kBAAa,cAAb,mBAAyB,OAAM;AACxD,QAAI,gBAAiB,gBAAe,eAAe;AAAA,EACrD,GAAG,CAAC,YAAY,CAAC;AAGjB,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,aAAa,CAAC,iBAAiB,kBAAkB,eAAe,cAAc,SAAS;AAC1F;AAAA,IACF;AAEA,kBAAc,UAAU;AAIxB,UAAM,kBAAkB,IAAI,gBAAgB,aAAa,SAAS,CAAC;AACnE,oBAAgB,IAAI,UAAU,aAAa;AAC3C,QAAI,qCAAU,IAAI;AAChB,sBAAgB,IAAI,cAAc,OAAO,SAAS,EAAE,CAAC;AAAA,IACvD;AAGA,WAAO,QAAQ,GAAG,QAAQ,IAAI,gBAAgB,SAAS,CAAC,IAAI,EAAE,QAAQ,MAAM,CAAC;AAG7E,eAAW,MAAM;AACf,oBAAc,UAAU;AAAA,IAC1B,GAAG,GAAG;AAAA,EACR,GAAG,CAAC,eAAe,WAAW,UAAU,QAAQ,QAAQ,YAAY,CAAC;AAGrE,QAAM,UAAU,MAAM;AACpB,QAAI,aAAa,kBAAkB,eAAe,CAAC,cAAc,SAAS;AACxE,oBAAc,UAAU;AAExB,oBAAc;AAAA,QACZ,MAAM;AAAA,QACN,SAAS,EAAE,eAAe,YAAY;AAAA,MACxC,CAAC;AAGD,iBAAW,MAAM;AACf,sBAAc,UAAU;AAAA,MAC1B,GAAG,GAAG;AAAA,IACR;AAAA,EACF,GAAG,CAAC,aAAa,eAAe,WAAW,aAAa,CAAC;AAEzD,QAAM,iBACJ,iCACG;AAAA,KAAC,YAAY,KAAK,YAAY,KAAK,YAAY,UAAU,EAAE,SAAS,WAAW,KAAK,oBAAC,kBAAe;AAAA,IACrG,qBAAC,SAAI,OAAO,EAAE,QAAQ,QAAQ,OAAO,QAAQ,UAAU,WAAW,GAChE;AAAA,0BAAC,SAAI,OAAO,EAAE,SAAS,gBAAgB,YAAY,MAAM,UAAU,QAAQ,OAAO,QAAQ,QAAQ,OAAO,GACvG,8BAAC,aAAU,cAA4B,GACzC;AAAA,MACC,gBAAgB,YAAY,OAAO,oBAAC,aAAU;AAAA,MAC9C,gBAAgB,YAAY,cAAc,oBAAC,oBAAiB;AAAA,MAC5D,CAAC,YAAY,WAAW,YAAY,OAAO,YAAY,OAAO,YAAY,MAAM,YAAY,gBAAgB,YAAY,YAAY,YAAY,KAAK,EAAE,SAAS,WAAW,KAC1K,oBAAC,YAAS,eAAe,aAAa;AAAA,MAEvC,CAAC,YAAY,QAAQ,EAAE,SAAS,WAAW,KAC1C,oBAAC,gBAAa;AAAA,OAElB;AAAA,KACF;AAGF,SACE,iCACG;AAAA;AAAA,IACD,oBAAC,WAAQ,QAAQ,aAAa;AAAA,KAChC;AAEJ;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/core/components/viewers/Viewer.tsx"],"sourcesContent":["'use client'\r\n\r\n// Dependencies\r\nimport * as React from 'react'\r\nimport dynamic from 'next/dynamic'\r\nimport { Loader2 } from 'lucide-react'\r\nimport { useSearchParams, useRouter, usePathname } from 'next/navigation'\r\nimport { ViewerNames } from '../../types'\r\nimport { BuildingsContext, MenusContext } from '../../store'\r\nimport { MapViewer } from './map/MapViewer'\r\n// Deep file import (not the ui barrel): the barrel re-exports heavy modules\r\n// (InfoSidebar, useFileUploadHandler, …) that would land in the eager map-route bundle.\r\nimport { SidebarTrigger } from '../ui/Sidebar'\r\nimport { UserSettings } from '../settings'\r\nimport { Toolbar } from '../Toolbar'\r\nimport { switchLanguage } from '../../utils/utils'\r\nimport { Organization } from '../../types/dbTypes'\r\n\r\n// Code-split the heavy viewers: BimViewer pulls in ~456 KB gzipped of\r\n// @thatopen/*, PointCloudViewer the Potree loader stack — loaded only when\r\n// selected, so map-only sessions never pay their cost. MapViewer stays static\r\n// because every user lands on it.\r\nconst BimViewer = dynamic(\r\n () => import('./bim/BimViewer').then(m => ({ default: m.BimViewer })),\r\n { ssr: false, loading: () => <ViewerLoadingFallback label=\"Loading BIM viewer…\" /> },\r\n)\r\nconst PointCloudViewer = dynamic(\r\n () => import('./pointcloud/PointCloudViewer').then(m => ({ default: m.PointCloudViewer })),\r\n { ssr: false, loading: () => <ViewerLoadingFallback label=\"Loading point cloud viewer…\" /> },\r\n)\r\n\r\n// DataMenu transitively imports BimViewer (via FilePreview), so keep it lazy\r\n// too — a static import would pull @thatopen + three/webgpu back into the eager\r\n// bundle. Only rendered for the data viewers, so map-only sessions skip it.\r\nconst DataMenu = dynamic(\r\n () => import('./Data/DataMenu').then(m => ({ default: m.DataMenu })),\r\n { ssr: false, loading: () => <ViewerLoadingFallback label=\"Loading data…\" /> },\r\n)\r\n\r\n// Styled to match the in-viewer loading card (see BimLoadingState): a soft\r\n// backdrop-blurred overlay with a bordered card, spinner + label. Uses only\r\n// Tailwind tokens + one lucide icon, so it adds no meaningful weight to the\r\n// eager map-route bundle (Viewer.tsx is statically imported).\r\nfunction ViewerLoadingFallback({ label }: { label: string }) {\r\n return (\r\n <div className=\"absolute inset-0 z-10 flex items-center justify-center bg-background/50 backdrop-blur-[1px]\">\r\n <div className=\"flex items-center gap-3 rounded-md border border-border bg-card px-5 py-4 shadow-sm\">\r\n <Loader2 className=\"h-5 w-5 animate-spin text-muted-foreground\" />\r\n <span className=\"text-foreground text-base font-medium font-['Inter'] leading-7\">{label}</span>\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\ninterface ViewerProps {\r\n organization: Organization\r\n}\r\n\r\nexport function Viewer({ organization }: ViewerProps) {\r\n\r\n const searchParams = useSearchParams()\r\n const viewer = (searchParams.get('viewer') as ViewerNames) || ViewerNames.map\r\n\r\n const { dispatch: menusDispatch, state: menusState } = React.useContext(MenusContext)\r\n const { state: buildingState } = React.useContext(BuildingsContext)\r\n // const { dispatch: appConfigDispatch } = React.useContext(AppConfigContext)\r\n const { building } = buildingState.buildings\r\n const { currentViewer } = menusState.menus\r\n const router = useRouter()\r\n const pathname = usePathname()\r\n const [isMounted, setIsMounted] = React.useState(false)\r\n\r\n // Use a ref to track if we're currently updating -> prevent circular updates\r\n const isUpdatingRef = React.useRef(false)\r\n\r\n const { appContent } = organization\r\n\r\n // Check if viewer is valid based on appContent\r\n const isViewerValid = appContent.length === 0 || appContent.includes(viewer)\r\n \r\n // Use default viewer (map) if current viewer is not valid\r\n const validViewer = isViewerValid ? viewer : ViewerNames.map\r\n\r\n // Update URL if viewer was not available for the organization\r\n React.useEffect(() => {\r\n if (isMounted && !isViewerValid && viewer !== ViewerNames.map) {\r\n const newSearchParams = new URLSearchParams(searchParams.toString())\r\n newSearchParams.delete('viewer')\r\n if (building?.id) {\r\n newSearchParams.set('buildingId', String(building.id))\r\n }\r\n router.replace(`${pathname}?${newSearchParams.toString()}`, { scroll: false })\r\n }\r\n }, [isMounted, isViewerValid, viewer, searchParams, pathname, router, building?.id])\r\n\r\n // On first mount, respond to URL\r\n React.useEffect(() => {\r\n if (!isMounted) {\r\n menusDispatch({\r\n type: 'SET_VIEWER',\r\n payload: { currentViewer: validViewer },\r\n })\r\n setIsMounted(true)\r\n }\r\n }, [isMounted, validViewer, menusDispatch])\r\n\r\n React.useEffect(() => {\r\n if (!organization) return\r\n const defaultLanguage = organization.languages?.[0] || 'En'\r\n if (defaultLanguage) switchLanguage(defaultLanguage)\r\n }, [organization])\r\n\r\n // Handle context changes (from sidebar, HeaderButtons, etc.)\r\n React.useEffect(() => {\r\n if (!isMounted || !currentViewer || currentViewer === validViewer || isUpdatingRef.current) {\r\n return\r\n }\r\n\r\n isUpdatingRef.current = true\r\n\r\n // Create URLSearchParams to preserve existing search params\r\n\r\n const newSearchParams = new URLSearchParams(searchParams.toString())\r\n newSearchParams.set('viewer', currentViewer)\r\n if (building?.id) {\r\n newSearchParams.set('buildingId', String(building.id))\r\n }\r\n\r\n\r\n router.replace(`${pathname}?${newSearchParams.toString()}`, { scroll: false })\r\n\r\n // Reset the flag after a brief delay to allow the navigation to complete\r\n setTimeout(() => {\r\n isUpdatingRef.current = false\r\n }, 100)\r\n }, [currentViewer, isMounted, pathname, router, viewer, searchParams])\r\n\r\n // Handle URL changes (direct navigation)\r\n React.useEffect(() => {\r\n if (isMounted && currentViewer !== validViewer && !isUpdatingRef.current) {\r\n isUpdatingRef.current = true\r\n\r\n menusDispatch({\r\n type: 'SET_VIEWER',\r\n payload: { currentViewer: validViewer },\r\n })\r\n\r\n // Reset the flag after a brief delay\r\n setTimeout(() => {\r\n isUpdatingRef.current = false\r\n }, 100)\r\n }\r\n }, [validViewer, menusDispatch, isMounted, currentViewer])\r\n\r\n const selectedViewer = (\r\n <>\r\n {[ViewerNames.map, ViewerNames.bim, ViewerNames.pointcloud].includes(validViewer) && <SidebarTrigger />}\r\n <div style={{ height: '100%', width: '100%', position: 'relative' }}>\r\n <div style={{ display: validViewer === ViewerNames.map ? 'block' : 'none', width: '100%', height: '100%' }}>\r\n <MapViewer organization={organization} />\r\n </div>\r\n {validViewer === ViewerNames.bim && <BimViewer />}\r\n {validViewer === ViewerNames.pointcloud && <PointCloudViewer />}\r\n {[ViewerNames.buildings, ViewerNames.sites, ViewerNames.files, ViewerNames.land, ViewerNames.infrastructure, ViewerNames.extensions, ViewerNames.users].includes(validViewer) && (\r\n <DataMenu currentViewer={validViewer} />\r\n )}\r\n {[ViewerNames.settings].includes(validViewer) && (\r\n <UserSettings />\r\n )}\r\n </div>\r\n </>\r\n )\r\n\r\n return (\r\n <>\r\n {selectedViewer}\r\n <Toolbar viewer={validViewer} />\r\n </>\r\n )\r\n}"],"mappings":"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","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BimToolbar.d.ts","sourceRoot":"","sources":["../../../../../src/core/components/viewers/bim/BimToolbar.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"BimToolbar.d.ts","sourceRoot":"","sources":["../../../../../src/core/components/viewers/bim/BimToolbar.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B,wBAAgB,UAAU,sBAEzB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/core/components/viewers/bim/BimToolbar.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { bimToolbarTools } from './src/tools/bimToolbar'\nimport { ToolbarBody } from '../../ToolbarBody'\n\
|
|
1
|
+
{"version":3,"sources":["../../../../../src/core/components/viewers/bim/BimToolbar.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { bimToolbarTools } from './src/tools/bimToolbar'\nimport { ToolbarBody } from '../../ToolbarBody'\n\nexport function BimToolbar() {\n return <ToolbarBody viewer=\"bim\" tools={bimToolbarTools()} />\n}\n"],"mappings":";AAOS;AAJT,SAAS,uBAAuB;AAChC,SAAS,mBAAmB;AAErB,SAAS,aAAa;AAC3B,SAAO,oBAAC,eAAY,QAAO,OAAM,OAAO,gBAAgB,GAAG;AAC7D;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BimViewer.d.ts","sourceRoot":"","sources":["../../../../../src/core/components/viewers/bim/BimViewer.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAmB/B,wBAAgB,SAAS,
|
|
1
|
+
{"version":3,"file":"BimViewer.d.ts","sourceRoot":"","sources":["../../../../../src/core/components/viewers/bim/BimViewer.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAmB/B,wBAAgB,SAAS,sBA2PxB"}
|
|
@@ -29,9 +29,10 @@ function BimViewer() {
|
|
|
29
29
|
const containerRef = React.useRef(null);
|
|
30
30
|
const workerUrlRef = React.useRef(null);
|
|
31
31
|
const resizeObserverRef = React.useRef(null);
|
|
32
|
+
const componentsRef = React.useRef(null);
|
|
32
33
|
const createViewer = React.useCallback(
|
|
33
|
-
async () => {
|
|
34
|
-
if (!containerRef.current ||
|
|
34
|
+
async (isCancelled) => {
|
|
35
|
+
if (!containerRef.current || componentsRef.current) return;
|
|
35
36
|
const container = containerRef.current;
|
|
36
37
|
const components = new OBC.Components();
|
|
37
38
|
const worlds = components.get(OBC.Worlds);
|
|
@@ -95,6 +96,11 @@ function BimViewer() {
|
|
|
95
96
|
await world.scene.updateShadows();
|
|
96
97
|
});
|
|
97
98
|
world.scene.three.background = null;
|
|
99
|
+
if (isCancelled()) {
|
|
100
|
+
components.dispose();
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
componentsRef.current = components;
|
|
98
104
|
bimDispatch({
|
|
99
105
|
type: "SET_COMPONENTS",
|
|
100
106
|
payload: { bimComponents: components, world, fragments }
|
|
@@ -123,13 +129,16 @@ function BimViewer() {
|
|
|
123
129
|
[]
|
|
124
130
|
);
|
|
125
131
|
React.useEffect(() => {
|
|
126
|
-
|
|
132
|
+
let cancelled = false;
|
|
133
|
+
createViewer(() => cancelled);
|
|
127
134
|
return () => {
|
|
135
|
+
cancelled = true;
|
|
128
136
|
if (resizeObserverRef.current) {
|
|
129
137
|
resizeObserverRef.current.disconnect();
|
|
130
138
|
}
|
|
131
|
-
if (
|
|
132
|
-
|
|
139
|
+
if (componentsRef.current) {
|
|
140
|
+
componentsRef.current.dispose();
|
|
141
|
+
componentsRef.current = null;
|
|
133
142
|
}
|
|
134
143
|
bimDispatch({
|
|
135
144
|
type: "DISPOSE-BIM"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/core/components/viewers/bim/BimViewer.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport * as React from \"react\";\r\nimport * as OBC from \"@thatopen/components\";\r\nimport * as OBF from \"@thatopen/components-front\"\r\nimport * as THREE from \"three\";\r\nimport { useTranslations, useLocale } from 'next-intl';\r\nimport { ToolsContext, BimContext, MenusContext } from \"../../../store\";\r\n\r\nimport { CurrentWorld } from \"./src/CurrentWorld\";\r\nimport { CurrentCamera } from './src/CurrentCamera';\r\nimport { Highlighter } from \"./src/Highlighter\";\r\nimport { FloorplanTool } from \"./src/FloorplanTool\";\r\nimport { ElevationsTool } from \"./src/ElevationsTool\";\r\nimport { ViewModeCoordinator } from \"./src/lib/ViewModeCoordinator\";\r\n\r\nimport { PropertiesMenu } from \"./src/propertiesMenu\";\r\nimport { BimLoadingState } from \"./src/BimLoadingState\";\r\nimport { ViewportGizmo } from \"./src/ViewportGizmo\";\r\nimport { useBimCoordinateSystem } from \"../useCoordinateSystem\";\r\n\r\nexport function BimViewer() {\r\n\r\n const t = useTranslations('ViewportGizmo');\r\n const locale = useLocale();\r\n\r\n const { dispatch: bimDispatch, state: bimState } = React.useContext(BimContext);\r\n const { bimComponents } = bimState.bim;\r\n\r\n const { dispatch: toolsDispatch, state: toolsState } = React.useContext(ToolsContext);\r\n const { currentToolId } = toolsState.tools;\r\n\r\n const { state: menusState } = React.useContext(MenusContext);\r\n const { currentViewer } = menusState.menus;\r\n \r\n\r\n const containerRef = React.useRef<HTMLDivElement>(null);\r\n const workerUrlRef = React.useRef<string | null>(null);\r\n const resizeObserverRef = React.useRef<ResizeObserver | null>(null);\r\n\r\n const createViewer = React.useCallback(\r\n async () => {\r\n if (!containerRef.current || bimComponents) return;\r\n\r\n const container = containerRef.current;\r\n const components = new OBC.Components();\r\n const worlds = components.get(OBC.Worlds);\r\n const world = worlds.create<\r\n OBC.ShadowedScene,\r\n OBC.OrthoPerspectiveCamera,\r\n OBF.PostproductionRenderer\r\n >();\r\n\r\n world.scene = new OBC.ShadowedScene(components);\r\n\r\n world.renderer = new OBF.PostproductionRenderer(components, container);\r\n world.camera = new OBC.OrthoPerspectiveCamera(components);\r\n\r\n components.init();\r\n\r\n world.scene.setup();\r\n world.scene.three.background = null;\r\n\r\n const grids = components.get(OBC.Grids);\r\n const grid = grids.create(world);\r\n\r\n if (grid) {\r\n bimDispatch({\r\n \"type\": \"SET_GRID\",\r\n \"payload\": { grid }\r\n });\r\n }\r\n\r\n const axesHelper = new THREE.AxesHelper(5);\r\n world.scene.three.add(axesHelper);\r\n\r\n const fragments = components.get(OBC.FragmentsManager);\r\n\r\n const githubUrl =\r\n \"https://thatopen.github.io/engine_fragment/resources/worker.mjs\";\r\n const fetchedUrl = await fetch(githubUrl);\r\n const workerBlob = await fetchedUrl.blob();\r\n const workerFile = new File([workerBlob], \"worker.mjs\", {\r\n type: \"text/javascript\",\r\n });\r\n const workerUrl = URL.createObjectURL(workerFile);\r\n workerUrlRef.current = workerUrl; // Store reference for cleanup\r\n fragments.init(workerUrl);\r\n\r\n world.camera.controls.addEventListener(\"control\", () =>\r\n fragments.core.update(),\r\n );\r\n\r\n world.camera.controls.restThreshold = 0.005;\r\n world.camera.controls.addEventListener(\"rest\", () =>\r\n fragments.core.update(true)\r\n );\r\n\r\n components.get(CurrentWorld).world = world;\r\n components.get(CurrentCamera).camera = world.camera;\r\n components.get(Highlighter);\r\n components.get(ViewModeCoordinator);\r\n components.get(FloorplanTool);\r\n components.get(ElevationsTool);\r\n\r\n // Grid injection is safe here — fragments.core is initialized.\r\n if (grid) {\r\n components.get(FloorplanTool).setGrid(grid);\r\n components.get(ElevationsTool).setGrid(grid);\r\n }\r\n\r\n // Enable shadows\r\n world.renderer.three.shadowMap.enabled = true;\r\n world.renderer.three.shadowMap.type = THREE.PCFSoftShadowMap;\r\n world.scene.setup({\r\n shadows: {\r\n cascade: 1,\r\n resolution: 1024,\r\n },\r\n });\r\n\r\n world.scene.distanceRenderer.excludedObjects.add(grid.three);\r\n\r\n await world.scene.updateShadows();\r\n\r\n world.camera.controls.addEventListener(\"rest\", async () => {\r\n await world.scene.updateShadows();\r\n });\r\n\r\n world.scene.three.background = null;\r\n\r\n bimDispatch({\r\n type: \"SET_COMPONENTS\",\r\n payload: { bimComponents: components, world, fragments }\r\n });\r\n\r\n // Ensure canvas takes full container size\r\n const canvas = container.querySelector('canvas');\r\n if (canvas) {\r\n canvas.style.width = '100%';\r\n canvas.style.height = '100%';\r\n canvas.style.display = 'block';\r\n }\r\n\r\n // Handle resize using container dimensions\r\n const handleResize = () => {\r\n const width = container.clientWidth;\r\n const height = container.clientHeight;\r\n if (width && height) {\r\n world.renderer?.resize(new THREE.Vector2(width, height));\r\n }\r\n };\r\n \r\n // Initial resize\r\n handleResize();\r\n \r\n // Watch for container size changes using ResizeObserver. This\r\n // already covers the window-resize case: when the window resizes,\r\n // the flex layout reshapes this container, and ResizeObserver\r\n // fires.\r\n const resizeObserver = new ResizeObserver(() => {\r\n handleResize();\r\n });\r\n resizeObserver.observe(container);\r\n resizeObserverRef.current = resizeObserver;\r\n\r\n // Audit Phase 1.E (F-18 / F-B6): the previous\r\n // `window.addEventListener('resize', handleResize)` here had no\r\n // matching removeEventListener — every BimViewer mount leaked a\r\n // listener (Phase 0 baseline measured ~+9 listeners/min during\r\n // active use). Removed entirely; the ResizeObserver above is\r\n // sufficient for the redraw case.\r\n }, []\r\n );\r\n\r\n React.useEffect(() => {\r\n createViewer();\r\n\r\n // Cleanup function to properly dispose of components when unmounting\r\n return () => {\r\n if (resizeObserverRef.current) {\r\n resizeObserverRef.current.disconnect();\r\n }\r\n if (bimComponents) {\r\n bimComponents.dispose();\r\n }\r\n bimDispatch({\r\n type: \"DISPOSE-BIM\"\r\n });\r\n };\r\n }, []);\r\n\r\n // Enforce Y-up coordinate system for Three.js / camera-controls.\r\n // Runs whenever the world (and its controls) becomes available, and resets on unmount.\r\n useBimCoordinateSystem(bimState.bim.world?.camera?.controls ?? null);\r\n\r\n // Control ViewportGizmo based on current viewer\r\n React.useEffect(() => {\r\n if (!bimComponents) return;\r\n\r\n const viewportGizmo = bimComponents.get(ViewportGizmo);\r\n\r\n viewportGizmo.setLabels({\r\n top: t('top'),\r\n right: t('right'),\r\n bottom: t('bottom'),\r\n left: t('left'),\r\n front: t('front'),\r\n back: t('back')\r\n });\r\n\r\n if (!viewportGizmo) return;\r\n\r\n if (currentViewer === 'bim') {\r\n viewportGizmo.enabled = true;\r\n viewportGizmo.add();\r\n } else {\r\n viewportGizmo.enabled = false;\r\n viewportGizmo.remove();\r\n }\r\n }, [bimComponents, currentViewer, locale, t]);\r\n\r\n return (\r\n <div\r\n style={{\r\n position: \"relative\",\r\n width: \"100%\",\r\n height: \"100%\",\r\n overflow: \"hidden\"\r\n }}\r\n >\r\n <BimLoadingState />\r\n <div\r\n className=\"bim-container\"\r\n id=\"bim-viewer-container\"\r\n ref={containerRef}\r\n style={{\r\n width: \"100%\",\r\n height: \"100%\",\r\n position: \"relative\",\r\n background: \"radial-gradient(circle, rgba(255, 255, 255, 1) 50%, rgba(220, 220, 220, 1) 100%)\",\r\n }}\r\n />\r\n <PropertiesMenu />\r\n </div>\r\n );\r\n}"],"mappings":"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","names":["_a"]}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/core/components/viewers/bim/BimViewer.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport * as React from \"react\";\r\nimport * as OBC from \"@thatopen/components\";\r\nimport * as OBF from \"@thatopen/components-front\"\r\nimport * as THREE from \"three\";\r\nimport { useTranslations, useLocale } from 'next-intl';\r\nimport { ToolsContext, BimContext, MenusContext } from \"../../../store\";\r\n\r\nimport { CurrentWorld } from \"./src/CurrentWorld\";\r\nimport { CurrentCamera } from './src/CurrentCamera';\r\nimport { Highlighter } from \"./src/Highlighter\";\r\nimport { FloorplanTool } from \"./src/FloorplanTool\";\r\nimport { ElevationsTool } from \"./src/ElevationsTool\";\r\nimport { ViewModeCoordinator } from \"./src/lib/ViewModeCoordinator\";\r\n\r\nimport { PropertiesMenu } from \"./src/propertiesMenu\";\r\nimport { BimLoadingState } from \"./src/BimLoadingState\";\r\nimport { ViewportGizmo } from \"./src/ViewportGizmo\";\r\nimport { useBimCoordinateSystem } from \"../useCoordinateSystem\";\r\n\r\nexport function BimViewer() {\r\n\r\n const t = useTranslations('ViewportGizmo');\r\n const locale = useLocale();\r\n\r\n const { dispatch: bimDispatch, state: bimState } = React.useContext(BimContext);\r\n const { bimComponents } = bimState.bim;\r\n\r\n const { dispatch: toolsDispatch, state: toolsState } = React.useContext(ToolsContext);\r\n const { currentToolId } = toolsState.tools;\r\n\r\n const { state: menusState } = React.useContext(MenusContext);\r\n const { currentViewer } = menusState.menus;\r\n \r\n\r\n const containerRef = React.useRef<HTMLDivElement>(null);\r\n const workerUrlRef = React.useRef<string | null>(null);\r\n const resizeObserverRef = React.useRef<ResizeObserver | null>(null);\r\n // Tracks the Components instance THIS mount created, so cleanup disposes the\r\n // real one and the create-guard can't be defeated by a stale [] closure.\r\n const componentsRef = React.useRef<OBC.Components | null>(null);\r\n\r\n const createViewer = React.useCallback(\r\n async (isCancelled: () => boolean) => {\r\n // Re-entrancy guard keyed to the ref we actually set — NOT the stale\r\n // `bimComponents` from this useCallback's [] closure (always null on\r\n // first run, so it could never stop a second init). Without this,\r\n // React StrictMode (dev) and rapid viewer remounts (prod) build a\r\n // second Components + PostproductionRenderer — a second <canvas> —\r\n // and whichever instance wins the SET_COMPONENTS race may be the one\r\n // whose canvas was detached on remount. Models then load into a scene\r\n // that is never painted: the spatial tree builds (metadata) but no\r\n // geometry shows and floorplan nav drives the dead world's camera.\r\n if (!containerRef.current || componentsRef.current) return;\r\n\r\n const container = containerRef.current;\r\n const components = new OBC.Components();\r\n const worlds = components.get(OBC.Worlds);\r\n const world = worlds.create<\r\n OBC.ShadowedScene,\r\n OBC.OrthoPerspectiveCamera,\r\n OBF.PostproductionRenderer\r\n >();\r\n\r\n world.scene = new OBC.ShadowedScene(components);\r\n\r\n world.renderer = new OBF.PostproductionRenderer(components, container);\r\n world.camera = new OBC.OrthoPerspectiveCamera(components);\r\n\r\n components.init();\r\n\r\n world.scene.setup();\r\n world.scene.three.background = null;\r\n\r\n const grids = components.get(OBC.Grids);\r\n const grid = grids.create(world);\r\n\r\n if (grid) {\r\n bimDispatch({\r\n \"type\": \"SET_GRID\",\r\n \"payload\": { grid }\r\n });\r\n }\r\n\r\n const axesHelper = new THREE.AxesHelper(5);\r\n world.scene.three.add(axesHelper);\r\n\r\n const fragments = components.get(OBC.FragmentsManager);\r\n\r\n const githubUrl =\r\n \"https://thatopen.github.io/engine_fragment/resources/worker.mjs\";\r\n const fetchedUrl = await fetch(githubUrl);\r\n const workerBlob = await fetchedUrl.blob();\r\n const workerFile = new File([workerBlob], \"worker.mjs\", {\r\n type: \"text/javascript\",\r\n });\r\n const workerUrl = URL.createObjectURL(workerFile);\r\n workerUrlRef.current = workerUrl; // Store reference for cleanup\r\n fragments.init(workerUrl);\r\n\r\n world.camera.controls.addEventListener(\"control\", () =>\r\n fragments.core.update(),\r\n );\r\n\r\n world.camera.controls.restThreshold = 0.005;\r\n world.camera.controls.addEventListener(\"rest\", () =>\r\n fragments.core.update(true)\r\n );\r\n\r\n components.get(CurrentWorld).world = world;\r\n components.get(CurrentCamera).camera = world.camera;\r\n components.get(Highlighter);\r\n components.get(ViewModeCoordinator);\r\n components.get(FloorplanTool);\r\n components.get(ElevationsTool);\r\n\r\n // Grid injection is safe here — fragments.core is initialized.\r\n if (grid) {\r\n components.get(FloorplanTool).setGrid(grid);\r\n components.get(ElevationsTool).setGrid(grid);\r\n }\r\n\r\n // Enable shadows\r\n world.renderer.three.shadowMap.enabled = true;\r\n world.renderer.three.shadowMap.type = THREE.PCFSoftShadowMap;\r\n world.scene.setup({\r\n shadows: {\r\n cascade: 1,\r\n resolution: 1024,\r\n },\r\n });\r\n\r\n world.scene.distanceRenderer.excludedObjects.add(grid.three);\r\n\r\n await world.scene.updateShadows();\r\n\r\n world.camera.controls.addEventListener(\"rest\", async () => {\r\n await world.scene.updateShadows();\r\n });\r\n\r\n world.scene.three.background = null;\r\n\r\n // If this init was superseded (StrictMode re-run) or the viewer\r\n // unmounted while we awaited the worker fetch / shadow update, throw\r\n // this instance away instead of publishing it. Prevents an orphaned\r\n // world (whose canvas is detached) from winning the store and starving\r\n // the visible canvas of geometry.\r\n if (isCancelled()) {\r\n components.dispose();\r\n return;\r\n }\r\n componentsRef.current = components;\r\n bimDispatch({\r\n type: \"SET_COMPONENTS\",\r\n payload: { bimComponents: components, world, fragments }\r\n });\r\n\r\n // Ensure canvas takes full container size\r\n const canvas = container.querySelector('canvas');\r\n if (canvas) {\r\n canvas.style.width = '100%';\r\n canvas.style.height = '100%';\r\n canvas.style.display = 'block';\r\n }\r\n\r\n // Handle resize using container dimensions\r\n const handleResize = () => {\r\n const width = container.clientWidth;\r\n const height = container.clientHeight;\r\n if (width && height) {\r\n world.renderer?.resize(new THREE.Vector2(width, height));\r\n }\r\n };\r\n \r\n // Initial resize\r\n handleResize();\r\n \r\n // Watch for container size changes using ResizeObserver. This\r\n // already covers the window-resize case: when the window resizes,\r\n // the flex layout reshapes this container, and ResizeObserver\r\n // fires.\r\n const resizeObserver = new ResizeObserver(() => {\r\n handleResize();\r\n });\r\n resizeObserver.observe(container);\r\n resizeObserverRef.current = resizeObserver;\r\n\r\n // The ResizeObserver above is sufficient for redraws. A window\r\n // 'resize' listener here previously leaked on every mount (no matching\r\n // removeEventListener), so it was removed.\r\n }, []\r\n );\r\n\r\n React.useEffect(() => {\r\n let cancelled = false;\r\n createViewer(() => cancelled);\r\n\r\n // Cleanup: mark this init cancelled (so an in-flight createViewer disposes\r\n // itself instead of publishing), and dispose the instance we actually\r\n // created (componentsRef). The old `if (bimComponents)` read the stale []\r\n // closure value (null at mount), so the real Components was never disposed\r\n // — leaking its renderer/canvas and letting orphans race the store.\r\n return () => {\r\n cancelled = true;\r\n if (resizeObserverRef.current) {\r\n resizeObserverRef.current.disconnect();\r\n }\r\n if (componentsRef.current) {\r\n componentsRef.current.dispose();\r\n componentsRef.current = null;\r\n }\r\n bimDispatch({\r\n type: \"DISPOSE-BIM\"\r\n });\r\n };\r\n }, []);\r\n\r\n // Enforce Y-up coordinate system for Three.js / camera-controls.\r\n // Runs whenever the world (and its controls) becomes available, and resets on unmount.\r\n useBimCoordinateSystem(bimState.bim.world?.camera?.controls ?? null);\r\n\r\n // Control ViewportGizmo based on current viewer\r\n React.useEffect(() => {\r\n if (!bimComponents) return;\r\n\r\n const viewportGizmo = bimComponents.get(ViewportGizmo);\r\n\r\n viewportGizmo.setLabels({\r\n top: t('top'),\r\n right: t('right'),\r\n bottom: t('bottom'),\r\n left: t('left'),\r\n front: t('front'),\r\n back: t('back')\r\n });\r\n\r\n if (!viewportGizmo) return;\r\n\r\n if (currentViewer === 'bim') {\r\n viewportGizmo.enabled = true;\r\n viewportGizmo.add();\r\n } else {\r\n viewportGizmo.enabled = false;\r\n viewportGizmo.remove();\r\n }\r\n }, [bimComponents, currentViewer, locale, t]);\r\n\r\n return (\r\n <div\r\n style={{\r\n position: \"relative\",\r\n width: \"100%\",\r\n height: \"100%\",\r\n overflow: \"hidden\"\r\n }}\r\n >\r\n <BimLoadingState />\r\n <div\r\n className=\"bim-container\"\r\n id=\"bim-viewer-container\"\r\n ref={containerRef}\r\n style={{\r\n width: \"100%\",\r\n height: \"100%\",\r\n position: \"relative\",\r\n background: \"radial-gradient(circle, rgba(255, 255, 255, 1) 50%, rgba(220, 220, 220, 1) 100%)\",\r\n }}\r\n />\r\n <PropertiesMenu />\r\n </div>\r\n );\r\n}"],"mappings":"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","names":["_a"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../src/core/components/viewers/bim/src/BimLoadingState/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAA;AAiBzB,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,YAAY,GAAG,YAAY,CAAA;AAEpG,wBAAgB,eAAe,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../src/core/components/viewers/bim/src/BimLoadingState/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAA;AAiBzB,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,YAAY,GAAG,YAAY,CAAA;AAEpG,wBAAgB,eAAe,sBAoa9B"}
|
|
@@ -136,9 +136,11 @@ function BimLoadingState() {
|
|
|
136
136
|
const loadModels = bimComponents.get(LoadModels);
|
|
137
137
|
const { sharing } = setCameraLookAt(world, searchParams);
|
|
138
138
|
loadModels.sharing = sharing;
|
|
139
|
+
let loadedCount = 0;
|
|
139
140
|
for (const bimFile of bimFiles) {
|
|
140
141
|
try {
|
|
141
142
|
await loadModels.load(bimFile.url, bimFile.name);
|
|
143
|
+
loadedCount++;
|
|
142
144
|
if ((bimFile.x != null || bimFile.y != null || bimFile.z != null) && fragments) {
|
|
143
145
|
const fragModel = fragments.core.models.list.get(bimFile.name);
|
|
144
146
|
if (fragModel) {
|
|
@@ -154,6 +156,10 @@ function BimLoadingState() {
|
|
|
154
156
|
if (fragments) {
|
|
155
157
|
fragments.core.update(true);
|
|
156
158
|
}
|
|
159
|
+
if (loadedCount === 0) {
|
|
160
|
+
setCurrentState("error");
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
157
163
|
for (const bimFile of bimFiles) {
|
|
158
164
|
bimDispatch({ type: "SET_MODEL_UI_STATE", payload: { fileId: bimFile.id, isVisible: true } });
|
|
159
165
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../src/core/components/viewers/bim/src/BimLoadingState/index.tsx"],"sourcesContent":["'use client'\r\n\r\nimport React from 'react'\r\nimport { Button } from '../../../../ui/Button'\r\nimport { Card, CardContent, CardHeader } from '../../../../ui/Card'\r\nimport { Input } from '../../../../ui/Input'\r\nimport { LoadingSpinner } from '../../../../ui/LoadingSpinner'\r\nimport { Upload, Box, Building2, Search, X, SquareArrowOutUpRight } from 'lucide-react'\r\nimport { BimContext, BuildingsContext, usePermissions } from '../../../../../store'\r\nimport { LoadModels } from '../LoadModels'\r\nimport { useTranslations } from 'next-intl'\r\nimport { useFilesByBuildingId, useUploadFileToBuilding } from '../../../../../hooks/files/files'\r\nimport { useFileUploadHandler } from '../../../../ui/FilesManager/src/useFileUploadHandler'\r\nimport type { DbFile as DbFile } from '../../../../../types/dbTypes'\r\nimport { cn } from '../../../../../utils/utils'\r\nimport { useSearchParams, useRouter } from 'next/navigation'\r\nimport { useBuilding, useBuildings } from '../../../../../hooks/buildings/buildings'\r\nimport { setCameraLookAt } from '../../utils/setCameraLookAt'\r\n\r\nexport type bimViewerState = 'opening' | 'loading' | 'ready' | 'error' | 'noBimFiles' | 'noBuilding'\r\n\r\nexport function BimLoadingState() {\r\n const t = useTranslations('BimLoadingState')\r\n // Permissions\r\n const { ability } = usePermissions()\r\n\r\n const { state: bimState, dispatch: bimDispatch } = React.useContext(BimContext)\r\n const { bimComponents, world, fragments } = bimState.bim\r\n const { state: buildingState, dispatch: buildingDispatch } = React.useContext(BuildingsContext)\r\n const { building: storeBuilding } = buildingState.buildings\r\n\r\n const searchParams = useSearchParams()\r\n const buildingId = searchParams.get(\"buildingId\")\r\n const { building: urlBuilding, isLoading: buildingLoading, isError: buildingError } = useBuilding(buildingId ? Number(buildingId) : null)\r\n const { buildings, isLoading: buildingsLoading } = useBuildings()\r\n\r\n // Determine the current building to use\r\n const building = storeBuilding || urlBuilding\r\n\r\n React.useEffect(() => {\r\n if (!storeBuilding && urlBuilding ) {\r\n buildingDispatch({ type: \"SET-CURRENT-BUILDING\", payload: { building: urlBuilding } })\r\n }\r\n }, [urlBuilding, storeBuilding, buildingDispatch])\r\n\r\n const router = useRouter()\r\n const fileInputRef = React.useRef<HTMLInputElement>(null)\r\n\r\n // Upload file hooks\r\n const { uploadFile } = useUploadFileToBuilding(building?.id)\r\n\r\n // Use the reusable upload handler\r\n const { handleFileUpload } = useFileUploadHandler({\r\n buildingId: building?.id,\r\n tag: 'bim-file',\r\n isVisible: true,\r\n uploadFile,\r\n })\r\n\r\n const [currentState, setCurrentState] = React.useState<bimViewerState>('opening')\r\n const [hasLoadedModels, setHasLoadedModels] = React.useState(false)\r\n const [cameraHasMoved, setCameraHasMoved] = React.useState(false)\r\n const isLoadingModelsRef = React.useRef(false)\r\n const [searchTerm, setSearchTerm] = React.useState('')\r\n const [searchResults, setSearchResults] = React.useState<any[]>([])\r\n const [selectedBuilding, setSelectedBuilding] = React.useState<any>(null)\r\n \r\n const { files, isLoading: filesLoading } = useFilesByBuildingId(building?.id)\r\n const bimFiles: DbFile[] = React.useMemo(() => (\r\n files.filter(file => {\r\n const ext = file?.extension?.toLowerCase()\r\n return ext === 'frag' || ext === 'ifc'\r\n })\r\n ), [files])\r\n\r\n // Fuzzy search function for buildings\r\n const fuzzySearchBuildings = React.useCallback((buildings: any[], searchTerm: string) => {\r\n if (!searchTerm.trim()) return buildings.slice(0, 10)\r\n \r\n const fuzzySearchScore = (search: string, text: string): number => {\r\n if (!search || !text) return 0\r\n const searchLower = search.toLowerCase()\r\n const textLower = text.toLowerCase()\r\n \r\n // Exact match gets highest score\r\n if (textLower === searchLower) return 1000\r\n // Starts with search term gets high score\r\n if (textLower.startsWith(searchLower)) return 800\r\n // Contains search term gets medium score\r\n if (textLower.includes(searchLower)) return 600\r\n \r\n return 0\r\n }\r\n\r\n return buildings\r\n .map((building) => {\r\n const address = building.buildingAddress || ''\r\n const name = building.buildingName || ''\r\n const id = building.id.toString()\r\n \r\n const addressScore = fuzzySearchScore(searchTerm, address)\r\n const nameScore = fuzzySearchScore(searchTerm, name)\r\n const idScore = fuzzySearchScore(searchTerm, id)\r\n \r\n const maxScore = Math.max(addressScore, nameScore, idScore)\r\n return { ...building, searchScore: maxScore }\r\n })\r\n .filter(building => building.searchScore > 0)\r\n .sort((a, b) => b.searchScore - a.searchScore)\r\n .slice(0, 10)\r\n }, [])\r\n\r\n // Handle search\r\n const handleSearch = React.useCallback((term: string) => {\r\n setSearchTerm(term)\r\n if (buildings) {\r\n setSearchResults(fuzzySearchBuildings(buildings, term))\r\n }\r\n }, [buildings, fuzzySearchBuildings])\r\n\r\n const shouldShow = (currentState === 'opening' || currentState === 'noBimFiles' || currentState === 'loading' || currentState === 'noBuilding') && !cameraHasMoved\r\n\r\n // Once models have loaded, start a fallback timer to dismiss the card if camera doesn't move\r\n React.useEffect(() => {\r\n if (currentState === 'loading' && hasLoadedModels) {\r\n const fallbackTimer = setTimeout(() => {\r\n setCameraHasMoved(true)\r\n setCurrentState('ready')\r\n }, 5000)\r\n\r\n return () => clearTimeout(fallbackTimer)\r\n }\r\n }, [currentState, hasLoadedModels])\r\n\r\n // Set up camera movement detection\r\n React.useEffect(() => {\r\n if (bimState.bim.world?.camera?.controls) {\r\n const controls = bimState.bim.world.camera.controls\r\n\r\n const handleCameraChange = () => {\r\n setCameraHasMoved(true)\r\n if (hasLoadedModels) {\r\n setCurrentState('ready')\r\n }\r\n }\r\n\r\n // Listen for camera control event (when user moves the camera)\r\n controls.addEventListener('control', handleCameraChange)\r\n\r\n return () => {\r\n controls.removeEventListener('control', handleCameraChange)\r\n }\r\n }\r\n }, [bimState.bim.world, hasLoadedModels])\r\n\r\n const loadBimModels = React.useCallback(async () => {\r\n if (!bimComponents || bimFiles.length === 0) return\r\n if (isLoadingModelsRef.current) return\r\n\r\n isLoadingModelsRef.current = true\r\n\r\n try {\r\n // State should already be 'loading' when this is called\r\n const loadModels = bimComponents.get(LoadModels)\r\n\r\n const {sharing} = setCameraLookAt(world, searchParams)\r\n loadModels.sharing = sharing\r\n\r\n for (const bimFile of bimFiles) {\r\n try {\r\n await loadModels.load(bimFile.url, bimFile.name)\r\n // Apply saved 3D position after load (setupModel resets to origin)\r\n if ((bimFile.x != null || bimFile.y != null || bimFile.z != null) && fragments) {\r\n const fragModel = fragments.core.models.list.get(bimFile.name)\r\n if (fragModel) {\r\n fragModel.object.position.set(bimFile.x ?? 0, bimFile.y ?? 0, bimFile.z ?? 0)\r\n if (bimFile.rotation != null) fragModel.object.rotation.y = bimFile.rotation\r\n fragModel.object.updateMatrixWorld(true)\r\n }\r\n }\r\n } catch (e) {\r\n console.error(\"Error loading BIM file\", bimFile.name, e)\r\n }\r\n }\r\n\r\n // Force update the fragments to render geometry immediately\r\n if (fragments) {\r\n fragments.core.update(true)\r\n }\r\n\r\n // Mark each loaded file as visible in the BIM store so ModelsSection reflects it\r\n for (const bimFile of bimFiles) {\r\n bimDispatch({ type: 'SET_MODEL_UI_STATE', payload: { fileId: bimFile.id, isVisible: true } })\r\n }\r\n\r\n // Signal that models have loaded — the fallback timer will dismiss the card\r\n setHasLoadedModels(true)\r\n } catch (error) {\r\n console.error('Error loading BIM models:', error)\r\n setCurrentState('error')\r\n } finally {\r\n isLoadingModelsRef.current = false\r\n }\r\n }, [bimComponents, bimFiles, fragments])\r\n\r\n // Handle initial state transitions\r\n React.useEffect(() => {\r\n // If no bimComponents available, stay in opening state\r\n if (!bimComponents) {\r\n setCurrentState('opening')\r\n setHasLoadedModels(false)\r\n return\r\n }\r\n\r\n // If building is loading, stay in opening state\r\n if (buildingLoading) {\r\n setCurrentState('opening')\r\n return\r\n }\r\n\r\n // If building failed to load or no buildingId provided, show noBuilding state\r\n if (buildingError || (!buildingId && !building)) {\r\n setCurrentState('noBuilding')\r\n setHasLoadedModels(false)\r\n return\r\n }\r\n\r\n // If we have a building but files are still loading, stay in opening state\r\n if (building && filesLoading) {\r\n setCurrentState('opening')\r\n return\r\n }\r\n\r\n // If we've already loaded models (or are currently loading), don't reload\r\n if (hasLoadedModels) {\r\n return\r\n }\r\n\r\n // If we have a building but no BIM files, show noBimFiles state\r\n if (building && bimFiles.length === 0) {\r\n setCurrentState('noBimFiles')\r\n return\r\n }\r\n\r\n // We have BIM files, set to loading and start loading them\r\n if (building && bimFiles.length > 0) {\r\n setCurrentState('loading')\r\n setCameraHasMoved(false) // Reset camera moved state for new model\r\n loadBimModels()\r\n }\r\n }, [bimComponents, building, buildingLoading, buildingError, buildingId, filesLoading, bimFiles.length, loadBimModels, hasLoadedModels])\r\n\r\n // Don't render if not visible\r\n if (!shouldShow) {\r\n return null\r\n }\r\n\r\n const handleUploadClick = () => {\r\n fileInputRef.current?.click()\r\n }\r\n\r\n const handleBuildingSelect = (building: any) => {\r\n const url = new URL(window.location.href)\r\n url.searchParams.set('buildingId', building.id.toString())\r\n buildingDispatch({ type: 'SET-CURRENT-BUILDING', payload: { building } })\r\n setSelectedBuilding(building)\r\n setSearchTerm('')\r\n setSearchResults([])\r\n router.push(url.toString())\r\n }\r\n\r\n const handleFileChange = async (event: React.ChangeEvent<HTMLInputElement>) => {\r\n const files = event.target.files\r\n if (!files || files.length === 0) return\r\n\r\n const file = files[0]\r\n\r\n try {\r\n const modelId = file.name\r\n setCurrentState('loading')\r\n setCameraHasMoved(false) // Reset camera moved state for new upload\r\n await handleFileUpload(file)\r\n\r\n window.dispatchEvent(new CustomEvent('bim-model-loaded-from-file', { detail: { modelId } }))\r\n bimDispatch({\r\n type: 'SET_MODEL', payload: { modelId },\r\n })\r\n setCurrentState('ready')\r\n }\r\n catch (error) {\r\n console.error('Error uploading file:', error)\r\n setCurrentState('error')\r\n }\r\n }\r\n\r\n return (\r\n <>\r\n <div className=\"absolute z-10 inset-0 bg-background/50 backdrop-blur-[1px] flex items-center justify-center pointer-events-none\">\r\n <Card className={cn(\"w-[536px] pointer-events-auto flex flex-col justify-start items-center gap-2\")}>\r\n <CardHeader className=\"flex justify-center items-center\">\r\n <div className=\"w-12 h-12 p-2 bg-card rounded-md shadow-sm border border-border flex justify-center items-center\">\r\n {currentState === 'noBuilding' ? (\r\n <Building2 className={cn(\"w-4 h-5 text-foreground\", buildingsLoading && \"animate-pulse\")} strokeWidth={2} />\r\n ) : (\r\n <Box className={cn(\"w-4 h-5 text-foreground\", currentState === 'opening' && \"animate-pulse\")} strokeWidth={2} />\r\n )}\r\n </div>\r\n </CardHeader>\r\n\r\n <CardContent className=\"self-stretch flex flex-col justify-start items-center gap-6 pt-0\">\r\n <div className=\"self-stretch flex flex-col justify-start items-center gap-2\">\r\n <div className=\"self-stretch text-center text-foreground text-xl font-semibold font-['Inter'] leading-7 flex items-center justify-center gap-2\">\r\n {currentState === 'opening' ? (\r\n <>\r\n {t('openingText')}\r\n <LoadingSpinner size={20} />\r\n </>\r\n ) : currentState === 'loading' ? (\r\n <>\r\n {t('loadingBimModel')}\r\n <LoadingSpinner size={20} />\r\n </>\r\n ) : currentState === 'noBuilding' ? (\r\n <>\r\n {t('noBuilding')}\r\n </>\r\n ) : (\r\n t('noBIMLoaded')\r\n )}\r\n </div>\r\n {(currentState === 'noBimFiles' || currentState === 'noBuilding') && (\r\n <div className=\"self-stretch text-center text-muted-foreground text-sm font-normal font-['Inter'] leading-tight\">\r\n {currentState === 'noBuilding' ? t('selectBuildingHelpText') : t('helpText')}\r\n </div>\r\n )}\r\n </div>\r\n\r\n {currentState === 'noBuilding' && (\r\n <div className=\"self-stretch flex flex-col gap-3 justify-centre items-center\">\r\n {buildingsLoading ? (\r\n <div className=\"flex items-center justify-center gap-2 text-muted-foreground\">\r\n <LoadingSpinner size={16} />\r\n <span>{t('loadingBuildings') || 'Loading buildings...'}</span>\r\n </div>\r\n ) : buildings && buildings.length > 0 ? (\r\n <div className=\"w-full relative\">\r\n {selectedBuilding ? (\r\n <div className=\"relative flex justify-end items-center\">\r\n <Input\r\n type=\"text\"\r\n value={\r\n 'Building: '\r\n + (selectedBuilding.buildingName && selectedBuilding.buildingAddress\r\n ? `${selectedBuilding.buildingName}, ${selectedBuilding.buildingAddress}`\r\n : selectedBuilding.buildingName || selectedBuilding.buildingAddress || `Building ${selectedBuilding.id}`)\r\n }\r\n readOnly\r\n className=\"w-full\"\r\n />\r\n <X \r\n className=\"absolute right-2 cursor-pointer w-4 h-4 text-muted-foreground hover:text-foreground\" \r\n onClick={() => {\r\n setSelectedBuilding(null)\r\n setSearchTerm('')\r\n setSearchResults([])\r\n }} \r\n />\r\n </div>\r\n ) : (\r\n <div className=\"relative\">\r\n <Search className=\"absolute left-3 top-1/2 transform -translate-y-1/2 text-muted-foreground w-4 h-4\" />\r\n <Input\r\n placeholder={t('searchBuildings') || 'Search buildings...'}\r\n value={searchTerm}\r\n onChange={(e) => handleSearch(e.target.value)}\r\n className=\"w-full pl-10\"\r\n disabled={!ability.can('read', 'Building')}\r\n />\r\n </div>\r\n )}\r\n \r\n {/* Search results dropdown */}\r\n {searchResults.length > 0 && searchTerm !== '' && !selectedBuilding && (\r\n <div className=\"absolute top-full left-0 right-0 mt-1 bg-background border border-border rounded-md shadow-lg max-h-60 overflow-y-auto z-20\">\r\n {searchResults.map(building => (\r\n <div\r\n key={building.id}\r\n className=\"px-3 py-2 text-sm cursor-pointer hover:bg-muted transition-colors flex gap-2 items-center\"\r\n onClick={() => handleBuildingSelect(building)}\r\n >\r\n <SquareArrowOutUpRight className=\"w-3 h-3\" />\r\n {building.buildingName\r\n ? `${building.buildingName}, ${building.buildingAddress}`\r\n : building.buildingAddress || `Building ${building.id}`}\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n ) : (\r\n <div className=\"text-muted-foreground text-center\">\r\n {t('noBuildings') || 'No buildings available'}\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n\r\n {currentState === 'noBimFiles' && (\r\n <div className=\"self-stretch flex justify-center items-center gap-3\">\r\n <Input\r\n ref={fileInputRef}\r\n type=\"file\"\r\n accept=\".ifc,.frag\"\r\n onChange={handleFileChange}\r\n className=\"hidden\"\r\n />\r\n <Button\r\n onClick={handleUploadClick}\r\n size=\"sm\"\r\n className=\"gap-2\"\r\n disabled={!ability.can('create', 'File')}\r\n >\r\n <Upload className=\"w-4 h-4\" />\r\n {t('uploadButton')}\r\n </Button>\r\n </div>\r\n )}\r\n </CardContent>\r\n </Card>\r\n </div>\r\n </>\r\n )\r\n}\r\n"],"mappings":"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","names":["buildings","searchTerm","building","files"]}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../src/core/components/viewers/bim/src/BimLoadingState/index.tsx"],"sourcesContent":["'use client'\r\n\r\nimport React from 'react'\r\nimport { Button } from '../../../../ui/Button'\r\nimport { Card, CardContent, CardHeader } from '../../../../ui/Card'\r\nimport { Input } from '../../../../ui/Input'\r\nimport { LoadingSpinner } from '../../../../ui/LoadingSpinner'\r\nimport { Upload, Box, Building2, Search, X, SquareArrowOutUpRight } from 'lucide-react'\r\nimport { BimContext, BuildingsContext, usePermissions } from '../../../../../store'\r\nimport { LoadModels } from '../LoadModels'\r\nimport { useTranslations } from 'next-intl'\r\nimport { useFilesByBuildingId, useUploadFileToBuilding } from '../../../../../hooks/files/files'\r\nimport { useFileUploadHandler } from '../../../../ui/FilesManager/src/useFileUploadHandler'\r\nimport type { DbFile as DbFile } from '../../../../../types/dbTypes'\r\nimport { cn } from '../../../../../utils/utils'\r\nimport { useSearchParams, useRouter } from 'next/navigation'\r\nimport { useBuilding, useBuildings } from '../../../../../hooks/buildings/buildings'\r\nimport { setCameraLookAt } from '../../utils/setCameraLookAt'\r\n\r\nexport type bimViewerState = 'opening' | 'loading' | 'ready' | 'error' | 'noBimFiles' | 'noBuilding'\r\n\r\nexport function BimLoadingState() {\r\n const t = useTranslations('BimLoadingState')\r\n // Permissions\r\n const { ability } = usePermissions()\r\n\r\n const { state: bimState, dispatch: bimDispatch } = React.useContext(BimContext)\r\n const { bimComponents, world, fragments } = bimState.bim\r\n const { state: buildingState, dispatch: buildingDispatch } = React.useContext(BuildingsContext)\r\n const { building: storeBuilding } = buildingState.buildings\r\n\r\n const searchParams = useSearchParams()\r\n const buildingId = searchParams.get(\"buildingId\")\r\n const { building: urlBuilding, isLoading: buildingLoading, isError: buildingError } = useBuilding(buildingId ? Number(buildingId) : null)\r\n const { buildings, isLoading: buildingsLoading } = useBuildings()\r\n\r\n // Determine the current building to use\r\n const building = storeBuilding || urlBuilding\r\n\r\n React.useEffect(() => {\r\n if (!storeBuilding && urlBuilding ) {\r\n buildingDispatch({ type: \"SET-CURRENT-BUILDING\", payload: { building: urlBuilding } })\r\n }\r\n }, [urlBuilding, storeBuilding, buildingDispatch])\r\n\r\n const router = useRouter()\r\n const fileInputRef = React.useRef<HTMLInputElement>(null)\r\n\r\n // Upload file hooks\r\n const { uploadFile } = useUploadFileToBuilding(building?.id)\r\n\r\n // Use the reusable upload handler\r\n const { handleFileUpload } = useFileUploadHandler({\r\n buildingId: building?.id,\r\n tag: 'bim-file',\r\n isVisible: true,\r\n uploadFile,\r\n })\r\n\r\n const [currentState, setCurrentState] = React.useState<bimViewerState>('opening')\r\n const [hasLoadedModels, setHasLoadedModels] = React.useState(false)\r\n const [cameraHasMoved, setCameraHasMoved] = React.useState(false)\r\n const isLoadingModelsRef = React.useRef(false)\r\n const [searchTerm, setSearchTerm] = React.useState('')\r\n const [searchResults, setSearchResults] = React.useState<any[]>([])\r\n const [selectedBuilding, setSelectedBuilding] = React.useState<any>(null)\r\n \r\n const { files, isLoading: filesLoading } = useFilesByBuildingId(building?.id)\r\n const bimFiles: DbFile[] = React.useMemo(() => (\r\n files.filter(file => {\r\n const ext = file?.extension?.toLowerCase()\r\n return ext === 'frag' || ext === 'ifc'\r\n })\r\n ), [files])\r\n\r\n // Fuzzy search function for buildings\r\n const fuzzySearchBuildings = React.useCallback((buildings: any[], searchTerm: string) => {\r\n if (!searchTerm.trim()) return buildings.slice(0, 10)\r\n \r\n const fuzzySearchScore = (search: string, text: string): number => {\r\n if (!search || !text) return 0\r\n const searchLower = search.toLowerCase()\r\n const textLower = text.toLowerCase()\r\n \r\n // Exact match gets highest score\r\n if (textLower === searchLower) return 1000\r\n // Starts with search term gets high score\r\n if (textLower.startsWith(searchLower)) return 800\r\n // Contains search term gets medium score\r\n if (textLower.includes(searchLower)) return 600\r\n \r\n return 0\r\n }\r\n\r\n return buildings\r\n .map((building) => {\r\n const address = building.buildingAddress || ''\r\n const name = building.buildingName || ''\r\n const id = building.id.toString()\r\n \r\n const addressScore = fuzzySearchScore(searchTerm, address)\r\n const nameScore = fuzzySearchScore(searchTerm, name)\r\n const idScore = fuzzySearchScore(searchTerm, id)\r\n \r\n const maxScore = Math.max(addressScore, nameScore, idScore)\r\n return { ...building, searchScore: maxScore }\r\n })\r\n .filter(building => building.searchScore > 0)\r\n .sort((a, b) => b.searchScore - a.searchScore)\r\n .slice(0, 10)\r\n }, [])\r\n\r\n // Handle search\r\n const handleSearch = React.useCallback((term: string) => {\r\n setSearchTerm(term)\r\n if (buildings) {\r\n setSearchResults(fuzzySearchBuildings(buildings, term))\r\n }\r\n }, [buildings, fuzzySearchBuildings])\r\n\r\n const shouldShow = (currentState === 'opening' || currentState === 'noBimFiles' || currentState === 'loading' || currentState === 'noBuilding') && !cameraHasMoved\r\n\r\n // Once models have loaded, start a fallback timer to dismiss the card if camera doesn't move\r\n React.useEffect(() => {\r\n if (currentState === 'loading' && hasLoadedModels) {\r\n const fallbackTimer = setTimeout(() => {\r\n setCameraHasMoved(true)\r\n setCurrentState('ready')\r\n }, 5000)\r\n\r\n return () => clearTimeout(fallbackTimer)\r\n }\r\n }, [currentState, hasLoadedModels])\r\n\r\n // Set up camera movement detection\r\n React.useEffect(() => {\r\n if (bimState.bim.world?.camera?.controls) {\r\n const controls = bimState.bim.world.camera.controls\r\n\r\n const handleCameraChange = () => {\r\n setCameraHasMoved(true)\r\n if (hasLoadedModels) {\r\n setCurrentState('ready')\r\n }\r\n }\r\n\r\n // Listen for camera control event (when user moves the camera)\r\n controls.addEventListener('control', handleCameraChange)\r\n\r\n return () => {\r\n controls.removeEventListener('control', handleCameraChange)\r\n }\r\n }\r\n }, [bimState.bim.world, hasLoadedModels])\r\n\r\n const loadBimModels = React.useCallback(async () => {\r\n if (!bimComponents || bimFiles.length === 0) return\r\n if (isLoadingModelsRef.current) return\r\n\r\n isLoadingModelsRef.current = true\r\n\r\n try {\r\n // State should already be 'loading' when this is called\r\n const loadModels = bimComponents.get(LoadModels)\r\n\r\n const {sharing} = setCameraLookAt(world, searchParams)\r\n loadModels.sharing = sharing\r\n\r\n let loadedCount = 0\r\n for (const bimFile of bimFiles) {\r\n try {\r\n await loadModels.load(bimFile.url, bimFile.name)\r\n loadedCount++\r\n // Apply saved 3D position after load (setupModel resets to origin)\r\n if ((bimFile.x != null || bimFile.y != null || bimFile.z != null) && fragments) {\r\n const fragModel = fragments.core.models.list.get(bimFile.name)\r\n if (fragModel) {\r\n fragModel.object.position.set(bimFile.x ?? 0, bimFile.y ?? 0, bimFile.z ?? 0)\r\n if (bimFile.rotation != null) fragModel.object.rotation.y = bimFile.rotation\r\n fragModel.object.updateMatrixWorld(true)\r\n }\r\n }\r\n } catch (e) {\r\n console.error(\"Error loading BIM file\", bimFile.name, e)\r\n }\r\n }\r\n\r\n // Force update the fragments to render geometry immediately\r\n if (fragments) {\r\n fragments.core.update(true)\r\n }\r\n\r\n // If every file failed to load, surface an error instead of silently\r\n // dismissing the card as though the models were there.\r\n if (loadedCount === 0) {\r\n setCurrentState('error')\r\n return\r\n }\r\n\r\n // Mark each loaded file as visible in the BIM store so ModelsSection reflects it\r\n for (const bimFile of bimFiles) {\r\n bimDispatch({ type: 'SET_MODEL_UI_STATE', payload: { fileId: bimFile.id, isVisible: true } })\r\n }\r\n\r\n // Signal that models have loaded — the fallback timer will dismiss the card\r\n setHasLoadedModels(true)\r\n } catch (error) {\r\n console.error('Error loading BIM models:', error)\r\n setCurrentState('error')\r\n } finally {\r\n isLoadingModelsRef.current = false\r\n }\r\n }, [bimComponents, bimFiles, fragments])\r\n\r\n // Handle initial state transitions\r\n React.useEffect(() => {\r\n // If no bimComponents available, stay in opening state\r\n if (!bimComponents) {\r\n setCurrentState('opening')\r\n setHasLoadedModels(false)\r\n return\r\n }\r\n\r\n // If building is loading, stay in opening state\r\n if (buildingLoading) {\r\n setCurrentState('opening')\r\n return\r\n }\r\n\r\n // If building failed to load or no buildingId provided, show noBuilding state\r\n if (buildingError || (!buildingId && !building)) {\r\n setCurrentState('noBuilding')\r\n setHasLoadedModels(false)\r\n return\r\n }\r\n\r\n // If we have a building but files are still loading, stay in opening state\r\n if (building && filesLoading) {\r\n setCurrentState('opening')\r\n return\r\n }\r\n\r\n // If we've already loaded models (or are currently loading), don't reload\r\n if (hasLoadedModels) {\r\n return\r\n }\r\n\r\n // If we have a building but no BIM files, show noBimFiles state\r\n if (building && bimFiles.length === 0) {\r\n setCurrentState('noBimFiles')\r\n return\r\n }\r\n\r\n // We have BIM files, set to loading and start loading them\r\n if (building && bimFiles.length > 0) {\r\n setCurrentState('loading')\r\n setCameraHasMoved(false) // Reset camera moved state for new model\r\n loadBimModels()\r\n }\r\n }, [bimComponents, building, buildingLoading, buildingError, buildingId, filesLoading, bimFiles.length, loadBimModels, hasLoadedModels])\r\n\r\n // Don't render if not visible\r\n if (!shouldShow) {\r\n return null\r\n }\r\n\r\n const handleUploadClick = () => {\r\n fileInputRef.current?.click()\r\n }\r\n\r\n const handleBuildingSelect = (building: any) => {\r\n const url = new URL(window.location.href)\r\n url.searchParams.set('buildingId', building.id.toString())\r\n buildingDispatch({ type: 'SET-CURRENT-BUILDING', payload: { building } })\r\n setSelectedBuilding(building)\r\n setSearchTerm('')\r\n setSearchResults([])\r\n router.push(url.toString())\r\n }\r\n\r\n const handleFileChange = async (event: React.ChangeEvent<HTMLInputElement>) => {\r\n const files = event.target.files\r\n if (!files || files.length === 0) return\r\n\r\n const file = files[0]\r\n\r\n try {\r\n const modelId = file.name\r\n setCurrentState('loading')\r\n setCameraHasMoved(false) // Reset camera moved state for new upload\r\n await handleFileUpload(file)\r\n\r\n window.dispatchEvent(new CustomEvent('bim-model-loaded-from-file', { detail: { modelId } }))\r\n bimDispatch({\r\n type: 'SET_MODEL', payload: { modelId },\r\n })\r\n setCurrentState('ready')\r\n }\r\n catch (error) {\r\n console.error('Error uploading file:', error)\r\n setCurrentState('error')\r\n }\r\n }\r\n\r\n return (\r\n <>\r\n <div className=\"absolute z-10 inset-0 bg-background/50 backdrop-blur-[1px] flex items-center justify-center pointer-events-none\">\r\n <Card className={cn(\"w-[536px] pointer-events-auto flex flex-col justify-start items-center gap-2\")}>\r\n <CardHeader className=\"flex justify-center items-center\">\r\n <div className=\"w-12 h-12 p-2 bg-card rounded-md shadow-sm border border-border flex justify-center items-center\">\r\n {currentState === 'noBuilding' ? (\r\n <Building2 className={cn(\"w-4 h-5 text-foreground\", buildingsLoading && \"animate-pulse\")} strokeWidth={2} />\r\n ) : (\r\n <Box className={cn(\"w-4 h-5 text-foreground\", currentState === 'opening' && \"animate-pulse\")} strokeWidth={2} />\r\n )}\r\n </div>\r\n </CardHeader>\r\n\r\n <CardContent className=\"self-stretch flex flex-col justify-start items-center gap-6 pt-0\">\r\n <div className=\"self-stretch flex flex-col justify-start items-center gap-2\">\r\n <div className=\"self-stretch text-center text-foreground text-xl font-semibold font-['Inter'] leading-7 flex items-center justify-center gap-2\">\r\n {currentState === 'opening' ? (\r\n <>\r\n {t('openingText')}\r\n <LoadingSpinner size={20} />\r\n </>\r\n ) : currentState === 'loading' ? (\r\n <>\r\n {t('loadingBimModel')}\r\n <LoadingSpinner size={20} />\r\n </>\r\n ) : currentState === 'noBuilding' ? (\r\n <>\r\n {t('noBuilding')}\r\n </>\r\n ) : (\r\n t('noBIMLoaded')\r\n )}\r\n </div>\r\n {(currentState === 'noBimFiles' || currentState === 'noBuilding') && (\r\n <div className=\"self-stretch text-center text-muted-foreground text-sm font-normal font-['Inter'] leading-tight\">\r\n {currentState === 'noBuilding' ? t('selectBuildingHelpText') : t('helpText')}\r\n </div>\r\n )}\r\n </div>\r\n\r\n {currentState === 'noBuilding' && (\r\n <div className=\"self-stretch flex flex-col gap-3 justify-centre items-center\">\r\n {buildingsLoading ? (\r\n <div className=\"flex items-center justify-center gap-2 text-muted-foreground\">\r\n <LoadingSpinner size={16} />\r\n <span>{t('loadingBuildings') || 'Loading buildings...'}</span>\r\n </div>\r\n ) : buildings && buildings.length > 0 ? (\r\n <div className=\"w-full relative\">\r\n {selectedBuilding ? (\r\n <div className=\"relative flex justify-end items-center\">\r\n <Input\r\n type=\"text\"\r\n value={\r\n 'Building: '\r\n + (selectedBuilding.buildingName && selectedBuilding.buildingAddress\r\n ? `${selectedBuilding.buildingName}, ${selectedBuilding.buildingAddress}`\r\n : selectedBuilding.buildingName || selectedBuilding.buildingAddress || `Building ${selectedBuilding.id}`)\r\n }\r\n readOnly\r\n className=\"w-full\"\r\n />\r\n <X \r\n className=\"absolute right-2 cursor-pointer w-4 h-4 text-muted-foreground hover:text-foreground\" \r\n onClick={() => {\r\n setSelectedBuilding(null)\r\n setSearchTerm('')\r\n setSearchResults([])\r\n }} \r\n />\r\n </div>\r\n ) : (\r\n <div className=\"relative\">\r\n <Search className=\"absolute left-3 top-1/2 transform -translate-y-1/2 text-muted-foreground w-4 h-4\" />\r\n <Input\r\n placeholder={t('searchBuildings') || 'Search buildings...'}\r\n value={searchTerm}\r\n onChange={(e) => handleSearch(e.target.value)}\r\n className=\"w-full pl-10\"\r\n disabled={!ability.can('read', 'Building')}\r\n />\r\n </div>\r\n )}\r\n \r\n {/* Search results dropdown */}\r\n {searchResults.length > 0 && searchTerm !== '' && !selectedBuilding && (\r\n <div className=\"absolute top-full left-0 right-0 mt-1 bg-background border border-border rounded-md shadow-lg max-h-60 overflow-y-auto z-20\">\r\n {searchResults.map(building => (\r\n <div\r\n key={building.id}\r\n className=\"px-3 py-2 text-sm cursor-pointer hover:bg-muted transition-colors flex gap-2 items-center\"\r\n onClick={() => handleBuildingSelect(building)}\r\n >\r\n <SquareArrowOutUpRight className=\"w-3 h-3\" />\r\n {building.buildingName\r\n ? `${building.buildingName}, ${building.buildingAddress}`\r\n : building.buildingAddress || `Building ${building.id}`}\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n ) : (\r\n <div className=\"text-muted-foreground text-center\">\r\n {t('noBuildings') || 'No buildings available'}\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n\r\n {currentState === 'noBimFiles' && (\r\n <div className=\"self-stretch flex justify-center items-center gap-3\">\r\n <Input\r\n ref={fileInputRef}\r\n type=\"file\"\r\n accept=\".ifc,.frag\"\r\n onChange={handleFileChange}\r\n className=\"hidden\"\r\n />\r\n <Button\r\n onClick={handleUploadClick}\r\n size=\"sm\"\r\n className=\"gap-2\"\r\n disabled={!ability.can('create', 'File')}\r\n >\r\n <Upload className=\"w-4 h-4\" />\r\n {t('uploadButton')}\r\n </Button>\r\n </div>\r\n )}\r\n </CardContent>\r\n </Card>\r\n </div>\r\n </>\r\n )\r\n}\r\n"],"mappings":"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","names":["buildings","searchTerm","building","files"]}
|
package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/FilesSection.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilesSection.d.ts","sourceRoot":"","sources":["../../../../../../../../../../src/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/FilesSection.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"FilesSection.d.ts","sourceRoot":"","sources":["../../../../../../../../../../src/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/FilesSection.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAmB9B,OAAO,EAAE,MAAM,IAAI,KAAK,EAAE,MAAM,uCAAuC,CAAA;AAQvE,UAAU,iBAAiB;IACzB,KAAK,EAAE,KAAK,EAAE,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAUD,wBAAgB,YAAY,CAAC,EAAE,KAAK,EAAE,KAAU,EAAE,EAAE,iBAAiB,qBA+iBpE"}
|