@collabdt/core 0.0.56 → 0.0.57

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 (256) hide show
  1. package/dist/core/components/AppSidebarContent.d.ts +2 -1
  2. package/dist/core/components/AppSidebarContent.d.ts.map +1 -1
  3. package/dist/core/components/AppSidebarContent.js +10 -7
  4. package/dist/core/components/AppSidebarContent.js.map +1 -1
  5. package/dist/core/components/Toolbar.d.ts +7 -1
  6. package/dist/core/components/Toolbar.d.ts.map +1 -1
  7. package/dist/core/components/Toolbar.js +3 -3
  8. package/dist/core/components/Toolbar.js.map +1 -1
  9. package/dist/core/components/TopNavigationBar.d.ts +6 -1
  10. package/dist/core/components/TopNavigationBar.d.ts.map +1 -1
  11. package/dist/core/components/TopNavigationBar.js +2 -2
  12. package/dist/core/components/TopNavigationBar.js.map +1 -1
  13. package/dist/core/components/authentication/AuthPage.d.ts +2 -1
  14. package/dist/core/components/authentication/AuthPage.d.ts.map +1 -1
  15. package/dist/core/components/authentication/AuthPage.js +3 -5
  16. package/dist/core/components/authentication/AuthPage.js.map +1 -1
  17. package/dist/core/components/authentication/Signin.d.ts +2 -1
  18. package/dist/core/components/authentication/Signin.d.ts.map +1 -1
  19. package/dist/core/components/authentication/Signin.js +2 -2
  20. package/dist/core/components/authentication/Signin.js.map +1 -1
  21. package/dist/core/components/organizationConfig/src/organizationConfigContent.d.ts.map +1 -1
  22. package/dist/core/components/organizationConfig/src/organizationConfigContent.js +109 -36
  23. package/dist/core/components/organizationConfig/src/organizationConfigContent.js.map +1 -1
  24. package/dist/core/components/settings/index.d.ts +3 -1
  25. package/dist/core/components/settings/index.d.ts.map +1 -1
  26. package/dist/core/components/settings/index.js +2 -2
  27. package/dist/core/components/settings/index.js.map +1 -1
  28. package/dist/core/components/settings/src/AccountSettingsPanel.d.ts.map +1 -1
  29. package/dist/core/components/settings/src/AccountSettingsPanel.js +9 -2
  30. package/dist/core/components/settings/src/AccountSettingsPanel.js.map +1 -1
  31. package/dist/core/components/settings/src/OrganizationSettingsPanel.d.ts +5 -1
  32. package/dist/core/components/settings/src/OrganizationSettingsPanel.d.ts.map +1 -1
  33. package/dist/core/components/settings/src/OrganizationSettingsPanel.js +7 -5
  34. package/dist/core/components/settings/src/OrganizationSettingsPanel.js.map +1 -1
  35. package/dist/core/components/settings/src/SettingsContent.d.ts +2 -1
  36. package/dist/core/components/settings/src/SettingsContent.d.ts.map +1 -1
  37. package/dist/core/components/settings/src/SettingsContent.js +2 -2
  38. package/dist/core/components/settings/src/SettingsContent.js.map +1 -1
  39. package/dist/core/components/support/BugReportDialog.d.ts +3 -2
  40. package/dist/core/components/support/BugReportDialog.d.ts.map +1 -1
  41. package/dist/core/components/support/BugReportDialog.js +71 -25
  42. package/dist/core/components/support/BugReportDialog.js.map +1 -1
  43. package/dist/core/components/support/FeatureRequestDialog.d.ts +3 -1
  44. package/dist/core/components/support/FeatureRequestDialog.d.ts.map +1 -1
  45. package/dist/core/components/support/FeatureRequestDialog.js +7 -4
  46. package/dist/core/components/support/FeatureRequestDialog.js.map +1 -1
  47. package/dist/core/components/support/SupportMenu.d.ts.map +1 -1
  48. package/dist/core/components/support/SupportMenu.js +1 -4
  49. package/dist/core/components/support/SupportMenu.js.map +1 -1
  50. package/dist/core/components/ui/AnimatedBackground.d.ts +2 -1
  51. package/dist/core/components/ui/AnimatedBackground.d.ts.map +1 -1
  52. package/dist/core/components/ui/AnimatedBackground.js +2 -5
  53. package/dist/core/components/ui/AnimatedBackground.js.map +1 -1
  54. package/dist/core/components/ui/InfoSidebar/Container.d.ts +3 -1
  55. package/dist/core/components/ui/InfoSidebar/Container.d.ts.map +1 -1
  56. package/dist/core/components/ui/InfoSidebar/Container.js +4 -2
  57. package/dist/core/components/ui/InfoSidebar/Container.js.map +1 -1
  58. package/dist/core/components/ui/InfoSidebar/Header.d.ts +3 -2
  59. package/dist/core/components/ui/InfoSidebar/Header.d.ts.map +1 -1
  60. package/dist/core/components/ui/InfoSidebar/Header.js +5 -6
  61. package/dist/core/components/ui/InfoSidebar/Header.js.map +1 -1
  62. package/dist/core/components/ui/InfoSidebar/index.d.ts +7 -1
  63. package/dist/core/components/ui/InfoSidebar/index.d.ts.map +1 -1
  64. package/dist/core/components/ui/InfoSidebar/index.js +4 -4
  65. package/dist/core/components/ui/InfoSidebar/index.js.map +1 -1
  66. package/dist/core/components/ui/Sensors/CollapsibleSensorItem.d.ts +2 -1
  67. package/dist/core/components/ui/Sensors/CollapsibleSensorItem.d.ts.map +1 -1
  68. package/dist/core/components/ui/Sensors/CollapsibleSensorItem.js +3 -4
  69. package/dist/core/components/ui/Sensors/CollapsibleSensorItem.js.map +1 -1
  70. package/dist/core/components/ui/Sensors/SensorsSection.d.ts +3 -1
  71. package/dist/core/components/ui/Sensors/SensorsSection.d.ts.map +1 -1
  72. package/dist/core/components/ui/Sensors/SensorsSection.js +3 -1
  73. package/dist/core/components/ui/Sensors/SensorsSection.js.map +1 -1
  74. package/dist/core/components/ui/Sidebar.d.ts +8 -0
  75. package/dist/core/components/ui/Sidebar.d.ts.map +1 -1
  76. package/dist/core/components/ui/Sidebar.js +21 -7
  77. package/dist/core/components/ui/Sidebar.js.map +1 -1
  78. package/dist/core/components/ui/ToolbarButton.js +18 -1
  79. package/dist/core/components/ui/ToolbarButton.js.map +1 -1
  80. package/dist/core/components/viewers/Data/DataMenu.d.ts +5 -1
  81. package/dist/core/components/viewers/Data/DataMenu.d.ts.map +1 -1
  82. package/dist/core/components/viewers/Data/DataMenu.js +6 -3
  83. package/dist/core/components/viewers/Data/DataMenu.js.map +1 -1
  84. package/dist/core/components/viewers/Data/HeaderButtons.d.ts +3 -1
  85. package/dist/core/components/viewers/Data/HeaderButtons.d.ts.map +1 -1
  86. package/dist/core/components/viewers/Data/HeaderButtons.js +6 -2
  87. package/dist/core/components/viewers/Data/HeaderButtons.js.map +1 -1
  88. package/dist/core/components/viewers/Data/buildingDetails/AddBuilding.d.ts +3 -1
  89. package/dist/core/components/viewers/Data/buildingDetails/AddBuilding.d.ts.map +1 -1
  90. package/dist/core/components/viewers/Data/buildingDetails/AddBuilding.js +4 -2
  91. package/dist/core/components/viewers/Data/buildingDetails/AddBuilding.js.map +1 -1
  92. package/dist/core/components/viewers/Data/buildingDetails/GeocoderInput.d.ts +3 -1
  93. package/dist/core/components/viewers/Data/buildingDetails/GeocoderInput.d.ts.map +1 -1
  94. package/dist/core/components/viewers/Data/buildingDetails/GeocoderInput.js +3 -1
  95. package/dist/core/components/viewers/Data/buildingDetails/GeocoderInput.js.map +1 -1
  96. package/dist/core/components/viewers/Data/details/DetailHeader.d.ts +2 -1
  97. package/dist/core/components/viewers/Data/details/DetailHeader.d.ts.map +1 -1
  98. package/dist/core/components/viewers/Data/details/DetailHeader.js +3 -5
  99. package/dist/core/components/viewers/Data/details/DetailHeader.js.map +1 -1
  100. package/dist/core/components/viewers/Viewer.d.ts +7 -1
  101. package/dist/core/components/viewers/Viewer.d.ts.map +1 -1
  102. package/dist/core/components/viewers/Viewer.js +6 -6
  103. package/dist/core/components/viewers/Viewer.js.map +1 -1
  104. package/dist/core/components/viewers/bim/BimToolbar.d.ts +3 -1
  105. package/dist/core/components/viewers/bim/BimToolbar.d.ts.map +1 -1
  106. package/dist/core/components/viewers/bim/BimToolbar.js +2 -2
  107. package/dist/core/components/viewers/bim/BimToolbar.js.map +1 -1
  108. package/dist/core/components/viewers/bim/src/BimSidebar/src/SensorsTab/index.d.ts +3 -1
  109. package/dist/core/components/viewers/bim/src/BimSidebar/src/SensorsTab/index.d.ts.map +1 -1
  110. package/dist/core/components/viewers/bim/src/BimSidebar/src/SensorsTab/index.js +2 -2
  111. package/dist/core/components/viewers/bim/src/BimSidebar/src/SensorsTab/index.js.map +1 -1
  112. package/dist/core/components/viewers/bim/src/BimSidebar/src/index.d.ts +5 -1
  113. package/dist/core/components/viewers/bim/src/BimSidebar/src/index.d.ts.map +1 -1
  114. package/dist/core/components/viewers/bim/src/BimSidebar/src/index.js +3 -2
  115. package/dist/core/components/viewers/bim/src/BimSidebar/src/index.js.map +1 -1
  116. package/dist/core/components/viewers/bim/src/tools/AddToBim/index.d.ts +3 -1
  117. package/dist/core/components/viewers/bim/src/tools/AddToBim/index.d.ts.map +1 -1
  118. package/dist/core/components/viewers/bim/src/tools/AddToBim/index.js +2 -2
  119. package/dist/core/components/viewers/bim/src/tools/AddToBim/index.js.map +1 -1
  120. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useSensorMarkers.d.ts +1 -1
  121. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useSensorMarkers.d.ts.map +1 -1
  122. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useSensorMarkers.js +3 -5
  123. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useSensorMarkers.js.map +1 -1
  124. package/dist/core/components/viewers/bim/src/tools/bimToolbar.d.ts +3 -1
  125. package/dist/core/components/viewers/bim/src/tools/bimToolbar.d.ts.map +1 -1
  126. package/dist/core/components/viewers/bim/src/tools/bimToolbar.js +4 -2
  127. package/dist/core/components/viewers/bim/src/tools/bimToolbar.js.map +1 -1
  128. package/dist/core/components/viewers/map/MapViewer.d.ts +3 -1
  129. package/dist/core/components/viewers/map/MapViewer.d.ts.map +1 -1
  130. package/dist/core/components/viewers/map/MapViewer.js +2 -2
  131. package/dist/core/components/viewers/map/MapViewer.js.map +1 -1
  132. package/dist/core/components/viewers/map/datasets/RowActions.d.ts +2 -1
  133. package/dist/core/components/viewers/map/datasets/RowActions.d.ts.map +1 -1
  134. package/dist/core/components/viewers/map/datasets/RowActions.js +5 -6
  135. package/dist/core/components/viewers/map/datasets/RowActions.js.map +1 -1
  136. package/dist/core/components/viewers/map/datasets/index.d.ts +5 -1
  137. package/dist/core/components/viewers/map/datasets/index.d.ts.map +1 -1
  138. package/dist/core/components/viewers/map/datasets/index.js +15 -16
  139. package/dist/core/components/viewers/map/datasets/index.js.map +1 -1
  140. package/dist/core/components/viewers/map/src/Geocoder.d.ts +3 -1
  141. package/dist/core/components/viewers/map/src/Geocoder.d.ts.map +1 -1
  142. package/dist/core/components/viewers/map/src/Geocoder.js +5 -1
  143. package/dist/core/components/viewers/map/src/Geocoder.js.map +1 -1
  144. package/dist/core/components/viewers/map/src/MapLayers/index.d.ts +6 -1
  145. package/dist/core/components/viewers/map/src/MapLayers/index.d.ts.map +1 -1
  146. package/dist/core/components/viewers/map/src/MapLayers/index.js +3 -3
  147. package/dist/core/components/viewers/map/src/MapLayers/index.js.map +1 -1
  148. package/dist/core/components/viewers/map/src/MapLayers/src/CountryLayer/index.d.ts +5 -1
  149. package/dist/core/components/viewers/map/src/MapLayers/src/CountryLayer/index.d.ts.map +1 -1
  150. package/dist/core/components/viewers/map/src/MapLayers/src/CountryLayer/index.js +6 -10
  151. package/dist/core/components/viewers/map/src/MapLayers/src/CountryLayer/index.js.map +1 -1
  152. package/dist/core/components/viewers/map/src/MapLayers/src/SensorsLayer/index.d.ts +3 -1
  153. package/dist/core/components/viewers/map/src/MapLayers/src/SensorsLayer/index.d.ts.map +1 -1
  154. package/dist/core/components/viewers/map/src/MapLayers/src/SensorsLayer/index.js +4 -6
  155. package/dist/core/components/viewers/map/src/MapLayers/src/SensorsLayer/index.js.map +1 -1
  156. package/dist/core/components/viewers/map/src/MapSidebar/index.d.ts +6 -1
  157. package/dist/core/components/viewers/map/src/MapSidebar/index.d.ts.map +1 -1
  158. package/dist/core/components/viewers/map/src/MapSidebar/index.js +5 -4
  159. package/dist/core/components/viewers/map/src/MapSidebar/index.js.map +1 -1
  160. package/dist/core/components/viewers/map/src/MapSidebar/src/LayersTab/index.d.ts +5 -1
  161. package/dist/core/components/viewers/map/src/MapSidebar/src/LayersTab/index.d.ts.map +1 -1
  162. package/dist/core/components/viewers/map/src/MapSidebar/src/LayersTab/index.js +5 -8
  163. package/dist/core/components/viewers/map/src/MapSidebar/src/LayersTab/index.js.map +1 -1
  164. package/dist/core/components/viewers/map/src/MapSidebar/src/SensorsTab/index.d.ts +3 -1
  165. package/dist/core/components/viewers/map/src/MapSidebar/src/SensorsTab/index.d.ts.map +1 -1
  166. package/dist/core/components/viewers/map/src/MapSidebar/src/SensorsTab/index.js +2 -2
  167. package/dist/core/components/viewers/map/src/MapSidebar/src/SensorsTab/index.js.map +1 -1
  168. package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/index.d.ts +3 -1
  169. package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/index.d.ts.map +1 -1
  170. package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/index.js +2 -2
  171. package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/index.js.map +1 -1
  172. package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/src/LocationSettings.d.ts +3 -1
  173. package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/src/LocationSettings.d.ts.map +1 -1
  174. package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/src/LocationSettings.js +4 -7
  175. package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/src/LocationSettings.js.map +1 -1
  176. package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/src/TerrainLevel.d.ts.map +1 -1
  177. package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/src/TerrainLevel.js +8 -8
  178. package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/src/TerrainLevel.js.map +1 -1
  179. package/dist/core/components/viewers/map/src/tools/AddTools/AddToMap.d.ts +8 -1
  180. package/dist/core/components/viewers/map/src/tools/AddTools/AddToMap.d.ts.map +1 -1
  181. package/dist/core/components/viewers/map/src/tools/AddTools/AddToMap.js +8 -3
  182. package/dist/core/components/viewers/map/src/tools/AddTools/AddToMap.js.map +1 -1
  183. package/dist/core/components/viewers/map/src/tools/DatasetMapTool.d.ts +11 -1
  184. package/dist/core/components/viewers/map/src/tools/DatasetMapTool.d.ts.map +1 -1
  185. package/dist/core/components/viewers/map/src/tools/DatasetMapTool.js +5 -3
  186. package/dist/core/components/viewers/map/src/tools/DatasetMapTool.js.map +1 -1
  187. package/dist/core/components/viewers/map/src/tools/mapTools.d.ts +10 -1
  188. package/dist/core/components/viewers/map/src/tools/mapTools.d.ts.map +1 -1
  189. package/dist/core/components/viewers/map/src/tools/mapTools.js +5 -3
  190. package/dist/core/components/viewers/map/src/tools/mapTools.js.map +1 -1
  191. package/dist/core/components/viewers/map/utils/geocoding/config.d.ts +14 -5
  192. package/dist/core/components/viewers/map/utils/geocoding/config.d.ts.map +1 -1
  193. package/dist/core/components/viewers/map/utils/geocoding/config.js +22 -11
  194. package/dist/core/components/viewers/map/utils/geocoding/config.js.map +1 -1
  195. package/dist/core/components/viewers/map/utils/geocoding/index.d.ts.map +1 -1
  196. package/dist/core/components/viewers/map/utils/geocoding/index.js +2 -2
  197. package/dist/core/components/viewers/map/utils/geocoding/index.js.map +1 -1
  198. package/dist/core/components/viewers/map/utils/geocoding/osm.d.ts.map +1 -1
  199. package/dist/core/components/viewers/map/utils/geocoding/osm.js +5 -4
  200. package/dist/core/components/viewers/map/utils/geocoding/osm.js.map +1 -1
  201. package/dist/core/components/viewers/map/utils/geocoding/pelias.d.ts.map +1 -1
  202. package/dist/core/components/viewers/map/utils/geocoding/pelias.js +7 -5
  203. package/dist/core/components/viewers/map/utils/geocoding/pelias.js.map +1 -1
  204. package/dist/core/components/viewers/pointcloud/PointCloudViewer.d.ts +3 -1
  205. package/dist/core/components/viewers/pointcloud/PointCloudViewer.d.ts.map +1 -1
  206. package/dist/core/components/viewers/pointcloud/PointCloudViewer.js +11 -14
  207. package/dist/core/components/viewers/pointcloud/PointCloudViewer.js.map +1 -1
  208. package/dist/core/components/viewers/pointcloud/src/PointCloudLoadingState/index.d.ts +3 -1
  209. package/dist/core/components/viewers/pointcloud/src/PointCloudLoadingState/index.d.ts.map +1 -1
  210. package/dist/core/components/viewers/pointcloud/src/PointCloudLoadingState/index.js +37 -52
  211. package/dist/core/components/viewers/pointcloud/src/PointCloudLoadingState/index.js.map +1 -1
  212. package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudManagementTable.d.ts +3 -1
  213. package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudManagementTable.d.ts.map +1 -1
  214. package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudManagementTable.js +5 -3
  215. package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudManagementTable.js.map +1 -1
  216. package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudTable.d.ts +2 -1
  217. package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudTable.d.ts.map +1 -1
  218. package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudTable.js +5 -6
  219. package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudTable.js.map +1 -1
  220. package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudUploadPanel.d.ts +2 -1
  221. package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudUploadPanel.d.ts.map +1 -1
  222. package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudUploadPanel.js +15 -9
  223. package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudUploadPanel.js.map +1 -1
  224. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/index.d.ts +5 -1
  225. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/index.d.ts.map +1 -1
  226. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/index.js +3 -2
  227. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/index.js.map +1 -1
  228. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/index.d.ts +3 -1
  229. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/index.d.ts.map +1 -1
  230. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/index.js +2 -2
  231. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/index.js.map +1 -1
  232. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/src/PointCloudSection.d.ts +2 -1
  233. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/src/PointCloudSection.d.ts.map +1 -1
  234. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/src/PointCloudSection.js +12 -23
  235. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/src/PointCloudSection.js.map +1 -1
  236. package/dist/core/hooks/useCaptureScreenshot.d.ts +2 -0
  237. package/dist/core/hooks/useCaptureScreenshot.d.ts.map +1 -0
  238. package/dist/core/hooks/useCaptureScreenshot.js +63 -0
  239. package/dist/core/hooks/useCaptureScreenshot.js.map +1 -0
  240. package/dist/core/hooks/useGeocodingRuntimeConfig.d.ts +3 -0
  241. package/dist/core/hooks/useGeocodingRuntimeConfig.d.ts.map +1 -0
  242. package/dist/core/hooks/useGeocodingRuntimeConfig.js +17 -0
  243. package/dist/core/hooks/useGeocodingRuntimeConfig.js.map +1 -0
  244. package/dist/core/store/AppConfig/context.d.ts +5 -0
  245. package/dist/core/store/AppConfig/context.d.ts.map +1 -1
  246. package/dist/core/store/AppConfig/context.js.map +1 -1
  247. package/dist/core/store/CombineProviders.d.ts +6 -1
  248. package/dist/core/store/CombineProviders.d.ts.map +1 -1
  249. package/dist/core/store/CombineProviders.js +4 -3
  250. package/dist/core/store/CombineProviders.js.map +1 -1
  251. package/dist/core/types/tools.d.ts +2 -1
  252. package/dist/core/types/tools.d.ts.map +1 -1
  253. package/dist/core/utils/imageUtils.d.ts.map +1 -1
  254. package/dist/core/utils/imageUtils.js +2 -1
  255. package/dist/core/utils/imageUtils.js.map +1 -1
  256. package/package.json +1 -1
@@ -28,18 +28,12 @@ import { FileItemComponent } from "../../../../../../../ui/FilesManager/src/File
28
28
  import { useFileActions } from "../../../../../../../ui/FilesManager/src/useFileActions";
29
29
  import ConfirmDialog from "../../../../../../../ConfirmDialog";
30
30
  import { Button } from "../../../../../../../ui/Button";
31
- import { useOrganization } from "../../../../../../../../hooks/organizations/organizations";
32
31
  import { PointCloudContext } from "../../../../../../../../store";
33
- import { useAppConfigContext } from "../../../../../../../../store/AppConfig/context";
34
32
  const POINT_CLOUD_OPTIONS = ["view", "delete", "info"];
35
- function PointCloudsSection({ files }) {
36
- var _a, _b, _c;
33
+ function PointCloudsSection({ files, pointcloudApiUrl }) {
37
34
  const t = useTranslations("PointCloudManagement");
38
- const { state: appConfigState } = useAppConfigContext();
39
- const API_BASE = (_a = appConfigState.runtimeConfig.pointcloudApiUrl) != null ? _a : "http://localhost:5101";
35
+ const API_BASE = pointcloudApiUrl != null ? pointcloudApiUrl : "http://localhost:5101";
40
36
  const { data: session } = useSession();
41
- const organizationId = (_c = (_b = session == null ? void 0 : session.user) == null ? void 0 : _b.organizationId) != null ? _c : null;
42
- const { organization } = useOrganization(organizationId ? organizationId.toString() : null);
43
37
  const { dispatch: pointCloudDispatch } = React.useContext(PointCloudContext);
44
38
  const [pointcloudsFiles, setPointcloudsFiles] = React.useState(
45
39
  () => files.map((f) => __spreadProps(__spreadValues({}, f), { isVisible: false }))
@@ -48,17 +42,17 @@ function PointCloudsSection({ files }) {
48
42
  const autoLoadedRef = React.useRef(false);
49
43
  const fileSyncKey = files.map(
50
44
  (file) => {
51
- var _a2;
52
- return `${file.id}:${file.name}:${Boolean(file.pointCloudUploaded)}:${Boolean(file.pointCloudPotreeConverted)}:${file.uploadedAt}:${(_a2 = file.potreeMetadataFileKey) != null ? _a2 : ""}`;
45
+ var _a;
46
+ return `${file.id}:${file.name}:${Boolean(file.pointCloudUploaded)}:${Boolean(file.pointCloudPotreeConverted)}:${file.uploadedAt}:${(_a = file.potreeMetadataFileKey) != null ? _a : ""}`;
53
47
  }
54
48
  ).join("|");
55
49
  React.useEffect(() => {
56
50
  setPointcloudsFiles((prev) => {
57
51
  const prevMap = new Map(prev.map((f) => [String(f.id), f]));
58
52
  return files.map((f) => {
59
- var _a2, _b2;
53
+ var _a, _b;
60
54
  return __spreadProps(__spreadValues({}, f), {
61
- isVisible: (_b2 = (_a2 = prevMap.get(String(f.id))) == null ? void 0 : _a2.isVisible) != null ? _b2 : false
55
+ isVisible: (_b = (_a = prevMap.get(String(f.id))) == null ? void 0 : _a.isVisible) != null ? _b : false
62
56
  });
63
57
  });
64
58
  });
@@ -135,15 +129,10 @@ function PointCloudsSection({ files }) {
135
129
  });
136
130
  }, [pointcloudsFiles]);
137
131
  async function createPointCloud(name, uploadedBy) {
138
- const res = await fetch(`${API_BASE}/point-cloud`, {
132
+ const res = await fetch("/api/point-cloud", {
139
133
  method: "POST",
140
134
  headers: { "Content-Type": "application/json" },
141
- body: JSON.stringify({
142
- name,
143
- uploadedBy,
144
- organizationName: organization == null ? void 0 : organization.name,
145
- organizationId
146
- })
135
+ body: JSON.stringify({ name, uploadedBy })
147
136
  });
148
137
  if (!res.ok) {
149
138
  const msg = await res.text();
@@ -246,7 +235,7 @@ function PointCloudsSection({ files }) {
246
235
  });
247
236
  }
248
237
  const handleFileUpload = async (file) => {
249
- var _a2;
238
+ var _a;
250
239
  if (!file) return;
251
240
  const originalFileName = file.name;
252
241
  const fileExt = originalFileName.toLowerCase();
@@ -264,7 +253,7 @@ function PointCloudsSection({ files }) {
264
253
  }
265
254
  try {
266
255
  console.log("Creating point cloud entry...");
267
- const userEmail = ((_a2 = session == null ? void 0 : session.user) == null ? void 0 : _a2.email) || null;
256
+ const userEmail = ((_a = session == null ? void 0 : session.user) == null ? void 0 : _a.email) || null;
268
257
  const { pointCloud, upload } = await createPointCloud(fileName, userEmail);
269
258
  console.log("Point cloud created:", pointCloud.id);
270
259
  console.log("Uploading file...");
@@ -288,8 +277,8 @@ function PointCloudsSection({ files }) {
288
277
  input.type = "file";
289
278
  input.accept = ".laz,.las";
290
279
  input.onchange = (e) => {
291
- var _a2;
292
- const file = (_a2 = e.target.files) == null ? void 0 : _a2[0];
280
+ var _a;
281
+ const file = (_a = e.target.files) == null ? void 0 : _a[0];
293
282
  if (file) {
294
283
  handleFileUpload(file);
295
284
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../../../../src/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/src/PointCloudSection.tsx"],"sourcesContent":["'use client'\r\n\r\n// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\nimport * as React from 'react'\r\nimport * as LR from 'lucide-react'\r\nimport { useTranslations } from 'next-intl'\r\nimport { useSession } from 'next-auth/react'\r\nimport { CollapsibleSection } from '../../../../../../../ui/CollapsibleSection'\r\nimport { FileItemComponent } from '../../../../../../../ui/FilesManager/src/FileItemComponent'\r\nimport { useFileActions } from '../../../../../../../ui/FilesManager/src/useFileActions'\r\nimport ConfirmDialog from '../../../../../../../ConfirmDialog'\r\nimport { Button } from '../../../../../../../ui/Button'\r\nimport { useOrganization } from '../../../../../../../../hooks/organizations/organizations'\r\nimport { DbFile } from '../../../../../../../../types/dbTypes'\r\nimport { PointCloudContext } from '../../../../../../../../store'\r\nimport { useAppConfigContext } from '../../../../../../../../store/AppConfig/context'\r\n\r\ntype CreatePointCloudResponse = {\r\n pointCloud: {\r\n id: string\r\n name: string\r\n }\r\n upload: {\r\n uploadUrl: string\r\n }\r\n}\r\n\r\ntype StartConversionResponse = {\r\n jobId: string\r\n}\r\n\r\nconst POINT_CLOUD_OPTIONS: import('../../../../../../../../types/global').FileAction[] = ['view', 'delete', 'info']\r\n\r\ninterface PointCloudsSectionProps {\r\n files: DbFile[]\r\n}\r\n\r\nexport function PointCloudsSection({ files }: PointCloudsSectionProps) {\r\n // Translation\r\n const t = useTranslations('PointCloudManagement')\r\n const { state: appConfigState } = useAppConfigContext()\r\n const API_BASE = appConfigState.runtimeConfig.pointcloudApiUrl ?? 'http://localhost:5101'\r\n\r\n // Get current user session\r\n const { data: session } = useSession()\r\n const organizationId = session?.user?.organizationId ?? null;\r\n const { organization } = useOrganization(organizationId ? organizationId.toString() : null);\r\n\r\n // Point cloud context for loading/unloading clouds in the viewer\r\n const { dispatch: pointCloudDispatch } = React.useContext(PointCloudContext)\r\n\r\n // State for point clouds — includes isVisible to track which are loaded in viewer\r\n const [pointcloudsFiles, setPointcloudsFiles] = React.useState<(DbFile & { isVisible?: boolean })[]>(\r\n () => files.map(f => ({ ...f, isVisible: false }))\r\n )\r\n const esRef = React.useRef<EventSource | null>(null)\r\n const autoLoadedRef = React.useRef(false)\r\n\r\n const fileSyncKey = files\r\n .map(\r\n (file) =>\r\n `${file.id}:${file.name}:${Boolean(file.pointCloudUploaded)}:${Boolean(file.pointCloudPotreeConverted)}:${file.uploadedAt}:${file.potreeMetadataFileKey ?? ''}`\r\n )\r\n .join('|')\r\n\r\n // Sync incoming files from props while preserving isVisible state for known files\r\n React.useEffect(() => {\r\n setPointcloudsFiles(prev => {\r\n const prevMap = new Map(prev.map(f => [String(f.id), f]))\r\n return files.map(f => ({\r\n ...f,\r\n isVisible: prevMap.get(String(f.id))?.isVisible ?? false,\r\n }))\r\n })\r\n }, [fileSyncKey])\r\n\r\n // Auto-load the most recently uploaded converted file on first access\r\n React.useEffect(() => {\r\n if (autoLoadedRef.current || files.length === 0) return\r\n\r\n const readyFiles = files.filter(f => Boolean(f.pointCloudPotreeConverted))\r\n if (readyFiles.length === 0) return\r\n\r\n const lastFile = readyFiles.reduce((latest, f) =>\r\n new Date(f.uploadedAt) > new Date(latest.uploadedAt) ? f : latest\r\n )\r\n\r\n autoLoadedRef.current = true\r\n pointCloudDispatch({ type: 'LOAD_POINT_CLOUD', payload: { id: String(lastFile.id) } })\r\n setPointcloudsFiles(prev =>\r\n prev.map(f => ({ ...f, isVisible: String(f.id) === String(lastFile.id) }))\r\n )\r\n }, [fileSyncKey, files, pointCloudDispatch])\r\n\r\n React.useEffect(() => {\r\n // Cleanup SSE on unmount\r\n return () => {\r\n if (esRef.current) {\r\n esRef.current.close()\r\n }\r\n }\r\n }, [])\r\n\r\n // Toggle a point cloud on/off in the viewer via context\r\n const handleView = React.useCallback((file: DbFile, newVisibility: boolean) => {\r\n const id = String(file.id)\r\n if (newVisibility) {\r\n pointCloudDispatch({ type: 'LOAD_POINT_CLOUD', payload: { id } })\r\n } else {\r\n pointCloudDispatch({ type: 'UNLOAD_POINT_CLOUD', payload: { id } })\r\n }\r\n }, [pointCloudDispatch])\r\n\r\n const handleDeleteFile = React.useCallback(async (file: DbFile) => {\r\n const res = await fetch(`${API_BASE}/point-cloud/${encodeURIComponent(String(file.id))}`, {\r\n method: 'DELETE',\r\n })\r\n\r\n if (!res.ok) {\r\n const msg = await res.text()\r\n throw new Error(msg || `Delete failed (${res.status})`)\r\n }\r\n }, [])\r\n\r\n const handleConvert = React.useCallback(async (file: DbFile) => {\r\n const res = await fetch(\r\n `${API_BASE}/point-cloud/${encodeURIComponent(String(file.id))}/convert-to-potree`,\r\n {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ options: { sampling_method: 'poisson' } }),\r\n }\r\n )\r\n\r\n if (!res.ok) {\r\n const msg = await res.text()\r\n throw new Error(msg || `Conversion failed (${res.status})`)\r\n }\r\n\r\n const { jobId } = await res.json() as StartConversionResponse\r\n subscribeToProgress(jobId, file.id)\r\n }, [])\r\n\r\n const handleDeletePointCloud = React.useCallback((file: DbFile) => {\r\n pointCloudDispatch({ type: 'UNLOAD_POINT_CLOUD', payload: { id: String(file.id) } })\r\n }, [pointCloudDispatch])\r\n\r\n // Use the generic file actions hook\r\n const { handleAction, deleteDialog } = useFileActions({\r\n files: pointcloudsFiles,\r\n setFiles: setPointcloudsFiles as React.Dispatch<React.SetStateAction<(DbFile & { isVisible?: boolean })[]>>,\r\n buildingId: 0,\r\n handleDeleteFile,\r\n onView: handleView,\r\n onDelete: handleDeletePointCloud,\r\n })\r\n\r\n // Sort: visible (loaded) files at the top, preserving relative order within each group\r\n const sortedFiles = React.useMemo(() => {\r\n return [...pointcloudsFiles].sort((a, b) => {\r\n const aLoaded = a.isVisible !== false ? 1 : 0\r\n const bLoaded = b.isVisible !== false ? 1 : 0\r\n return bLoaded - aLoaded\r\n })\r\n }, [pointcloudsFiles])\r\n\r\n // Create point cloud entry\r\n async function createPointCloud(name: string, uploadedBy: string | null): Promise<CreatePointCloudResponse> {\r\n const res = await fetch(`${API_BASE}/point-cloud`, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ \r\n name, \r\n uploadedBy,\r\n organizationName: organization?.name,\r\n organizationId: organizationId\r\n }),\r\n })\r\n\r\n if (!res.ok) {\r\n const msg = await res.text()\r\n throw new Error(`Create point-cloud failed: ${msg || res.status}`)\r\n }\r\n\r\n return res.json()\r\n }\r\n\r\n // Upload to presigned URL\r\n function uploadToPresignedUrl(\r\n url: string,\r\n file: File,\r\n onProgress?: (pct: number) => void\r\n ): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n try {\r\n const xhr = new XMLHttpRequest()\r\n xhr.open('PUT', url, true)\r\n\r\n if (onProgress) {\r\n xhr.upload.onprogress = (evt) => {\r\n if (evt.lengthComputable) {\r\n const pct = Math.round((evt.loaded / evt.total) * 100)\r\n onProgress(pct)\r\n }\r\n }\r\n }\r\n\r\n xhr.onload = () => {\r\n if (xhr.status >= 200 && xhr.status < 300) resolve()\r\n else reject(new Error(`Upload failed with status ${xhr.status}`))\r\n }\r\n\r\n xhr.onerror = () => reject(new Error('Network error during upload'))\r\n xhr.send(file)\r\n } catch (err) {\r\n reject(err)\r\n }\r\n })\r\n }\r\n\r\n // Start conversion\r\n async function startConversion(pointCloudId: string): Promise<StartConversionResponse> {\r\n const res = await fetch(\r\n `${API_BASE}/point-cloud/${encodeURIComponent(pointCloudId)}/convert-to-potree`,\r\n {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ options: { sampling_method: 'poisson' } }),\r\n }\r\n )\r\n\r\n if (!res.ok) {\r\n const msg = await res.text()\r\n throw new Error(`convert-to-potree failed: ${msg || res.status}`)\r\n }\r\n\r\n return res.json()\r\n }\r\n\r\n // Subscribe to conversion progress\r\n function subscribeToProgress(jobId: string, pointCloudId: number) {\r\n if (!jobId) return\r\n\r\n if (esRef.current) {\r\n esRef.current.close()\r\n }\r\n\r\n const es = new EventSource(\r\n `${API_BASE}/events/convert-progress/${encodeURIComponent(jobId)}`\r\n )\r\n esRef.current = es\r\n\r\n es.onopen = () => console.log('SSE connection opened')\r\n\r\n es.onerror = (event) => {\r\n console.error('SSE error:', event)\r\n // Update to failed state\r\n setPointcloudsFiles((prev) =>\r\n prev.map((pc) =>\r\n Number(pc.id) === pointCloudId\r\n ? { ...pc, status: 'idle', conversionProgress: 0 }\r\n : pc\r\n )\r\n )\r\n }\r\n\r\n es.addEventListener('progress', (event) => {\r\n try {\r\n const msgEvent = event as MessageEvent\r\n const data = JSON.parse(msgEvent.data)\r\n\r\n console.log('[progress]', data.status, data.message, data.progress)\r\n\r\n if (typeof data.progress === 'number') {\r\n setPointcloudsFiles((prev) =>\r\n prev.map((pc) =>\r\n Number(pc.id) === pointCloudId\r\n ? { ...pc, conversionProgress: data.progress }\r\n : pc\r\n )\r\n )\r\n }\r\n } catch (err) {\r\n console.error('Failed to parse progress event', err)\r\n }\r\n })\r\n\r\n es.addEventListener('finished', () => {\r\n console.log('[finished] Conversion completed')\r\n setPointcloudsFiles((prev) =>\r\n prev.map((pc) =>\r\n Number(pc.id) === pointCloudId\r\n ? { ...pc, status: 'idle', conversionProgress: 100 }\r\n : pc\r\n )\r\n )\r\n es.close()\r\n esRef.current = null\r\n })\r\n\r\n es.addEventListener('failed', () => {\r\n console.log('[failed] Conversion failed')\r\n setPointcloudsFiles((prev) =>\r\n prev.map((pc) =>\r\n Number(pc.id) === pointCloudId\r\n ? { ...pc, status: 'idle', conversionProgress: 0 }\r\n : pc\r\n )\r\n )\r\n es.close()\r\n esRef.current = null\r\n })\r\n }\r\n\r\n // Handle file upload\r\n const handleFileUpload = async (file: File) => {\r\n if (!file) return\r\n\r\n const originalFileName = file.name\r\n const fileExt = originalFileName.toLowerCase()\r\n const baseFileName = originalFileName.replace(/\\.(laz|las)$/i, '')\r\n\r\n // Validate file extension\r\n if (!fileExt.endsWith('.laz') && !fileExt.endsWith('.las')) {\r\n alert('Please select a LAZ or LAS file.')\r\n return\r\n }\r\n\r\n // Check for duplicate names and append (1), (2), etc.\r\n let fileName = baseFileName\r\n let counter = 1\r\n const existingNames = pointcloudsFiles.map((pc) => pc.name)\r\n \r\n while (existingNames.includes(fileName)) {\r\n fileName = `${baseFileName} (${counter})`\r\n counter++\r\n }\r\n\r\n try {\r\n console.log('Creating point cloud entry...')\r\n const userEmail = session?.user?.email || null\r\n const { pointCloud, upload } = await createPointCloud(fileName, userEmail)\r\n console.log('Point cloud created:', pointCloud.id)\r\n\r\n console.log('Uploading file...')\r\n await uploadToPresignedUrl(upload.uploadUrl, file, (pct) => {\r\n console.log(`Upload progress: ${pct}%`)\r\n })\r\n console.log('Upload complete!')\r\n\r\n console.log('Starting conversion...')\r\n const conversion = await startConversion(pointCloud.id)\r\n console.log('Conversion started:', conversion.jobId)\r\n\r\n // Subscribe to progress\r\n subscribeToProgress(conversion.jobId, Number(pointCloud.id))\r\n } catch (error) {\r\n console.error('Error uploading point cloud:', error)\r\n \r\n alert(\r\n error instanceof Error\r\n ? `Failed to upload: ${error.message}`\r\n : 'Failed to upload point cloud'\r\n )\r\n }\r\n }\r\n\r\n // Handle upload button click\r\n const handleUpload = () => {\r\n const input = document.createElement('input')\r\n input.type = 'file'\r\n input.accept = '.laz,.las'\r\n input.onchange = (e) => {\r\n const file = (e.target as HTMLInputElement).files?.[0]\r\n if (file) {\r\n handleFileUpload(file)\r\n }\r\n }\r\n input.click()\r\n }\r\n\r\n return (\r\n <>\r\n <CollapsibleSection\r\n title={t('title')}\r\n icon={LR.Grip}\r\n className=\"h-1/2 overflow-y-auto\"\r\n itemCount={pointcloudsFiles.length}\r\n onAddItem={handleUpload}\r\n addItemTitle={t('uploadTitle')}\r\n >\r\n <div className=\"space-y-1\">\r\n {sortedFiles.length === 0 ? (\r\n <div className=\"px-2 py-3 text-sm text-muted-foreground text-center\">\r\n {t('noPointClouds')}\r\n </div>\r\n ) : (\r\n sortedFiles.map((file) => (\r\n <div key={file.id} className=\"flex items-center gap-1\">\r\n <div className=\"flex-1 min-w-0\">\r\n <FileItemComponent\r\n file={file}\r\n onAction={handleAction}\r\n options={POINT_CLOUD_OPTIONS}\r\n />\r\n </div>\r\n {Boolean(file.pointCloudUploaded) && !Boolean(file.pointCloudPotreeConverted) && (\r\n <Button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n className=\"h-6 w-6 p-0\"\r\n onClick={() => void handleConvert(file)}\r\n title={t('convertTitle')}\r\n >\r\n <LR.RefreshCw className=\"h-3 w-3\" />\r\n </Button>\r\n )}\r\n </div>\r\n ))\r\n )}\r\n </div>\r\n </CollapsibleSection>\r\n\r\n <ConfirmDialog\r\n isOpen={deleteDialog.isOpen}\r\n isDeleting={deleteDialog.isDeleting}\r\n onOpenChange={deleteDialog.onOpenChange}\r\n handleConfirm={deleteDialog.onConfirm}\r\n itemName={deleteDialog.itemName}\r\n dataType=\"file\"\r\n />\r\n </>\r\n )\r\n}\r\n"],"mappings":"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","names":["_a","_b"]}
1
+ {"version":3,"sources":["../../../../../../../../../../src/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/src/PointCloudSection.tsx"],"sourcesContent":["'use client'\r\n\r\n// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\nimport * as React from 'react'\r\nimport * as LR from 'lucide-react'\r\nimport { useTranslations } from 'next-intl'\r\nimport { useSession } from 'next-auth/react'\r\nimport { CollapsibleSection } from '../../../../../../../ui/CollapsibleSection'\r\nimport { FileItemComponent } from '../../../../../../../ui/FilesManager/src/FileItemComponent'\r\nimport { useFileActions } from '../../../../../../../ui/FilesManager/src/useFileActions'\r\nimport ConfirmDialog from '../../../../../../../ConfirmDialog'\r\nimport { Button } from '../../../../../../../ui/Button'\r\nimport { DbFile } from '../../../../../../../../types/dbTypes'\r\nimport { PointCloudContext } from '../../../../../../../../store'\r\n// import { useAppConfigContext } from '../../../../../../../../store/AppConfig/context'\r\n\r\ntype CreatePointCloudResponse = {\r\n pointCloud: {\r\n id: string\r\n name: string\r\n }\r\n upload: {\r\n uploadUrl: string\r\n }\r\n}\r\n\r\ntype StartConversionResponse = {\r\n jobId: string\r\n}\r\n\r\nconst POINT_CLOUD_OPTIONS: import('../../../../../../../../types/global').FileAction[] = ['view', 'delete', 'info']\r\n\r\ninterface PointCloudsSectionProps {\r\n files: DbFile[]\r\n pointcloudApiUrl?: string\r\n}\r\n\r\nexport function PointCloudsSection({ files, pointcloudApiUrl }: PointCloudsSectionProps) {\r\n // Translation\r\n const t = useTranslations('PointCloudManagement')\r\n const API_BASE = pointcloudApiUrl ?? 'http://localhost:5101'\r\n\r\n // Get current user session (needed for uploadedBy)\r\n const { data: session } = useSession()\r\n\r\n // Point cloud context for loading/unloading clouds in the viewer\r\n const { dispatch: pointCloudDispatch } = React.useContext(PointCloudContext)\r\n\r\n // State for point clouds — includes isVisible to track which are loaded in viewer\r\n const [pointcloudsFiles, setPointcloudsFiles] = React.useState<(DbFile & { isVisible?: boolean })[]>(\r\n () => files.map(f => ({ ...f, isVisible: false }))\r\n )\r\n const esRef = React.useRef<EventSource | null>(null)\r\n const autoLoadedRef = React.useRef(false)\r\n\r\n const fileSyncKey = files\r\n .map(\r\n (file) =>\r\n `${file.id}:${file.name}:${Boolean(file.pointCloudUploaded)}:${Boolean(file.pointCloudPotreeConverted)}:${file.uploadedAt}:${file.potreeMetadataFileKey ?? ''}`\r\n )\r\n .join('|')\r\n\r\n // Sync incoming files from props while preserving isVisible state for known files\r\n React.useEffect(() => {\r\n setPointcloudsFiles(prev => {\r\n const prevMap = new Map(prev.map(f => [String(f.id), f]))\r\n return files.map(f => ({\r\n ...f,\r\n isVisible: prevMap.get(String(f.id))?.isVisible ?? false,\r\n }))\r\n })\r\n }, [fileSyncKey])\r\n\r\n // Auto-load the most recently uploaded converted file on first access\r\n React.useEffect(() => {\r\n if (autoLoadedRef.current || files.length === 0) return\r\n\r\n const readyFiles = files.filter(f => Boolean(f.pointCloudPotreeConverted))\r\n if (readyFiles.length === 0) return\r\n\r\n const lastFile = readyFiles.reduce((latest, f) =>\r\n new Date(f.uploadedAt) > new Date(latest.uploadedAt) ? f : latest\r\n )\r\n\r\n autoLoadedRef.current = true\r\n pointCloudDispatch({ type: 'LOAD_POINT_CLOUD', payload: { id: String(lastFile.id) } })\r\n setPointcloudsFiles(prev =>\r\n prev.map(f => ({ ...f, isVisible: String(f.id) === String(lastFile.id) }))\r\n )\r\n }, [fileSyncKey, files, pointCloudDispatch])\r\n\r\n React.useEffect(() => {\r\n // Cleanup SSE on unmount\r\n return () => {\r\n if (esRef.current) {\r\n esRef.current.close()\r\n }\r\n }\r\n }, [])\r\n\r\n // Toggle a point cloud on/off in the viewer via context\r\n const handleView = React.useCallback((file: DbFile, newVisibility: boolean) => {\r\n const id = String(file.id)\r\n if (newVisibility) {\r\n pointCloudDispatch({ type: 'LOAD_POINT_CLOUD', payload: { id } })\r\n } else {\r\n pointCloudDispatch({ type: 'UNLOAD_POINT_CLOUD', payload: { id } })\r\n }\r\n }, [pointCloudDispatch])\r\n\r\n const handleDeleteFile = React.useCallback(async (file: DbFile) => {\r\n const res = await fetch(`${API_BASE}/point-cloud/${encodeURIComponent(String(file.id))}`, {\r\n method: 'DELETE',\r\n })\r\n\r\n if (!res.ok) {\r\n const msg = await res.text()\r\n throw new Error(msg || `Delete failed (${res.status})`)\r\n }\r\n }, [])\r\n\r\n const handleConvert = React.useCallback(async (file: DbFile) => {\r\n const res = await fetch(\r\n `${API_BASE}/point-cloud/${encodeURIComponent(String(file.id))}/convert-to-potree`,\r\n {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ options: { sampling_method: 'poisson' } }),\r\n }\r\n )\r\n\r\n if (!res.ok) {\r\n const msg = await res.text()\r\n throw new Error(msg || `Conversion failed (${res.status})`)\r\n }\r\n\r\n const { jobId } = await res.json() as StartConversionResponse\r\n subscribeToProgress(jobId, file.id)\r\n }, [])\r\n\r\n const handleDeletePointCloud = React.useCallback((file: DbFile) => {\r\n pointCloudDispatch({ type: 'UNLOAD_POINT_CLOUD', payload: { id: String(file.id) } })\r\n }, [pointCloudDispatch])\r\n\r\n // Use the generic file actions hook\r\n const { handleAction, deleteDialog } = useFileActions({\r\n files: pointcloudsFiles,\r\n setFiles: setPointcloudsFiles as React.Dispatch<React.SetStateAction<(DbFile & { isVisible?: boolean })[]>>,\r\n buildingId: 0,\r\n handleDeleteFile,\r\n onView: handleView,\r\n onDelete: handleDeletePointCloud,\r\n })\r\n\r\n // Sort: visible (loaded) files at the top, preserving relative order within each group\r\n const sortedFiles = React.useMemo(() => {\r\n return [...pointcloudsFiles].sort((a, b) => {\r\n const aLoaded = a.isVisible !== false ? 1 : 0\r\n const bLoaded = b.isVisible !== false ? 1 : 0\r\n return bLoaded - aLoaded\r\n })\r\n }, [pointcloudsFiles])\r\n\r\n // Create point cloud entry — routed through the CDT proxy so that\r\n // organizationId is injected server-side from the authenticated session.\r\n async function createPointCloud(name: string, uploadedBy: string | null): Promise<CreatePointCloudResponse> {\r\n const res = await fetch('/api/point-cloud', {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ name, uploadedBy }),\r\n })\r\n\r\n if (!res.ok) {\r\n const msg = await res.text()\r\n throw new Error(`Create point-cloud failed: ${msg || res.status}`)\r\n }\r\n\r\n return res.json()\r\n }\r\n\r\n // Upload to presigned URL\r\n function uploadToPresignedUrl(\r\n url: string,\r\n file: File,\r\n onProgress?: (pct: number) => void\r\n ): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n try {\r\n const xhr = new XMLHttpRequest()\r\n xhr.open('PUT', url, true)\r\n\r\n if (onProgress) {\r\n xhr.upload.onprogress = (evt) => {\r\n if (evt.lengthComputable) {\r\n const pct = Math.round((evt.loaded / evt.total) * 100)\r\n onProgress(pct)\r\n }\r\n }\r\n }\r\n\r\n xhr.onload = () => {\r\n if (xhr.status >= 200 && xhr.status < 300) resolve()\r\n else reject(new Error(`Upload failed with status ${xhr.status}`))\r\n }\r\n\r\n xhr.onerror = () => reject(new Error('Network error during upload'))\r\n xhr.send(file)\r\n } catch (err) {\r\n reject(err)\r\n }\r\n })\r\n }\r\n\r\n // Start conversion\r\n async function startConversion(pointCloudId: string): Promise<StartConversionResponse> {\r\n const res = await fetch(\r\n `${API_BASE}/point-cloud/${encodeURIComponent(pointCloudId)}/convert-to-potree`,\r\n {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ options: { sampling_method: 'poisson' } }),\r\n }\r\n )\r\n\r\n if (!res.ok) {\r\n const msg = await res.text()\r\n throw new Error(`convert-to-potree failed: ${msg || res.status}`)\r\n }\r\n\r\n return res.json()\r\n }\r\n\r\n // Subscribe to conversion progress\r\n function subscribeToProgress(jobId: string, pointCloudId: number) {\r\n if (!jobId) return\r\n\r\n if (esRef.current) {\r\n esRef.current.close()\r\n }\r\n\r\n const es = new EventSource(\r\n `${API_BASE}/events/convert-progress/${encodeURIComponent(jobId)}`\r\n )\r\n esRef.current = es\r\n\r\n es.onopen = () => console.log('SSE connection opened')\r\n\r\n es.onerror = (event) => {\r\n console.error('SSE error:', event)\r\n // Update to failed state\r\n setPointcloudsFiles((prev) =>\r\n prev.map((pc) =>\r\n Number(pc.id) === pointCloudId\r\n ? { ...pc, status: 'idle', conversionProgress: 0 }\r\n : pc\r\n )\r\n )\r\n }\r\n\r\n es.addEventListener('progress', (event) => {\r\n try {\r\n const msgEvent = event as MessageEvent\r\n const data = JSON.parse(msgEvent.data)\r\n\r\n console.log('[progress]', data.status, data.message, data.progress)\r\n\r\n if (typeof data.progress === 'number') {\r\n setPointcloudsFiles((prev) =>\r\n prev.map((pc) =>\r\n Number(pc.id) === pointCloudId\r\n ? { ...pc, conversionProgress: data.progress }\r\n : pc\r\n )\r\n )\r\n }\r\n } catch (err) {\r\n console.error('Failed to parse progress event', err)\r\n }\r\n })\r\n\r\n es.addEventListener('finished', () => {\r\n console.log('[finished] Conversion completed')\r\n setPointcloudsFiles((prev) =>\r\n prev.map((pc) =>\r\n Number(pc.id) === pointCloudId\r\n ? { ...pc, status: 'idle', conversionProgress: 100 }\r\n : pc\r\n )\r\n )\r\n es.close()\r\n esRef.current = null\r\n })\r\n\r\n es.addEventListener('failed', () => {\r\n console.log('[failed] Conversion failed')\r\n setPointcloudsFiles((prev) =>\r\n prev.map((pc) =>\r\n Number(pc.id) === pointCloudId\r\n ? { ...pc, status: 'idle', conversionProgress: 0 }\r\n : pc\r\n )\r\n )\r\n es.close()\r\n esRef.current = null\r\n })\r\n }\r\n\r\n // Handle file upload\r\n const handleFileUpload = async (file: File) => {\r\n if (!file) return\r\n\r\n const originalFileName = file.name\r\n const fileExt = originalFileName.toLowerCase()\r\n const baseFileName = originalFileName.replace(/\\.(laz|las)$/i, '')\r\n\r\n // Validate file extension\r\n if (!fileExt.endsWith('.laz') && !fileExt.endsWith('.las')) {\r\n alert('Please select a LAZ or LAS file.')\r\n return\r\n }\r\n\r\n // Check for duplicate names and append (1), (2), etc.\r\n let fileName = baseFileName\r\n let counter = 1\r\n const existingNames = pointcloudsFiles.map((pc) => pc.name)\r\n \r\n while (existingNames.includes(fileName)) {\r\n fileName = `${baseFileName} (${counter})`\r\n counter++\r\n }\r\n\r\n try {\r\n console.log('Creating point cloud entry...')\r\n const userEmail = session?.user?.email || null\r\n const { pointCloud, upload } = await createPointCloud(fileName, userEmail)\r\n console.log('Point cloud created:', pointCloud.id)\r\n\r\n console.log('Uploading file...')\r\n await uploadToPresignedUrl(upload.uploadUrl, file, (pct) => {\r\n console.log(`Upload progress: ${pct}%`)\r\n })\r\n console.log('Upload complete!')\r\n\r\n console.log('Starting conversion...')\r\n const conversion = await startConversion(pointCloud.id)\r\n console.log('Conversion started:', conversion.jobId)\r\n\r\n // Subscribe to progress\r\n subscribeToProgress(conversion.jobId, Number(pointCloud.id))\r\n } catch (error) {\r\n console.error('Error uploading point cloud:', error)\r\n \r\n alert(\r\n error instanceof Error\r\n ? `Failed to upload: ${error.message}`\r\n : 'Failed to upload point cloud'\r\n )\r\n }\r\n }\r\n\r\n // Handle upload button click\r\n const handleUpload = () => {\r\n const input = document.createElement('input')\r\n input.type = 'file'\r\n input.accept = '.laz,.las'\r\n input.onchange = (e) => {\r\n const file = (e.target as HTMLInputElement).files?.[0]\r\n if (file) {\r\n handleFileUpload(file)\r\n }\r\n }\r\n input.click()\r\n }\r\n\r\n return (\r\n <>\r\n <CollapsibleSection\r\n title={t('title')}\r\n icon={LR.Grip}\r\n className=\"h-1/2 overflow-y-auto\"\r\n itemCount={pointcloudsFiles.length}\r\n onAddItem={handleUpload}\r\n addItemTitle={t('uploadTitle')}\r\n >\r\n <div className=\"space-y-1\">\r\n {sortedFiles.length === 0 ? (\r\n <div className=\"px-2 py-3 text-sm text-muted-foreground text-center\">\r\n {t('noPointClouds')}\r\n </div>\r\n ) : (\r\n sortedFiles.map((file) => (\r\n <div key={file.id} className=\"flex items-center gap-1\">\r\n <div className=\"flex-1 min-w-0\">\r\n <FileItemComponent\r\n file={file}\r\n onAction={handleAction}\r\n options={POINT_CLOUD_OPTIONS}\r\n />\r\n </div>\r\n {Boolean(file.pointCloudUploaded) && !Boolean(file.pointCloudPotreeConverted) && (\r\n <Button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n className=\"h-6 w-6 p-0\"\r\n onClick={() => void handleConvert(file)}\r\n title={t('convertTitle')}\r\n >\r\n <LR.RefreshCw className=\"h-3 w-3\" />\r\n </Button>\r\n )}\r\n </div>\r\n ))\r\n )}\r\n </div>\r\n </CollapsibleSection>\r\n\r\n <ConfirmDialog\r\n isOpen={deleteDialog.isOpen}\r\n isDeleting={deleteDialog.isDeleting}\r\n onOpenChange={deleteDialog.onOpenChange}\r\n handleConfirm={deleteDialog.onConfirm}\r\n itemName={deleteDialog.itemName}\r\n dataType=\"file\"\r\n />\r\n </>\r\n )\r\n}\r\n"],"mappings":"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","names":[]}
@@ -0,0 +1,2 @@
1
+ export declare function useCaptureScreenshot(): () => Promise<string | null>;
2
+ //# sourceMappingURL=useCaptureScreenshot.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,63 @@
1
+ "use client";
2
+ import * as React from "react";
3
+ import { MenusContext, MapContext, BimContext } from "../store";
4
+ import { ViewerNames } from "../types";
5
+ function blobToBase64(blob) {
6
+ return new Promise((resolve) => {
7
+ const reader = new FileReader();
8
+ reader.onload = () => resolve(reader.result);
9
+ reader.readAsDataURL(blob);
10
+ });
11
+ }
12
+ function useCaptureScreenshot() {
13
+ const { state: menusState } = React.useContext(MenusContext);
14
+ const { currentViewer } = menusState.menus;
15
+ const { state: mapState } = React.useContext(MapContext);
16
+ const { map } = mapState.map;
17
+ const { state: bimState } = React.useContext(BimContext);
18
+ const { world } = bimState.bim;
19
+ return React.useCallback(() => {
20
+ return new Promise((resolve) => {
21
+ try {
22
+ if (currentViewer === ViewerNames.map && map) {
23
+ map.once("render", () => {
24
+ map.getCanvas().toBlob(async (blob) => {
25
+ resolve(blob ? await blobToBase64(blob) : null);
26
+ }, "image/png", 1);
27
+ });
28
+ 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;
39
+ }
40
+ }
41
+ let canvas = null;
42
+ if (currentViewer === ViewerNames.pointcloud) {
43
+ canvas = document.querySelector("#pointcloud-viewer-container canvas");
44
+ } else {
45
+ canvas = document.querySelector("canvas");
46
+ }
47
+ if (!canvas) {
48
+ resolve(null);
49
+ return;
50
+ }
51
+ canvas.toBlob(async (blob) => {
52
+ resolve(blob ? await blobToBase64(blob) : null);
53
+ }, "image/png", 1);
54
+ } catch (e) {
55
+ resolve(null);
56
+ }
57
+ });
58
+ }, [currentViewer, map, world]);
59
+ }
60
+ export {
61
+ useCaptureScreenshot
62
+ };
63
+ //# sourceMappingURL=useCaptureScreenshot.js.map
@@ -0,0 +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"]}
@@ -0,0 +1,3 @@
1
+ import { GeocodingRuntimeConfig } from '../components/viewers/map/utils/geocoding/config';
2
+ export declare function useGeocodingRuntimeConfig(config?: GeocodingRuntimeConfig): void;
3
+ //# sourceMappingURL=useGeocodingRuntimeConfig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useGeocodingRuntimeConfig.d.ts","sourceRoot":"","sources":["../../../src/core/hooks/useGeocodingRuntimeConfig.ts"],"names":[],"mappings":"AAOA,OAAO,EAAsB,sBAAsB,EAAE,MAAM,kDAAkD,CAAA;AAK7G,wBAAgB,yBAAyB,CAAC,MAAM,CAAC,EAAE,sBAAsB,GAAG,IAAI,CAS/E"}
@@ -0,0 +1,17 @@
1
+ "use client";
2
+ import * as React from "react";
3
+ import { setGeocodingConfig } from "../components/viewers/map/utils/geocoding/config";
4
+ function useGeocodingRuntimeConfig(config) {
5
+ React.useEffect(() => {
6
+ setGeocodingConfig(config != null ? config : {});
7
+ }, [
8
+ config == null ? void 0 : config.geocodeEarthApiKey,
9
+ config == null ? void 0 : config.geocoderUrl,
10
+ config == null ? void 0 : config.photonUrl,
11
+ config == null ? void 0 : config.nominatimUrl
12
+ ]);
13
+ }
14
+ export {
15
+ useGeocodingRuntimeConfig
16
+ };
17
+ //# sourceMappingURL=useGeocodingRuntimeConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/core/hooks/useGeocodingRuntimeConfig.ts"],"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\n// import { useAppConfigContext } from '../store'\r\nimport { setGeocodingConfig, GeocodingRuntimeConfig } from '../components/viewers/map/utils/geocoding/config'\r\n\r\n// Syncs geocoding runtime values into the geocoding module's mutable state.\r\n// Must be called once in a client component before any geocoding request fires.\r\n// When called without args, falls back to free public services (Photon + Nominatim).\r\nexport function useGeocodingRuntimeConfig(config?: GeocodingRuntimeConfig): void {\r\n React.useEffect(() => {\r\n setGeocodingConfig(config ?? {})\r\n }, [\r\n config?.geocodeEarthApiKey,\r\n config?.geocoderUrl,\r\n config?.photonUrl,\r\n config?.nominatimUrl,\r\n ])\r\n}\r\n"],"mappings":";AAKA,YAAY,WAAW;AAEvB,SAAS,0BAAkD;AAKpD,SAAS,0BAA0B,QAAuC;AAC/E,QAAM,UAAU,MAAM;AACpB,uBAAmB,0BAAU,CAAC,CAAC;AAAA,EACjC,GAAG;AAAA,IACD,iCAAQ;AAAA,IACR,iCAAQ;AAAA,IACR,iCAAQ;AAAA,IACR,iCAAQ;AAAA,EACV,CAAC;AACH;","names":[]}
@@ -5,6 +5,11 @@ export type RuntimeConfig = {
5
5
  martinUrl?: string;
6
6
  recaptchaSiteKey?: string;
7
7
  pointcloudApiUrl?: string;
8
+ geocodeEarthApiKey?: string;
9
+ geocoderUrl?: string;
10
+ photonUrl?: string;
11
+ nominatimUrl?: string;
12
+ maptilerKey?: string;
8
13
  };
9
14
  type InitialStateType = {
10
15
  appConfig: AppConfigState;
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../../src/core/store/AppConfig/context.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAoB,gBAAgB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAE9E,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B,CAAA;AAED,KAAK,gBAAgB,GAAG;IACtB,SAAS,EAAE,cAAc,CAAA;IACzB,aAAa,EAAE,aAAa,CAAA;CAC7B,CAAA;AAkBD,eAAO,MAAM,gBAAgB;WACpB,gBAAgB;cACb,KAAK,CAAC,QAAQ,CAAC,gBAAgB,CAAC;EAI1C,CAAA;AAEF,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC;IAAE,aAAa,CAAC,EAAE,aAAa,CAAA;CAAE,CAAC,CAQlG,CAAA;AAED,eAAO,MAAM,mBAAmB;WAjBvB,gBAAgB;cACb,KAAK,CAAC,QAAQ,CAAC,gBAAgB,CAAC;CAgB+B,CAAA"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../../src/core/store/AppConfig/context.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAoB,gBAAgB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAE9E,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,KAAK,gBAAgB,GAAG;IACtB,SAAS,EAAE,cAAc,CAAA;IACzB,aAAa,EAAE,aAAa,CAAA;CAC7B,CAAA;AAkBD,eAAO,MAAM,gBAAgB;WACpB,gBAAgB;cACb,KAAK,CAAC,QAAQ,CAAC,gBAAgB,CAAC;EAI1C,CAAA;AAEF,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC;IAAE,aAAa,CAAC,EAAE,aAAa,CAAA;CAAE,CAAC,CAQlG,CAAA;AAED,eAAO,MAAM,mBAAmB;WAjBvB,gBAAgB;cACb,KAAK,CAAC,QAAQ,CAAC,gBAAgB,CAAC;CAgB+B,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/core/store/AppConfig/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 { AppConfigReducer, AppConfigActions, AppConfigState } from './reducer'\r\n\r\nexport type RuntimeConfig = {\r\n minioUrl?: string\r\n martinUrl?: string\r\n recaptchaSiteKey?: string\r\n pointcloudApiUrl?: string\r\n}\r\n\r\ntype InitialStateType = {\r\n appConfig: AppConfigState\r\n runtimeConfig: RuntimeConfig\r\n}\r\n\r\nconst initialState: InitialStateType = {\r\n appConfig: {\r\n organization: null,\r\n user: null,\r\n },\r\n runtimeConfig: {},\r\n}\r\n\r\nconst reducer = (\r\n { appConfig, runtimeConfig }: InitialStateType,\r\n action: AppConfigActions,\r\n): InitialStateType => ({\r\n appConfig: AppConfigReducer(appConfig, action),\r\n runtimeConfig,\r\n})\r\n\r\nexport const AppConfigContext = React.createContext<{\r\n state: InitialStateType\r\n dispatch: React.Dispatch<AppConfigActions>\r\n}>({\r\n state: initialState,\r\n dispatch: () => null,\r\n})\r\n\r\nexport const AppConfigProvider: React.FC<React.PropsWithChildren<{ runtimeConfig?: RuntimeConfig }>> = ({ children, runtimeConfig = {} }) => {\r\n const [state, dispatch] = React.useReducer(reducer, { ...initialState, runtimeConfig })\r\n const value = React.useMemo(() => ({ state, dispatch }), [state])\r\n return (\r\n <AppConfigContext.Provider value={value}>\r\n {children}\r\n </AppConfigContext.Provider>\r\n )\r\n}\r\n\r\nexport const useAppConfigContext = () => React.useContext(AppConfigContext)"],"mappings":";;;;;;;;;;;;;;;;;;;;AAgDI;AA3CJ,YAAY,WAAW;AACvB,SAAS,wBAA0D;AAcnE,MAAM,eAAiC;AAAA,EACrC,WAAW;AAAA,IACT,cAAc;AAAA,IACd,MAAM;AAAA,EACR;AAAA,EACA,eAAe,CAAC;AAClB;AAEA,MAAM,UAAU,CACd,EAAE,WAAW,cAAc,GAC3B,YACsB;AAAA,EACtB,WAAW,iBAAiB,WAAW,MAAM;AAAA,EAC7C;AACF;AAEO,MAAM,mBAAmB,MAAM,cAGnC;AAAA,EACD,OAAO;AAAA,EACP,UAAU,MAAM;AAClB,CAAC;AAEM,MAAM,oBAA0F,CAAC,EAAE,UAAU,gBAAgB,CAAC,EAAE,MAAM;AAC3I,QAAM,CAAC,OAAO,QAAQ,IAAI,MAAM,WAAW,SAAS,iCAAK,eAAL,EAAmB,cAAc,EAAC;AACtF,QAAM,QAAQ,MAAM,QAAQ,OAAO,EAAE,OAAO,SAAS,IAAI,CAAC,KAAK,CAAC;AAChE,SACE,oBAAC,iBAAiB,UAAjB,EAA0B,OACxB,UACH;AAEJ;AAEO,MAAM,sBAAsB,MAAM,MAAM,WAAW,gBAAgB;","names":[]}
1
+ {"version":3,"sources":["../../../../src/core/store/AppConfig/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 { AppConfigReducer, AppConfigActions, AppConfigState } from './reducer'\r\n\r\nexport type RuntimeConfig = {\r\n minioUrl?: string\r\n martinUrl?: string\r\n recaptchaSiteKey?: string\r\n pointcloudApiUrl?: string\r\n geocodeEarthApiKey?: string\r\n geocoderUrl?: string\r\n photonUrl?: string\r\n nominatimUrl?: string\r\n maptilerKey?: string\r\n}\r\n\r\ntype InitialStateType = {\r\n appConfig: AppConfigState\r\n runtimeConfig: RuntimeConfig\r\n}\r\n\r\nconst initialState: InitialStateType = {\r\n appConfig: {\r\n organization: null,\r\n user: null,\r\n },\r\n runtimeConfig: {},\r\n}\r\n\r\nconst reducer = (\r\n { appConfig, runtimeConfig }: InitialStateType,\r\n action: AppConfigActions,\r\n): InitialStateType => ({\r\n appConfig: AppConfigReducer(appConfig, action),\r\n runtimeConfig,\r\n})\r\n\r\nexport const AppConfigContext = React.createContext<{\r\n state: InitialStateType\r\n dispatch: React.Dispatch<AppConfigActions>\r\n}>({\r\n state: initialState,\r\n dispatch: () => null,\r\n})\r\n\r\nexport const AppConfigProvider: React.FC<React.PropsWithChildren<{ runtimeConfig?: RuntimeConfig }>> = ({ children, runtimeConfig = {} }) => {\r\n const [state, dispatch] = React.useReducer(reducer, { ...initialState, runtimeConfig })\r\n const value = React.useMemo(() => ({ state, dispatch }), [state])\r\n return (\r\n <AppConfigContext.Provider value={value}>\r\n {children}\r\n </AppConfigContext.Provider>\r\n )\r\n}\r\n\r\nexport const useAppConfigContext = () => React.useContext(AppConfigContext)"],"mappings":";;;;;;;;;;;;;;;;;;;;AAqDI;AAhDJ,YAAY,WAAW;AACvB,SAAS,wBAA0D;AAmBnE,MAAM,eAAiC;AAAA,EACrC,WAAW;AAAA,IACT,cAAc;AAAA,IACd,MAAM;AAAA,EACR;AAAA,EACA,eAAe,CAAC;AAClB;AAEA,MAAM,UAAU,CACd,EAAE,WAAW,cAAc,GAC3B,YACsB;AAAA,EACtB,WAAW,iBAAiB,WAAW,MAAM;AAAA,EAC7C;AACF;AAEO,MAAM,mBAAmB,MAAM,cAGnC;AAAA,EACD,OAAO;AAAA,EACP,UAAU,MAAM;AAClB,CAAC;AAEM,MAAM,oBAA0F,CAAC,EAAE,UAAU,gBAAgB,CAAC,EAAE,MAAM;AAC3I,QAAM,CAAC,OAAO,QAAQ,IAAI,MAAM,WAAW,SAAS,iCAAK,eAAL,EAAmB,cAAc,EAAC;AACtF,QAAM,QAAQ,MAAM,QAAQ,OAAO,EAAE,OAAO,SAAS,IAAI,CAAC,KAAK,CAAC;AAChE,SACE,oBAAC,iBAAiB,UAAjB,EAA0B,OACxB,UACH;AAEJ;AAEO,MAAM,sBAAsB,MAAM,MAAM,WAAW,gBAAgB;","names":[]}
@@ -1,2 +1,7 @@
1
- export declare const AppProvider: any;
1
+ import * as React from 'react';
2
+ import { type RuntimeConfig } from './AppConfig/context';
3
+ export declare function AppProvider({ children, runtimeConfig }: {
4
+ children: React.ReactNode;
5
+ runtimeConfig?: RuntimeConfig;
6
+ }): React.JSX.Element;
2
7
  //# sourceMappingURL=CombineProviders.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CombineProviders.d.ts","sourceRoot":"","sources":["../../../src/core/store/CombineProviders.tsx"],"names":[],"mappings":"AA8BA,eAAO,MAAM,WAAW,KAatB,CAAA"}
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"}
@@ -17,8 +17,7 @@ const compose = (providers) => providers.reduce(
17
17
  return /* @__PURE__ */ jsx(Prev, { children: /* @__PURE__ */ jsx(Curr, { children }) });
18
18
  }
19
19
  );
20
- const AppProvider = compose([
21
- AppConfigProvider,
20
+ const InnerProviders = compose([
22
21
  BimProvider,
23
22
  MapProvider,
24
23
  MenusProvider,
@@ -31,7 +30,9 @@ const AppProvider = compose([
31
30
  PermissionsProvider,
32
31
  PluginHostProvider
33
32
  ]);
34
- compose.displayName = "compose";
33
+ function AppProvider({ children, runtimeConfig }) {
34
+ return /* @__PURE__ */ jsx(AppConfigProvider, { runtimeConfig, children: /* @__PURE__ */ jsx(InnerProviders, { children }) });
35
+ }
35
36
  export {
36
37
  AppProvider
37
38
  };
@@ -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 { AppConfigProvider } 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\nexport const AppProvider = compose([\r\n AppConfigProvider,\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\ncompose.displayName = 'compose'\r\n"],"mappings":";AAwBY;AAnBZ,SAAS,yBAAyB;AAClC,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;AAEK,MAAM,cAAc,QAAQ;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AACD,QAAQ,cAAc;","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 { 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":[]}
@@ -19,7 +19,8 @@ export interface Tool {
19
19
  component?: React.ComponentType<{
20
20
  tool: Tool;
21
21
  building?: Building;
22
- }>;
22
+ } & Record<string, unknown>>;
23
+ extraProps?: Record<string, unknown>;
23
24
  onClick?: (e: React.MouseEvent<HTMLButtonElement>) => void;
24
25
  measure?: () => {
25
26
  enable: () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/core/types/tools.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gDAAgD,CAAA;AACzF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8CAA8C,CAAA;AACtF,OAAO,EAAE,kBAAkB,EAAE,MAAM,mEAAmE,CAAA;AAEtG,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAEhD,MAAM,MAAM,eAAe,GAAG,mBAAmB,GAAG,kBAAkB,GAAG,kBAAkB,GAAG,UAAU,GAAG,cAAc,GAAG,IAAI,CAAA;AAChI,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,eAAe,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,CAAA;IACtC,MAAM,CAAC,EAAE,UAAU,CAAA;IACnB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,IAAI,EAAE,IAAI,CAAC;QAAC,QAAQ,CAAC,EAAE,QAAQ,CAAA;KAAE,CAAC,CAAA;IACpE,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAA;IAC1D,OAAO,CAAC,EAAE,MAAM;QACd,MAAM,EAAE,MAAM,IAAI,CAAA;QAClB,OAAO,EAAE,MAAM,IAAI,CAAA;QACnB,KAAK,EAAE,MAAM,IAAI,CAAA;KAClB,CAAA;CACF"}
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/core/types/tools.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gDAAgD,CAAA;AACzF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8CAA8C,CAAA;AACtF,OAAO,EAAE,kBAAkB,EAAE,MAAM,mEAAmE,CAAA;AAEtG,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAEhD,MAAM,MAAM,eAAe,GAAG,mBAAmB,GAAG,kBAAkB,GAAG,kBAAkB,GAAG,UAAU,GAAG,cAAc,GAAG,IAAI,CAAA;AAChI,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,eAAe,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,CAAA;IACtC,MAAM,CAAC,EAAE,UAAU,CAAA;IACnB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,IAAI,EAAE,IAAI,CAAC;QAAC,QAAQ,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;IAC9F,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACpC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAA;IAC1D,OAAO,CAAC,EAAE,MAAM;QACd,MAAM,EAAE,MAAM,IAAI,CAAA;QAClB,OAAO,EAAE,MAAM,IAAI,CAAA;QACnB,KAAK,EAAE,MAAM,IAAI,CAAA;KAClB,CAAA;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"imageUtils.d.ts","sourceRoot":"","sources":["../../../src/core/utils/imageUtils.ts"],"names":[],"mappings":"AAGA,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOjE;AAED,wBAAsB,oCAAoC,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAatF"}
1
+ {"version":3,"file":"imageUtils.d.ts","sourceRoot":"","sources":["../../../src/core/utils/imageUtils.ts"],"names":[],"mappings":"AAGA,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOjE;AAED,wBAAsB,oCAAoC,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CActF"}
@@ -7,7 +7,8 @@ async function checkImageUrl(url) {
7
7
  }
8
8
  }
9
9
  async function uploadOrganizationLogoToPublicBucket(file) {
10
- const presignedUrlResult = await fetch(`/api/presigned-url-upload?asset=${encodeURIComponent(file.name)}&bucket=org-logos`);
10
+ const uniqueName = `${crypto.randomUUID()}-${file.name}`;
11
+ const presignedUrlResult = await fetch(`/api/presigned-url-upload?asset=${encodeURIComponent(uniqueName)}&bucket=org-logos`);
11
12
  if (!presignedUrlResult.ok) throw new Error("Failed to get presigned URL for org logo");
12
13
  const { presignedUrl, key } = await presignedUrlResult.json();
13
14
  const uploadResult = await fetch(presignedUrl, {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/utils/imageUtils.ts"],"sourcesContent":["// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\nexport async function checkImageUrl(url: string): Promise<boolean> {\r\n try {\r\n const response = await fetch(url, { method: 'HEAD' })\r\n return response.ok\r\n } catch {\r\n return false\r\n }\r\n}\r\n\r\nexport async function uploadOrganizationLogoToPublicBucket(file: File): Promise<string> {\r\n const presignedUrlResult = await fetch(`/api/presigned-url-upload?asset=${encodeURIComponent(file.name)}&bucket=org-logos`)\r\n if (!presignedUrlResult.ok) throw new Error('Failed to get presigned URL for org logo')\r\n const { presignedUrl, key } = await presignedUrlResult.json()\r\n\r\n const uploadResult = await fetch(presignedUrl, {\r\n method: 'PUT',\r\n body: file,\r\n headers: { 'Content-Type': file.type || 'application/octet-stream' },\r\n })\r\n if (!uploadResult.ok) throw new Error('Failed to upload organization logo')\r\n\r\n return key\r\n}\r\n"],"mappings":"AAGA,eAAsB,cAAc,KAA+B;AACjE,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,KAAK,EAAE,QAAQ,OAAO,CAAC;AACpD,WAAO,SAAS;AAAA,EAClB,SAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,qCAAqC,MAA6B;AACtF,QAAM,qBAAqB,MAAM,MAAM,mCAAmC,mBAAmB,KAAK,IAAI,CAAC,mBAAmB;AAC1H,MAAI,CAAC,mBAAmB,GAAI,OAAM,IAAI,MAAM,0CAA0C;AACtF,QAAM,EAAE,cAAc,IAAI,IAAI,MAAM,mBAAmB,KAAK;AAE5D,QAAM,eAAe,MAAM,MAAM,cAAc;AAAA,IAC7C,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,SAAS,EAAE,gBAAgB,KAAK,QAAQ,2BAA2B;AAAA,EACrE,CAAC;AACD,MAAI,CAAC,aAAa,GAAI,OAAM,IAAI,MAAM,oCAAoC;AAE1E,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../../src/core/utils/imageUtils.ts"],"sourcesContent":["// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\nexport async function checkImageUrl(url: string): Promise<boolean> {\r\n try {\r\n const response = await fetch(url, { method: 'HEAD' })\r\n return response.ok\r\n } catch {\r\n return false\r\n }\r\n}\r\n\r\nexport async function uploadOrganizationLogoToPublicBucket(file: File): Promise<string> {\r\n const uniqueName = `${crypto.randomUUID()}-${file.name}`\r\n const presignedUrlResult = await fetch(`/api/presigned-url-upload?asset=${encodeURIComponent(uniqueName)}&bucket=org-logos`)\r\n if (!presignedUrlResult.ok) throw new Error('Failed to get presigned URL for org logo')\r\n const { presignedUrl, key } = await presignedUrlResult.json()\r\n\r\n const uploadResult = await fetch(presignedUrl, {\r\n method: 'PUT',\r\n body: file,\r\n headers: { 'Content-Type': file.type || 'application/octet-stream' },\r\n })\r\n if (!uploadResult.ok) throw new Error('Failed to upload organization logo')\r\n\r\n return key\r\n}\r\n"],"mappings":"AAGA,eAAsB,cAAc,KAA+B;AACjE,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,KAAK,EAAE,QAAQ,OAAO,CAAC;AACpD,WAAO,SAAS;AAAA,EAClB,SAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,qCAAqC,MAA6B;AACtF,QAAM,aAAa,GAAG,OAAO,WAAW,CAAC,IAAI,KAAK,IAAI;AACtD,QAAM,qBAAqB,MAAM,MAAM,mCAAmC,mBAAmB,UAAU,CAAC,mBAAmB;AAC3H,MAAI,CAAC,mBAAmB,GAAI,OAAM,IAAI,MAAM,0CAA0C;AACtF,QAAM,EAAE,cAAc,IAAI,IAAI,MAAM,mBAAmB,KAAK;AAE5D,QAAM,eAAe,MAAM,MAAM,cAAc;AAAA,IAC7C,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,SAAS,EAAE,gBAAgB,KAAK,QAAQ,2BAA2B;AAAA,EACrE,CAAC;AACD,MAAI,CAAC,aAAa,GAAI,OAAM,IAAI,MAAM,oCAAoC;AAE1E,SAAO;AACT;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@collabdt/core",
3
- "version": "0.0.56",
3
+ "version": "0.0.57",
4
4
  "description": "CDT Core contains all the core technology for your CDT platform",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",