@collabdt/core 0.0.57 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/README.md +4 -26
  2. package/dist/core/components/support/BugReportDialog.d.ts.map +1 -1
  3. package/dist/core/components/support/BugReportDialog.js +32 -0
  4. package/dist/core/components/support/BugReportDialog.js.map +1 -1
  5. package/dist/core/components/support/FeatureRequestDialog.d.ts.map +1 -1
  6. package/dist/core/components/support/FeatureRequestDialog.js +32 -0
  7. package/dist/core/components/support/FeatureRequestDialog.js.map +1 -1
  8. package/dist/core/components/viewers/Data/DataMenu.d.ts.map +1 -1
  9. package/dist/core/components/viewers/Data/DataMenu.js +9 -1
  10. package/dist/core/components/viewers/Data/DataMenu.js.map +1 -1
  11. package/dist/core/components/viewers/Data/HeaderButtons.d.ts.map +1 -1
  12. package/dist/core/components/viewers/Data/HeaderButtons.js +5 -12
  13. package/dist/core/components/viewers/Data/HeaderButtons.js.map +1 -1
  14. package/dist/core/components/viewers/Data/MoreOptions.d.ts.map +1 -1
  15. package/dist/core/components/viewers/Data/MoreOptions.js +14 -27
  16. package/dist/core/components/viewers/Data/MoreOptions.js.map +1 -1
  17. package/dist/core/components/viewers/Data/buildingDetails/FieldRenderer.d.ts.map +1 -1
  18. package/dist/core/components/viewers/Data/buildingDetails/FieldRenderer.js +13 -18
  19. package/dist/core/components/viewers/Data/buildingDetails/FieldRenderer.js.map +1 -1
  20. package/dist/core/components/viewers/Data/details/FieldValue.d.ts.map +1 -1
  21. package/dist/core/components/viewers/Data/details/FieldValue.js +13 -3
  22. package/dist/core/components/viewers/Data/details/FieldValue.js.map +1 -1
  23. package/dist/core/components/viewers/Data/siteDetails/AssociatedBuildings.d.ts +2 -0
  24. package/dist/core/components/viewers/Data/siteDetails/AssociatedBuildings.d.ts.map +1 -1
  25. package/dist/core/components/viewers/Data/siteDetails/AssociatedBuildings.js +84 -3
  26. package/dist/core/components/viewers/Data/siteDetails/AssociatedBuildings.js.map +1 -1
  27. package/dist/core/components/viewers/Data/siteDetails/SiteDetails.d.ts.map +1 -1
  28. package/dist/core/components/viewers/Data/siteDetails/SiteDetails.js +23 -2
  29. package/dist/core/components/viewers/Data/siteDetails/SiteDetails.js.map +1 -1
  30. package/dist/core/components/viewers/map/src/MapLayers/index.d.ts.map +1 -1
  31. package/dist/core/components/viewers/map/src/MapLayers/index.js +2 -0
  32. package/dist/core/components/viewers/map/src/MapLayers/index.js.map +1 -1
  33. package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/SiteContextMenu.d.ts +19 -0
  34. package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/SiteContextMenu.d.ts.map +1 -0
  35. package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/SiteContextMenu.js +163 -0
  36. package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/SiteContextMenu.js.map +1 -0
  37. package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/SiteLayer.d.ts +3 -0
  38. package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/SiteLayer.d.ts.map +1 -0
  39. package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/SiteLayer.js +310 -0
  40. package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/SiteLayer.js.map +1 -0
  41. package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/siteGeometry.d.ts +30 -0
  42. package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/siteGeometry.d.ts.map +1 -0
  43. package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/siteGeometry.js +122 -0
  44. package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/siteGeometry.js.map +1 -0
  45. package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/useShowSitesOnMap.d.ts +13 -0
  46. package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/useShowSitesOnMap.d.ts.map +1 -0
  47. package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/useShowSitesOnMap.js +58 -0
  48. package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/useShowSitesOnMap.js.map +1 -0
  49. package/dist/core/components/viewers/map/src/tools/AddTools/AddSite/AssociateBuildingsDialog.d.ts +18 -0
  50. package/dist/core/components/viewers/map/src/tools/AddTools/AddSite/AssociateBuildingsDialog.d.ts.map +1 -0
  51. package/dist/core/components/viewers/map/src/tools/AddTools/AddSite/AssociateBuildingsDialog.js +102 -0
  52. package/dist/core/components/viewers/map/src/tools/AddTools/AddSite/AssociateBuildingsDialog.js.map +1 -0
  53. package/dist/core/components/viewers/map/src/tools/AddTools/AddSite/SiteAdder.d.ts.map +1 -1
  54. package/dist/core/components/viewers/map/src/tools/AddTools/AddSite/SiteAdder.js +243 -176
  55. package/dist/core/components/viewers/map/src/tools/AddTools/AddSite/SiteAdder.js.map +1 -1
  56. package/dist/core/components/viewers/map/src/tools/AddTools/AddSite/persistSite.d.ts +24 -0
  57. package/dist/core/components/viewers/map/src/tools/AddTools/AddSite/persistSite.d.ts.map +1 -0
  58. package/dist/core/components/viewers/map/src/tools/AddTools/AddSite/persistSite.js +46 -0
  59. package/dist/core/components/viewers/map/src/tools/AddTools/AddSite/persistSite.js.map +1 -0
  60. package/dist/core/components/viewers/map/utils/MapEventManager/MapClickManager.d.ts +1 -0
  61. package/dist/core/components/viewers/map/utils/MapEventManager/MapClickManager.d.ts.map +1 -1
  62. package/dist/core/components/viewers/map/utils/MapEventManager/MapClickManager.js +1 -0
  63. package/dist/core/components/viewers/map/utils/MapEventManager/MapClickManager.js.map +1 -1
  64. package/dist/core/hooks/sites/createSiteHooks.d.ts.map +1 -1
  65. package/dist/core/hooks/sites/createSiteHooks.js +0 -1
  66. package/dist/core/hooks/sites/createSiteHooks.js.map +1 -1
  67. package/dist/core/hooks/useCaptureScreenshot.d.ts.map +1 -1
  68. package/dist/core/hooks/useCaptureScreenshot.js +77 -30
  69. package/dist/core/hooks/useCaptureScreenshot.js.map +1 -1
  70. package/dist/core/store/CombineProviders.d.ts.map +1 -1
  71. package/dist/core/store/CombineProviders.js +2 -0
  72. package/dist/core/store/CombineProviders.js.map +1 -1
  73. package/dist/core/store/MapSites/context.d.ts +16 -0
  74. package/dist/core/store/MapSites/context.d.ts.map +1 -0
  75. package/dist/core/store/MapSites/context.js +29 -0
  76. package/dist/core/store/MapSites/context.js.map +1 -0
  77. package/dist/core/store/MapSites/reducer.d.ts +52 -0
  78. package/dist/core/store/MapSites/reducer.d.ts.map +1 -0
  79. package/dist/core/store/MapSites/reducer.js +70 -0
  80. package/dist/core/store/MapSites/reducer.js.map +1 -0
  81. package/dist/core/store/index.d.ts +1 -0
  82. package/dist/core/store/index.d.ts.map +1 -1
  83. package/dist/core/store/index.js +1 -0
  84. package/dist/core/store/index.js.map +1 -1
  85. package/package.json +1 -1
@@ -0,0 +1,46 @@
1
+ import { uploadToPresignedUrl } from "../AddFile/utils/uploadToPresignedURLS";
2
+ import { ringToFeatureCollection } from "../../../MapLayers/src/SiteLayer/siteGeometry";
3
+ const SITE_GEOMETRY_TAG = "site-geometry";
4
+ const persistDrawnSite = async (params) => {
5
+ var _a;
6
+ const { name, ring, centroid, createSite } = params;
7
+ const site = await createSite({
8
+ siteName: name,
9
+ siteLongitude: centroid[0],
10
+ siteLatitude: centroid[1]
11
+ });
12
+ const siteId = site == null ? void 0 : site.id;
13
+ if (!siteId) throw new Error("Site creation did not return an id");
14
+ const assetId = `${crypto.randomUUID()}.geojson`;
15
+ const fc = ringToFeatureCollection(ring, name);
16
+ const file = new File([JSON.stringify(fc)], `${name || "site"}.geojson`, {
17
+ type: "application/geo+json"
18
+ });
19
+ const presRes = await fetch(`/api/presigned-url-upload?asset=${encodeURIComponent(assetId)}`);
20
+ if (!presRes.ok) throw new Error("Failed to get an upload URL");
21
+ const { presignedUrl } = await presRes.json();
22
+ await uploadToPresignedUrl(presignedUrl, file);
23
+ const fileRes = await fetch(`/api/files/site/${siteId}`, {
24
+ method: "POST",
25
+ headers: { "Content-Type": "application/json" },
26
+ body: JSON.stringify({
27
+ type: "map-file",
28
+ name: `${name || "site"}.geojson`,
29
+ assetId,
30
+ mimeType: "application/geo+json",
31
+ extension: "geojson",
32
+ sizeBytes: file.size,
33
+ tag: SITE_GEOMETRY_TAG,
34
+ isVisible: false
35
+ })
36
+ });
37
+ if (!fileRes.ok) throw new Error("Failed to attach the geometry file to the site");
38
+ const data = await fileRes.json().catch(() => null);
39
+ const fileId = (_a = data == null ? void 0 : data.newFile) == null ? void 0 : _a.id;
40
+ return { siteId, assetId, fileId };
41
+ };
42
+ export {
43
+ SITE_GEOMETRY_TAG,
44
+ persistDrawnSite
45
+ };
46
+ //# sourceMappingURL=persistSite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../../../src/core/components/viewers/map/src/tools/AddTools/AddSite/persistSite.ts"],"sourcesContent":["// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\nimport { uploadToPresignedUrl } from '../AddFile/utils/uploadToPresignedURLS'\r\nimport { ringToFeatureCollection, type Ring } from '../../../MapLayers/src/SiteLayer/siteGeometry'\r\n\r\n/** Tag stored on the File row so the site's boundary geojson can be found later. */\r\nexport const SITE_GEOMETRY_TAG = 'site-geometry'\r\n\r\nexport interface PersistedSite {\r\n siteId: number\r\n assetId: string\r\n fileId?: number\r\n}\r\n\r\n/**\r\n * Persist a freshly drawn site:\r\n * 1. create the DB Site (via the injected `createSite` hook trigger),\r\n * 2. upload the polygon GeoJSON to minio (presigned PUT),\r\n * 3. create a File row attached to the site that references the minio object.\r\n *\r\n * The polygon geometry lives in minio (there is no geometry column on Site);\r\n * the File row links it to the site via `attachedFilesSiteId` + the geometry tag.\r\n */\r\nexport const persistDrawnSite = async (params: {\r\n name: string\r\n ring: Ring\r\n centroid: [number, number]\r\n createSite: (arg: any) => Promise<any>\r\n}): Promise<PersistedSite> => {\r\n const { name, ring, centroid, createSite } = params\r\n\r\n const site = await createSite({\r\n siteName: name,\r\n siteLongitude: centroid[0],\r\n siteLatitude: centroid[1],\r\n })\r\n const siteId = site?.id\r\n if (!siteId) throw new Error('Site creation did not return an id')\r\n\r\n const assetId = `${crypto.randomUUID()}.geojson`\r\n const fc = ringToFeatureCollection(ring, name)\r\n const file = new File([JSON.stringify(fc)], `${name || 'site'}.geojson`, {\r\n type: 'application/geo+json',\r\n })\r\n\r\n const presRes = await fetch(`/api/presigned-url-upload?asset=${encodeURIComponent(assetId)}`)\r\n if (!presRes.ok) throw new Error('Failed to get an upload URL')\r\n const { presignedUrl } = await presRes.json()\r\n await uploadToPresignedUrl(presignedUrl, file)\r\n\r\n const fileRes = await fetch(`/api/files/site/${siteId}`, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({\r\n type: 'map-file',\r\n name: `${name || 'site'}.geojson`,\r\n assetId,\r\n mimeType: 'application/geo+json',\r\n extension: 'geojson',\r\n sizeBytes: file.size,\r\n tag: SITE_GEOMETRY_TAG,\r\n isVisible: false,\r\n }),\r\n })\r\n // The DB link is required: without it the boundary is orphaned in minio and\r\n // can never be re-shown. Treat failure as fatal so the caller can retry.\r\n if (!fileRes.ok) throw new Error('Failed to attach the geometry file to the site')\r\n const data = await fileRes.json().catch(() => null)\r\n const fileId: number | undefined = data?.newFile?.id\r\n\r\n return { siteId, assetId, fileId }\r\n}\r\n"],"mappings":"AAGA,SAAS,4BAA4B;AACrC,SAAS,+BAA0C;AAG5C,MAAM,oBAAoB;AAiB1B,MAAM,mBAAmB,OAAO,WAKT;AA7B9B;AA8BE,QAAM,EAAE,MAAM,MAAM,UAAU,WAAW,IAAI;AAE7C,QAAM,OAAO,MAAM,WAAW;AAAA,IAC5B,UAAU;AAAA,IACV,eAAe,SAAS,CAAC;AAAA,IACzB,cAAc,SAAS,CAAC;AAAA,EAC1B,CAAC;AACD,QAAM,SAAS,6BAAM;AACrB,MAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,oCAAoC;AAEjE,QAAM,UAAU,GAAG,OAAO,WAAW,CAAC;AACtC,QAAM,KAAK,wBAAwB,MAAM,IAAI;AAC7C,QAAM,OAAO,IAAI,KAAK,CAAC,KAAK,UAAU,EAAE,CAAC,GAAG,GAAG,QAAQ,MAAM,YAAY;AAAA,IACvE,MAAM;AAAA,EACR,CAAC;AAED,QAAM,UAAU,MAAM,MAAM,mCAAmC,mBAAmB,OAAO,CAAC,EAAE;AAC5F,MAAI,CAAC,QAAQ,GAAI,OAAM,IAAI,MAAM,6BAA6B;AAC9D,QAAM,EAAE,aAAa,IAAI,MAAM,QAAQ,KAAK;AAC5C,QAAM,qBAAqB,cAAc,IAAI;AAE7C,QAAM,UAAU,MAAM,MAAM,mBAAmB,MAAM,IAAI;AAAA,IACvD,QAAQ;AAAA,IACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,IAC9C,MAAM,KAAK,UAAU;AAAA,MACnB,MAAM;AAAA,MACN,MAAM,GAAG,QAAQ,MAAM;AAAA,MACvB;AAAA,MACA,UAAU;AAAA,MACV,WAAW;AAAA,MACX,WAAW,KAAK;AAAA,MAChB,KAAK;AAAA,MACL,WAAW;AAAA,IACb,CAAC;AAAA,EACH,CAAC;AAGD,MAAI,CAAC,QAAQ,GAAI,OAAM,IAAI,MAAM,gDAAgD;AACjF,QAAM,OAAO,MAAM,QAAQ,KAAK,EAAE,MAAM,MAAM,IAAI;AAClD,QAAM,UAA6B,kCAAM,YAAN,mBAAe;AAElD,SAAO,EAAE,QAAQ,SAAS,OAAO;AACnC;","names":[]}
@@ -5,6 +5,7 @@ import type maplibregl from 'maplibre-gl';
5
5
  * Higher priority is clicked first.
6
6
  */
7
7
  export declare enum MapLayerClickPriority {
8
+ SiteLayerClickPriority = 50,
8
9
  BuildingLayersClickPriority = 100,
9
10
  CommentLayersClickPriority = 200,
10
11
  MartinLayerClickPriority = 300,
@@ -1 +1 @@
1
- {"version":3,"file":"MapClickManager.d.ts","sourceRoot":"","sources":["../../../../../../../src/core/components/viewers/map/utils/MapEventManager/MapClickManager.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,UAAU,MAAM,aAAa,CAAA;AAEzC;;;;GAIG;AACH,oBAAY,qBAAqB;IAC/B,2BAA2B,MAAM;IACjC,0BAA0B,MAAM;IAChC,wBAAwB,MAAM;IAC9B,0BAA0B,MAAM;IAChC,sBAAsB,MAAM;IAC5B,qBAAqB,MAAM;IAC3B,UAAU,OAAO;CAClB;AACD,MAAM,MAAM,aAAa,GAAG,CAC1B,KAAK,EAAE,UAAU,CAAC,aAAa,EAC/B,QAAQ,EAAE,UAAU,CAAC,iBAAiB,EAAE,KACrC,IAAI,CAAA;AAQT,qBAAa,eAAe;IAC1B,OAAO,CAAC,GAAG,CAAgB;IAC3B,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,mBAAmB,CAAqC;gBAEpD,GAAG,EAAE,UAAU,CAAC,GAAG;IAOxB,QAAQ,CACb,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,qBAAqB,EAC/B,QAAQ,EAAE,aAAa;IAOlB,UAAU,CAAC,OAAO,KAAA;IAKzB,OAAO,CAAC,cAAc;IA4BtB,OAAO;CAIR"}
1
+ {"version":3,"file":"MapClickManager.d.ts","sourceRoot":"","sources":["../../../../../../../src/core/components/viewers/map/utils/MapEventManager/MapClickManager.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,UAAU,MAAM,aAAa,CAAA;AAEzC;;;;GAIG;AACH,oBAAY,qBAAqB;IAG/B,sBAAsB,KAAK;IAC3B,2BAA2B,MAAM;IACjC,0BAA0B,MAAM;IAChC,wBAAwB,MAAM;IAC9B,0BAA0B,MAAM;IAChC,sBAAsB,MAAM;IAC5B,qBAAqB,MAAM;IAC3B,UAAU,OAAO;CAClB;AACD,MAAM,MAAM,aAAa,GAAG,CAC1B,KAAK,EAAE,UAAU,CAAC,aAAa,EAC/B,QAAQ,EAAE,UAAU,CAAC,iBAAiB,EAAE,KACrC,IAAI,CAAA;AAQT,qBAAa,eAAe;IAC1B,OAAO,CAAC,GAAG,CAAgB;IAC3B,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,mBAAmB,CAAqC;gBAEpD,GAAG,EAAE,UAAU,CAAC,GAAG;IAOxB,QAAQ,CACb,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,qBAAqB,EAC/B,QAAQ,EAAE,aAAa;IAOlB,UAAU,CAAC,OAAO,KAAA;IAKzB,OAAO,CAAC,cAAc;IA4BtB,OAAO;CAIR"}
@@ -1,4 +1,5 @@
1
1
  var MapLayerClickPriority = /* @__PURE__ */ ((MapLayerClickPriority2) => {
2
+ MapLayerClickPriority2[MapLayerClickPriority2["SiteLayerClickPriority"] = 50] = "SiteLayerClickPriority";
2
3
  MapLayerClickPriority2[MapLayerClickPriority2["BuildingLayersClickPriority"] = 100] = "BuildingLayersClickPriority";
3
4
  MapLayerClickPriority2[MapLayerClickPriority2["CommentLayersClickPriority"] = 200] = "CommentLayersClickPriority";
4
5
  MapLayerClickPriority2[MapLayerClickPriority2["MartinLayerClickPriority"] = 300] = "MartinLayerClickPriority";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../src/core/components/viewers/map/utils/MapEventManager/MapClickManager.ts"],"sourcesContent":["// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\n// MapClickManager.ts\r\nimport type maplibregl from 'maplibre-gl'\r\n\r\n/**\r\n * This is very important. Declare a new priority for your layer in this enum if you need to,\r\n * otherwise, just use the one that has been declared\r\n * Higher priority is clicked first.\r\n */\r\nexport enum MapLayerClickPriority {\r\n BuildingLayersClickPriority = 100,\r\n CommentLayersClickPriority = 200,\r\n MartinLayerClickPriority = 300,\r\n OpenDataLayerClickPriority = 350,\r\n FileLayerCLickPriority = 400,\r\n BimModelLayerPriority = 600,\r\n ActiveTool = 1000, // SPECIAL ONE, MAKE SURE TO DISABLE THE TOOL WHEN YOU ARE FINISH.\r\n}\r\nexport type ClickCallback = (\r\n event: maplibregl.MapMouseEvent,\r\n features: maplibregl.MapGeoJSONFeature[],\r\n) => void\r\n\r\ninterface LayerClickHandler {\r\n layerId: string\r\n priority: number\r\n callback: ClickCallback\r\n}\r\n\r\nexport class MapClickManager {\r\n private map: maplibregl.Map // the instance of the map\r\n private clickHandlers: LayerClickHandler[] // all click handlers for layers that has been registered\r\n private boundedClickHandler: (e: maplibregl.MapMouseEvent) => {} // clickHandler has \"this\" object binded to it, so inside the handleClick private function, we can still access this.map.\r\n\r\n constructor(map: maplibregl.Map) {\r\n this.map = map\r\n this.boundedClickHandler = this.handleMapClick.bind(this)\r\n this.clickHandlers = []\r\n this.map.on('click', this.boundedClickHandler)\r\n }\r\n\r\n public register(\r\n layerId: string,\r\n priority: MapLayerClickPriority,\r\n callback: ClickCallback,\r\n ) {\r\n this.clickHandlers.push({ layerId, priority, callback })\r\n this.clickHandlers.sort((a, b) => b.priority - a.priority)\r\n // console.log(this.clickHandlers)\r\n }\r\n\r\n public unregister(layerId) {\r\n this.clickHandlers = this.clickHandlers.filter(handler => handler.layerId !== layerId)\r\n // console.log(this.clickHandlers)\r\n }\r\n\r\n private handleMapClick(e: maplibregl.MapMouseEvent) {\r\n // for active tools\r\n for (const handler of this.clickHandlers) {\r\n if (handler.priority === MapLayerClickPriority.ActiveTool) {\r\n handler.callback(e, [])\r\n console.log('call back return ')\r\n return\r\n }\r\n }\r\n\r\n // console.log(e.point)\r\n const features = this.map.queryRenderedFeatures(e.point)\r\n // console.log(features)\r\n\r\n if (!features) return\r\n\r\n for (let i = 0; i < this.clickHandlers.length; i++) {\r\n const currentHandler = this.clickHandlers[i]\r\n const hits = features.filter(f => f.layer?.id == currentHandler.layerId)\r\n\r\n if (hits.length > 0) {\r\n // console.log(currentHandler)\r\n currentHandler.callback(e, hits)\r\n break\r\n }\r\n }\r\n }\r\n\r\n destroy() {\r\n this.map.off('click', this.boundedClickHandler)\r\n this.clickHandlers = []\r\n }\r\n}\r\n"],"mappings":"AAWO,IAAK,wBAAL,kBAAKA,2BAAL;AACL,EAAAA,8CAAA,iCAA8B,OAA9B;AACA,EAAAA,8CAAA,gCAA6B,OAA7B;AACA,EAAAA,8CAAA,8BAA2B,OAA3B;AACA,EAAAA,8CAAA,gCAA6B,OAA7B;AACA,EAAAA,8CAAA,4BAAyB,OAAzB;AACA,EAAAA,8CAAA,2BAAwB,OAAxB;AACA,EAAAA,8CAAA,gBAAa,OAAb;AAPU,SAAAA;AAAA,GAAA;AAoBL,MAAM,gBAAgB;AAAA;AAAA,EAK3B,YAAY,KAAqB;AAC/B,SAAK,MAAM;AACX,SAAK,sBAAsB,KAAK,eAAe,KAAK,IAAI;AACxD,SAAK,gBAAgB,CAAC;AACtB,SAAK,IAAI,GAAG,SAAS,KAAK,mBAAmB;AAAA,EAC/C;AAAA,EAEO,SACL,SACA,UACA,UACA;AACA,SAAK,cAAc,KAAK,EAAE,SAAS,UAAU,SAAS,CAAC;AACvD,SAAK,cAAc,KAAK,CAAC,GAAG,MAAM,EAAE,WAAW,EAAE,QAAQ;AAAA,EAE3D;AAAA,EAEO,WAAW,SAAS;AACzB,SAAK,gBAAgB,KAAK,cAAc,OAAO,aAAW,QAAQ,YAAY,OAAO;AAAA,EAEvF;AAAA,EAEQ,eAAe,GAA6B;AAElD,eAAW,WAAW,KAAK,eAAe;AACxC,UAAI,QAAQ,aAAa,sBAAkC;AACzD,gBAAQ,SAAS,GAAG,CAAC,CAAC;AACtB,gBAAQ,IAAI,mBAAmB;AAC/B;AAAA,MACF;AAAA,IACF;AAGA,UAAM,WAAW,KAAK,IAAI,sBAAsB,EAAE,KAAK;AAGvD,QAAI,CAAC,SAAU;AAEf,aAAS,IAAI,GAAG,IAAI,KAAK,cAAc,QAAQ,KAAK;AAClD,YAAM,iBAAiB,KAAK,cAAc,CAAC;AAC3C,YAAM,OAAO,SAAS,OAAO,OAAE;AA5ErC;AA4EwC,wBAAE,UAAF,mBAAS,OAAM,eAAe;AAAA,OAAO;AAEvE,UAAI,KAAK,SAAS,GAAG;AAEnB,uBAAe,SAAS,GAAG,IAAI;AAC/B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,UAAU;AACR,SAAK,IAAI,IAAI,SAAS,KAAK,mBAAmB;AAC9C,SAAK,gBAAgB,CAAC;AAAA,EACxB;AACF;","names":["MapLayerClickPriority"]}
1
+ {"version":3,"sources":["../../../../../../../src/core/components/viewers/map/utils/MapEventManager/MapClickManager.ts"],"sourcesContent":["// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\n// MapClickManager.ts\r\nimport type maplibregl from 'maplibre-gl'\r\n\r\n/**\r\n * This is very important. Declare a new priority for your layer in this enum if you need to,\r\n * otherwise, just use the one that has been declared\r\n * Higher priority is clicked first.\r\n */\r\nexport enum MapLayerClickPriority {\r\n // Lowest priority: a site polygon only handles a click when no other\r\n // interactive layer (buildings, comments, sensors, files, ...) was hit.\r\n SiteLayerClickPriority = 50,\r\n BuildingLayersClickPriority = 100,\r\n CommentLayersClickPriority = 200,\r\n MartinLayerClickPriority = 300,\r\n OpenDataLayerClickPriority = 350,\r\n FileLayerCLickPriority = 400,\r\n BimModelLayerPriority = 600,\r\n ActiveTool = 1000, // SPECIAL ONE, MAKE SURE TO DISABLE THE TOOL WHEN YOU ARE FINISH.\r\n}\r\nexport type ClickCallback = (\r\n event: maplibregl.MapMouseEvent,\r\n features: maplibregl.MapGeoJSONFeature[],\r\n) => void\r\n\r\ninterface LayerClickHandler {\r\n layerId: string\r\n priority: number\r\n callback: ClickCallback\r\n}\r\n\r\nexport class MapClickManager {\r\n private map: maplibregl.Map // the instance of the map\r\n private clickHandlers: LayerClickHandler[] // all click handlers for layers that has been registered\r\n private boundedClickHandler: (e: maplibregl.MapMouseEvent) => {} // clickHandler has \"this\" object binded to it, so inside the handleClick private function, we can still access this.map.\r\n\r\n constructor(map: maplibregl.Map) {\r\n this.map = map\r\n this.boundedClickHandler = this.handleMapClick.bind(this)\r\n this.clickHandlers = []\r\n this.map.on('click', this.boundedClickHandler)\r\n }\r\n\r\n public register(\r\n layerId: string,\r\n priority: MapLayerClickPriority,\r\n callback: ClickCallback,\r\n ) {\r\n this.clickHandlers.push({ layerId, priority, callback })\r\n this.clickHandlers.sort((a, b) => b.priority - a.priority)\r\n // console.log(this.clickHandlers)\r\n }\r\n\r\n public unregister(layerId) {\r\n this.clickHandlers = this.clickHandlers.filter(handler => handler.layerId !== layerId)\r\n // console.log(this.clickHandlers)\r\n }\r\n\r\n private handleMapClick(e: maplibregl.MapMouseEvent) {\r\n // for active tools\r\n for (const handler of this.clickHandlers) {\r\n if (handler.priority === MapLayerClickPriority.ActiveTool) {\r\n handler.callback(e, [])\r\n console.log('call back return ')\r\n return\r\n }\r\n }\r\n\r\n // console.log(e.point)\r\n const features = this.map.queryRenderedFeatures(e.point)\r\n // console.log(features)\r\n\r\n if (!features) return\r\n\r\n for (let i = 0; i < this.clickHandlers.length; i++) {\r\n const currentHandler = this.clickHandlers[i]\r\n const hits = features.filter(f => f.layer?.id == currentHandler.layerId)\r\n\r\n if (hits.length > 0) {\r\n // console.log(currentHandler)\r\n currentHandler.callback(e, hits)\r\n break\r\n }\r\n }\r\n }\r\n\r\n destroy() {\r\n this.map.off('click', this.boundedClickHandler)\r\n this.clickHandlers = []\r\n }\r\n}\r\n"],"mappings":"AAWO,IAAK,wBAAL,kBAAKA,2BAAL;AAGL,EAAAA,8CAAA,4BAAyB,MAAzB;AACA,EAAAA,8CAAA,iCAA8B,OAA9B;AACA,EAAAA,8CAAA,gCAA6B,OAA7B;AACA,EAAAA,8CAAA,8BAA2B,OAA3B;AACA,EAAAA,8CAAA,gCAA6B,OAA7B;AACA,EAAAA,8CAAA,4BAAyB,OAAzB;AACA,EAAAA,8CAAA,2BAAwB,OAAxB;AACA,EAAAA,8CAAA,gBAAa,OAAb;AAVU,SAAAA;AAAA,GAAA;AAuBL,MAAM,gBAAgB;AAAA;AAAA,EAK3B,YAAY,KAAqB;AAC/B,SAAK,MAAM;AACX,SAAK,sBAAsB,KAAK,eAAe,KAAK,IAAI;AACxD,SAAK,gBAAgB,CAAC;AACtB,SAAK,IAAI,GAAG,SAAS,KAAK,mBAAmB;AAAA,EAC/C;AAAA,EAEO,SACL,SACA,UACA,UACA;AACA,SAAK,cAAc,KAAK,EAAE,SAAS,UAAU,SAAS,CAAC;AACvD,SAAK,cAAc,KAAK,CAAC,GAAG,MAAM,EAAE,WAAW,EAAE,QAAQ;AAAA,EAE3D;AAAA,EAEO,WAAW,SAAS;AACzB,SAAK,gBAAgB,KAAK,cAAc,OAAO,aAAW,QAAQ,YAAY,OAAO;AAAA,EAEvF;AAAA,EAEQ,eAAe,GAA6B;AAElD,eAAW,WAAW,KAAK,eAAe;AACxC,UAAI,QAAQ,aAAa,sBAAkC;AACzD,gBAAQ,SAAS,GAAG,CAAC,CAAC;AACtB,gBAAQ,IAAI,mBAAmB;AAC/B;AAAA,MACF;AAAA,IACF;AAGA,UAAM,WAAW,KAAK,IAAI,sBAAsB,EAAE,KAAK;AAGvD,QAAI,CAAC,SAAU;AAEf,aAAS,IAAI,GAAG,IAAI,KAAK,cAAc,QAAQ,KAAK;AAClD,YAAM,iBAAiB,KAAK,cAAc,CAAC;AAC3C,YAAM,OAAO,SAAS,OAAO,OAAE;AA/ErC;AA+EwC,wBAAE,UAAF,mBAAS,OAAM,eAAe;AAAA,OAAO;AAEvE,UAAI,KAAK,SAAS,GAAG;AAEnB,uBAAe,SAAS,GAAG,IAAI;AAC/B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,UAAU;AACR,SAAK,IAAI,IAAI,SAAS,KAAK,mBAAmB;AAC9C,SAAK,gBAAgB,CAAC;AAAA,EACxB;AACF;","names":["MapLayerClickPriority"]}
@@ -1 +1 @@
1
- {"version":3,"file":"createSiteHooks.d.ts","sourceRoot":"","sources":["../../../../src/core/hooks/sites/createSiteHooks.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAEhD,KAAK,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG;IACrC,aAAa,CAAC,EAAE;QACd,OAAO,CAAC,EAAE;YAAE,EAAE,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAC3B,UAAU,CAAC,EAAE;YAAE,EAAE,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;KAC/B,CAAC;CACH,CAAC;AAEF,wBAAgB,eAAe,CAAC,OAAO,EAAE,UAAU;;;;;;sBASxB,MAAM;;;;;;;;;;;;;;;6BAiCC,MAAM,GAAG,MAAM;yBAMf,MAAM,GAAG,MAAM;;;;;EAehD"}
1
+ {"version":3,"file":"createSiteHooks.d.ts","sourceRoot":"","sources":["../../../../src/core/hooks/sites/createSiteHooks.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAEhD,KAAK,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG;IACrC,aAAa,CAAC,EAAE;QACd,OAAO,CAAC,EAAE;YAAE,EAAE,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAC3B,UAAU,CAAC,EAAE;YAAE,EAAE,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;KAC/B,CAAC;CACH,CAAC;AAEF,wBAAgB,eAAe,CAAC,OAAO,EAAE,UAAU;;;;;;sBASxB,MAAM;;;;;;;;;;;;;;;6BAoCC,MAAM,GAAG,MAAM;yBAMf,MAAM,GAAG,MAAM;;;;;EAehD"}
@@ -16,7 +16,6 @@ function createSiteHooks(adapter) {
16
16
  onSuccess: () => {
17
17
  mutate(["site", siteId]);
18
18
  mutate(["sites"]);
19
- mutate(["buildings"]);
20
19
  }
21
20
  }
22
21
  );
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/core/hooks/sites/createSiteHooks.ts"],"sourcesContent":["// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\nimport useSWR, { mutate } from \"swr\";\r\nimport useSWRMutation from \"swr/mutation\";\r\nimport type { ApiAdapter } from \"../ports/apiAdapter\";\r\nimport type { Site } from \"../../types/dbTypes\";\r\n\r\ntype SiteUpdateInput = Partial<Site> & {\r\n siteBuildings?: {\r\n connect?: { id: number }[];\r\n disconnect?: { id: number }[];\r\n };\r\n};\r\n\r\nexport function createSiteHooks(adapter: ApiAdapter) {\r\n // Call adapter methods inside hooks\r\n \r\n const useSites = () => {\r\n const key = [\"sites\"];\r\n const { data, error, isLoading } = useSWR<Site[]>(key, () => adapter.listSites());\r\n return { sites: data ?? [], isLoading, isError: error };\r\n };\r\n\r\n const useSite = (siteId: string) => {\r\n const key = siteId ? ([\"site\", siteId] as const) : null;\r\n const { data, error, isLoading } = useSWR<Site>(key, () => adapter.getSite(siteId));\r\n\r\n const { trigger: updateSite, isMutating, data: updatedData, error: updateError } = useSWRMutation(\r\n siteId ? [\"updateSite\", siteId] : null,\r\n async (_k, { arg }: { arg: SiteUpdateInput }) => adapter.updateSite(siteId, arg),\r\n {\r\n onSuccess: () => {\r\n mutate([\"site\", siteId]);\r\n mutate([\"sites\"]);\r\n mutate([\"buildings\"]); // Revalidate buildings in case any were associated with the site and changed \r\n },\r\n }\r\n );\r\n\r\n return { site: data ?? null, isLoading, isError: error, updateSite, isMutating, updateError, updatedData };\r\n };\r\n\r\n const useCreateSite = () => {\r\n const { trigger: createSite, isMutating, data: createdData, error } = useSWRMutation(\r\n [\"createSite\"],\r\n async (_k, { arg }: { arg: Partial<Site> }) => adapter.createSite(arg),\r\n {\r\n onSuccess: () => {\r\n mutate([\"sites\"]);\r\n },\r\n }\r\n );\r\n\r\n return { createSite, isMutating, createError: error, createdData };\r\n };\r\n\r\n const useDeleteSite = (siteId?: number | string) => {\r\n const { trigger, isMutating, data, error } = useSWRMutation(\r\n siteId ? [\"deleteSite\", String(siteId)] : [\"deleteSite\"],\r\n async (_k, { arg }: { arg: string | number }) => adapter.deleteSite(arg)\r\n );\r\n\r\n const deleteSite = async (id: string | number) => {\r\n await trigger(id);\r\n mutate([\"sites\"]);\r\n mutate([\"buildings\"]) // Revalidate buildings in case any were associated with the deleted site\r\n };\r\n\r\n return { deleteSite, isMutating, deleteError: error, deletedData: data };\r\n };\r\n\r\n return { \r\n useSites, \r\n useSite, \r\n useCreateSite, \r\n useDeleteSite \r\n };\r\n}\r\n"],"mappings":"AAGA,OAAO,UAAU,cAAc;AAC/B,OAAO,oBAAoB;AAWpB,SAAS,gBAAgB,SAAqB;AAGnD,QAAM,WAAW,MAAM;AACrB,UAAM,MAAM,CAAC,OAAO;AACpB,UAAM,EAAE,MAAM,OAAO,UAAU,IAAI,OAAe,KAAK,MAAM,QAAQ,UAAU,CAAC;AAChF,WAAO,EAAE,OAAO,sBAAQ,CAAC,GAAG,WAAW,SAAS,MAAM;AAAA,EACxD;AAEA,QAAM,UAAU,CAAC,WAAmB;AAClC,UAAM,MAAM,SAAU,CAAC,QAAQ,MAAM,IAAc;AACnD,UAAM,EAAE,MAAM,OAAO,UAAU,IAAI,OAAa,KAAK,MAAM,QAAQ,QAAQ,MAAM,CAAC;AAElF,UAAM,EAAE,SAAS,YAAY,YAAY,MAAM,aAAa,OAAO,YAAY,IAAI;AAAA,MACjF,SAAS,CAAC,cAAc,MAAM,IAAI;AAAA,MAClC,OAAO,IAAI,EAAE,IAAI,MAAgC,QAAQ,WAAW,QAAQ,GAAG;AAAA,MAC/E;AAAA,QACE,WAAW,MAAM;AACf,iBAAO,CAAC,QAAQ,MAAM,CAAC;AACvB,iBAAO,CAAC,OAAO,CAAC;AAChB,iBAAO,CAAC,WAAW,CAAC;AAAA,QACtB;AAAA,MACF;AAAA,IACF;AAEA,WAAO,EAAE,MAAM,sBAAQ,MAAM,WAAW,SAAS,OAAO,YAAY,YAAY,aAAa,YAAY;AAAA,EAC3G;AAEA,QAAM,gBAAgB,MAAM;AAC1B,UAAM,EAAE,SAAS,YAAY,YAAY,MAAM,aAAa,MAAM,IAAI;AAAA,MACpE,CAAC,YAAY;AAAA,MACb,OAAO,IAAI,EAAE,IAAI,MAA8B,QAAQ,WAAW,GAAG;AAAA,MACrE;AAAA,QACE,WAAW,MAAM;AACf,iBAAO,CAAC,OAAO,CAAC;AAAA,QAClB;AAAA,MACF;AAAA,IACF;AAEA,WAAO,EAAE,YAAY,YAAY,aAAa,OAAO,YAAY;AAAA,EACnE;AAEA,QAAM,gBAAgB,CAAC,WAA6B;AAClD,UAAM,EAAE,SAAS,YAAY,MAAM,MAAM,IAAI;AAAA,MAC3C,SAAS,CAAC,cAAc,OAAO,MAAM,CAAC,IAAI,CAAC,YAAY;AAAA,MACvD,OAAO,IAAI,EAAE,IAAI,MAAgC,QAAQ,WAAW,GAAG;AAAA,IACzE;AAEA,UAAM,aAAa,OAAO,OAAwB;AAChD,YAAM,QAAQ,EAAE;AAChB,aAAO,CAAC,OAAO,CAAC;AAChB,aAAO,CAAC,WAAW,CAAC;AAAA,IACtB;AAEA,WAAO,EAAE,YAAY,YAAY,aAAa,OAAO,aAAa,KAAK;AAAA,EACzE;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../../src/core/hooks/sites/createSiteHooks.ts"],"sourcesContent":["// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\nimport useSWR, { mutate } from \"swr\";\r\nimport useSWRMutation from \"swr/mutation\";\r\nimport type { ApiAdapter } from \"../ports/apiAdapter\";\r\nimport type { Site } from \"../../types/dbTypes\";\r\n\r\ntype SiteUpdateInput = Partial<Site> & {\r\n siteBuildings?: {\r\n connect?: { id: number }[];\r\n disconnect?: { id: number }[];\r\n };\r\n};\r\n\r\nexport function createSiteHooks(adapter: ApiAdapter) {\r\n // Call adapter methods inside hooks\r\n \r\n const useSites = () => {\r\n const key = [\"sites\"];\r\n const { data, error, isLoading } = useSWR<Site[]>(key, () => adapter.listSites());\r\n return { sites: data ?? [], isLoading, isError: error };\r\n };\r\n\r\n const useSite = (siteId: string) => {\r\n const key = siteId ? ([\"site\", siteId] as const) : null;\r\n const { data, error, isLoading } = useSWR<Site>(key, () => adapter.getSite(siteId));\r\n\r\n const { trigger: updateSite, isMutating, data: updatedData, error: updateError } = useSWRMutation(\r\n siteId ? [\"updateSite\", siteId] : null,\r\n async (_k, { arg }: { arg: SiteUpdateInput }) => adapter.updateSite(siteId, arg),\r\n {\r\n onSuccess: () => {\r\n mutate([\"site\", siteId]);\r\n mutate([\"sites\"]);\r\n // NOTE: intentionally not revalidating [\"buildings\"] associating a\r\n // building to a site doesn't change the buildings list's displayed\r\n // data, and revalidating it re-renders the always-mounted map's\r\n // building layer (a heavy, jank-inducing churn after bulk associate).\r\n },\r\n }\r\n );\r\n\r\n return { site: data ?? null, isLoading, isError: error, updateSite, isMutating, updateError, updatedData };\r\n };\r\n\r\n const useCreateSite = () => {\r\n const { trigger: createSite, isMutating, data: createdData, error } = useSWRMutation(\r\n [\"createSite\"],\r\n async (_k, { arg }: { arg: Partial<Site> }) => adapter.createSite(arg),\r\n {\r\n onSuccess: () => {\r\n mutate([\"sites\"]);\r\n },\r\n }\r\n );\r\n\r\n return { createSite, isMutating, createError: error, createdData };\r\n };\r\n\r\n const useDeleteSite = (siteId?: number | string) => {\r\n const { trigger, isMutating, data, error } = useSWRMutation(\r\n siteId ? [\"deleteSite\", String(siteId)] : [\"deleteSite\"],\r\n async (_k, { arg }: { arg: string | number }) => adapter.deleteSite(arg)\r\n );\r\n\r\n const deleteSite = async (id: string | number) => {\r\n await trigger(id);\r\n mutate([\"sites\"]);\r\n mutate([\"buildings\"]) // Revalidate buildings in case any were associated with the deleted site\r\n };\r\n\r\n return { deleteSite, isMutating, deleteError: error, deletedData: data };\r\n };\r\n\r\n return { \r\n useSites, \r\n useSite, \r\n useCreateSite, \r\n useDeleteSite \r\n };\r\n}\r\n"],"mappings":"AAGA,OAAO,UAAU,cAAc;AAC/B,OAAO,oBAAoB;AAWpB,SAAS,gBAAgB,SAAqB;AAGnD,QAAM,WAAW,MAAM;AACrB,UAAM,MAAM,CAAC,OAAO;AACpB,UAAM,EAAE,MAAM,OAAO,UAAU,IAAI,OAAe,KAAK,MAAM,QAAQ,UAAU,CAAC;AAChF,WAAO,EAAE,OAAO,sBAAQ,CAAC,GAAG,WAAW,SAAS,MAAM;AAAA,EACxD;AAEA,QAAM,UAAU,CAAC,WAAmB;AAClC,UAAM,MAAM,SAAU,CAAC,QAAQ,MAAM,IAAc;AACnD,UAAM,EAAE,MAAM,OAAO,UAAU,IAAI,OAAa,KAAK,MAAM,QAAQ,QAAQ,MAAM,CAAC;AAElF,UAAM,EAAE,SAAS,YAAY,YAAY,MAAM,aAAa,OAAO,YAAY,IAAI;AAAA,MACjF,SAAS,CAAC,cAAc,MAAM,IAAI;AAAA,MAClC,OAAO,IAAI,EAAE,IAAI,MAAgC,QAAQ,WAAW,QAAQ,GAAG;AAAA,MAC/E;AAAA,QACE,WAAW,MAAM;AACf,iBAAO,CAAC,QAAQ,MAAM,CAAC;AACvB,iBAAO,CAAC,OAAO,CAAC;AAAA,QAKlB;AAAA,MACF;AAAA,IACF;AAEA,WAAO,EAAE,MAAM,sBAAQ,MAAM,WAAW,SAAS,OAAO,YAAY,YAAY,aAAa,YAAY;AAAA,EAC3G;AAEA,QAAM,gBAAgB,MAAM;AAC1B,UAAM,EAAE,SAAS,YAAY,YAAY,MAAM,aAAa,MAAM,IAAI;AAAA,MACpE,CAAC,YAAY;AAAA,MACb,OAAO,IAAI,EAAE,IAAI,MAA8B,QAAQ,WAAW,GAAG;AAAA,MACrE;AAAA,QACE,WAAW,MAAM;AACf,iBAAO,CAAC,OAAO,CAAC;AAAA,QAClB;AAAA,MACF;AAAA,IACF;AAEA,WAAO,EAAE,YAAY,YAAY,aAAa,OAAO,YAAY;AAAA,EACnE;AAEA,QAAM,gBAAgB,CAAC,WAA6B;AAClD,UAAM,EAAE,SAAS,YAAY,MAAM,MAAM,IAAI;AAAA,MAC3C,SAAS,CAAC,cAAc,OAAO,MAAM,CAAC,IAAI,CAAC,YAAY;AAAA,MACvD,OAAO,IAAI,EAAE,IAAI,MAAgC,QAAQ,WAAW,GAAG;AAAA,IACzE;AAEA,UAAM,aAAa,OAAO,OAAwB;AAChD,YAAM,QAAQ,EAAE;AAChB,aAAO,CAAC,OAAO,CAAC;AAChB,aAAO,CAAC,WAAW,CAAC;AAAA,IACtB;AAEA,WAAO,EAAE,YAAY,YAAY,aAAa,OAAO,aAAa,KAAK;AAAA,EACzE;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"useCaptureScreenshot.d.ts","sourceRoot":"","sources":["../../../src/core/hooks/useCaptureScreenshot.ts"],"names":[],"mappings":"AAcA,wBAAgB,oBAAoB,IAAI,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAkDnE"}
1
+ {"version":3,"file":"useCaptureScreenshot.d.ts","sourceRoot":"","sources":["../../../src/core/hooks/useCaptureScreenshot.ts"],"names":[],"mappings":"AAuBA,wBAAgB,oBAAoB,IAAI,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAyFnE"}
@@ -9,6 +9,14 @@ function blobToBase64(blob) {
9
9
  reader.readAsDataURL(blob);
10
10
  });
11
11
  }
12
+ function loadImage(src) {
13
+ return new Promise((resolve, reject) => {
14
+ const img = new Image();
15
+ img.onload = () => resolve(img);
16
+ img.onerror = reject;
17
+ img.src = src;
18
+ });
19
+ }
12
20
  function useCaptureScreenshot() {
13
21
  const { state: menusState } = React.useContext(MenusContext);
14
22
  const { currentViewer } = menusState.menus;
@@ -17,44 +25,83 @@ function useCaptureScreenshot() {
17
25
  const { state: bimState } = React.useContext(BimContext);
18
26
  const { world } = bimState.bim;
19
27
  return React.useCallback(() => {
20
- return new Promise((resolve) => {
21
- try {
22
- if (currentViewer === ViewerNames.map && map) {
28
+ const capture = async () => {
29
+ let viewerDataUrl = null;
30
+ let viewerBounds = null;
31
+ let viewerCanvasElement = null;
32
+ if (currentViewer === ViewerNames.map && map) {
33
+ await new Promise((res) => {
23
34
  map.once("render", () => {
24
- map.getCanvas().toBlob(async (blob) => {
25
- resolve(blob ? await blobToBase64(blob) : null);
26
- }, "image/png", 1);
35
+ const canvas = map.getCanvas();
36
+ viewerCanvasElement = canvas;
37
+ viewerBounds = canvas.getBoundingClientRect();
38
+ try {
39
+ viewerDataUrl = canvas.toDataURL("image/png");
40
+ } catch (e) {
41
+ }
42
+ res();
27
43
  });
28
44
  map.triggerRepaint();
29
- return;
30
- }
31
- if (currentViewer === ViewerNames.bim && (world == null ? void 0 : world.renderer) && (world == null ? void 0 : world.scene) && (world == null ? void 0 : world.camera)) {
32
- world.renderer.three.render(world.scene.three, world.camera.three);
33
- const canvas2 = document.querySelector("#bim-viewer-container canvas");
34
- if (canvas2) {
35
- canvas2.toBlob(async (blob) => {
36
- resolve(blob ? await blobToBase64(blob) : null);
37
- }, "image/png", 1);
38
- return;
45
+ });
46
+ } else if (currentViewer === ViewerNames.bim && (world == null ? void 0 : world.renderer) && (world == null ? void 0 : world.scene) && (world == null ? void 0 : world.camera)) {
47
+ world.renderer.three.render(world.scene.three, world.camera.three);
48
+ const canvas = document.querySelector("#bim-viewer-container canvas");
49
+ if (canvas) {
50
+ viewerCanvasElement = canvas;
51
+ viewerBounds = canvas.getBoundingClientRect();
52
+ try {
53
+ viewerDataUrl = canvas.toDataURL("image/png");
54
+ } catch (e) {
39
55
  }
40
56
  }
41
- let canvas = null;
42
- if (currentViewer === ViewerNames.pointcloud) {
43
- canvas = document.querySelector("#pointcloud-viewer-container canvas");
44
- } else {
45
- canvas = document.querySelector("canvas");
57
+ } else {
58
+ const canvas = currentViewer === ViewerNames.pointcloud ? document.querySelector("#pointcloud-viewer-container canvas") : document.querySelector("canvas");
59
+ if (canvas) {
60
+ viewerCanvasElement = canvas;
61
+ viewerBounds = canvas.getBoundingClientRect();
62
+ try {
63
+ viewerDataUrl = canvas.toDataURL("image/png");
64
+ } catch (e) {
65
+ }
46
66
  }
47
- if (!canvas) {
48
- resolve(null);
49
- return;
67
+ }
68
+ const { default: html2canvas } = await import("html2canvas");
69
+ const uiCanvas = await html2canvas(document.body, {
70
+ useCORS: true,
71
+ allowTaint: false,
72
+ logging: false,
73
+ removeContainer: true,
74
+ scale: window.devicePixelRatio || 1,
75
+ ignoreElements: (el) => el === viewerCanvasElement
76
+ });
77
+ if (viewerDataUrl && viewerBounds) {
78
+ const ctx = uiCanvas.getContext("2d");
79
+ if (ctx) {
80
+ try {
81
+ const img = await loadImage(viewerDataUrl);
82
+ const dpr = window.devicePixelRatio || 1;
83
+ ctx.drawImage(
84
+ img,
85
+ viewerBounds.left * dpr,
86
+ viewerBounds.top * dpr,
87
+ viewerBounds.width * dpr,
88
+ viewerBounds.height * dpr
89
+ );
90
+ } catch (e) {
91
+ }
50
92
  }
51
- canvas.toBlob(async (blob) => {
52
- resolve(blob ? await blobToBase64(blob) : null);
53
- }, "image/png", 1);
54
- } catch (e) {
55
- resolve(null);
56
93
  }
57
- });
94
+ return new Promise((resolve) => {
95
+ uiCanvas.toBlob((blob) => {
96
+ if (!blob) {
97
+ resolve(null);
98
+ return;
99
+ }
100
+ blobToBase64(blob).then(resolve);
101
+ }, "image/png", 1);
102
+ });
103
+ };
104
+ return capture().catch(() => null);
58
105
  }, [currentViewer, map, world]);
59
106
  }
60
107
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/hooks/useCaptureScreenshot.ts"],"sourcesContent":["'use client'\r\n\r\nimport * as React from 'react'\r\nimport { MenusContext, MapContext, BimContext } from '../store'\r\nimport { ViewerNames } from '../types'\r\n\r\nfunction blobToBase64(blob: Blob): Promise<string> {\r\n return new Promise((resolve) => {\r\n const reader = new FileReader()\r\n reader.onload = () => resolve(reader.result as string)\r\n reader.readAsDataURL(blob)\r\n })\r\n}\r\n\r\nexport function useCaptureScreenshot(): () => Promise<string | null> {\r\n const { state: menusState } = React.useContext(MenusContext)\r\n const { currentViewer } = menusState.menus\r\n\r\n const { state: mapState } = React.useContext(MapContext)\r\n const { map } = mapState.map\r\n\r\n const { state: bimState } = React.useContext(BimContext)\r\n const { world } = bimState.bim\r\n\r\n return React.useCallback((): Promise<string | null> => {\r\n return new Promise((resolve) => {\r\n try {\r\n if (currentViewer === ViewerNames.map && map) {\r\n map.once('render', () => {\r\n map.getCanvas().toBlob(async (blob: Blob | null) => {\r\n resolve(blob ? await blobToBase64(blob) : null)\r\n }, 'image/png', 1.0)\r\n })\r\n map.triggerRepaint()\r\n return\r\n }\r\n\r\n if (currentViewer === ViewerNames.bim && world?.renderer && world?.scene && world?.camera) {\r\n world.renderer.three.render(world.scene.three, world.camera.three)\r\n const canvas = document.querySelector<HTMLCanvasElement>('#bim-viewer-container canvas')\r\n if (canvas) {\r\n canvas.toBlob(async (blob: Blob | null) => {\r\n resolve(blob ? await blobToBase64(blob) : null)\r\n }, 'image/png', 1.0)\r\n return\r\n }\r\n }\r\n\r\n let canvas: HTMLCanvasElement | null = null\r\n if (currentViewer === ViewerNames.pointcloud) {\r\n canvas = document.querySelector<HTMLCanvasElement>('#pointcloud-viewer-container canvas')\r\n } else {\r\n canvas = document.querySelector<HTMLCanvasElement>('canvas')\r\n }\r\n\r\n if (!canvas) { resolve(null); return }\r\n canvas.toBlob(async (blob: Blob | null) => {\r\n resolve(blob ? await blobToBase64(blob) : null)\r\n }, 'image/png', 1.0)\r\n } catch {\r\n resolve(null)\r\n }\r\n })\r\n }, [currentViewer, map, world])\r\n}\r\n"],"mappings":";AAEA,YAAY,WAAW;AACvB,SAAS,cAAc,YAAY,kBAAkB;AACrD,SAAS,mBAAmB;AAE5B,SAAS,aAAa,MAA6B;AACjD,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAM,SAAS,IAAI,WAAW;AAC9B,WAAO,SAAS,MAAM,QAAQ,OAAO,MAAgB;AACrD,WAAO,cAAc,IAAI;AAAA,EAC3B,CAAC;AACH;AAEO,SAAS,uBAAqD;AACnE,QAAM,EAAE,OAAO,WAAW,IAAI,MAAM,WAAW,YAAY;AAC3D,QAAM,EAAE,cAAc,IAAI,WAAW;AAErC,QAAM,EAAE,OAAO,SAAS,IAAI,MAAM,WAAW,UAAU;AACvD,QAAM,EAAE,IAAI,IAAI,SAAS;AAEzB,QAAM,EAAE,OAAO,SAAS,IAAI,MAAM,WAAW,UAAU;AACvD,QAAM,EAAE,MAAM,IAAI,SAAS;AAE3B,SAAO,MAAM,YAAY,MAA8B;AACrD,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAI;AACF,YAAI,kBAAkB,YAAY,OAAO,KAAK;AAC5C,cAAI,KAAK,UAAU,MAAM;AACvB,gBAAI,UAAU,EAAE,OAAO,OAAO,SAAsB;AAClD,sBAAQ,OAAO,MAAM,aAAa,IAAI,IAAI,IAAI;AAAA,YAChD,GAAG,aAAa,CAAG;AAAA,UACrB,CAAC;AACD,cAAI,eAAe;AACnB;AAAA,QACF;AAEA,YAAI,kBAAkB,YAAY,QAAO,+BAAO,cAAY,+BAAO,WAAS,+BAAO,SAAQ;AACzF,gBAAM,SAAS,MAAM,OAAO,MAAM,MAAM,OAAO,MAAM,OAAO,KAAK;AACjE,gBAAMA,UAAS,SAAS,cAAiC,8BAA8B;AACvF,cAAIA,SAAQ;AACV,YAAAA,QAAO,OAAO,OAAO,SAAsB;AACzC,sBAAQ,OAAO,MAAM,aAAa,IAAI,IAAI,IAAI;AAAA,YAChD,GAAG,aAAa,CAAG;AACnB;AAAA,UACF;AAAA,QACF;AAEA,YAAI,SAAmC;AACvC,YAAI,kBAAkB,YAAY,YAAY;AAC5C,mBAAS,SAAS,cAAiC,qCAAqC;AAAA,QAC1F,OAAO;AACL,mBAAS,SAAS,cAAiC,QAAQ;AAAA,QAC7D;AAEA,YAAI,CAAC,QAAQ;AAAE,kBAAQ,IAAI;AAAG;AAAA,QAAO;AACrC,eAAO,OAAO,OAAO,SAAsB;AACzC,kBAAQ,OAAO,MAAM,aAAa,IAAI,IAAI,IAAI;AAAA,QAChD,GAAG,aAAa,CAAG;AAAA,MACrB,SAAQ;AACN,gBAAQ,IAAI;AAAA,MACd;AAAA,IACF,CAAC;AAAA,EACH,GAAG,CAAC,eAAe,KAAK,KAAK,CAAC;AAChC;","names":["canvas"]}
1
+ {"version":3,"sources":["../../../src/core/hooks/useCaptureScreenshot.ts"],"sourcesContent":["'use client'\r\n\r\nimport * as React from 'react'\r\nimport { MenusContext, MapContext, BimContext } from '../store'\r\nimport { ViewerNames } from '../types'\r\n\r\nfunction blobToBase64(blob: Blob): Promise<string> {\r\n return new Promise((resolve) => {\r\n const reader = new FileReader()\r\n reader.onload = () => resolve(reader.result as string)\r\n reader.readAsDataURL(blob)\r\n })\r\n}\r\n\r\nfunction loadImage(src: string): Promise<HTMLImageElement> {\r\n return new Promise((resolve, reject) => {\r\n const img = new Image()\r\n img.onload = () => resolve(img)\r\n img.onerror = reject\r\n img.src = src\r\n })\r\n}\r\n\r\nexport function useCaptureScreenshot(): () => Promise<string | null> {\r\n const { state: menusState } = React.useContext(MenusContext)\r\n const { currentViewer } = menusState.menus\r\n\r\n const { state: mapState } = React.useContext(MapContext)\r\n const { map } = mapState.map\r\n\r\n const { state: bimState } = React.useContext(BimContext)\r\n const { world } = bimState.bim\r\n\r\n return React.useCallback((): Promise<string | null> => {\r\n const capture = async (): Promise<string | null> => {\r\n let viewerDataUrl: string | null = null\r\n let viewerBounds: DOMRect | null = null\r\n let viewerCanvasElement: HTMLCanvasElement | null = null\r\n\r\n // WebGL canvases clear their back-buffer after each frame, so we must\r\n // read them synchronously at the exact moment they have valid content —\r\n // before yielding to the event loop for html2canvas.\r\n if (currentViewer === ViewerNames.map && map) {\r\n await new Promise<void>((res) => {\r\n map.once('render', () => {\r\n const canvas = map.getCanvas()\r\n viewerCanvasElement = canvas\r\n viewerBounds = canvas.getBoundingClientRect()\r\n try { viewerDataUrl = canvas.toDataURL('image/png') } catch { /* cross-origin taint */ }\r\n res()\r\n })\r\n map.triggerRepaint()\r\n })\r\n } else if (currentViewer === ViewerNames.bim && world?.renderer && world?.scene && world?.camera) {\r\n world.renderer.three.render(world.scene.three, world.camera.three)\r\n const canvas = document.querySelector<HTMLCanvasElement>('#bim-viewer-container canvas')\r\n if (canvas) {\r\n viewerCanvasElement = canvas\r\n viewerBounds = canvas.getBoundingClientRect()\r\n try { viewerDataUrl = canvas.toDataURL('image/png') } catch { /* ignore */ }\r\n }\r\n } else {\r\n const canvas = currentViewer === ViewerNames.pointcloud\r\n ? document.querySelector<HTMLCanvasElement>('#pointcloud-viewer-container canvas')\r\n : document.querySelector<HTMLCanvasElement>('canvas')\r\n if (canvas) {\r\n viewerCanvasElement = canvas\r\n viewerBounds = canvas.getBoundingClientRect()\r\n try { viewerDataUrl = canvas.toDataURL('image/png') } catch { /* ignore */ }\r\n }\r\n }\r\n\r\n // Capture the full DOM — sidebar, toolbar, all UI panels — but skip the\r\n // viewer canvas (we have its pixels already; html2canvas can't read WebGL).\r\n const { default: html2canvas } = await import('html2canvas')\r\n const uiCanvas = await html2canvas(document.body, {\r\n useCORS: true,\r\n allowTaint: false,\r\n logging: false,\r\n removeContainer: true,\r\n scale: window.devicePixelRatio || 1,\r\n ignoreElements: (el) => el === viewerCanvasElement,\r\n })\r\n\r\n // Draw the pre-captured viewer image into the blank region.\r\n if (viewerDataUrl && viewerBounds) {\r\n const ctx = uiCanvas.getContext('2d')\r\n if (ctx) {\r\n try {\r\n const img = await loadImage(viewerDataUrl)\r\n const dpr = window.devicePixelRatio || 1\r\n ctx.drawImage(\r\n img,\r\n viewerBounds.left * dpr,\r\n viewerBounds.top * dpr,\r\n viewerBounds.width * dpr,\r\n viewerBounds.height * dpr,\r\n )\r\n } catch { /* skip compositing on error */ }\r\n }\r\n }\r\n\r\n return new Promise<string | null>((resolve) => {\r\n uiCanvas.toBlob((blob) => {\r\n if (!blob) { resolve(null); return }\r\n blobToBase64(blob).then(resolve)\r\n }, 'image/png', 1.0)\r\n })\r\n }\r\n\r\n return capture().catch(() => null)\r\n }, [currentViewer, map, world])\r\n}\r\n"],"mappings":";AAEA,YAAY,WAAW;AACvB,SAAS,cAAc,YAAY,kBAAkB;AACrD,SAAS,mBAAmB;AAE5B,SAAS,aAAa,MAA6B;AACjD,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAM,SAAS,IAAI,WAAW;AAC9B,WAAO,SAAS,MAAM,QAAQ,OAAO,MAAgB;AACrD,WAAO,cAAc,IAAI;AAAA,EAC3B,CAAC;AACH;AAEA,SAAS,UAAU,KAAwC;AACzD,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,MAAM,IAAI,MAAM;AACtB,QAAI,SAAS,MAAM,QAAQ,GAAG;AAC9B,QAAI,UAAU;AACd,QAAI,MAAM;AAAA,EACZ,CAAC;AACH;AAEO,SAAS,uBAAqD;AACnE,QAAM,EAAE,OAAO,WAAW,IAAI,MAAM,WAAW,YAAY;AAC3D,QAAM,EAAE,cAAc,IAAI,WAAW;AAErC,QAAM,EAAE,OAAO,SAAS,IAAI,MAAM,WAAW,UAAU;AACvD,QAAM,EAAE,IAAI,IAAI,SAAS;AAEzB,QAAM,EAAE,OAAO,SAAS,IAAI,MAAM,WAAW,UAAU;AACvD,QAAM,EAAE,MAAM,IAAI,SAAS;AAE3B,SAAO,MAAM,YAAY,MAA8B;AACrD,UAAM,UAAU,YAAoC;AAClD,UAAI,gBAA+B;AACnC,UAAI,eAA+B;AACnC,UAAI,sBAAgD;AAKpD,UAAI,kBAAkB,YAAY,OAAO,KAAK;AAC5C,cAAM,IAAI,QAAc,CAAC,QAAQ;AAC/B,cAAI,KAAK,UAAU,MAAM;AACvB,kBAAM,SAAS,IAAI,UAAU;AAC7B,kCAAsB;AACtB,2BAAe,OAAO,sBAAsB;AAC5C,gBAAI;AAAE,8BAAgB,OAAO,UAAU,WAAW;AAAA,YAAE,SAAQ;AAAA,YAA2B;AACvF,gBAAI;AAAA,UACN,CAAC;AACD,cAAI,eAAe;AAAA,QACrB,CAAC;AAAA,MACH,WAAW,kBAAkB,YAAY,QAAO,+BAAO,cAAY,+BAAO,WAAS,+BAAO,SAAQ;AAChG,cAAM,SAAS,MAAM,OAAO,MAAM,MAAM,OAAO,MAAM,OAAO,KAAK;AACjE,cAAM,SAAS,SAAS,cAAiC,8BAA8B;AACvF,YAAI,QAAQ;AACV,gCAAsB;AACtB,yBAAe,OAAO,sBAAsB;AAC5C,cAAI;AAAE,4BAAgB,OAAO,UAAU,WAAW;AAAA,UAAE,SAAQ;AAAA,UAAe;AAAA,QAC7E;AAAA,MACF,OAAO;AACL,cAAM,SAAS,kBAAkB,YAAY,aACzC,SAAS,cAAiC,qCAAqC,IAC/E,SAAS,cAAiC,QAAQ;AACtD,YAAI,QAAQ;AACV,gCAAsB;AACtB,yBAAe,OAAO,sBAAsB;AAC5C,cAAI;AAAE,4BAAgB,OAAO,UAAU,WAAW;AAAA,UAAE,SAAQ;AAAA,UAAe;AAAA,QAC7E;AAAA,MACF;AAIA,YAAM,EAAE,SAAS,YAAY,IAAI,MAAM,OAAO,aAAa;AAC3D,YAAM,WAAW,MAAM,YAAY,SAAS,MAAM;AAAA,QAChD,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,SAAS;AAAA,QACT,iBAAiB;AAAA,QACjB,OAAO,OAAO,oBAAoB;AAAA,QAClC,gBAAgB,CAAC,OAAO,OAAO;AAAA,MACjC,CAAC;AAGD,UAAI,iBAAiB,cAAc;AACjC,cAAM,MAAM,SAAS,WAAW,IAAI;AACpC,YAAI,KAAK;AACP,cAAI;AACF,kBAAM,MAAM,MAAM,UAAU,aAAa;AACzC,kBAAM,MAAM,OAAO,oBAAoB;AACvC,gBAAI;AAAA,cACF;AAAA,cACA,aAAa,OAAO;AAAA,cACpB,aAAa,MAAM;AAAA,cACnB,aAAa,QAAQ;AAAA,cACrB,aAAa,SAAS;AAAA,YACxB;AAAA,UACF,SAAQ;AAAA,UAAkC;AAAA,QAC5C;AAAA,MACF;AAEA,aAAO,IAAI,QAAuB,CAAC,YAAY;AAC7C,iBAAS,OAAO,CAAC,SAAS;AACxB,cAAI,CAAC,MAAM;AAAE,oBAAQ,IAAI;AAAG;AAAA,UAAO;AACnC,uBAAa,IAAI,EAAE,KAAK,OAAO;AAAA,QACjC,GAAG,aAAa,CAAG;AAAA,MACrB,CAAC;AAAA,IACH;AAEA,WAAO,QAAQ,EAAE,MAAM,MAAM,IAAI;AAAA,EACnC,GAAG,CAAC,eAAe,KAAK,KAAK,CAAC;AAChC;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"CombineProviders.d.ts","sourceRoot":"","sources":["../../../src/core/store/CombineProviders.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAqB,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAuC3E,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,aAAa,EAAE,EAAE;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAAC,aAAa,CAAC,EAAE,aAAa,CAAA;CAAE,qBAQpH"}
1
+ {"version":3,"file":"CombineProviders.d.ts","sourceRoot":"","sources":["../../../src/core/store/CombineProviders.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAqB,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAyC3E,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,aAAa,EAAE,EAAE;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAAC,aAAa,CAAC,EAAE,aAAa,CAAA;CAAE,qBAQpH"}
@@ -9,6 +9,7 @@ import { ToolsProvider } from "./Tools/context";
9
9
  import { FilesProvider } from "./Files/context";
10
10
  import { BuildingsProvider } from "./Buildings/context";
11
11
  import { DatasetsProvider } from "./Datasets/context";
12
+ import { MapSitesProvider } from "./MapSites/context";
12
13
  import { PointCloudProvider } from "./PointCloud/context";
13
14
  import { PermissionsProvider } from "./Permissions/context";
14
15
  import { PluginHostProvider } from "../plugins/host/provider";
@@ -24,6 +25,7 @@ const InnerProviders = compose([
24
25
  ToolsProvider,
25
26
  ContentProvider,
26
27
  DatasetsProvider,
28
+ MapSitesProvider,
27
29
  FilesProvider,
28
30
  BuildingsProvider,
29
31
  PointCloudProvider,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/store/CombineProviders.tsx"],"sourcesContent":["'use client'\r\n\r\n// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\nimport * as React from 'react'\r\nimport { AppConfigProvider, type RuntimeConfig } from './AppConfig/context'\r\nimport { BimProvider } from './BIM/context'\r\nimport { ContentProvider } from './Content/context'\r\nimport { MapProvider } from './Map/context'\r\nimport { MenusProvider } from './Menus/context'\r\nimport { ToolsProvider } from './Tools/context'\r\nimport { FilesProvider } from './Files/context'\r\nimport { BuildingsProvider } from './Buildings/context'\r\nimport { DatasetsProvider } from './Datasets/context'\r\nimport { PointCloudProvider } from './PointCloud/context'\r\nimport { PermissionsProvider } from './Permissions/context'\r\nimport { PluginHostProvider } from '../plugins/host/provider'\r\n\r\nconst compose = providers =>\r\n providers.reduce(\r\n (Prev, Curr) =>\r\n function ComposedProvider({ children }) {\r\n return (\r\n <Prev>\r\n <Curr>{children}</Curr>\r\n </Prev>\r\n )\r\n },\r\n )\r\n\r\nconst InnerProviders = compose([\r\n BimProvider,\r\n MapProvider,\r\n MenusProvider,\r\n ToolsProvider,\r\n ContentProvider,\r\n DatasetsProvider,\r\n FilesProvider,\r\n BuildingsProvider,\r\n PointCloudProvider,\r\n PermissionsProvider,\r\n PluginHostProvider,\r\n])\r\n\r\nexport function AppProvider({ children, runtimeConfig }: { children: React.ReactNode, runtimeConfig?: RuntimeConfig }) {\r\n return (\r\n <AppConfigProvider runtimeConfig={runtimeConfig}>\r\n <InnerProviders>\r\n {children}\r\n </InnerProviders>\r\n </AppConfigProvider>\r\n )\r\n}\r\n"],"mappings":";AAyBY;AAnBZ,SAAS,yBAA6C;AACtD,SAAS,mBAAmB;AAC5B,SAAS,uBAAuB;AAChC,SAAS,mBAAmB;AAC5B,SAAS,qBAAqB;AAC9B,SAAS,qBAAqB;AAC9B,SAAS,qBAAqB;AAC9B,SAAS,yBAAyB;AAClC,SAAS,wBAAwB;AACjC,SAAS,0BAA0B;AACnC,SAAS,2BAA2B;AACpC,SAAS,0BAA0B;AAEnC,MAAM,UAAU,eACd,UAAU;AAAA,EACR,CAAC,MAAM,SACL,SAAS,iBAAiB,EAAE,SAAS,GAAG;AACtC,WACE,oBAAC,QACC,8BAAC,QAAM,UAAS,GAClB;AAAA,EAEJ;AACJ;AAEF,MAAM,iBAAiB,QAAQ;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,SAAS,YAAY,EAAE,UAAU,cAAc,GAAiE;AACrH,SACE,oBAAC,qBAAkB,eACjB,8BAAC,kBACE,UACH,GACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/core/store/CombineProviders.tsx"],"sourcesContent":["'use client'\r\n\r\n// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\nimport * as React from 'react'\r\nimport { AppConfigProvider, type RuntimeConfig } from './AppConfig/context'\r\nimport { BimProvider } from './BIM/context'\r\nimport { ContentProvider } from './Content/context'\r\nimport { MapProvider } from './Map/context'\r\nimport { MenusProvider } from './Menus/context'\r\nimport { ToolsProvider } from './Tools/context'\r\nimport { FilesProvider } from './Files/context'\r\nimport { BuildingsProvider } from './Buildings/context'\r\nimport { DatasetsProvider } from './Datasets/context'\r\nimport { MapSitesProvider } from './MapSites/context'\r\nimport { PointCloudProvider } from './PointCloud/context'\r\nimport { PermissionsProvider } from './Permissions/context'\r\nimport { PluginHostProvider } from '../plugins/host/provider'\r\n\r\nconst compose = providers =>\r\n providers.reduce(\r\n (Prev, Curr) =>\r\n function ComposedProvider({ children }) {\r\n return (\r\n <Prev>\r\n <Curr>{children}</Curr>\r\n </Prev>\r\n )\r\n },\r\n )\r\n\r\nconst InnerProviders = compose([\r\n BimProvider,\r\n MapProvider,\r\n MenusProvider,\r\n ToolsProvider,\r\n ContentProvider,\r\n DatasetsProvider,\r\n MapSitesProvider,\r\n FilesProvider,\r\n BuildingsProvider,\r\n PointCloudProvider,\r\n PermissionsProvider,\r\n PluginHostProvider,\r\n])\r\n\r\nexport function AppProvider({ children, runtimeConfig }: { children: React.ReactNode, runtimeConfig?: RuntimeConfig }) {\r\n return (\r\n <AppConfigProvider runtimeConfig={runtimeConfig}>\r\n <InnerProviders>\r\n {children}\r\n </InnerProviders>\r\n </AppConfigProvider>\r\n )\r\n}\r\n"],"mappings":";AA0BY;AApBZ,SAAS,yBAA6C;AACtD,SAAS,mBAAmB;AAC5B,SAAS,uBAAuB;AAChC,SAAS,mBAAmB;AAC5B,SAAS,qBAAqB;AAC9B,SAAS,qBAAqB;AAC9B,SAAS,qBAAqB;AAC9B,SAAS,yBAAyB;AAClC,SAAS,wBAAwB;AACjC,SAAS,wBAAwB;AACjC,SAAS,0BAA0B;AACnC,SAAS,2BAA2B;AACpC,SAAS,0BAA0B;AAEnC,MAAM,UAAU,eACd,UAAU;AAAA,EACR,CAAC,MAAM,SACL,SAAS,iBAAiB,EAAE,SAAS,GAAG;AACtC,WACE,oBAAC,QACC,8BAAC,QAAM,UAAS,GAClB;AAAA,EAEJ;AACJ;AAEF,MAAM,iBAAiB,QAAQ;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,SAAS,YAAY,EAAE,UAAU,cAAc,GAAiE;AACrH,SACE,oBAAC,qBAAkB,eACjB,8BAAC,kBACE,UACH,GACF;AAEJ;","names":[]}
@@ -0,0 +1,16 @@
1
+ import * as React from "react";
2
+ import { MapSitesActions, MapSitesState } from './reducer';
3
+ type InitialStateType = {
4
+ mapSites: MapSitesState;
5
+ };
6
+ export declare const MapSitesContext: React.Context<{
7
+ state: InitialStateType;
8
+ dispatch: React.Dispatch<MapSitesActions>;
9
+ }>;
10
+ export declare const MapSitesProvider: React.FC<React.PropsWithChildren>;
11
+ export declare const useMapSitesContext: () => {
12
+ state: InitialStateType;
13
+ dispatch: React.Dispatch<MapSitesActions>;
14
+ };
15
+ export {};
16
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../../src/core/store/MapSites/context.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAEL,eAAe,EACf,aAAa,EAEd,MAAM,WAAW,CAAA;AAElB,KAAK,gBAAgB,GAAG;IACtB,QAAQ,EAAE,aAAa,CAAA;CACxB,CAAA;AAUD,eAAO,MAAM,eAAe;WACnB,gBAAgB;cACb,KAAK,CAAC,QAAQ,CAAC,eAAe,CAAC;EAIzC,CAAA;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAQ9D,CAAA;AAED,eAAO,MAAM,kBAAkB;WAjBtB,gBAAgB;cACb,KAAK,CAAC,QAAQ,CAAC,eAAe,CAAC;CAgB8B,CAAA"}
@@ -0,0 +1,29 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import {
5
+ MapSitesReducer,
6
+ initialMapSitesState
7
+ } from "./reducer";
8
+ const initialState = {
9
+ mapSites: initialMapSitesState
10
+ };
11
+ const reducer = ({ mapSites }, action) => ({
12
+ mapSites: MapSitesReducer(mapSites, action)
13
+ });
14
+ const MapSitesContext = React.createContext({
15
+ state: initialState,
16
+ dispatch: () => null
17
+ });
18
+ const MapSitesProvider = ({ children }) => {
19
+ const [state, dispatch] = React.useReducer(reducer, initialState);
20
+ const value = React.useMemo(() => ({ state, dispatch }), [state]);
21
+ return /* @__PURE__ */ jsx(MapSitesContext.Provider, { value, children });
22
+ };
23
+ const useMapSitesContext = () => React.useContext(MapSitesContext);
24
+ export {
25
+ MapSitesContext,
26
+ MapSitesProvider,
27
+ useMapSitesContext
28
+ };
29
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/core/store/MapSites/context.tsx"],"sourcesContent":["\"use client\"\r\n\r\n// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\nimport * as React from \"react\";\r\nimport {\r\n MapSitesReducer,\r\n MapSitesActions,\r\n MapSitesState,\r\n initialMapSitesState,\r\n} from './reducer'\r\n\r\ntype InitialStateType = {\r\n mapSites: MapSitesState\r\n}\r\n\r\nconst initialState: InitialStateType = {\r\n mapSites: initialMapSitesState,\r\n}\r\n\r\nconst reducer = ({ mapSites }: InitialStateType, action: MapSitesActions) => ({\r\n mapSites: MapSitesReducer(mapSites, action),\r\n})\r\n\r\nexport const MapSitesContext = React.createContext<{\r\n state: InitialStateType\r\n dispatch: React.Dispatch<MapSitesActions>\r\n}>({\r\n state: initialState,\r\n dispatch: () => null,\r\n})\r\n\r\nexport const MapSitesProvider: React.FC<React.PropsWithChildren> = ({ children }) => {\r\n const [state, dispatch] = React.useReducer(reducer, initialState)\r\n const value = React.useMemo(() => ({ state, dispatch }), [state])\r\n return (\r\n <MapSitesContext.Provider value={value}>\r\n {children}\r\n </MapSitesContext.Provider>\r\n )\r\n}\r\n\r\nexport const useMapSitesContext = () => React.useContext(MapSitesContext)\r\n"],"mappings":";AAqCI;AAhCJ,YAAY,WAAW;AACvB;AAAA,EACE;AAAA,EAGA;AAAA,OACK;AAMP,MAAM,eAAiC;AAAA,EACrC,UAAU;AACZ;AAEA,MAAM,UAAU,CAAC,EAAE,SAAS,GAAqB,YAA6B;AAAA,EAC5E,UAAU,gBAAgB,UAAU,MAAM;AAC5C;AAEO,MAAM,kBAAkB,MAAM,cAGlC;AAAA,EACD,OAAO;AAAA,EACP,UAAU,MAAM;AAClB,CAAC;AAEM,MAAM,mBAAsD,CAAC,EAAE,SAAS,MAAM;AACnF,QAAM,CAAC,OAAO,QAAQ,IAAI,MAAM,WAAW,SAAS,YAAY;AAChE,QAAM,QAAQ,MAAM,QAAQ,OAAO,EAAE,OAAO,SAAS,IAAI,CAAC,KAAK,CAAC;AAChE,SACE,oBAAC,gBAAgB,UAAhB,EAAyB,OACvB,UACH;AAEJ;AAEO,MAAM,qBAAqB,MAAM,MAAM,WAAW,eAAe;","names":[]}
@@ -0,0 +1,52 @@
1
+ import { ActionMap } from '../ActionMap';
2
+ /**
3
+ * A site polygon currently shown on the map. The polygon geometry itself is
4
+ * persisted as a GeoJSON file in minio (referenced by `assetId`/`fileId`); this
5
+ * is the in-memory representation that drives the SiteLayer rendering.
6
+ */
7
+ export interface ShownSite {
8
+ /** DB site id */
9
+ id: number;
10
+ name: string;
11
+ /** Outer ring vertices [lng, lat], open (no repeated closing point) */
12
+ ring: [number, number][];
13
+ /** minio object key of the geometry geojson, for re-upload when edited */
14
+ assetId?: string;
15
+ /** DB file id of the geometry geojson, for deletion */
16
+ fileId?: number;
17
+ }
18
+ export interface MapSitesState {
19
+ /** Sites currently rendered on the map. */
20
+ sites: ShownSite[];
21
+ /** Site whose vertices are currently being dragged/edited, if any. */
22
+ editingSiteId: number | null;
23
+ }
24
+ export type MapSitesPayload = {
25
+ ['SHOW_SITE']: {
26
+ site: ShownSite;
27
+ };
28
+ ['HIDE_SITE']: {
29
+ id: number;
30
+ };
31
+ ['UPDATE_SITE_RING']: {
32
+ id: number;
33
+ ring: [number, number][];
34
+ };
35
+ ['UPDATE_SITE_NAME']: {
36
+ id: number;
37
+ name: string;
38
+ };
39
+ ['SET_SITE_GEOMETRY_REF']: {
40
+ id: number;
41
+ assetId?: string;
42
+ fileId?: number;
43
+ };
44
+ ['SET_EDITING_SITE']: {
45
+ id: number | null;
46
+ };
47
+ ['CLEAR_SITES']: undefined;
48
+ };
49
+ export type MapSitesActions = ActionMap<MapSitesPayload>[keyof ActionMap<MapSitesPayload>];
50
+ export declare const initialMapSitesState: MapSitesState;
51
+ export declare const MapSitesReducer: (state: MapSitesState, action: MapSitesActions) => MapSitesState;
52
+ //# sourceMappingURL=reducer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reducer.d.ts","sourceRoot":"","sources":["../../../../src/core/store/MapSites/reducer.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAExC;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,iBAAiB;IACjB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,uEAAuE;IACvE,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAA;IACxB,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,uDAAuD;IACvD,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,2CAA2C;IAC3C,KAAK,EAAE,SAAS,EAAE,CAAA;IAClB,sEAAsE;IACtE,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;CAC7B;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,CAAC,WAAW,CAAC,EAAE;QAAE,IAAI,EAAE,SAAS,CAAA;KAAE,CAAA;IAClC,CAAC,WAAW,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;IAC7B,CAAC,kBAAkB,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAA;KAAE,CAAA;IAC9D,CAAC,kBAAkB,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IAClD,CAAC,uBAAuB,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC5E,CAAC,kBAAkB,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAA;IAC3C,CAAC,aAAa,CAAC,EAAE,SAAS,CAAA;CAC3B,CAAA;AAED,MAAM,MAAM,eAAe,GACvB,SAAS,CAAC,eAAe,CAAC,CAAC,MAAM,SAAS,CAAC,eAAe,CAAC,CAAC,CAAA;AAEhE,eAAO,MAAM,oBAAoB,EAAE,aAGlC,CAAA;AAED,eAAO,MAAM,eAAe,GAC1B,OAAO,aAAa,EACpB,QAAQ,eAAe,KACtB,aA6CF,CAAA"}
@@ -0,0 +1,70 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ const initialMapSitesState = {
21
+ sites: [],
22
+ editingSiteId: null
23
+ };
24
+ const MapSitesReducer = (state, action) => {
25
+ switch (action.type) {
26
+ case "SHOW_SITE": {
27
+ const { site } = action.payload;
28
+ const others = state.sites.filter((s) => s.id !== site.id);
29
+ return __spreadProps(__spreadValues({}, state), { sites: [...others, site] });
30
+ }
31
+ case "HIDE_SITE": {
32
+ const { id } = action.payload;
33
+ return __spreadProps(__spreadValues({}, state), {
34
+ sites: state.sites.filter((s) => s.id !== id),
35
+ editingSiteId: state.editingSiteId === id ? null : state.editingSiteId
36
+ });
37
+ }
38
+ case "UPDATE_SITE_RING": {
39
+ const { id, ring } = action.payload;
40
+ return __spreadProps(__spreadValues({}, state), {
41
+ sites: state.sites.map((s) => s.id === id ? __spreadProps(__spreadValues({}, s), { ring }) : s)
42
+ });
43
+ }
44
+ case "UPDATE_SITE_NAME": {
45
+ const { id, name } = action.payload;
46
+ return __spreadProps(__spreadValues({}, state), {
47
+ sites: state.sites.map((s) => s.id === id ? __spreadProps(__spreadValues({}, s), { name }) : s)
48
+ });
49
+ }
50
+ case "SET_SITE_GEOMETRY_REF": {
51
+ const { id, assetId, fileId } = action.payload;
52
+ return __spreadProps(__spreadValues({}, state), {
53
+ sites: state.sites.map((s) => s.id === id ? __spreadProps(__spreadValues({}, s), { assetId, fileId }) : s)
54
+ });
55
+ }
56
+ case "SET_EDITING_SITE": {
57
+ const { id } = action.payload;
58
+ return __spreadProps(__spreadValues({}, state), { editingSiteId: id });
59
+ }
60
+ case "CLEAR_SITES":
61
+ return __spreadProps(__spreadValues({}, state), { sites: [], editingSiteId: null });
62
+ default:
63
+ return state;
64
+ }
65
+ };
66
+ export {
67
+ MapSitesReducer,
68
+ initialMapSitesState
69
+ };
70
+ //# sourceMappingURL=reducer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/core/store/MapSites/reducer.ts"],"sourcesContent":["// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\nimport { ActionMap } from '../ActionMap'\r\n\r\n/**\r\n * A site polygon currently shown on the map. The polygon geometry itself is\r\n * persisted as a GeoJSON file in minio (referenced by `assetId`/`fileId`); this\r\n * is the in-memory representation that drives the SiteLayer rendering.\r\n */\r\nexport interface ShownSite {\r\n /** DB site id */\r\n id: number\r\n name: string\r\n /** Outer ring vertices [lng, lat], open (no repeated closing point) */\r\n ring: [number, number][]\r\n /** minio object key of the geometry geojson, for re-upload when edited */\r\n assetId?: string\r\n /** DB file id of the geometry geojson, for deletion */\r\n fileId?: number\r\n}\r\n\r\nexport interface MapSitesState {\r\n /** Sites currently rendered on the map. */\r\n sites: ShownSite[]\r\n /** Site whose vertices are currently being dragged/edited, if any. */\r\n editingSiteId: number | null\r\n}\r\n\r\nexport type MapSitesPayload = {\r\n ['SHOW_SITE']: { site: ShownSite }\r\n ['HIDE_SITE']: { id: number }\r\n ['UPDATE_SITE_RING']: { id: number, ring: [number, number][] }\r\n ['UPDATE_SITE_NAME']: { id: number, name: string }\r\n ['SET_SITE_GEOMETRY_REF']: { id: number, assetId?: string, fileId?: number }\r\n ['SET_EDITING_SITE']: { id: number | null }\r\n ['CLEAR_SITES']: undefined\r\n}\r\n\r\nexport type MapSitesActions\r\n = ActionMap<MapSitesPayload>[keyof ActionMap<MapSitesPayload>]\r\n\r\nexport const initialMapSitesState: MapSitesState = {\r\n sites: [],\r\n editingSiteId: null,\r\n}\r\n\r\nexport const MapSitesReducer = (\r\n state: MapSitesState,\r\n action: MapSitesActions,\r\n): MapSitesState => {\r\n switch (action.type) {\r\n case 'SHOW_SITE': {\r\n const { site } = action.payload!\r\n const others = state.sites.filter(s => s.id !== site.id)\r\n return { ...state, sites: [...others, site] }\r\n }\r\n case 'HIDE_SITE': {\r\n const { id } = action.payload!\r\n return {\r\n ...state,\r\n sites: state.sites.filter(s => s.id !== id),\r\n editingSiteId: state.editingSiteId === id ? null : state.editingSiteId,\r\n }\r\n }\r\n case 'UPDATE_SITE_RING': {\r\n const { id, ring } = action.payload!\r\n return {\r\n ...state,\r\n sites: state.sites.map(s => (s.id === id ? { ...s, ring } : s)),\r\n }\r\n }\r\n case 'UPDATE_SITE_NAME': {\r\n const { id, name } = action.payload!\r\n return {\r\n ...state,\r\n sites: state.sites.map(s => (s.id === id ? { ...s, name } : s)),\r\n }\r\n }\r\n case 'SET_SITE_GEOMETRY_REF': {\r\n const { id, assetId, fileId } = action.payload!\r\n return {\r\n ...state,\r\n sites: state.sites.map(s => (s.id === id ? { ...s, assetId, fileId } : s)),\r\n }\r\n }\r\n case 'SET_EDITING_SITE': {\r\n const { id } = action.payload!\r\n return { ...state, editingSiteId: id }\r\n }\r\n case 'CLEAR_SITES':\r\n return { ...state, sites: [], editingSiteId: null }\r\n default:\r\n return state\r\n }\r\n}\r\n"],"mappings":";;;;;;;;;;;;;;;;;;;AA0CO,MAAM,uBAAsC;AAAA,EACjD,OAAO,CAAC;AAAA,EACR,eAAe;AACjB;AAEO,MAAM,kBAAkB,CAC7B,OACA,WACkB;AAClB,UAAQ,OAAO,MAAM;AAAA,IACnB,KAAK,aAAa;AAChB,YAAM,EAAE,KAAK,IAAI,OAAO;AACxB,YAAM,SAAS,MAAM,MAAM,OAAO,OAAK,EAAE,OAAO,KAAK,EAAE;AACvD,aAAO,iCAAK,QAAL,EAAY,OAAO,CAAC,GAAG,QAAQ,IAAI,EAAE;AAAA,IAC9C;AAAA,IACA,KAAK,aAAa;AAChB,YAAM,EAAE,GAAG,IAAI,OAAO;AACtB,aAAO,iCACF,QADE;AAAA,QAEL,OAAO,MAAM,MAAM,OAAO,OAAK,EAAE,OAAO,EAAE;AAAA,QAC1C,eAAe,MAAM,kBAAkB,KAAK,OAAO,MAAM;AAAA,MAC3D;AAAA,IACF;AAAA,IACA,KAAK,oBAAoB;AACvB,YAAM,EAAE,IAAI,KAAK,IAAI,OAAO;AAC5B,aAAO,iCACF,QADE;AAAA,QAEL,OAAO,MAAM,MAAM,IAAI,OAAM,EAAE,OAAO,KAAK,iCAAK,IAAL,EAAQ,KAAK,KAAI,CAAE;AAAA,MAChE;AAAA,IACF;AAAA,IACA,KAAK,oBAAoB;AACvB,YAAM,EAAE,IAAI,KAAK,IAAI,OAAO;AAC5B,aAAO,iCACF,QADE;AAAA,QAEL,OAAO,MAAM,MAAM,IAAI,OAAM,EAAE,OAAO,KAAK,iCAAK,IAAL,EAAQ,KAAK,KAAI,CAAE;AAAA,MAChE;AAAA,IACF;AAAA,IACA,KAAK,yBAAyB;AAC5B,YAAM,EAAE,IAAI,SAAS,OAAO,IAAI,OAAO;AACvC,aAAO,iCACF,QADE;AAAA,QAEL,OAAO,MAAM,MAAM,IAAI,OAAM,EAAE,OAAO,KAAK,iCAAK,IAAL,EAAQ,SAAS,OAAO,KAAI,CAAE;AAAA,MAC3E;AAAA,IACF;AAAA,IACA,KAAK,oBAAoB;AACvB,YAAM,EAAE,GAAG,IAAI,OAAO;AACtB,aAAO,iCAAK,QAAL,EAAY,eAAe,GAAG;AAAA,IACvC;AAAA,IACA,KAAK;AACH,aAAO,iCAAK,QAAL,EAAY,OAAO,CAAC,GAAG,eAAe,KAAK;AAAA,IACpD;AACE,aAAO;AAAA,EACX;AACF;","names":[]}
@@ -6,6 +6,7 @@ export * from './BIM/context';
6
6
  export * from './Files/context';
7
7
  export * from './Buildings/context';
8
8
  export * from './Datasets/context';
9
+ export * from './MapSites/context';
9
10
  export * from './PointCloud/context';
10
11
  export * from './Permissions/context';
11
12
  export * from './CombineProviders';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/store/index.ts"],"names":[],"mappings":"AAGA,cAAc,qBAAqB,CAAA;AACnC,cAAc,eAAe,CAAA;AAC7B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,eAAe,CAAA;AAC7B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,qBAAqB,CAAA;AACnC,cAAc,oBAAoB,CAAA;AAClC,cAAc,sBAAsB,CAAA;AACpC,cAAc,uBAAuB,CAAA;AACrC,cAAc,oBAAoB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/store/index.ts"],"names":[],"mappings":"AAGA,cAAc,qBAAqB,CAAA;AACnC,cAAc,eAAe,CAAA;AAC7B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,eAAe,CAAA;AAC7B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,qBAAqB,CAAA;AACnC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,sBAAsB,CAAA;AACpC,cAAc,uBAAuB,CAAA;AACrC,cAAc,oBAAoB,CAAA"}
@@ -6,6 +6,7 @@ export * from "./BIM/context";
6
6
  export * from "./Files/context";
7
7
  export * from "./Buildings/context";
8
8
  export * from "./Datasets/context";
9
+ export * from "./MapSites/context";
9
10
  export * from "./PointCloud/context";
10
11
  export * from "./Permissions/context";
11
12
  export * from "./CombineProviders";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/store/index.ts"],"sourcesContent":["// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\nexport * from './AppConfig/context'\r\nexport * from './Map/context'\r\nexport * from './Menus/context'\r\nexport * from './Tools/context'\r\nexport * from './BIM/context'\r\nexport * from './Files/context'\r\nexport * from './Buildings/context'\r\nexport * from './Datasets/context'\r\nexport * from './PointCloud/context'\r\nexport * from './Permissions/context'\r\nexport * from './CombineProviders'"],"mappings":"AAGA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
1
+ {"version":3,"sources":["../../../src/core/store/index.ts"],"sourcesContent":["// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\nexport * from './AppConfig/context'\r\nexport * from './Map/context'\r\nexport * from './Menus/context'\r\nexport * from './Tools/context'\r\nexport * from './BIM/context'\r\nexport * from './Files/context'\r\nexport * from './Buildings/context'\r\nexport * from './Datasets/context'\r\nexport * from './MapSites/context'\r\nexport * from './PointCloud/context'\r\nexport * from './Permissions/context'\r\nexport * from './CombineProviders'"],"mappings":"AAGA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@collabdt/core",
3
- "version": "0.0.57",
3
+ "version": "0.2.0",
4
4
  "description": "CDT Core contains all the core technology for your CDT platform",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",