@ifc-lite/viewer 1.17.3 → 1.17.4
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/.turbo/turbo-build.log +39 -30
- package/.turbo/turbo-typecheck.log +1 -1
- package/CHANGELOG.md +15 -0
- package/DESKTOP_CONTRACT_VERSION +1 -0
- package/dist/assets/arrow-CZ5kQ26f.js +20 -0
- package/dist/assets/basketViewActivator-BmnNtVfZ.js +1 -0
- package/dist/assets/{bcf-D5-QWGO9.js → bcf-DOG9_WPX.js} +1 -1
- package/dist/assets/{browser-CKs-FY1P.js → browser-C5TFR7sH.js} +1 -1
- package/dist/assets/cesium-ADbP7waU.css +1 -0
- package/dist/assets/cesium-DUOzBlqv.js +17817 -0
- package/dist/assets/{exporters-C_6J153K.js → exporters-ChAtBmlj.js} +2225 -1754
- package/dist/assets/geometry.worker-BQ0rzNo-.js +1 -0
- package/dist/assets/ifc-lite_bg-BX4E7TX8.wasm +0 -0
- package/dist/assets/{index-jhBr1wbn.js → index-Co8E2-FE.js} +28959 -24612
- package/dist/assets/index-DckuDqlv.css +1 -0
- package/dist/assets/{maplibre-gl-BpvwNKKy.js → maplibre-gl-CGLcoNXc.js} +1 -1
- package/dist/assets/native-bridge-BRvbckFQ.js +429 -0
- package/dist/assets/{sandbox-B79eavQ3.js → sandbox-DZiNLNMk.js} +5 -5
- package/dist/assets/{server-client-D3bUPJJc.js → server-client-BV8zHZ7Y.js} +4 -4
- package/dist/assets/tauri-core-stub-D8Fa-u43.js +1 -0
- package/dist/assets/tauri-dialog-stub-r7Wksg7o.js +1 -0
- package/dist/assets/tauri-fs-stub-BdeRC7aK.js +1 -0
- package/dist/assets/wasm-bridge-g01g7T9b.js +1 -0
- package/dist/assets/{zip-B-jFFAGa.js → zip-DBEtpeu6.js} +3 -3
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_0.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_1.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_10.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_11.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_12.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_13.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_14.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_15.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_16.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_17.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_18.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_19.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_2.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_20.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_21.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_22.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_23.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_24.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_25.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_26.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_27.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_3.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_4.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_5.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_6.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_7.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_8.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_9.json +1 -0
- package/dist/cesium/Assets/Images/bing_maps_credit.png +0 -0
- package/dist/cesium/Assets/Images/cesium_credit.png +0 -0
- package/dist/cesium/Assets/Images/google_earth_credit.png +0 -0
- package/dist/cesium/Assets/Images/ion-credit.png +0 -0
- package/dist/cesium/Assets/Textures/LensFlare/DirtMask.jpg +0 -0
- package/dist/cesium/Assets/Textures/LensFlare/StarBurst.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/0/0/0.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/0/1/0.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/1/0/0.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/1/0/1.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/1/1/0.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/1/1/1.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/1/2/0.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/1/2/1.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/1/3/0.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/1/3/1.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/0/0.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/0/1.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/0/2.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/0/3.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/1/0.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/1/1.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/1/2.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/1/3.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/2/0.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/2/1.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/2/2.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/2/3.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/3/0.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/3/1.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/3/2.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/3/3.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/4/0.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/4/1.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/4/2.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/4/3.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/5/0.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/5/1.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/5/2.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/5/3.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/6/0.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/6/1.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/6/2.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/6/3.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/7/0.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/7/1.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/7/2.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/7/3.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/tilemapresource.xml +14 -0
- package/dist/cesium/Assets/Textures/SkyBox/tycho2t3_80_mx.jpg +0 -0
- package/dist/cesium/Assets/Textures/SkyBox/tycho2t3_80_my.jpg +0 -0
- package/dist/cesium/Assets/Textures/SkyBox/tycho2t3_80_mz.jpg +0 -0
- package/dist/cesium/Assets/Textures/SkyBox/tycho2t3_80_px.jpg +0 -0
- package/dist/cesium/Assets/Textures/SkyBox/tycho2t3_80_py.jpg +0 -0
- package/dist/cesium/Assets/Textures/SkyBox/tycho2t3_80_pz.jpg +0 -0
- package/dist/cesium/Assets/Textures/maki/airfield.png +0 -0
- package/dist/cesium/Assets/Textures/maki/airport.png +0 -0
- package/dist/cesium/Assets/Textures/maki/alcohol-shop.png +0 -0
- package/dist/cesium/Assets/Textures/maki/america-football.png +0 -0
- package/dist/cesium/Assets/Textures/maki/art-gallery.png +0 -0
- package/dist/cesium/Assets/Textures/maki/bakery.png +0 -0
- package/dist/cesium/Assets/Textures/maki/bank.png +0 -0
- package/dist/cesium/Assets/Textures/maki/bar.png +0 -0
- package/dist/cesium/Assets/Textures/maki/baseball.png +0 -0
- package/dist/cesium/Assets/Textures/maki/basketball.png +0 -0
- package/dist/cesium/Assets/Textures/maki/beer.png +0 -0
- package/dist/cesium/Assets/Textures/maki/bicycle.png +0 -0
- package/dist/cesium/Assets/Textures/maki/building.png +0 -0
- package/dist/cesium/Assets/Textures/maki/bus.png +0 -0
- package/dist/cesium/Assets/Textures/maki/cafe.png +0 -0
- package/dist/cesium/Assets/Textures/maki/camera.png +0 -0
- package/dist/cesium/Assets/Textures/maki/campsite.png +0 -0
- package/dist/cesium/Assets/Textures/maki/car.png +0 -0
- package/dist/cesium/Assets/Textures/maki/cemetery.png +0 -0
- package/dist/cesium/Assets/Textures/maki/cesium.png +0 -0
- package/dist/cesium/Assets/Textures/maki/chemist.png +0 -0
- package/dist/cesium/Assets/Textures/maki/cinema.png +0 -0
- package/dist/cesium/Assets/Textures/maki/circle-stroked.png +0 -0
- package/dist/cesium/Assets/Textures/maki/circle.png +0 -0
- package/dist/cesium/Assets/Textures/maki/city.png +0 -0
- package/dist/cesium/Assets/Textures/maki/clothing-store.png +0 -0
- package/dist/cesium/Assets/Textures/maki/college.png +0 -0
- package/dist/cesium/Assets/Textures/maki/commercial.png +0 -0
- package/dist/cesium/Assets/Textures/maki/cricket.png +0 -0
- package/dist/cesium/Assets/Textures/maki/cross.png +0 -0
- package/dist/cesium/Assets/Textures/maki/dam.png +0 -0
- package/dist/cesium/Assets/Textures/maki/danger.png +0 -0
- package/dist/cesium/Assets/Textures/maki/disability.png +0 -0
- package/dist/cesium/Assets/Textures/maki/dog-park.png +0 -0
- package/dist/cesium/Assets/Textures/maki/embassy.png +0 -0
- package/dist/cesium/Assets/Textures/maki/emergency-telephone.png +0 -0
- package/dist/cesium/Assets/Textures/maki/entrance.png +0 -0
- package/dist/cesium/Assets/Textures/maki/farm.png +0 -0
- package/dist/cesium/Assets/Textures/maki/fast-food.png +0 -0
- package/dist/cesium/Assets/Textures/maki/ferry.png +0 -0
- package/dist/cesium/Assets/Textures/maki/fire-station.png +0 -0
- package/dist/cesium/Assets/Textures/maki/fuel.png +0 -0
- package/dist/cesium/Assets/Textures/maki/garden.png +0 -0
- package/dist/cesium/Assets/Textures/maki/gift.png +0 -0
- package/dist/cesium/Assets/Textures/maki/golf.png +0 -0
- package/dist/cesium/Assets/Textures/maki/grocery.png +0 -0
- package/dist/cesium/Assets/Textures/maki/hairdresser.png +0 -0
- package/dist/cesium/Assets/Textures/maki/harbor.png +0 -0
- package/dist/cesium/Assets/Textures/maki/heart.png +0 -0
- package/dist/cesium/Assets/Textures/maki/heliport.png +0 -0
- package/dist/cesium/Assets/Textures/maki/hospital.png +0 -0
- package/dist/cesium/Assets/Textures/maki/ice-cream.png +0 -0
- package/dist/cesium/Assets/Textures/maki/industrial.png +0 -0
- package/dist/cesium/Assets/Textures/maki/land-use.png +0 -0
- package/dist/cesium/Assets/Textures/maki/laundry.png +0 -0
- package/dist/cesium/Assets/Textures/maki/library.png +0 -0
- package/dist/cesium/Assets/Textures/maki/lighthouse.png +0 -0
- package/dist/cesium/Assets/Textures/maki/lodging.png +0 -0
- package/dist/cesium/Assets/Textures/maki/logging.png +0 -0
- package/dist/cesium/Assets/Textures/maki/london-underground.png +0 -0
- package/dist/cesium/Assets/Textures/maki/marker-stroked.png +0 -0
- package/dist/cesium/Assets/Textures/maki/marker.png +0 -0
- package/dist/cesium/Assets/Textures/maki/minefield.png +0 -0
- package/dist/cesium/Assets/Textures/maki/mobilephone.png +0 -0
- package/dist/cesium/Assets/Textures/maki/monument.png +0 -0
- package/dist/cesium/Assets/Textures/maki/museum.png +0 -0
- package/dist/cesium/Assets/Textures/maki/music.png +0 -0
- package/dist/cesium/Assets/Textures/maki/oil-well.png +0 -0
- package/dist/cesium/Assets/Textures/maki/park.png +0 -0
- package/dist/cesium/Assets/Textures/maki/park2.png +0 -0
- package/dist/cesium/Assets/Textures/maki/parking-garage.png +0 -0
- package/dist/cesium/Assets/Textures/maki/parking.png +0 -0
- package/dist/cesium/Assets/Textures/maki/pharmacy.png +0 -0
- package/dist/cesium/Assets/Textures/maki/pitch.png +0 -0
- package/dist/cesium/Assets/Textures/maki/place-of-worship.png +0 -0
- package/dist/cesium/Assets/Textures/maki/playground.png +0 -0
- package/dist/cesium/Assets/Textures/maki/police.png +0 -0
- package/dist/cesium/Assets/Textures/maki/polling-place.png +0 -0
- package/dist/cesium/Assets/Textures/maki/post.png +0 -0
- package/dist/cesium/Assets/Textures/maki/prison.png +0 -0
- package/dist/cesium/Assets/Textures/maki/rail-above.png +0 -0
- package/dist/cesium/Assets/Textures/maki/rail-light.png +0 -0
- package/dist/cesium/Assets/Textures/maki/rail-metro.png +0 -0
- package/dist/cesium/Assets/Textures/maki/rail-underground.png +0 -0
- package/dist/cesium/Assets/Textures/maki/rail.png +0 -0
- package/dist/cesium/Assets/Textures/maki/religious-christian.png +0 -0
- package/dist/cesium/Assets/Textures/maki/religious-jewish.png +0 -0
- package/dist/cesium/Assets/Textures/maki/religious-muslim.png +0 -0
- package/dist/cesium/Assets/Textures/maki/restaurant.png +0 -0
- package/dist/cesium/Assets/Textures/maki/roadblock.png +0 -0
- package/dist/cesium/Assets/Textures/maki/rocket.png +0 -0
- package/dist/cesium/Assets/Textures/maki/school.png +0 -0
- package/dist/cesium/Assets/Textures/maki/scooter.png +0 -0
- package/dist/cesium/Assets/Textures/maki/shop.png +0 -0
- package/dist/cesium/Assets/Textures/maki/skiing.png +0 -0
- package/dist/cesium/Assets/Textures/maki/slaughterhouse.png +0 -0
- package/dist/cesium/Assets/Textures/maki/soccer.png +0 -0
- package/dist/cesium/Assets/Textures/maki/square-stroked.png +0 -0
- package/dist/cesium/Assets/Textures/maki/square.png +0 -0
- package/dist/cesium/Assets/Textures/maki/star-stroked.png +0 -0
- package/dist/cesium/Assets/Textures/maki/star.png +0 -0
- package/dist/cesium/Assets/Textures/maki/suitcase.png +0 -0
- package/dist/cesium/Assets/Textures/maki/swimming.png +0 -0
- package/dist/cesium/Assets/Textures/maki/telephone.png +0 -0
- package/dist/cesium/Assets/Textures/maki/tennis.png +0 -0
- package/dist/cesium/Assets/Textures/maki/theatre.png +0 -0
- package/dist/cesium/Assets/Textures/maki/toilets.png +0 -0
- package/dist/cesium/Assets/Textures/maki/town-hall.png +0 -0
- package/dist/cesium/Assets/Textures/maki/town.png +0 -0
- package/dist/cesium/Assets/Textures/maki/triangle-stroked.png +0 -0
- package/dist/cesium/Assets/Textures/maki/triangle.png +0 -0
- package/dist/cesium/Assets/Textures/maki/village.png +0 -0
- package/dist/cesium/Assets/Textures/maki/warehouse.png +0 -0
- package/dist/cesium/Assets/Textures/maki/waste-basket.png +0 -0
- package/dist/cesium/Assets/Textures/maki/water.png +0 -0
- package/dist/cesium/Assets/Textures/maki/wetland.png +0 -0
- package/dist/cesium/Assets/Textures/maki/zoo.png +0 -0
- package/dist/cesium/Assets/Textures/moonSmall.jpg +0 -0
- package/dist/cesium/Assets/Textures/pin.svg +1 -0
- package/dist/cesium/Assets/Textures/waterNormals.jpg +0 -0
- package/dist/cesium/Assets/Textures/waterNormalsSmall.jpg +0 -0
- package/dist/cesium/Assets/approximateTerrainHeights.json +1 -0
- package/dist/cesium/ThirdParty/Workers/package.json +1 -0
- package/dist/cesium/ThirdParty/Workers/zip-web-worker.js +1 -0
- package/dist/cesium/ThirdParty/basis_transcoder.wasm +0 -0
- package/dist/cesium/ThirdParty/draco_decoder.wasm +0 -0
- package/dist/cesium/ThirdParty/google-earth-dbroot-parser.js +1 -0
- package/dist/cesium/ThirdParty/wasm_splats_bg.wasm +0 -0
- package/dist/cesium/ThirdParty/zip-module.wasm +0 -0
- package/dist/cesium/Widgets/Animation/Animation.css +127 -0
- package/dist/cesium/Widgets/Animation/lighter.css +70 -0
- package/dist/cesium/Widgets/BaseLayerPicker/BaseLayerPicker.css +108 -0
- package/dist/cesium/Widgets/BaseLayerPicker/lighter.css +22 -0
- package/dist/cesium/Widgets/Cesium3DTilesInspector/Cesium3DTilesInspector.css +102 -0
- package/dist/cesium/Widgets/CesiumInspector/CesiumInspector.css +113 -0
- package/dist/cesium/Widgets/CesiumWidget/CesiumWidget.css +119 -0
- package/dist/cesium/Widgets/CesiumWidget/lighter.css +14 -0
- package/dist/cesium/Widgets/FullscreenButton/FullscreenButton.css +8 -0
- package/dist/cesium/Widgets/Geocoder/Geocoder.css +70 -0
- package/dist/cesium/Widgets/Geocoder/lighter.css +17 -0
- package/dist/cesium/Widgets/I3SBuildingSceneLayerExplorer/I3SBuildingSceneLayerExplorer.css +27 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/ArcGisMapServiceWorldHillshade.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/ArcGisMapServiceWorldImagery.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/ArcGisMapServiceWorldOcean.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/azureAerial.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/azureRoads.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/bingAerial.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/bingAerialLabels.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/bingRoads.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/blueMarble.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/earthAtNight.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/googleContour.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/googleRoadmap.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/googleSatellite.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/googleSatelliteLabels.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/mapQuestOpenStreetMap.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/mapboxSatellite.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/mapboxStreets.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/mapboxTerrain.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/naturalEarthII.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/openStreetMap.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/sentinel-2.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/stadiaAlidadeSmooth.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/stadiaAlidadeSmoothDark.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/stamenToner.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/stamenWatercolor.png +0 -0
- package/dist/cesium/Widgets/Images/NavigationHelp/Mouse.svg +84 -0
- package/dist/cesium/Widgets/Images/NavigationHelp/MouseLeft.svg +76 -0
- package/dist/cesium/Widgets/Images/NavigationHelp/MouseMiddle.svg +76 -0
- package/dist/cesium/Widgets/Images/NavigationHelp/MouseRight.svg +76 -0
- package/dist/cesium/Widgets/Images/NavigationHelp/Touch.svg +120 -0
- package/dist/cesium/Widgets/Images/NavigationHelp/TouchDrag.svg +129 -0
- package/dist/cesium/Widgets/Images/NavigationHelp/TouchRotate.svg +76 -0
- package/dist/cesium/Widgets/Images/NavigationHelp/TouchTilt.svg +135 -0
- package/dist/cesium/Widgets/Images/NavigationHelp/TouchZoom.svg +74 -0
- package/dist/cesium/Widgets/Images/TerrainProviders/CesiumWorldTerrain.png +0 -0
- package/dist/cesium/Widgets/Images/TerrainProviders/Ellipsoid.png +0 -0
- package/dist/cesium/Widgets/Images/TimelineIcons.png +0 -0
- package/dist/cesium/Widgets/Images/info-loading.gif +0 -0
- package/dist/cesium/Widgets/InfoBox/InfoBox.css +92 -0
- package/dist/cesium/Widgets/InfoBox/InfoBoxDescription.css +178 -0
- package/dist/cesium/Widgets/NavigationHelpButton/NavigationHelpButton.css +93 -0
- package/dist/cesium/Widgets/NavigationHelpButton/lighter.css +38 -0
- package/dist/cesium/Widgets/PerformanceWatchdog/PerformanceWatchdog.css +15 -0
- package/dist/cesium/Widgets/ProjectionPicker/ProjectionPicker.css +38 -0
- package/dist/cesium/Widgets/SceneModePicker/SceneModePicker.css +56 -0
- package/dist/cesium/Widgets/SelectionIndicator/SelectionIndicator.css +20 -0
- package/dist/cesium/Widgets/Timeline/Timeline.css +103 -0
- package/dist/cesium/Widgets/Timeline/lighter.css +23 -0
- package/dist/cesium/Widgets/VRButton/VRButton.css +8 -0
- package/dist/cesium/Widgets/Viewer/Viewer.css +107 -0
- package/dist/cesium/Widgets/VoxelInspector/VoxelInspector.css +16 -0
- package/dist/cesium/Widgets/lighter.css +237 -0
- package/dist/cesium/Widgets/lighterShared.css +46 -0
- package/dist/cesium/Widgets/shared.css +103 -0
- package/dist/cesium/Widgets/widgets.css +1342 -0
- package/dist/cesium/Workers/chunk-23ZQ2IVV.js +29 -0
- package/dist/cesium/Workers/chunk-2EQO3Q56.js +26 -0
- package/dist/cesium/Workers/chunk-2MJIIVP4.js +26 -0
- package/dist/cesium/Workers/chunk-2TE5NTVD.js +26 -0
- package/dist/cesium/Workers/chunk-2ZBHLJST.js +26 -0
- package/dist/cesium/Workers/chunk-5TJMAQVL.js +26 -0
- package/dist/cesium/Workers/chunk-6BD4U3VO.js +26 -0
- package/dist/cesium/Workers/chunk-7TVGLKQF.js +26 -0
- package/dist/cesium/Workers/chunk-BTSYJ5XU.js +26 -0
- package/dist/cesium/Workers/chunk-BXMEEOCS.js +63 -0
- package/dist/cesium/Workers/chunk-BYLCY7GP.js +29 -0
- package/dist/cesium/Workers/chunk-CTHM3W6I.js +26 -0
- package/dist/cesium/Workers/chunk-CUUSNIVQ.js +26 -0
- package/dist/cesium/Workers/chunk-E3JOOS3S.js +26 -0
- package/dist/cesium/Workers/chunk-E7KYDCM5.js +26 -0
- package/dist/cesium/Workers/chunk-EDVBB7SS.js +27 -0
- package/dist/cesium/Workers/chunk-EFBN7QNX.js +26 -0
- package/dist/cesium/Workers/chunk-EQ4YRVWL.js +26 -0
- package/dist/cesium/Workers/chunk-F6PRE7D6.js +26 -0
- package/dist/cesium/Workers/chunk-FC4ZZ65J.js +26 -0
- package/dist/cesium/Workers/chunk-FFBVWF2L.js +26 -0
- package/dist/cesium/Workers/chunk-GBAA6GVX.js +26 -0
- package/dist/cesium/Workers/chunk-ICALLYLG.js +26 -0
- package/dist/cesium/Workers/chunk-ILRYTWTP.js +26 -0
- package/dist/cesium/Workers/chunk-IRNLBSEJ.js +26 -0
- package/dist/cesium/Workers/chunk-IX4VMHEV.js +26 -0
- package/dist/cesium/Workers/chunk-L6QHHACZ.js +26 -0
- package/dist/cesium/Workers/chunk-LI2ZSORM.js +26 -0
- package/dist/cesium/Workers/chunk-LSLE2RL4.js +26 -0
- package/dist/cesium/Workers/chunk-M4HLDBCG.js +26 -0
- package/dist/cesium/Workers/chunk-MJHHSGEH.js +26 -0
- package/dist/cesium/Workers/chunk-NMVKML6W.js +26 -0
- package/dist/cesium/Workers/chunk-OCWJRAXS.js +26 -0
- package/dist/cesium/Workers/chunk-OIRKANTH.js +26 -0
- package/dist/cesium/Workers/chunk-OIT7J4IC.js +26 -0
- package/dist/cesium/Workers/chunk-OLZ3FYUM.js +26 -0
- package/dist/cesium/Workers/chunk-Q5BPHJQF.js +26 -0
- package/dist/cesium/Workers/chunk-QFM5DCMQ.js +26 -0
- package/dist/cesium/Workers/chunk-QKUIYMGC.js +28 -0
- package/dist/cesium/Workers/chunk-S44JILQT.js +26 -0
- package/dist/cesium/Workers/chunk-SLT4J352.js +26 -0
- package/dist/cesium/Workers/chunk-SQMIIXB7.js +26 -0
- package/dist/cesium/Workers/chunk-TJ4XLGBQ.js +26 -0
- package/dist/cesium/Workers/chunk-TNSUQXWK.js +27 -0
- package/dist/cesium/Workers/chunk-UBOGZS7F.js +26 -0
- package/dist/cesium/Workers/chunk-V3OSTMM6.js +26 -0
- package/dist/cesium/Workers/chunk-V7QEYVP3.js +26 -0
- package/dist/cesium/Workers/chunk-VUKYSU4H.js +26 -0
- package/dist/cesium/Workers/chunk-W37FE5GR.js +26 -0
- package/dist/cesium/Workers/chunk-WBOV35NL.js +26 -0
- package/dist/cesium/Workers/chunk-WPMZLB3Y.js +26 -0
- package/dist/cesium/Workers/chunk-WWWZVEEH.js +26 -0
- package/dist/cesium/Workers/chunk-XFIQ5DEQ.js +28 -0
- package/dist/cesium/Workers/chunk-XQHLGIO7.js +26 -0
- package/dist/cesium/Workers/chunk-XUSCFAVF.js +26 -0
- package/dist/cesium/Workers/chunk-YP7I5QBZ.js +26 -0
- package/dist/cesium/Workers/chunk-Z3QF2EHT.js +26 -0
- package/dist/cesium/Workers/combineGeometry.js +26 -0
- package/dist/cesium/Workers/createBoxGeometry.js +26 -0
- package/dist/cesium/Workers/createBoxOutlineGeometry.js +26 -0
- package/dist/cesium/Workers/createCircleGeometry.js +26 -0
- package/dist/cesium/Workers/createCircleOutlineGeometry.js +26 -0
- package/dist/cesium/Workers/createCoplanarPolygonGeometry.js +26 -0
- package/dist/cesium/Workers/createCoplanarPolygonOutlineGeometry.js +26 -0
- package/dist/cesium/Workers/createCorridorGeometry.js +26 -0
- package/dist/cesium/Workers/createCorridorOutlineGeometry.js +26 -0
- package/dist/cesium/Workers/createCylinderGeometry.js +26 -0
- package/dist/cesium/Workers/createCylinderOutlineGeometry.js +26 -0
- package/dist/cesium/Workers/createEllipseGeometry.js +26 -0
- package/dist/cesium/Workers/createEllipseOutlineGeometry.js +26 -0
- package/dist/cesium/Workers/createEllipsoidGeometry.js +26 -0
- package/dist/cesium/Workers/createEllipsoidOutlineGeometry.js +26 -0
- package/dist/cesium/Workers/createFrustumGeometry.js +26 -0
- package/dist/cesium/Workers/createFrustumOutlineGeometry.js +26 -0
- package/dist/cesium/Workers/createGeometry.js +26 -0
- package/dist/cesium/Workers/createGroundPolylineGeometry.js +26 -0
- package/dist/cesium/Workers/createPlaneGeometry.js +26 -0
- package/dist/cesium/Workers/createPlaneOutlineGeometry.js +26 -0
- package/dist/cesium/Workers/createPolygonGeometry.js +26 -0
- package/dist/cesium/Workers/createPolygonOutlineGeometry.js +26 -0
- package/dist/cesium/Workers/createPolylineGeometry.js +26 -0
- package/dist/cesium/Workers/createPolylineVolumeGeometry.js +26 -0
- package/dist/cesium/Workers/createPolylineVolumeOutlineGeometry.js +26 -0
- package/dist/cesium/Workers/createRectangleGeometry.js +26 -0
- package/dist/cesium/Workers/createRectangleOutlineGeometry.js +26 -0
- package/dist/cesium/Workers/createSimplePolylineGeometry.js +26 -0
- package/dist/cesium/Workers/createSphereGeometry.js +26 -0
- package/dist/cesium/Workers/createSphereOutlineGeometry.js +26 -0
- package/dist/cesium/Workers/createTaskProcessorWorker.js +26 -0
- package/dist/cesium/Workers/createVectorTileClampedPolylines.js +26 -0
- package/dist/cesium/Workers/createVectorTileGeometries.js +26 -0
- package/dist/cesium/Workers/createVectorTilePoints.js +26 -0
- package/dist/cesium/Workers/createVectorTilePolygons.js +26 -0
- package/dist/cesium/Workers/createVectorTilePolylines.js +26 -0
- package/dist/cesium/Workers/createVerticesFromCesium3DTilesTerrain.js +26 -0
- package/dist/cesium/Workers/createVerticesFromGoogleEarthEnterpriseBuffer.js +26 -0
- package/dist/cesium/Workers/createVerticesFromHeightmap.js +26 -0
- package/dist/cesium/Workers/createVerticesFromQuantizedTerrainMesh.js +26 -0
- package/dist/cesium/Workers/createWallGeometry.js +26 -0
- package/dist/cesium/Workers/createWallOutlineGeometry.js +26 -0
- package/dist/cesium/Workers/decodeDraco.js +26 -0
- package/dist/cesium/Workers/decodeGoogleEarthEnterprisePacket.js +26 -0
- package/dist/cesium/Workers/decodeI3S.js +26 -0
- package/dist/cesium/Workers/gaussianSplatSorter.js +26 -0
- package/dist/cesium/Workers/gaussianSplatTextureGenerator.js +26 -0
- package/dist/cesium/Workers/incrementallyBuildTerrainPicker.js +26 -0
- package/dist/cesium/Workers/transcodeKTX2.js +56 -0
- package/dist/cesium/Workers/transferTypedArrayTest.js +26 -0
- package/dist/cesium/Workers/upsampleQuantizedTerrainMesh.js +26 -0
- package/dist/cesium/Workers/upsampleVerticesFromCesium3DTilesTerrain.js +26 -0
- package/dist/index.html +10 -8
- package/package.json +15 -12
- package/src/App.tsx +1 -17
- package/src/components/viewer/BCFPanel.tsx +46 -4
- package/src/components/viewer/CesiumOverlay.tsx +672 -0
- package/src/components/viewer/CesiumSettingsDialog.tsx +100 -0
- package/src/components/viewer/ChatPanel.tsx +54 -16
- package/src/components/viewer/CommandPalette.tsx +6 -1
- package/src/components/viewer/DesktopEntitlementBanner.tsx +74 -0
- package/src/components/viewer/ExportChangesButton.tsx +6 -1
- package/src/components/viewer/ExportDialog.tsx +22 -6
- package/src/components/viewer/HierarchyPanel.tsx +196 -0
- package/src/components/viewer/IDSPanel.tsx +52 -3
- package/src/components/viewer/KeyboardShortcutsDialog.tsx +1 -1
- package/src/components/viewer/MainToolbar.tsx +353 -27
- package/src/components/viewer/PropertiesPanel.tsx +218 -79
- package/src/components/viewer/ScriptPanel.tsx +34 -8
- package/src/components/viewer/SettingsPage.tsx +430 -0
- package/src/components/viewer/StatusBar.tsx +17 -1
- package/src/components/viewer/UpgradePage.tsx +6 -4
- package/src/components/viewer/ViewerLayout.tsx +47 -6
- package/src/components/viewer/Viewport.tsx +49 -8
- package/src/components/viewer/ViewportContainer.tsx +280 -28
- package/src/components/viewer/ViewportOverlays.tsx +129 -27
- package/src/components/viewer/properties/GeoreferencingPanel.tsx +117 -5
- package/src/components/viewer/properties/LocationMap.tsx +458 -17
- package/src/components/viewer/selectionHandlers.ts +4 -3
- package/src/components/viewer/useAnimationLoop.ts +4 -0
- package/src/components/viewer/useGeometryStreaming.ts +127 -40
- package/src/components/viewer/useMouseControls.ts +4 -1
- package/src/hooks/ingest/viewerModelIngest.ts +275 -0
- package/src/hooks/useIDS.ts +1 -1
- package/src/hooks/useIfc.ts +7 -1
- package/src/hooks/useIfcCache.ts +28 -15
- package/src/hooks/useIfcFederation.ts +57 -225
- package/src/hooks/useIfcLoader.ts +1656 -130
- package/src/hooks/useIfcServer.ts +0 -69
- package/src/lib/desktop/ClerkDesktopEntitlementSync.tsx +175 -0
- package/src/lib/desktop/desktopEntitlementEvents.ts +39 -0
- package/src/lib/desktop-entitlement.ts +45 -0
- package/src/lib/desktop-product.ts +124 -0
- package/src/lib/geo/cesium-bridge.ts +310 -0
- package/src/lib/geo/reproject.ts +151 -25
- package/src/lib/recent-files.ts +2 -1
- package/src/services/analysis-extensions.ts +125 -0
- package/src/services/app-navigation.ts +13 -0
- package/src/services/bsdd.ts +53 -4
- package/src/services/cacheService.ts +1 -1
- package/src/services/desktop-cache.ts +43 -0
- package/src/services/desktop-export.ts +77 -0
- package/src/services/desktop-harness.ts +196 -0
- package/src/services/desktop-logger.ts +20 -0
- package/src/services/desktop-native-metadata.ts +207 -0
- package/src/services/desktop-panel-actions.ts +43 -0
- package/src/services/desktop-preferences.ts +44 -0
- package/src/services/file-dialog.ts +147 -0
- package/src/services/tauri-core-stub.ts +7 -0
- package/src/services/tauri-dialog-stub.ts +7 -0
- package/src/services/tauri-fs-stub.ts +7 -0
- package/src/store/index.ts +40 -2
- package/src/store/slices/cesiumSlice.ts +122 -0
- package/src/store/slices/chatSlice.ts +5 -1
- package/src/store/slices/dataSlice.ts +139 -28
- package/src/store/slices/desktopEntitlementSlice.ts +86 -0
- package/src/store/slices/loadingSlice.ts +14 -2
- package/src/store/slices/modelSlice.ts +58 -3
- package/src/store/types.ts +96 -2
- package/src/store.ts +1 -1
- package/src/utils/desktopModelSnapshot.ts +358 -0
- package/src/utils/ifcConfig.ts +6 -1
- package/src/utils/nativeSpatialDataStore.ts +250 -0
- package/src/utils/serverDataModel.ts +4 -0
- package/src/utils/spatialHierarchy.ts +10 -11
- package/vite.config.ts +24 -0
- package/dist/assets/arrow-DJf2ErbF.js +0 -20
- package/dist/assets/basketViewActivator-aojwdomq.js +0 -1
- package/dist/assets/desktop-cache-oPzaWXYE.js +0 -1
- package/dist/assets/geometry.worker-Nz9_YIqh.js +0 -1
- package/dist/assets/ifc-lite_bg-eSkBTizQ.wasm +0 -0
- package/dist/assets/index-pbE7itQS.css +0 -1
- package/dist/assets/native-bridge-DSIyEYXG.js +0 -113
- package/dist/assets/wasm-bridge-B0J07fZZ.js +0 -1
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
|
|
5
|
+
import { SignInButton, SignedIn, SignedOut, UserButton, useAuth, useUser } from '@clerk/clerk-react';
|
|
6
|
+
import {
|
|
7
|
+
ArrowLeft,
|
|
8
|
+
Bot,
|
|
9
|
+
Check,
|
|
10
|
+
Clock3,
|
|
11
|
+
Cloud,
|
|
12
|
+
CreditCard,
|
|
13
|
+
FolderOpen,
|
|
14
|
+
LayoutPanelTop,
|
|
15
|
+
Lock,
|
|
16
|
+
RefreshCw,
|
|
17
|
+
Settings2,
|
|
18
|
+
ShieldCheck,
|
|
19
|
+
WifiOff,
|
|
20
|
+
} from 'lucide-react';
|
|
21
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
22
|
+
import { Badge } from '@/components/ui/badge';
|
|
23
|
+
import { Button } from '@/components/ui/button';
|
|
24
|
+
import { Switch } from '@/components/ui/switch';
|
|
25
|
+
import { toast } from '@/components/ui/toast';
|
|
26
|
+
import { useViewerStore } from '@/store';
|
|
27
|
+
import {
|
|
28
|
+
buildDesktopUpgradeUrl,
|
|
29
|
+
getDesktopFeatureCatalog,
|
|
30
|
+
getDesktopPlanSummary,
|
|
31
|
+
getDesktopPlanTier,
|
|
32
|
+
hasDesktopPro,
|
|
33
|
+
isDesktopBillingEnforced,
|
|
34
|
+
type DesktopEntitlement,
|
|
35
|
+
} from '@/lib/desktop-product';
|
|
36
|
+
import { isClerkConfigured } from '@/lib/llm/clerk-auth';
|
|
37
|
+
import { navigateToPath } from '@/services/app-navigation';
|
|
38
|
+
import { requestDesktopEntitlementRefresh } from '@/lib/desktop/desktopEntitlementEvents';
|
|
39
|
+
import {
|
|
40
|
+
getDesktopPreferences,
|
|
41
|
+
subscribeDesktopPreferences,
|
|
42
|
+
updateDesktopPreferences,
|
|
43
|
+
} from '@/services/desktop-preferences';
|
|
44
|
+
|
|
45
|
+
export function SettingsPage() {
|
|
46
|
+
const clerkEnabled = isClerkConfigured();
|
|
47
|
+
const desktopEntitlement = useViewerStore((s) => s.desktopEntitlement);
|
|
48
|
+
const chatUsage = useViewerStore((s) => s.chatUsage);
|
|
49
|
+
const [preferences, setPreferences] = useState(() => getDesktopPreferences());
|
|
50
|
+
const [isRefreshingAccount, setIsRefreshingAccount] = useState(false);
|
|
51
|
+
const returnTo = (() => {
|
|
52
|
+
const params = new URLSearchParams(window.location.search);
|
|
53
|
+
const candidate = params.get('returnTo');
|
|
54
|
+
return candidate && candidate.startsWith('/') ? candidate : '/';
|
|
55
|
+
})();
|
|
56
|
+
useEffect(() => subscribeDesktopPreferences(() => {
|
|
57
|
+
setPreferences(getDesktopPreferences());
|
|
58
|
+
}), []);
|
|
59
|
+
|
|
60
|
+
const updatePreference = (updates: Partial<typeof preferences>) => {
|
|
61
|
+
setPreferences(updateDesktopPreferences(updates));
|
|
62
|
+
};
|
|
63
|
+
const planTier = getDesktopPlanTier(desktopEntitlement);
|
|
64
|
+
const planSummary = getDesktopPlanSummary(desktopEntitlement, chatUsage);
|
|
65
|
+
const featureCatalog = getDesktopFeatureCatalog(desktopEntitlement);
|
|
66
|
+
const canRestoreWorkspace = hasDesktopPro(desktopEntitlement);
|
|
67
|
+
const usageSummary = useMemo(() => {
|
|
68
|
+
if (!chatUsage) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
const resetLabel = chatUsage.resetAt
|
|
72
|
+
? new Date(chatUsage.resetAt * 1000).toLocaleDateString()
|
|
73
|
+
: 'Unknown';
|
|
74
|
+
const unit = chatUsage.type === 'credits' ? 'credits' : 'requests';
|
|
75
|
+
return `${chatUsage.used}/${chatUsage.limit} ${unit} used. Resets ${resetLabel}.`;
|
|
76
|
+
}, [chatUsage]);
|
|
77
|
+
|
|
78
|
+
const handleRefreshAccount = async () => {
|
|
79
|
+
setIsRefreshingAccount(true);
|
|
80
|
+
try {
|
|
81
|
+
await requestDesktopEntitlementRefresh();
|
|
82
|
+
toast.success('Account status refreshed');
|
|
83
|
+
} catch (error) {
|
|
84
|
+
const message = error instanceof Error ? error.message : 'Could not refresh account status';
|
|
85
|
+
toast.error(message);
|
|
86
|
+
} finally {
|
|
87
|
+
setIsRefreshingAccount(false);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
return (
|
|
92
|
+
<div className="min-h-screen bg-background text-foreground">
|
|
93
|
+
<div className="mx-auto w-full max-w-4xl px-6 py-8">
|
|
94
|
+
<div className="mb-6 flex items-center justify-between">
|
|
95
|
+
<Button variant="ghost" size="sm" onClick={() => navigateToPath(returnTo, { replace: true })}>
|
|
96
|
+
<ArrowLeft className="mr-2 h-4 w-4" />
|
|
97
|
+
Back to Viewer
|
|
98
|
+
</Button>
|
|
99
|
+
</div>
|
|
100
|
+
|
|
101
|
+
<div className="space-y-6">
|
|
102
|
+
<section className="rounded-lg border bg-card p-6 shadow-sm">
|
|
103
|
+
<div className="mb-5 flex items-center gap-3">
|
|
104
|
+
<ShieldCheck className="h-5 w-5" />
|
|
105
|
+
<div>
|
|
106
|
+
<h1 className="text-2xl font-semibold">Desktop Account</h1>
|
|
107
|
+
<p className="text-sm text-muted-foreground">
|
|
108
|
+
App-wide entitlement, trial state, offline grace, and AI usage limits.
|
|
109
|
+
</p>
|
|
110
|
+
</div>
|
|
111
|
+
</div>
|
|
112
|
+
|
|
113
|
+
<div className="mb-5 flex flex-wrap items-center gap-2">
|
|
114
|
+
<StatusBadge entitlement={desktopEntitlement} />
|
|
115
|
+
<Badge variant={hasDesktopPro(desktopEntitlement) ? 'default' : 'secondary'}>
|
|
116
|
+
{planTier === 'pro' ? 'Desktop Pro' : 'Desktop Free'}
|
|
117
|
+
</Badge>
|
|
118
|
+
<Badge variant="outline">
|
|
119
|
+
Source: {desktopEntitlement.source.replace('_', ' ')}
|
|
120
|
+
</Badge>
|
|
121
|
+
</div>
|
|
122
|
+
|
|
123
|
+
<div className="mb-5 grid gap-3 md:grid-cols-2">
|
|
124
|
+
<InfoCard
|
|
125
|
+
title="Plan Summary"
|
|
126
|
+
body={planSummary}
|
|
127
|
+
icon={<CreditCard className="h-4 w-4" />}
|
|
128
|
+
/>
|
|
129
|
+
<InfoCard
|
|
130
|
+
title="AI Usage"
|
|
131
|
+
body={usageSummary ?? 'No AI usage data yet. Pro usage appears after the first synced usage snapshot.'}
|
|
132
|
+
icon={<Bot className="h-4 w-4" />}
|
|
133
|
+
/>
|
|
134
|
+
<InfoCard
|
|
135
|
+
title="Last Validated"
|
|
136
|
+
body={formatTimestamp(desktopEntitlement.validatedAt)}
|
|
137
|
+
icon={<Clock3 className="h-4 w-4" />}
|
|
138
|
+
/>
|
|
139
|
+
<InfoCard
|
|
140
|
+
title="Offline Grace"
|
|
141
|
+
body={formatOfflineGrace(desktopEntitlement)}
|
|
142
|
+
icon={<WifiOff className="h-4 w-4" />}
|
|
143
|
+
/>
|
|
144
|
+
</div>
|
|
145
|
+
|
|
146
|
+
{clerkEnabled ? (
|
|
147
|
+
<div className="flex flex-wrap gap-3">
|
|
148
|
+
<Button
|
|
149
|
+
variant="outline"
|
|
150
|
+
onClick={() => void handleRefreshAccount()}
|
|
151
|
+
disabled={isRefreshingAccount}
|
|
152
|
+
>
|
|
153
|
+
<RefreshCw className={`mr-2 h-4 w-4 ${isRefreshingAccount ? 'animate-spin' : ''}`} />
|
|
154
|
+
Refresh Account Status
|
|
155
|
+
</Button>
|
|
156
|
+
{!hasDesktopPro(desktopEntitlement) ? (
|
|
157
|
+
<Button onClick={() => navigateToPath(buildDesktopUpgradeUrl('/settings'))}>
|
|
158
|
+
Upgrade to Pro
|
|
159
|
+
</Button>
|
|
160
|
+
) : null}
|
|
161
|
+
</div>
|
|
162
|
+
) : null}
|
|
163
|
+
</section>
|
|
164
|
+
|
|
165
|
+
<section className="rounded-lg border bg-card p-6 shadow-sm">
|
|
166
|
+
<div className="mb-5 flex items-center gap-3">
|
|
167
|
+
<Settings2 className="h-5 w-5" />
|
|
168
|
+
<div>
|
|
169
|
+
<h1 className="text-2xl font-semibold">Desktop Settings</h1>
|
|
170
|
+
<p className="text-sm text-muted-foreground">
|
|
171
|
+
Local preferences for startup behavior and account access.
|
|
172
|
+
</p>
|
|
173
|
+
</div>
|
|
174
|
+
</div>
|
|
175
|
+
|
|
176
|
+
<div className="space-y-5">
|
|
177
|
+
<div className="flex items-start justify-between gap-4 rounded-md border p-4">
|
|
178
|
+
<div className="space-y-1">
|
|
179
|
+
<div className="flex items-center gap-2 font-medium">
|
|
180
|
+
<FolderOpen className="h-4 w-4" />
|
|
181
|
+
Reopen last model on launch
|
|
182
|
+
</div>
|
|
183
|
+
<p className="text-sm text-muted-foreground">
|
|
184
|
+
Automatically load the most recently used IFC file when the desktop app starts.
|
|
185
|
+
</p>
|
|
186
|
+
</div>
|
|
187
|
+
<Switch
|
|
188
|
+
checked={preferences.reopenLastModelOnLaunch}
|
|
189
|
+
onCheckedChange={(checked) => updatePreference({ reopenLastModelOnLaunch: checked })}
|
|
190
|
+
/>
|
|
191
|
+
</div>
|
|
192
|
+
|
|
193
|
+
<div className="flex items-start justify-between gap-4 rounded-md border p-4">
|
|
194
|
+
<div className="space-y-1">
|
|
195
|
+
<div className="flex items-center gap-2 font-medium">
|
|
196
|
+
<LayoutPanelTop className="h-4 w-4" />
|
|
197
|
+
Restore workspace layout
|
|
198
|
+
</div>
|
|
199
|
+
<p className="text-sm text-muted-foreground">
|
|
200
|
+
Restore panel visibility, camera view, sectioning, and other saved workspace state on launch. Desktop Pro feature.
|
|
201
|
+
</p>
|
|
202
|
+
</div>
|
|
203
|
+
<Switch
|
|
204
|
+
checked={preferences.restoreWorkspaceLayoutOnLaunch}
|
|
205
|
+
disabled={!canRestoreWorkspace}
|
|
206
|
+
onCheckedChange={(checked) => updatePreference({ restoreWorkspaceLayoutOnLaunch: checked })}
|
|
207
|
+
/>
|
|
208
|
+
</div>
|
|
209
|
+
{!canRestoreWorkspace && (
|
|
210
|
+
<div className="rounded-md border border-dashed p-4 text-sm text-muted-foreground">
|
|
211
|
+
Workspace restore is included with Desktop Pro. Reopening the last model remains available on Free.
|
|
212
|
+
<div className="mt-3">
|
|
213
|
+
<Button size="sm" onClick={() => navigateToPath(buildDesktopUpgradeUrl('/settings'))}>
|
|
214
|
+
Upgrade to Desktop Pro
|
|
215
|
+
</Button>
|
|
216
|
+
</div>
|
|
217
|
+
</div>
|
|
218
|
+
)}
|
|
219
|
+
</div>
|
|
220
|
+
</section>
|
|
221
|
+
|
|
222
|
+
<section className="rounded-lg border bg-card p-6 shadow-sm">
|
|
223
|
+
<div className="mb-5 flex items-center gap-3">
|
|
224
|
+
<CreditCard className="h-5 w-5" />
|
|
225
|
+
<div>
|
|
226
|
+
<h2 className="text-xl font-semibold">Billing & Features</h2>
|
|
227
|
+
<p className="text-sm text-muted-foreground">
|
|
228
|
+
Desktop billing is app-wide. The viewer stays available on Free, while Pro unlocks advanced desktop features and full AI access.
|
|
229
|
+
</p>
|
|
230
|
+
</div>
|
|
231
|
+
</div>
|
|
232
|
+
|
|
233
|
+
<div className="mb-5 rounded-md border p-4">
|
|
234
|
+
<div className="flex items-center justify-between gap-4">
|
|
235
|
+
<div>
|
|
236
|
+
<div className="font-medium capitalize">{planTier} plan</div>
|
|
237
|
+
<p className="text-sm text-muted-foreground">{planSummary}</p>
|
|
238
|
+
<p className="text-sm text-muted-foreground">
|
|
239
|
+
Desktop caches the latest validated plan locally and stores the auth bearer in native secure storage when available.
|
|
240
|
+
</p>
|
|
241
|
+
</div>
|
|
242
|
+
{isDesktopBillingEnforced() && !hasDesktopPro(desktopEntitlement) && (
|
|
243
|
+
<Button onClick={() => navigateToPath(buildDesktopUpgradeUrl('/settings'))}>
|
|
244
|
+
Upgrade to Pro
|
|
245
|
+
</Button>
|
|
246
|
+
)}
|
|
247
|
+
</div>
|
|
248
|
+
</div>
|
|
249
|
+
|
|
250
|
+
<div className="mb-5 grid gap-3">
|
|
251
|
+
{featureCatalog.map((feature) => (
|
|
252
|
+
<div key={feature.key} className="flex items-start justify-between gap-4 rounded-md border p-4">
|
|
253
|
+
<div>
|
|
254
|
+
<div className="font-medium">{feature.label}</div>
|
|
255
|
+
<p className="text-sm text-muted-foreground">{feature.description}</p>
|
|
256
|
+
</div>
|
|
257
|
+
<div className="flex items-center gap-2 text-sm">
|
|
258
|
+
{feature.enabled ? (
|
|
259
|
+
<>
|
|
260
|
+
<Check className="h-4 w-4 text-emerald-500" />
|
|
261
|
+
Included
|
|
262
|
+
</>
|
|
263
|
+
) : (
|
|
264
|
+
<>
|
|
265
|
+
<Lock className="h-4 w-4 text-amber-500" />
|
|
266
|
+
Pro
|
|
267
|
+
</>
|
|
268
|
+
)}
|
|
269
|
+
</div>
|
|
270
|
+
</div>
|
|
271
|
+
))}
|
|
272
|
+
</div>
|
|
273
|
+
|
|
274
|
+
{!clerkEnabled ? (
|
|
275
|
+
<div className="rounded-md border border-dashed p-4 text-sm text-muted-foreground">
|
|
276
|
+
Auth and billing are not configured in this build. Set `VITE_CLERK_PUBLISHABLE_KEY` to enable sign-in and subscription flows.
|
|
277
|
+
</div>
|
|
278
|
+
) : (
|
|
279
|
+
<SettingsAccountSection desktopEntitlement={desktopEntitlement} />
|
|
280
|
+
)}
|
|
281
|
+
</section>
|
|
282
|
+
|
|
283
|
+
<section className="rounded-lg border bg-card p-6 shadow-sm">
|
|
284
|
+
<div className="mb-5 flex items-center gap-3">
|
|
285
|
+
<Cloud className="h-5 w-5" />
|
|
286
|
+
<div>
|
|
287
|
+
<h2 className="text-xl font-semibold">Privacy & Network</h2>
|
|
288
|
+
<p className="text-sm text-muted-foreground">
|
|
289
|
+
Local IFC viewing remains available offline. Connected services degrade individually instead of blocking the desktop viewer.
|
|
290
|
+
</p>
|
|
291
|
+
</div>
|
|
292
|
+
</div>
|
|
293
|
+
|
|
294
|
+
<div className="grid gap-3 md:grid-cols-2">
|
|
295
|
+
<InfoCard
|
|
296
|
+
title="Always Local"
|
|
297
|
+
body="Model loading, hierarchy, properties, navigation, measurement, and core viewing stay on your machine."
|
|
298
|
+
icon={<ShieldCheck className="h-4 w-4" />}
|
|
299
|
+
/>
|
|
300
|
+
<InfoCard
|
|
301
|
+
title="Needs Network"
|
|
302
|
+
body="Cloud AI assistant, billing sync, and live bSDD lookups require network access. Cached Pro can continue during offline grace."
|
|
303
|
+
icon={<Cloud className="h-4 w-4" />}
|
|
304
|
+
/>
|
|
305
|
+
</div>
|
|
306
|
+
</section>
|
|
307
|
+
</div>
|
|
308
|
+
</div>
|
|
309
|
+
</div>
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
function formatTimestamp(value: number | null): string {
|
|
314
|
+
if (!value) {
|
|
315
|
+
return 'Not validated yet';
|
|
316
|
+
}
|
|
317
|
+
return new Date(value).toLocaleString();
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
function formatOfflineGrace(entitlement: DesktopEntitlement): string {
|
|
321
|
+
if (!entitlement.graceUntil) {
|
|
322
|
+
return 'No offline grace cached yet';
|
|
323
|
+
}
|
|
324
|
+
const remainingDays = Math.max(0, Math.ceil((entitlement.graceUntil - Date.now()) / (24 * 60 * 60 * 1000)));
|
|
325
|
+
return `${new Date(entitlement.graceUntil).toLocaleString()}${remainingDays > 0 ? ` (${remainingDays} day${remainingDays === 1 ? '' : 's'} left)` : ''}`;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
function describeDesktopStatus(entitlement: DesktopEntitlement): string {
|
|
329
|
+
switch (entitlement.status) {
|
|
330
|
+
case 'trial':
|
|
331
|
+
return entitlement.trialEndsAt
|
|
332
|
+
? `Trial active until ${new Date(entitlement.trialEndsAt).toLocaleDateString()}`
|
|
333
|
+
: 'Trial active';
|
|
334
|
+
case 'grace_offline':
|
|
335
|
+
return entitlement.graceUntil
|
|
336
|
+
? `Offline grace until ${new Date(entitlement.graceUntil).toLocaleDateString()}`
|
|
337
|
+
: 'Offline grace active';
|
|
338
|
+
case 'expired':
|
|
339
|
+
return 'Subscription expired';
|
|
340
|
+
case 'active':
|
|
341
|
+
return 'Subscription active';
|
|
342
|
+
case 'signed_out':
|
|
343
|
+
return 'Signed out';
|
|
344
|
+
case 'anonymous':
|
|
345
|
+
return 'Auth unavailable in this build';
|
|
346
|
+
default:
|
|
347
|
+
return entitlement.status;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
function getStatusBadgeVariant(entitlement: DesktopEntitlement): 'default' | 'secondary' | 'destructive' | 'outline' {
|
|
352
|
+
switch (entitlement.status) {
|
|
353
|
+
case 'active':
|
|
354
|
+
case 'trial':
|
|
355
|
+
return 'default';
|
|
356
|
+
case 'grace_offline':
|
|
357
|
+
return 'secondary';
|
|
358
|
+
case 'expired':
|
|
359
|
+
return 'destructive';
|
|
360
|
+
default:
|
|
361
|
+
return 'outline';
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
function StatusBadge({ entitlement }: { entitlement: DesktopEntitlement }) {
|
|
366
|
+
return (
|
|
367
|
+
<Badge variant={getStatusBadgeVariant(entitlement)}>
|
|
368
|
+
{describeDesktopStatus(entitlement)}
|
|
369
|
+
</Badge>
|
|
370
|
+
);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
function InfoCard({ title, body, icon }: { title: string; body: string; icon: React.ReactNode }) {
|
|
374
|
+
return (
|
|
375
|
+
<div className="rounded-md border p-4">
|
|
376
|
+
<div className="mb-2 flex items-center gap-2 text-sm font-medium">
|
|
377
|
+
{icon}
|
|
378
|
+
{title}
|
|
379
|
+
</div>
|
|
380
|
+
<p className="text-sm text-muted-foreground">{body}</p>
|
|
381
|
+
</div>
|
|
382
|
+
);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
function SettingsAccountSection({ desktopEntitlement }: { desktopEntitlement: DesktopEntitlement }) {
|
|
386
|
+
const { isSignedIn } = useAuth();
|
|
387
|
+
const { user } = useUser();
|
|
388
|
+
const hasPro = hasDesktopPro(desktopEntitlement);
|
|
389
|
+
const statusLabel = describeDesktopStatus(desktopEntitlement);
|
|
390
|
+
|
|
391
|
+
return (
|
|
392
|
+
<div className="space-y-4">
|
|
393
|
+
<SignedOut>
|
|
394
|
+
<div className="rounded-md border p-4">
|
|
395
|
+
<p className="mb-3 text-sm text-muted-foreground">
|
|
396
|
+
Sign in to sync your desktop plan, subscription status, and AI usage limits across web and desktop.
|
|
397
|
+
</p>
|
|
398
|
+
<SignInButton mode="modal" forceRedirectUrl="/settings" fallbackRedirectUrl="/settings">
|
|
399
|
+
<Button>Sign in</Button>
|
|
400
|
+
</SignInButton>
|
|
401
|
+
</div>
|
|
402
|
+
</SignedOut>
|
|
403
|
+
|
|
404
|
+
<SignedIn>
|
|
405
|
+
<div className="flex items-center justify-between gap-4 rounded-md border p-4">
|
|
406
|
+
<div>
|
|
407
|
+
<div className="font-medium">
|
|
408
|
+
{user?.primaryEmailAddress?.emailAddress ?? user?.username ?? 'Signed in'}
|
|
409
|
+
</div>
|
|
410
|
+
<p className="text-sm text-muted-foreground">
|
|
411
|
+
Plan: {hasPro ? 'Pro' : 'Free'}
|
|
412
|
+
</p>
|
|
413
|
+
<p className="text-sm text-muted-foreground">
|
|
414
|
+
Status: {statusLabel}
|
|
415
|
+
</p>
|
|
416
|
+
<p className="text-sm text-muted-foreground">
|
|
417
|
+
Last validated: {formatTimestamp(desktopEntitlement.validatedAt)}
|
|
418
|
+
</p>
|
|
419
|
+
</div>
|
|
420
|
+
<div className="flex items-center gap-3">
|
|
421
|
+
<UserButton afterSignOutUrl="/" />
|
|
422
|
+
<Button onClick={() => navigateToPath(buildDesktopUpgradeUrl('/settings'))}>
|
|
423
|
+
{isSignedIn && hasPro ? 'Manage Plan' : 'Upgrade to Pro'}
|
|
424
|
+
</Button>
|
|
425
|
+
</div>
|
|
426
|
+
</div>
|
|
427
|
+
</SignedIn>
|
|
428
|
+
</div>
|
|
429
|
+
);
|
|
430
|
+
}
|
|
@@ -60,8 +60,24 @@ export function StatusBar() {
|
|
|
60
60
|
if (!geometryResult) {
|
|
61
61
|
return { elements: 0, triangles: 0 };
|
|
62
62
|
}
|
|
63
|
+
// Count actual entities: for color-merged meshes, count unique entity IDs
|
|
64
|
+
let elements = 0;
|
|
65
|
+
const meshes = geometryResult.meshes;
|
|
66
|
+
if (meshes) {
|
|
67
|
+
for (let i = 0; i < meshes.length; i++) {
|
|
68
|
+
const m = meshes[i] as { entityIds?: Uint32Array };
|
|
69
|
+
if (m.entityIds && m.entityIds.length > 0) {
|
|
70
|
+
// Count unique entity IDs in this merged mesh
|
|
71
|
+
const seen = new Set<number>();
|
|
72
|
+
for (let j = 0; j < m.entityIds.length; j++) seen.add(m.entityIds[j]);
|
|
73
|
+
elements += seen.size;
|
|
74
|
+
} else {
|
|
75
|
+
elements += 1;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
63
79
|
return {
|
|
64
|
-
elements
|
|
80
|
+
elements,
|
|
65
81
|
triangles: geometryResult.totalTriangles ?? 0,
|
|
66
82
|
};
|
|
67
83
|
}, [geometryResult]);
|
|
@@ -7,9 +7,12 @@ import { useEffect, useMemo } from 'react';
|
|
|
7
7
|
import { ArrowLeft } from 'lucide-react';
|
|
8
8
|
import { Button } from '@/components/ui/button';
|
|
9
9
|
import { useViewerStore } from '@/store';
|
|
10
|
+
import { hasDesktopPro } from '@/lib/desktop-product';
|
|
11
|
+
import { navigateToPath } from '@/services/app-navigation';
|
|
10
12
|
|
|
11
13
|
export function UpgradePage() {
|
|
12
|
-
const
|
|
14
|
+
const desktopEntitlement = useViewerStore((s) => s.desktopEntitlement);
|
|
15
|
+
const hasPro = hasDesktopPro(desktopEntitlement);
|
|
13
16
|
const returnTo = useMemo(() => {
|
|
14
17
|
const params = new URLSearchParams(window.location.search);
|
|
15
18
|
const candidate = params.get('returnTo');
|
|
@@ -17,8 +20,7 @@ export function UpgradePage() {
|
|
|
17
20
|
}, []);
|
|
18
21
|
|
|
19
22
|
const navigateBack = () => {
|
|
20
|
-
|
|
21
|
-
window.dispatchEvent(new PopStateEvent('popstate'));
|
|
23
|
+
navigateToPath(returnTo, { replace: true });
|
|
22
24
|
};
|
|
23
25
|
|
|
24
26
|
// Automatically return to the previous app view once upgrade is active.
|
|
@@ -43,7 +45,7 @@ export function UpgradePage() {
|
|
|
43
45
|
<div className="rounded-lg border bg-card p-6 shadow-sm">
|
|
44
46
|
<h1 className="text-2xl font-semibold">Upgrade to Pro</h1>
|
|
45
47
|
<p className="mt-2 text-sm text-muted-foreground">
|
|
46
|
-
Free
|
|
48
|
+
Free keeps the core desktop viewer available. Pro unlocks advanced desktop features, plus the AI assistant with the same monthly limits and routing used on web.
|
|
47
49
|
</p>
|
|
48
50
|
|
|
49
51
|
<div className="mt-6">
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
4
|
|
|
5
|
-
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
5
|
+
import { useCallback, useEffect, useRef, useState, useSyncExternalStore } from 'react';
|
|
6
6
|
import { Panel, Group as PanelGroup, Separator as PanelResizeHandle } from 'react-resizable-panels';
|
|
7
7
|
import type { PanelImperativeHandle } from 'react-resizable-panels';
|
|
8
8
|
import { TooltipProvider } from '@/components/ui/tooltip';
|
|
@@ -22,6 +22,13 @@ import { LensPanel } from './LensPanel';
|
|
|
22
22
|
import { ListPanel } from './lists/ListPanel';
|
|
23
23
|
import { ScriptPanel } from './ScriptPanel';
|
|
24
24
|
import { CommandPalette } from './CommandPalette';
|
|
25
|
+
import { DesktopEntitlementBanner } from './DesktopEntitlementBanner';
|
|
26
|
+
import {
|
|
27
|
+
closeActiveAnalysisExtension,
|
|
28
|
+
getAnalysisExtensionById,
|
|
29
|
+
getAnalysisExtensionsSnapshot,
|
|
30
|
+
subscribeAnalysisExtensions,
|
|
31
|
+
} from '@/services/analysis-extensions';
|
|
25
32
|
|
|
26
33
|
const BOTTOM_PANEL_MIN_HEIGHT = 120;
|
|
27
34
|
const BOTTOM_PANEL_DEFAULT_HEIGHT = 300;
|
|
@@ -47,6 +54,18 @@ export function ViewerLayout() {
|
|
|
47
54
|
return () => window.removeEventListener('keydown', handler);
|
|
48
55
|
}, []);
|
|
49
56
|
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
const openCommandPalette = () => setCommandPaletteOpen(true);
|
|
59
|
+
const showShortcuts = () => shortcutsDialog.toggle();
|
|
60
|
+
|
|
61
|
+
window.addEventListener('ifc-lite:open-command-palette', openCommandPalette);
|
|
62
|
+
window.addEventListener('ifc-lite:show-shortcuts', showShortcuts);
|
|
63
|
+
return () => {
|
|
64
|
+
window.removeEventListener('ifc-lite:open-command-palette', openCommandPalette);
|
|
65
|
+
window.removeEventListener('ifc-lite:show-shortcuts', showShortcuts);
|
|
66
|
+
};
|
|
67
|
+
}, [shortcutsDialog]);
|
|
68
|
+
|
|
50
69
|
// Initialize theme on mount
|
|
51
70
|
const theme = useViewerStore((s) => s.theme);
|
|
52
71
|
const isMobile = useViewerStore((s) => s.isMobile);
|
|
@@ -65,6 +84,18 @@ export function ViewerLayout() {
|
|
|
65
84
|
const setLensPanelVisible = useViewerStore((s) => s.setLensPanelVisible);
|
|
66
85
|
const scriptPanelVisible = useViewerStore((s) => s.scriptPanelVisible);
|
|
67
86
|
const setScriptPanelVisible = useViewerStore((s) => s.setScriptPanelVisible);
|
|
87
|
+
const analysisExtensionState = useSyncExternalStore(
|
|
88
|
+
subscribeAnalysisExtensions,
|
|
89
|
+
getAnalysisExtensionsSnapshot,
|
|
90
|
+
getAnalysisExtensionsSnapshot,
|
|
91
|
+
);
|
|
92
|
+
const activeAnalysisExtension = getAnalysisExtensionById(analysisExtensionState.activeId);
|
|
93
|
+
const activeRightAnalysisExtension = (activeAnalysisExtension?.placement ?? 'right') === 'right'
|
|
94
|
+
? activeAnalysisExtension
|
|
95
|
+
: null;
|
|
96
|
+
const activeBottomAnalysisExtension = activeAnalysisExtension?.placement === 'bottom'
|
|
97
|
+
? activeAnalysisExtension
|
|
98
|
+
: null;
|
|
68
99
|
|
|
69
100
|
// Panel refs for programmatic collapse/expand (command palette, keyboard shortcuts)
|
|
70
101
|
const leftPanelRef = useRef<PanelImperativeHandle>(null);
|
|
@@ -171,6 +202,7 @@ export function ViewerLayout() {
|
|
|
171
202
|
|
|
172
203
|
{/* Main Toolbar */}
|
|
173
204
|
<MainToolbar onShowShortcuts={shortcutsDialog.toggle} />
|
|
205
|
+
<DesktopEntitlementBanner />
|
|
174
206
|
|
|
175
207
|
{/* Main Content Area - Desktop Layout */}
|
|
176
208
|
{!isMobile && (
|
|
@@ -221,7 +253,9 @@ export function ViewerLayout() {
|
|
|
221
253
|
}}
|
|
222
254
|
>
|
|
223
255
|
<div className="h-full w-full overflow-hidden panel-container">
|
|
224
|
-
{
|
|
256
|
+
{activeRightAnalysisExtension ? (
|
|
257
|
+
activeRightAnalysisExtension.renderPanel({ onClose: closeActiveAnalysisExtension })
|
|
258
|
+
) : lensPanelVisible ? (
|
|
225
259
|
<LensPanel onClose={() => setLensPanelVisible(false)} />
|
|
226
260
|
) : idsPanelVisible ? (
|
|
227
261
|
<IDSPanel onClose={() => setIdsPanelVisible(false)} />
|
|
@@ -236,7 +270,7 @@ export function ViewerLayout() {
|
|
|
236
270
|
</div>
|
|
237
271
|
|
|
238
272
|
{/* Bottom Panel - Lists or Script (custom resizable, outside PanelGroup) */}
|
|
239
|
-
{(listPanelVisible || scriptPanelVisible) && (
|
|
273
|
+
{(listPanelVisible || scriptPanelVisible || !!activeBottomAnalysisExtension) && (
|
|
240
274
|
<div style={{ height: bottomHeight, flexShrink: 0 }} className="relative">
|
|
241
275
|
{/* Drag handle */}
|
|
242
276
|
<div
|
|
@@ -244,7 +278,9 @@ export function ViewerLayout() {
|
|
|
244
278
|
onMouseDown={handleResizeStart}
|
|
245
279
|
/>
|
|
246
280
|
<div className="h-full w-full overflow-hidden border-t pt-1.5">
|
|
247
|
-
{
|
|
281
|
+
{activeBottomAnalysisExtension ? (
|
|
282
|
+
activeBottomAnalysisExtension.renderPanel({ onClose: closeActiveAnalysisExtension })
|
|
283
|
+
) : scriptPanelVisible ? (
|
|
248
284
|
<ScriptPanel onClose={() => setScriptPanelVisible(false)} />
|
|
249
285
|
) : (
|
|
250
286
|
<ListPanel onClose={() => setListPanelVisible(false)} />
|
|
@@ -289,7 +325,7 @@ export function ViewerLayout() {
|
|
|
289
325
|
<div className="absolute inset-x-0 bottom-0 h-[50vh] bg-background border-t rounded-t-xl shadow-xl z-40 animate-in slide-in-from-bottom">
|
|
290
326
|
<div className="flex items-center justify-between p-2 border-b">
|
|
291
327
|
<span className="font-medium text-sm">
|
|
292
|
-
{scriptPanelVisible ? 'Script' : listPanelVisible ? 'Lists' : lensPanelVisible ? 'Lens' : idsPanelVisible ? 'IDS Validation' : bcfPanelVisible ? 'BCF Issues' : 'Properties'}
|
|
328
|
+
{activeAnalysisExtension ? activeAnalysisExtension.label : scriptPanelVisible ? 'Script' : listPanelVisible ? 'Lists' : lensPanelVisible ? 'Lens' : idsPanelVisible ? 'IDS Validation' : bcfPanelVisible ? 'BCF Issues' : 'Properties'}
|
|
293
329
|
</span>
|
|
294
330
|
<button
|
|
295
331
|
className="p-1 hover:bg-muted rounded"
|
|
@@ -300,6 +336,7 @@ export function ViewerLayout() {
|
|
|
300
336
|
if (bcfPanelVisible) setBcfPanelVisible(false);
|
|
301
337
|
if (lensPanelVisible) setLensPanelVisible(false);
|
|
302
338
|
if (idsPanelVisible) setIdsPanelVisible(false);
|
|
339
|
+
if (activeAnalysisExtension) closeActiveAnalysisExtension();
|
|
303
340
|
}}
|
|
304
341
|
>
|
|
305
342
|
<span className="sr-only">Close</span>
|
|
@@ -309,7 +346,11 @@ export function ViewerLayout() {
|
|
|
309
346
|
</button>
|
|
310
347
|
</div>
|
|
311
348
|
<div className="h-[calc(50vh-48px)] overflow-auto">
|
|
312
|
-
{
|
|
349
|
+
{activeBottomAnalysisExtension ? (
|
|
350
|
+
activeBottomAnalysisExtension.renderPanel({ onClose: closeActiveAnalysisExtension })
|
|
351
|
+
) : activeRightAnalysisExtension ? (
|
|
352
|
+
activeRightAnalysisExtension.renderPanel({ onClose: closeActiveAnalysisExtension })
|
|
353
|
+
) : scriptPanelVisible ? (
|
|
313
354
|
<ScriptPanel onClose={() => setScriptPanelVisible(false)} />
|
|
314
355
|
) : listPanelVisible ? (
|
|
315
356
|
<ListPanel onClose={() => setListPanelVisible(false)} />
|