@collabdt/core 0.0.42 → 0.0.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (275) hide show
  1. package/dist/core/components/Toolbar.d.ts.map +1 -1
  2. package/dist/core/components/Toolbar.js.map +1 -1
  3. package/dist/core/components/ToolbarBody.js.map +1 -1
  4. package/dist/core/components/TopNavigationBar.js.map +1 -1
  5. package/dist/core/components/authentication/ForgotPassword.js.map +1 -1
  6. package/dist/core/components/authentication/Signin.js.map +1 -1
  7. package/dist/core/components/authentication/Signup.js.map +1 -1
  8. package/dist/core/components/settings/src/OrganizationSkeleton.js.map +1 -1
  9. package/dist/core/components/settings/src/SettingsSkeleton.js.map +1 -1
  10. package/dist/core/components/ui/Comments/CollapsibleCommentItem.d.ts.map +1 -1
  11. package/dist/core/components/ui/Comments/CollapsibleCommentItem.js.map +1 -1
  12. package/dist/core/components/ui/Comments/CommentsSection.d.ts.map +1 -1
  13. package/dist/core/components/ui/Comments/CommentsSection.js.map +1 -1
  14. package/dist/core/components/ui/DataTable.d.ts.map +1 -1
  15. package/dist/core/components/ui/DataTable.js +7 -0
  16. package/dist/core/components/ui/DataTable.js.map +1 -1
  17. package/dist/core/components/ui/FilesManager/src/FileItemComponent.d.ts.map +1 -1
  18. package/dist/core/components/ui/FilesManager/src/FileItemComponent.js.map +1 -1
  19. package/dist/core/components/ui/FilesManager/src/FileMarker.d.ts +5 -2
  20. package/dist/core/components/ui/FilesManager/src/FileMarker.d.ts.map +1 -1
  21. package/dist/core/components/ui/FilesManager/src/FileMarker.js +84 -21
  22. package/dist/core/components/ui/FilesManager/src/FileMarker.js.map +1 -1
  23. package/dist/core/components/ui/FilesManager/src/convertIfcToFragmentsFile.d.ts.map +1 -1
  24. package/dist/core/components/ui/FilesManager/src/convertIfcToFragmentsFile.js.map +1 -1
  25. package/dist/core/components/ui/FilesManager/src/useFileUploadHandler.d.ts.map +1 -1
  26. package/dist/core/components/ui/FilesManager/src/useFileUploadHandler.js.map +1 -1
  27. package/dist/core/components/ui/Icons/IfcIcon.d.ts.map +1 -1
  28. package/dist/core/components/ui/Icons/IfcIcon.js.map +1 -1
  29. package/dist/core/components/ui/InfoSidebar/index.d.ts.map +1 -1
  30. package/dist/core/components/ui/InfoSidebar/index.js.map +1 -1
  31. package/dist/core/components/ui/Navbar.d.ts.map +1 -1
  32. package/dist/core/components/ui/Navbar.js.map +1 -1
  33. package/dist/core/components/ui/Sensors/CollapsibleSensorItem.d.ts.map +1 -1
  34. package/dist/core/components/ui/Sensors/CollapsibleSensorItem.js.map +1 -1
  35. package/dist/core/components/ui/Sensors/SensorTagsSection.d.ts.map +1 -1
  36. package/dist/core/components/ui/Sensors/SensorTagsSection.js.map +1 -1
  37. package/dist/core/components/ui/Sensors/SensorsSection.d.ts.map +1 -1
  38. package/dist/core/components/ui/Sensors/SensorsSection.js.map +1 -1
  39. package/dist/core/components/ui/ShareFeature/ShareToolSubmenu.d.ts.map +1 -1
  40. package/dist/core/components/ui/ShareFeature/ShareToolSubmenu.js.map +1 -1
  41. package/dist/core/components/viewers/Data/buildingDetails/GeocoderInput.js +2 -2
  42. package/dist/core/components/viewers/Data/buildingDetails/GeocoderInput.js.map +1 -1
  43. package/dist/core/components/viewers/Data/infrastructureDetails/FieldRenderer.d.ts.map +1 -1
  44. package/dist/core/components/viewers/Data/infrastructureDetails/FieldRenderer.js.map +1 -1
  45. package/dist/core/components/viewers/Data/siteDetails/AssociatedBuildings.js +2 -2
  46. package/dist/core/components/viewers/Data/siteDetails/AssociatedBuildings.js.map +1 -1
  47. package/dist/core/components/viewers/Viewer.d.ts.map +1 -1
  48. package/dist/core/components/viewers/Viewer.js +5 -1
  49. package/dist/core/components/viewers/Viewer.js.map +1 -1
  50. package/dist/core/components/viewers/bim/BimToolbar.d.ts.map +1 -1
  51. package/dist/core/components/viewers/bim/BimToolbar.js.map +1 -1
  52. package/dist/core/components/viewers/bim/BimViewer.d.ts.map +1 -1
  53. package/dist/core/components/viewers/bim/BimViewer.js +14 -5
  54. package/dist/core/components/viewers/bim/BimViewer.js.map +1 -1
  55. package/dist/core/components/viewers/bim/src/BimLoadingState/index.d.ts.map +1 -1
  56. package/dist/core/components/viewers/bim/src/BimLoadingState/index.js +6 -0
  57. package/dist/core/components/viewers/bim/src/BimLoadingState/index.js.map +1 -1
  58. package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/FilesSection.d.ts.map +1 -1
  59. package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/FilesSection.js +168 -39
  60. package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/FilesSection.js.map +1 -1
  61. package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/ModelsSection.d.ts.map +1 -1
  62. package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/ModelsSection.js.map +1 -1
  63. package/dist/core/components/viewers/bim/src/BimSidebar/src/LayersTab/src/FloorplanSection.d.ts.map +1 -1
  64. package/dist/core/components/viewers/bim/src/BimSidebar/src/LayersTab/src/FloorplanSection.js +1 -1
  65. package/dist/core/components/viewers/bim/src/BimSidebar/src/LayersTab/src/FloorplanSection.js.map +1 -1
  66. package/dist/core/components/viewers/bim/src/ClippingPlane.d.ts.map +1 -1
  67. package/dist/core/components/viewers/bim/src/ClippingPlane.js.map +1 -1
  68. package/dist/core/components/viewers/bim/src/DXFLoader/index.d.ts +14 -37
  69. package/dist/core/components/viewers/bim/src/DXFLoader/index.d.ts.map +1 -1
  70. package/dist/core/components/viewers/bim/src/DXFLoader/index.js +31 -318
  71. package/dist/core/components/viewers/bim/src/DXFLoader/index.js.map +1 -1
  72. package/dist/core/components/viewers/bim/src/FloorplanTool/index.d.ts +66 -7
  73. package/dist/core/components/viewers/bim/src/FloorplanTool/index.d.ts.map +1 -1
  74. package/dist/core/components/viewers/bim/src/FloorplanTool/index.js +253 -21
  75. package/dist/core/components/viewers/bim/src/FloorplanTool/index.js.map +1 -1
  76. package/dist/core/components/viewers/bim/src/ModelManager/index.d.ts.map +1 -1
  77. package/dist/core/components/viewers/bim/src/ModelManager/index.js +9 -0
  78. package/dist/core/components/viewers/bim/src/ModelManager/index.js.map +1 -1
  79. package/dist/core/components/viewers/bim/src/SimpleBimViewer.d.ts.map +1 -1
  80. package/dist/core/components/viewers/bim/src/SimpleBimViewer.js.map +1 -1
  81. package/dist/core/components/viewers/bim/src/lib/TrueNorthPopover.d.ts +3 -2
  82. package/dist/core/components/viewers/bim/src/lib/TrueNorthPopover.d.ts.map +1 -1
  83. package/dist/core/components/viewers/bim/src/lib/TrueNorthPopover.js.map +1 -1
  84. package/dist/core/components/viewers/bim/src/lib/useFriendlyIfcClassName.d.ts.map +1 -1
  85. package/dist/core/components/viewers/bim/src/lib/useFriendlyIfcClassName.js +3 -4
  86. package/dist/core/components/viewers/bim/src/lib/useFriendlyIfcClassName.js.map +1 -1
  87. package/dist/core/components/viewers/bim/src/tools/AddToBim/index.d.ts.map +1 -1
  88. package/dist/core/components/viewers/bim/src/tools/AddToBim/index.js +40 -18
  89. package/dist/core/components/viewers/bim/src/tools/AddToBim/index.js.map +1 -1
  90. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/AddDxf.d.ts +2 -5
  91. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/AddDxf.d.ts.map +1 -1
  92. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/AddDxf.js +45 -59
  93. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/AddDxf.js.map +1 -1
  94. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/AddSensor.d.ts.map +1 -1
  95. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/AddSensor.js.map +1 -1
  96. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimSensor.js +1 -0
  97. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimSensor.js.map +1 -1
  98. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/FileHandler.d.ts +10 -1
  99. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/FileHandler.d.ts.map +1 -1
  100. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/FileHandler.js +25 -73
  101. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/FileHandler.js.map +1 -1
  102. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/FileMarkerUtils.d.ts +7 -3
  103. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/FileMarkerUtils.d.ts.map +1 -1
  104. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/FileMarkerUtils.js +42 -78
  105. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/FileMarkerUtils.js.map +1 -1
  106. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/Position3DCard.d.ts.map +1 -1
  107. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/Position3DCard.js +52 -75
  108. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/Position3DCard.js.map +1 -1
  109. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useFilePlacement.d.ts +15 -3
  110. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useFilePlacement.d.ts.map +1 -1
  111. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useFilePlacement.js +165 -105
  112. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useFilePlacement.js.map +1 -1
  113. package/dist/core/components/viewers/index.d.ts.map +1 -1
  114. package/dist/core/components/viewers/index.js.map +1 -1
  115. package/dist/core/components/viewers/map/MapViewer.d.ts.map +1 -1
  116. package/dist/core/components/viewers/map/MapViewer.js +32 -8
  117. package/dist/core/components/viewers/map/MapViewer.js.map +1 -1
  118. package/dist/core/components/viewers/map/datasets/DatasetManager/index.d.ts.map +1 -1
  119. package/dist/core/components/viewers/map/datasets/DatasetManager/index.js +4 -3
  120. package/dist/core/components/viewers/map/datasets/DatasetManager/index.js.map +1 -1
  121. package/dist/core/components/viewers/map/datasets/RowActions.d.ts.map +1 -1
  122. package/dist/core/components/viewers/map/datasets/RowActions.js +148 -0
  123. package/dist/core/components/viewers/map/datasets/RowActions.js.map +1 -1
  124. package/dist/core/components/viewers/map/datasets/index.d.ts.map +1 -1
  125. package/dist/core/components/viewers/map/datasets/index.js +32 -15
  126. package/dist/core/components/viewers/map/datasets/index.js.map +1 -1
  127. package/dist/core/components/viewers/map/datasets/src/builtinLiveDatasets.d.ts +4 -0
  128. package/dist/core/components/viewers/map/datasets/src/builtinLiveDatasets.d.ts.map +1 -0
  129. package/dist/core/components/viewers/map/datasets/src/builtinLiveDatasets.js +43 -0
  130. package/dist/core/components/viewers/map/datasets/src/builtinLiveDatasets.js.map +1 -0
  131. package/dist/core/components/viewers/map/datasets/src/localDatasets.d.ts.map +1 -1
  132. package/dist/core/components/viewers/map/datasets/src/localDatasets.js +39 -3
  133. package/dist/core/components/viewers/map/datasets/src/localDatasets.js.map +1 -1
  134. package/dist/core/components/viewers/map/datasets/src/minioDatasets.d.ts +1 -1
  135. package/dist/core/components/viewers/map/datasets/src/minioDatasets.d.ts.map +1 -1
  136. package/dist/core/components/viewers/map/datasets/src/minioDatasets.js +2 -1
  137. package/dist/core/components/viewers/map/datasets/src/minioDatasets.js.map +1 -1
  138. package/dist/core/components/viewers/map/datasets/src/publishedTiles.d.ts +47 -0
  139. package/dist/core/components/viewers/map/datasets/src/publishedTiles.d.ts.map +1 -0
  140. package/dist/core/components/viewers/map/datasets/src/publishedTiles.js +114 -0
  141. package/dist/core/components/viewers/map/datasets/src/publishedTiles.js.map +1 -0
  142. package/dist/core/components/viewers/map/datasets/src/wmsTime.d.ts +49 -0
  143. package/dist/core/components/viewers/map/datasets/src/wmsTime.d.ts.map +1 -0
  144. package/dist/core/components/viewers/map/datasets/src/wmsTime.js +100 -0
  145. package/dist/core/components/viewers/map/datasets/src/wmsTime.js.map +1 -0
  146. package/dist/core/components/viewers/map/src/Geocoder.d.ts.map +1 -1
  147. package/dist/core/components/viewers/map/src/Geocoder.js +9 -9
  148. package/dist/core/components/viewers/map/src/Geocoder.js.map +1 -1
  149. package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/NonDatabaseBuildingPopover.d.ts.map +1 -1
  150. package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/NonDatabaseBuildingPopover.js +25 -43
  151. package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/NonDatabaseBuildingPopover.js.map +1 -1
  152. package/dist/core/components/viewers/map/src/MapLayers/index.d.ts.map +1 -1
  153. package/dist/core/components/viewers/map/src/MapLayers/index.js.map +1 -1
  154. package/dist/core/components/viewers/map/src/MapLayers/src/BimLayer/index.d.ts.map +1 -1
  155. package/dist/core/components/viewers/map/src/MapLayers/src/BimLayer/index.js +19 -2
  156. package/dist/core/components/viewers/map/src/MapLayers/src/BimLayer/index.js.map +1 -1
  157. package/dist/core/components/viewers/map/src/MapLayers/src/CountryLayer/countryLayerUtils.d.ts +9 -0
  158. package/dist/core/components/viewers/map/src/MapLayers/src/CountryLayer/countryLayerUtils.d.ts.map +1 -0
  159. package/dist/core/components/viewers/map/src/MapLayers/src/CountryLayer/countryLayerUtils.js +28 -0
  160. package/dist/core/components/viewers/map/src/MapLayers/src/CountryLayer/countryLayerUtils.js.map +1 -0
  161. package/dist/core/components/viewers/map/src/MapLayers/src/CountryLayer/index.d.ts.map +1 -1
  162. package/dist/core/components/viewers/map/src/MapLayers/src/CountryLayer/index.js +1 -16
  163. package/dist/core/components/viewers/map/src/MapLayers/src/CountryLayer/index.js.map +1 -1
  164. package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/FileModelLayer/FileModelLayer.d.ts.map +1 -1
  165. package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/FileModelLayer/FileModelLayer.js.map +1 -1
  166. package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/utils/CustomModelLayer.d.ts.map +1 -1
  167. package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/utils/CustomModelLayer.js +31 -2
  168. package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/utils/CustomModelLayer.js.map +1 -1
  169. package/dist/core/components/viewers/map/src/MapLayers/src/OpenDataLayer/src/WmsTimeControl.d.ts +21 -0
  170. package/dist/core/components/viewers/map/src/MapLayers/src/OpenDataLayer/src/WmsTimeControl.d.ts.map +1 -0
  171. package/dist/core/components/viewers/map/src/MapLayers/src/OpenDataLayer/src/WmsTimeControl.js +111 -0
  172. package/dist/core/components/viewers/map/src/MapLayers/src/OpenDataLayer/src/WmsTimeControl.js.map +1 -0
  173. package/dist/core/components/viewers/map/src/MapLayers/src/OpenDataLayer/src/index.d.ts.map +1 -1
  174. package/dist/core/components/viewers/map/src/MapLayers/src/OpenDataLayer/src/index.js +77 -2
  175. package/dist/core/components/viewers/map/src/MapLayers/src/OpenDataLayer/src/index.js.map +1 -1
  176. package/dist/core/components/viewers/map/src/MapSidebar/index.d.ts.map +1 -1
  177. package/dist/core/components/viewers/map/src/MapSidebar/index.js.map +1 -1
  178. package/dist/core/components/viewers/map/src/MapSidebar/src/FileTab/src/FilesSection.d.ts.map +1 -1
  179. package/dist/core/components/viewers/map/src/MapSidebar/src/FileTab/src/FilesSection.js.map +1 -1
  180. package/dist/core/components/viewers/map/src/MapSidebar/src/FileTab/src/ModelsSection.d.ts.map +1 -1
  181. package/dist/core/components/viewers/map/src/MapSidebar/src/FileTab/src/ModelsSection.js.map +1 -1
  182. package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/src/MapProjection.d.ts.map +1 -1
  183. package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/src/MapProjection.js +19 -9
  184. package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/src/MapProjection.js.map +1 -1
  185. package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/src/TerrainLevel.d.ts.map +1 -1
  186. package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/src/TerrainLevel.js +10 -3
  187. package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/src/TerrainLevel.js.map +1 -1
  188. package/dist/core/components/viewers/map/utils/geocoder.d.ts +6 -2
  189. package/dist/core/components/viewers/map/utils/geocoder.d.ts.map +1 -1
  190. package/dist/core/components/viewers/map/utils/geocoder.js +10 -62
  191. package/dist/core/components/viewers/map/utils/geocoder.js.map +1 -1
  192. package/dist/core/components/viewers/map/utils/geocoding/adapters.d.ts +5 -0
  193. package/dist/core/components/viewers/map/utils/geocoding/adapters.d.ts.map +1 -0
  194. package/dist/core/components/viewers/map/utils/geocoding/adapters.js +192 -0
  195. package/dist/core/components/viewers/map/utils/geocoding/adapters.js.map +1 -0
  196. package/dist/core/components/viewers/map/utils/geocoding/config.d.ts +6 -0
  197. package/dist/core/components/viewers/map/utils/geocoding/config.d.ts.map +1 -0
  198. package/dist/core/components/viewers/map/utils/geocoding/config.js +14 -0
  199. package/dist/core/components/viewers/map/utils/geocoding/config.js.map +1 -0
  200. package/dist/core/components/viewers/map/utils/geocoding/index.d.ts +8 -0
  201. package/dist/core/components/viewers/map/utils/geocoding/index.d.ts.map +1 -0
  202. package/dist/core/components/viewers/map/utils/geocoding/index.js +44 -0
  203. package/dist/core/components/viewers/map/utils/geocoding/index.js.map +1 -0
  204. package/dist/core/components/viewers/map/utils/geocoding/osm.d.ts +6 -0
  205. package/dist/core/components/viewers/map/utils/geocoding/osm.d.ts.map +1 -0
  206. package/dist/core/components/viewers/map/utils/geocoding/osm.js +39 -0
  207. package/dist/core/components/viewers/map/utils/geocoding/osm.js.map +1 -0
  208. package/dist/core/components/viewers/map/utils/geocoding/pelias.d.ts +8 -0
  209. package/dist/core/components/viewers/map/utils/geocoding/pelias.d.ts.map +1 -0
  210. package/dist/core/components/viewers/map/utils/geocoding/pelias.js +35 -0
  211. package/dist/core/components/viewers/map/utils/geocoding/pelias.js.map +1 -0
  212. package/dist/core/components/viewers/pointcloud/PointCloudToolbar.d.ts.map +1 -1
  213. package/dist/core/components/viewers/pointcloud/PointCloudToolbar.js.map +1 -1
  214. package/dist/core/components/viewers/pointcloud/PointCloudViewer.js +1 -3
  215. package/dist/core/components/viewers/pointcloud/PointCloudViewer.js.map +1 -1
  216. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/index.d.ts.map +1 -1
  217. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/index.js +2 -3
  218. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/index.js.map +1 -1
  219. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/src/FilesSection.d.ts.map +1 -1
  220. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/src/FilesSection.js +8 -2
  221. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/src/FilesSection.js.map +1 -1
  222. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/src/PointCloudSection.d.ts.map +1 -1
  223. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/src/PointCloudSection.js.map +1 -1
  224. package/dist/core/components/viewers/pointcloud/src/tools/PerformanceSettingsTools/NodeSizeSelectionTool.js +9 -9
  225. package/dist/core/components/viewers/pointcloud/src/tools/PerformanceSettingsTools/NodeSizeSelectionTool.js.map +1 -1
  226. package/dist/core/hooks/provider.js.map +1 -1
  227. package/dist/core/plugins/host/provider.d.ts.map +1 -1
  228. package/dist/core/plugins/host/provider.js.map +1 -1
  229. package/dist/core/store/AppConfig/context.d.ts.map +1 -1
  230. package/dist/core/store/AppConfig/context.js.map +1 -1
  231. package/dist/core/store/BIM/context.d.ts.map +1 -1
  232. package/dist/core/store/BIM/context.js.map +1 -1
  233. package/dist/core/store/BIM/reducer.d.ts +0 -1
  234. package/dist/core/store/BIM/reducer.d.ts.map +1 -1
  235. package/dist/core/store/BIM/reducer.js +0 -4
  236. package/dist/core/store/BIM/reducer.js.map +1 -1
  237. package/dist/core/store/Buildings/context.d.ts.map +1 -1
  238. package/dist/core/store/Buildings/context.js.map +1 -1
  239. package/dist/core/store/Content/context.d.ts.map +1 -1
  240. package/dist/core/store/Content/context.js.map +1 -1
  241. package/dist/core/store/Datasets/context.d.ts.map +1 -1
  242. package/dist/core/store/Datasets/context.js +2 -1
  243. package/dist/core/store/Datasets/context.js.map +1 -1
  244. package/dist/core/store/Datasets/reducer.d.ts +2 -0
  245. package/dist/core/store/Datasets/reducer.d.ts.map +1 -1
  246. package/dist/core/store/Datasets/reducer.js +9 -4
  247. package/dist/core/store/Datasets/reducer.js.map +1 -1
  248. package/dist/core/store/Files/context.d.ts.map +1 -1
  249. package/dist/core/store/Files/context.js.map +1 -1
  250. package/dist/core/store/Map/context.d.ts.map +1 -1
  251. package/dist/core/store/Map/context.js.map +1 -1
  252. package/dist/core/store/Menus/context.d.ts.map +1 -1
  253. package/dist/core/store/Menus/context.js.map +1 -1
  254. package/dist/core/store/Permissions/context.d.ts.map +1 -1
  255. package/dist/core/store/Permissions/context.js.map +1 -1
  256. package/dist/core/store/PointCloud/context.d.ts.map +1 -1
  257. package/dist/core/store/PointCloud/context.js.map +1 -1
  258. package/dist/core/store/Tools/context.d.ts.map +1 -1
  259. package/dist/core/store/Tools/context.js.map +1 -1
  260. package/dist/core/types/datasetTypes.d.ts +8 -1
  261. package/dist/core/types/datasetTypes.d.ts.map +1 -1
  262. package/dist/core/types/dbTypes.d.ts +13 -13
  263. package/dist/core/types/dbTypes.d.ts.map +1 -1
  264. package/dist/core/types/dbTypes.js +13 -13
  265. package/dist/core/types/dbTypes.js.map +1 -1
  266. package/dist/core/types/index.d.ts +1 -1
  267. package/dist/core/types/index.d.ts.map +1 -1
  268. package/dist/core/types/index.js.map +1 -1
  269. package/dist/core/utils/imageUtils.js +1 -1
  270. package/dist/core/utils/imageUtils.js.map +1 -1
  271. package/package.json +4 -3
  272. package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudViewer-old.d.ts +0 -3
  273. package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudViewer-old.d.ts.map +0 -1
  274. package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudViewer-old.js +0 -173
  275. package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudViewer-old.js.map +0 -1
@@ -22,6 +22,7 @@ import * as React from "react";
22
22
  import * as LR from "lucide-react";
23
23
  import { BimContext, BuildingsContext, MenusContext } from "../../../../../../../../store";
24
24
  import { ModelManager } from "../../../../ModelManager";
25
+ import { DXFManager } from "../../../../DXFLoader";
25
26
  import * as THREE from "three";
26
27
  import { GizmoController } from "../../../../../utils/GizmoController";
27
28
  import { CurrentWorld } from "../../../../CurrentWorld";
@@ -34,12 +35,14 @@ import { useUploadFileToBuilding, useDeleteFile, useFile } from "../../../../../
34
35
  import { useFileUploadHandler, useFileDeleteHandler, FileItemComponent, useFileActions, useCommonFileUpload } from "../../../../../../../ui/FilesManager";
35
36
  import { IDSManager } from "../../../../IDSManager";
36
37
  import { BCFTopicsManager } from "../../../../BCFTopicsManager";
38
+ import { createFileMarker, removeMarker } from "../../../../tools/AddToBim/src/FileMarkerUtils";
37
39
  const OPTIONS_3D = ["download", "view", "move", "info", "delete"];
38
40
  const OPTIONS_NON_3D = ["download", "view", "delete"];
39
41
  const is3DFile = (ext) => {
40
42
  if (!ext) return false;
41
43
  return ["glb", "gltf", "fbx", "obj", "collada"].includes(ext.toLowerCase());
42
44
  };
45
+ const isPlaceable = (ext) => is3DFile(ext) || (ext == null ? void 0 : ext.toLowerCase()) === "dxf";
43
46
  function FilesSection({ files, query = "" }) {
44
47
  const t = useTranslations("FileSelection");
45
48
  const { state: bimState, dispatch: bimDispatch } = React.useContext(BimContext);
@@ -72,7 +75,8 @@ function FilesSection({ files, query = "" }) {
72
75
  })
73
76
  );
74
77
  return files.filter((file) => file.tag !== "user").filter((file) => file.type !== "map-file").map((file) => {
75
- let isVisible = visibilityMap.has(file.id) ? visibilityMap.get(file.id) : false;
78
+ var _a;
79
+ let isVisible = visibilityMap.has(file.id) ? visibilityMap.get(file.id) : (_a = file.isVisible) != null ? _a : false;
76
80
  if (file.extension === "ids" && activeIDSFileId === file.id) {
77
81
  isVisible = true;
78
82
  } else if (file.extension === "ids" && activeIDSFileId !== null && activeIDSFileId !== file.id) {
@@ -114,6 +118,48 @@ function FilesSection({ files, query = "" }) {
114
118
  React.useEffect(() => {
115
119
  modelManagerRef.current = modelManager;
116
120
  }, [modelManager]);
121
+ const dxfManager = React.useMemo(() => {
122
+ if (!bimComponents) return null;
123
+ try {
124
+ return bimComponents.get(DXFManager);
125
+ } catch (e) {
126
+ return null;
127
+ }
128
+ }, [bimComponents]);
129
+ const dxfGroupsRef = React.useRef(/* @__PURE__ */ new Map());
130
+ const markersRef = React.useRef(/* @__PURE__ */ new Map());
131
+ const [loadedTick, setLoadedTick] = React.useState(0);
132
+ const toggleDxfVisibility = React.useCallback(async (file, visible) => {
133
+ if (!dxfManager || !bimComponents) return;
134
+ const world = bimComponents.get(CurrentWorld).world;
135
+ if (!world) return;
136
+ const key = file.id.toString();
137
+ const existing = dxfGroupsRef.current.get(key);
138
+ if (visible) {
139
+ if (existing) {
140
+ existing.visible = true;
141
+ return;
142
+ }
143
+ try {
144
+ const res = await fetch(`/api/presignedUrlDownload/${file.id}`);
145
+ if (!res.ok) throw new Error(`Failed to get download URL: ${res.status}`);
146
+ const { presignedUrl } = await res.json();
147
+ const group = await dxfManager.parse(presignedUrl);
148
+ group.name = key;
149
+ const placed = file.x != null && file.y != null && file.z != null;
150
+ group.position.copy(placed ? new THREE.Vector3(file.x, file.y, file.z) : new THREE.Vector3());
151
+ group.scale.setScalar(1e-3);
152
+ if (file.rotation != null) group.rotation.y = file.rotation;
153
+ world.scene.three.add(group);
154
+ dxfGroupsRef.current.set(key, group);
155
+ setLoadedTick((t2) => t2 + 1);
156
+ } catch (err) {
157
+ console.error(`[FilesSection] Failed to load DXF "${file.name}":`, err);
158
+ }
159
+ } else if (existing) {
160
+ existing.visible = false;
161
+ }
162
+ }, [dxfManager, bimComponents]);
117
163
  const gizmoControllersRef = React.useRef(/* @__PURE__ */ new Map());
118
164
  const [moveFileId, setMoveFileId] = React.useState(null);
119
165
  const { updateFile } = useFile(moveFileId);
@@ -193,7 +239,12 @@ function FilesSection({ files, query = "" }) {
193
239
  }
194
240
  if (fragments) fragments.core.update(true);
195
241
  }
196
- }, [bimComponents, menusDispatch, bimState, bimDispatch, modelManager, fragments]);
242
+ if (file.extension === "dxf") {
243
+ await toggleDxfVisibility(file, newVisibility);
244
+ if (fragments) fragments.core.update(true);
245
+ }
246
+ setLoadedTick((t2) => t2 + 1);
247
+ }, [bimComponents, menusDispatch, bimState, bimDispatch, modelManager, fragments, toggleDxfVisibility]);
197
248
  const highlighter = React.useMemo(() => {
198
249
  if (!bimComponents) return null;
199
250
  try {
@@ -281,6 +332,44 @@ function FilesSection({ files, query = "" }) {
281
332
  if (cursor) cursor.cursor = "";
282
333
  };
283
334
  }, [placingFile, bimComponents, raycast]);
335
+ const getSceneObject = React.useCallback((file) => {
336
+ var _a, _b, _c;
337
+ if (file.extension === "dxf") return (_a = dxfGroupsRef.current.get(file.id.toString())) != null ? _a : null;
338
+ return (_c = (_b = modelManager == null ? void 0 : modelManager.getModelByName(file.name)) == null ? void 0 : _b.model) != null ? _c : null;
339
+ }, [modelManager]);
340
+ const editObject = React.useCallback((file, mode = "translate") => {
341
+ if (!bimComponents) return;
342
+ const world = bimComponents.get(CurrentWorld).world;
343
+ if (!world) return;
344
+ const obj = getSceneObject(file);
345
+ if (!obj) return;
346
+ const key = file.id.toString();
347
+ const existing = gizmoControllersRef.current.get(key);
348
+ if (existing) {
349
+ existing.setMode(mode);
350
+ return;
351
+ }
352
+ const gizmo = new GizmoController(world);
353
+ const cleanup = (save) => {
354
+ if (save) {
355
+ const { x, y, z } = obj.position;
356
+ const rotation = obj.rotation.y;
357
+ updateFileRef.current({ x, y, z, rotation }).catch((err) => console.error(`Failed to save position for "${file.name}":`, err));
358
+ file.x = x;
359
+ file.y = y;
360
+ file.z = z;
361
+ file.rotation = rotation;
362
+ }
363
+ gizmoControllersRef.current.delete(key);
364
+ setMoveFileId(null);
365
+ };
366
+ gizmo.onAccept = () => cleanup(true);
367
+ gizmo.onCancel = () => cleanup(false);
368
+ gizmo.setMode(mode);
369
+ setMoveFileId(file.id);
370
+ gizmo.attach(obj);
371
+ gizmoControllersRef.current.set(key, gizmo);
372
+ }, [bimComponents, getSceneObject]);
284
373
  const handleBimMove = React.useCallback((file) => {
285
374
  const isPlaced = file.x != null && file.y != null && file.z != null;
286
375
  if (!isPlaced) {
@@ -288,37 +377,12 @@ function FilesSection({ files, query = "" }) {
288
377
  setMoveFileId(file.id);
289
378
  return;
290
379
  }
291
- if (!bimComponents || !modelManager) return;
292
- const world = bimComponents.get(CurrentWorld).world;
293
- if (!world) return;
294
- const modelInfo = modelManager.getModelByName(file.name);
295
- if (!modelInfo) return;
296
- const existing = gizmoControllersRef.current.get(file.name);
297
- if (existing) {
298
- existing.dispose();
299
- gizmoControllersRef.current.delete(file.name);
300
- } else {
301
- const gizmo = new GizmoController(world);
302
- const cleanupGizmo = (savePosition) => {
303
- if (savePosition) {
304
- const { x, y, z } = modelInfo.model.position;
305
- const rotation = modelInfo.model.rotation.y;
306
- updateFileRef.current({ x, y, z, rotation }).catch((err) => console.error(`Failed to save position for "${file.name}":`, err));
307
- file.x = x;
308
- file.y = y;
309
- file.z = z;
310
- file.rotation = rotation;
311
- }
312
- gizmoControllersRef.current.delete(file.name);
313
- setMoveFileId(null);
314
- };
315
- gizmo.onAccept = () => cleanupGizmo(true);
316
- gizmo.onCancel = () => cleanupGizmo(false);
317
- setMoveFileId(file.id);
318
- gizmo.attach(modelInfo.model);
319
- gizmoControllersRef.current.set(file.name, gizmo);
380
+ if (file.extension === "dxf" && !dxfGroupsRef.current.has(file.id.toString())) {
381
+ void toggleDxfVisibility(file, true).then(() => editObject(file, "translate"));
382
+ return;
320
383
  }
321
- }, [bimComponents, modelManager]);
384
+ editObject(file, "translate");
385
+ }, [editObject, toggleDxfVisibility]);
322
386
  const { handleAction, deleteDialog } = useFileActions({
323
387
  files: localFiles,
324
388
  setFiles: setLocalFiles,
@@ -352,9 +416,8 @@ function FilesSection({ files, query = "" }) {
352
416
  onCheckedChange: async (checked) => {
353
417
  var _a;
354
418
  setLocalFiles((prev) => prev.map((f) => __spreadProps(__spreadValues({}, f), { isVisible: checked })));
355
- if (modelManager) {
356
- for (const f of localFiles) {
357
- if (!is3DFile(f.extension)) continue;
419
+ for (const f of localFiles) {
420
+ if (is3DFile(f.extension) && modelManager) {
358
421
  const existingModel = modelManager.getModelByName(f.name);
359
422
  if (checked) {
360
423
  if (existingModel) {
@@ -374,14 +437,80 @@ function FilesSection({ files, query = "" }) {
374
437
  console.error(`[FilesSection] Failed to load model "${f.name}":`, err);
375
438
  }
376
439
  }
377
- } else {
378
- if (existingModel) existingModel.model.visible = false;
440
+ } else if (existingModel) {
441
+ existingModel.model.visible = false;
379
442
  }
443
+ } else if (f.extension === "dxf") {
444
+ await toggleDxfVisibility(f, checked);
380
445
  }
381
- if (fragments) fragments.core.update(true);
382
446
  }
447
+ if (fragments) fragments.core.update(true);
448
+ setLoadedTick((t2) => t2 + 1);
383
449
  }
384
450
  });
451
+ const makeMarkerInput = React.useCallback((file, position) => {
452
+ var _a;
453
+ return {
454
+ id: file.id.toString(),
455
+ file: new File([], file.name, { type: (_a = file.mimeType) != null ? _a : "" }),
456
+ position
457
+ };
458
+ }, []);
459
+ React.useEffect(() => {
460
+ if (!bimComponents) return;
461
+ const world = bimComponents.get(CurrentWorld).world;
462
+ if (!world) return;
463
+ const wanted = new Map(
464
+ localFiles.filter((f) => f.isVisible && isPlaceable(f.extension)).map((f) => [f.id.toString(), f])
465
+ );
466
+ for (const [key, entry] of markersRef.current) {
467
+ if (!wanted.has(key)) {
468
+ removeMarker(entry.marker, world);
469
+ markersRef.current.delete(key);
470
+ }
471
+ }
472
+ for (const [key, file] of wanted) {
473
+ if (markersRef.current.has(key)) continue;
474
+ const obj = getSceneObject(file);
475
+ if (!obj) continue;
476
+ const marker = createFileMarker(makeMarkerInput(file, obj.position.clone()), obj, world, (action) => {
477
+ if (action === "delete") {
478
+ handleAction("delete", file);
479
+ return;
480
+ }
481
+ editObject(file, action === "move" ? "translate" : action);
482
+ });
483
+ if (marker) markersRef.current.set(key, { marker, file });
484
+ }
485
+ }, [localFiles, loadedTick, bimComponents, getSceneObject, editObject, handleAction, makeMarkerInput]);
486
+ React.useEffect(() => {
487
+ if (!bimComponents) return;
488
+ let raf = 0;
489
+ const worldPos = new THREE.Vector3();
490
+ const tick = () => {
491
+ markersRef.current.forEach(({ marker, file }, key) => {
492
+ const obj = getSceneObject(file);
493
+ if (!obj) {
494
+ marker.visible = false;
495
+ return;
496
+ }
497
+ obj.getWorldPosition(worldPos);
498
+ marker.position.set(worldPos.x, worldPos.y + 0.2, worldPos.z);
499
+ marker.visible = !gizmoControllersRef.current.has(key);
500
+ });
501
+ raf = requestAnimationFrame(tick);
502
+ };
503
+ raf = requestAnimationFrame(tick);
504
+ return () => cancelAnimationFrame(raf);
505
+ }, [bimComponents, getSceneObject]);
506
+ const markersCleanupRef = React.useRef(markersRef.current);
507
+ React.useEffect(() => {
508
+ const markers = markersCleanupRef.current;
509
+ return () => {
510
+ markers.forEach(({ marker }) => removeMarker(marker));
511
+ markers.clear();
512
+ };
513
+ }, []);
385
514
  return /* @__PURE__ */ jsxs(Fragment, { children: [
386
515
  /* @__PURE__ */ jsx(
387
516
  CollapsibleSection,
@@ -398,7 +527,7 @@ function FilesSection({ files, query = "" }) {
398
527
  {
399
528
  file: item,
400
529
  onAction: handleAction,
401
- options: is3DFile(item.extension) ? OPTIONS_3D : OPTIONS_NON_3D,
530
+ options: isPlaceable(item.extension) ? OPTIONS_3D : OPTIONS_NON_3D,
402
531
  translationKey: "FileSelection",
403
532
  confirmDelete: false
404
533
  },
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../../../../src/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/FilesSection.tsx"],"sourcesContent":["import * as React from 'react'\r\nimport * as LR from 'lucide-react'\r\nimport { BimContext, BuildingsContext, MenusContext } from '../../../../../../../../store'\r\nimport { ModelManager } from '../../../../ModelManager'\r\nimport * as THREE from 'three'\r\nimport { GizmoController } from '../../../../../utils/GizmoController'\r\nimport { CurrentWorld } from '../../../../CurrentWorld'\r\nimport { Cursor } from '../../../../Cursor'\r\nimport { Highlighter } from '../../../../Highlighter'\r\nimport { CollapsibleSection } from '../../../../../../../ui/CollapsibleSection'\r\nimport { useTranslations } from 'next-intl'\r\nimport ConfirmDialog from '../../../../../../../ConfirmDialog'\r\nimport { useUploadFileToBuilding, useDeleteFile, useFile } from '../../../../../../../../hooks/files/files'\r\nimport { useFileUploadHandler, useFileDeleteHandler, FileItemComponent, useFileActions, useCommonFileUpload } from '../../../../../../../ui/FilesManager'\r\nimport { IDSManager } from '../../../../IDSManager'\r\nimport { BCFTopicsManager } from '../../../../BCFTopicsManager'\r\nimport { DbFile as IFile } from '../../../../../../../../types/dbTypes'\r\n\r\n// Audit Phase 1.C (F-19): hoist options arrays so the array identity is\r\n// stable across renders. Inline `options={[...]}` defeats React.memo on\r\n// FileItemComponent.\r\ntype FileAction = import('../../../../../../../../types/global').FileAction\r\nconst OPTIONS_3D: FileAction[] = ['download', 'view', 'move', 'info', 'delete']\r\nconst OPTIONS_NON_3D: FileAction[] = ['download', 'view', 'delete']\r\n\r\ninterface FilesSectionProps {\r\n files: IFile[]\r\n query?: string\r\n}\r\n\r\nconst is3DFile = (ext?: string | null): boolean => {\r\n if (!ext) return false\r\n return ['glb', 'gltf', 'fbx', 'obj', 'collada'].includes(ext.toLowerCase())\r\n}\r\n\r\nexport function FilesSection({ files, query = '' }: FilesSectionProps) {\r\n const t = useTranslations('FileSelection')\r\n\r\n const { state: bimState, dispatch: bimDispatch } = React.useContext(BimContext)\r\n const { bimComponents, fragments } = bimState.bim\r\n const { state: buildingsState } = React.useContext(BuildingsContext)\r\n const { building } = buildingsState.buildings\r\n const buildingId = building?.id || -1\r\n const { dispatch: menusDispatch } = React.useContext(MenusContext)\r\n\r\n const { uploadFile } = useUploadFileToBuilding(buildingId)\r\n const { deleteFile } = useDeleteFile(buildingId)\r\n\r\n const { handleFileUpload } = useFileUploadHandler({\r\n buildingId,\r\n tag: 'file',\r\n uploadFile,\r\n })\r\n\r\n const { handleDeleteFile } = useFileDeleteHandler({\r\n deleteFile,\r\n onDeleteSuccess: () => {\r\n console.log('File deleted successfully')\r\n },\r\n })\r\n\r\n // Local state for file management with isVisible property\r\n const [localFiles, setLocalFiles] = React.useState<(IFile & { isVisible?: boolean })[]>([])\r\n const [activeIDSFileId, setActiveIDSFileId] = React.useState<number | null>(null)\r\n\r\n // Initialize and sync files\r\n React.useEffect(() => {\r\n setLocalFiles(prevFiles => {\r\n const visibilityMap = new Map(\r\n prevFiles.map(f => [f.id, f.isVisible ?? false])\r\n )\r\n return files\r\n .filter(file => file.tag !== 'user')\r\n .filter(file => (file as any).type !== 'map-file')\r\n .map(file => {\r\n // Preserve user's toggle state for already-tracked files.\r\n // All new files start hidden — user explicitly adds them via the eye icon.\r\n let isVisible = visibilityMap.has(file.id) ? visibilityMap.get(file.id)! : false\r\n if (file.extension === 'ids' && activeIDSFileId === file.id) {\r\n isVisible = true\r\n } else if (file.extension === 'ids' && activeIDSFileId !== null && activeIDSFileId !== file.id) {\r\n isVisible = false\r\n }\r\n return { ...file, isVisible }\r\n })\r\n .sort((a, b) => a.name.localeCompare(b.name))\r\n })\r\n }, [files, activeIDSFileId])\r\n\r\n // Listen to IDS reset events\r\n React.useEffect(() => {\r\n if (!bimComponents) return\r\n try {\r\n const idsManager = bimComponents.get(IDSManager)\r\n const handleIDSReset = () => {\r\n setActiveIDSFileId(null)\r\n setLocalFiles(prevFiles =>\r\n prevFiles.map(file =>\r\n file.extension === 'ids' ? { ...file, isVisible: false } : file\r\n )\r\n )\r\n }\r\n idsManager.onReset.add(handleIDSReset)\r\n return () => { idsManager.onReset.remove(handleIDSReset) }\r\n } catch {\r\n return\r\n }\r\n }, [bimComponents])\r\n\r\n const modelManager = React.useMemo(() => {\r\n if (!bimComponents) return null\r\n try { return bimComponents.get(ModelManager) } catch { return null }\r\n }, [bimComponents])\r\n const modelManagerRef = React.useRef(modelManager)\r\n React.useEffect(() => { modelManagerRef.current = modelManager }, [modelManager])\r\n\r\n // Gizmo controllers keyed by file name (one gizmo per file at most)\r\n const gizmoControllersRef = React.useRef<Map<string, GizmoController>>(new Map())\r\n\r\n // Track the file ID currently being repositioned so useFile can provide updateFile\r\n const [moveFileId, setMoveFileId] = React.useState<number | null>(null)\r\n const { updateFile } = useFile(moveFileId)\r\n const updateFileRef = React.useRef(updateFile)\r\n React.useEffect(() => { updateFileRef.current = updateFile }, [updateFile])\r\n\r\n const fetchDbFileAsFile = async (file: IFile): Promise<globalThis.File> => {\r\n const response = await fetch(file.url)\r\n const blob = await response.blob()\r\n const mimeType = file.extension === 'ids' ? 'application/xml' : 'application/octet-stream'\r\n return new globalThis.File([blob], file.name, { type: mimeType })\r\n }\r\n\r\n // View handler: IDS, BCF, and 3D file visibility\r\n const handleBimView = React.useCallback(async (file: IFile & { isVisible?: boolean }, newVisibility: boolean) => {\r\n // IDS files\r\n if (file.extension === 'ids') {\r\n const idsManager = bimComponents?.get(IDSManager)\r\n if (!idsManager) return\r\n idsManager.enabled = newVisibility\r\n if (newVisibility) {\r\n setActiveIDSFileId(file.id)\r\n try {\r\n const dbFile = await fetchDbFileAsFile(file)\r\n await idsManager.loadFromFile(dbFile)\r\n await idsManager.loadAndTestIDS()\r\n } catch (error) {\r\n console.error('Error loading IDS file:', error)\r\n }\r\n } else {\r\n setActiveIDSFileId(null)\r\n await idsManager.reset()\r\n }\r\n }\r\n\r\n // BCF files\r\n if (file.extension === 'bcf') {\r\n menusDispatch({ type: 'SET_SIDEBAR_SELECTED_TAB', payload: { selectedTab: 'communication' } })\r\n const bcfManager = bimComponents?.get(BCFTopicsManager)\r\n if (!bcfManager) return\r\n try {\r\n const { topics } = await bcfManager.loadBCFFromUrl(file.url)\r\n if (topics?.length) {\r\n topics.forEach((topic) => {\r\n const exists = bimState.bim.bcfTopics.find(t => t.guid === topic.guid)\r\n if (!exists) {\r\n bimDispatch({ type: 'ADD_BCF_TOPIC', payload: { bcfTopic: topic } })\r\n }\r\n })\r\n }\r\n } catch (error) {\r\n console.error('Failed to load BCF from URL:', error)\r\n }\r\n }\r\n\r\n // 3D model files (GLB/GLTF/FBX/OBJ) managed by ModelManager\r\n if (is3DFile(file.extension) && modelManager) {\r\n const existingModel = modelManager.getModelByName(file.name)\r\n if (newVisibility) {\r\n if (existingModel) {\r\n // Already in scene — just show it\r\n existingModel.model.visible = true\r\n } else {\r\n // Not yet loaded — get a fresh presigned download URL then load\r\n try {\r\n const res = await fetch(`/api/presignedUrlDownload/${file.id}`)\r\n if (!res.ok) throw new Error(`Failed to get download URL: ${res.status}`)\r\n const { presignedUrl } = await res.json()\r\n const position = (file.x != null && file.y != null && file.z != null)\r\n ? new THREE.Vector3(file.x as number, file.y as number, file.z as number)\r\n : new THREE.Vector3(0, 0, 0)\r\n const rotation = file.rotation != null\r\n ? new THREE.Euler(0, file.rotation, 0)\r\n : undefined\r\n await modelManager.load(presignedUrl, file.id.toString(), file.name, {\r\n position,\r\n rotation,\r\n extension: file.extension ?? undefined,\r\n })\r\n } catch (err) {\r\n console.error(`[FilesSection] Failed to load model \"${file.name}\":`, err)\r\n }\r\n }\r\n } else {\r\n if (existingModel) {\r\n existingModel.model.visible = false\r\n }\r\n }\r\n if (fragments) fragments.core.update(true)\r\n }\r\n }, [bimComponents, menusDispatch, bimState, bimDispatch, modelManager, fragments])\r\n\r\n const highlighter = React.useMemo(() => {\r\n if (!bimComponents) return null\r\n try { return bimComponents.get(Highlighter) } catch { return null }\r\n }, [bimComponents])\r\n\r\n // Raycast into fragments (same logic as useFilePlacement)\r\n const raycast = React.useCallback(async (data: {\r\n camera: THREE.PerspectiveCamera | THREE.OrthographicCamera\r\n mouse: THREE.Vector2\r\n dom: HTMLCanvasElement\r\n }) => {\r\n if (!fragments || !highlighter) return null\r\n const results = []\r\n for (const [modelName, model] of fragments.core.models.list) {\r\n if (highlighter.isModelDisabled(modelName)) continue\r\n const result = await model.raycast(data)\r\n if (result) results.push(result)\r\n }\r\n await Promise.all(results)\r\n if (results.length === 0) return null\r\n let closest = results[0]\r\n for (let i = 1; i < results.length; i++) {\r\n if (results[i].distance < closest.distance) closest = results[i]\r\n }\r\n return closest\r\n }, [fragments, highlighter])\r\n\r\n // Track the file currently being placed (unplaced file → click-to-place)\r\n const [placingFile, setPlacingFile] = React.useState<IFile | null>(null)\r\n\r\n // Click-to-place effect: crosshair + double-click raycast for unplaced files\r\n React.useEffect(() => {\r\n if (!placingFile || !bimComponents) return\r\n\r\n const world = bimComponents.get(CurrentWorld).world\r\n if (!world) return\r\n\r\n const cursor = bimComponents.get(Cursor)\r\n if (cursor) cursor.cursor = 'crosshair'\r\n\r\n const mouse = new THREE.Vector2()\r\n\r\n const handleDblClick = async (e: MouseEvent) => {\r\n mouse.x = e.clientX\r\n mouse.y = e.clientY\r\n\r\n const result = await raycast({\r\n camera: world.camera.three,\r\n mouse,\r\n dom: world.renderer!.three.domElement!,\r\n })\r\n\r\n if (result?.point && (result.point.x !== 0 || result.point.y !== 0 || result.point.z !== 0)) {\r\n const { x, y, z } = result.point\r\n setMoveFileId(placingFile.id)\r\n // Save coordinates to DB\r\n setTimeout(() => {\r\n updateFileRef.current({ x, y, z } as any)\r\n .catch((err: unknown) => console.error(`Failed to save placement for \"${placingFile.name}\":`, err))\r\n }, 50)\r\n // Load model into scene at the placed position (for 3D files)\r\n if (is3DFile(placingFile.extension) && modelManagerRef.current) {\r\n const existing = modelManagerRef.current.getModelByName(placingFile.name)\r\n if (!existing) {\r\n fetch(`/api/presignedUrlDownload/${placingFile.id}`)\r\n .then(res => res.ok ? res.json() : Promise.reject(res.status))\r\n .then(({ presignedUrl }) =>\r\n modelManagerRef.current!.load(\r\n presignedUrl,\r\n placingFile.id.toString(),\r\n placingFile.name,\r\n { position: new THREE.Vector3(x, y, z), extension: placingFile.extension ?? undefined },\r\n )\r\n )\r\n .catch((err: unknown) => console.error(`Failed to load model \"${placingFile.name}\":`, err))\r\n } else {\r\n existing.model.position.set(x, y, z)\r\n existing.model.visible = true\r\n }\r\n }\r\n // Update local state so it shows as placed and visible\r\n placingFile.x = x\r\n placingFile.y = y\r\n placingFile.z = z\r\n setLocalFiles(prev => prev.map(f => f.id === placingFile.id ? { ...f, x, y, z, isVisible: true } : f))\r\n setPlacingFile(null)\r\n if (cursor) cursor.cursor = ''\r\n }\r\n }\r\n\r\n const handleKeyDown = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape') {\r\n setPlacingFile(null)\r\n if (cursor) cursor.cursor = ''\r\n }\r\n }\r\n\r\n document.addEventListener('dblclick', handleDblClick)\r\n document.addEventListener('keydown', handleKeyDown)\r\n\r\n return () => {\r\n document.removeEventListener('dblclick', handleDblClick)\r\n document.removeEventListener('keydown', handleKeyDown)\r\n if (cursor) cursor.cursor = ''\r\n }\r\n }, [placingFile, bimComponents, raycast])\r\n\r\n // Move handler: unplaced files → click-to-place; placed files → gizmo\r\n const handleBimMove = React.useCallback((file: IFile) => {\r\n const isPlaced = file.x != null && file.y != null && file.z != null\r\n\r\n // Unplaced file: enter click-to-place mode\r\n if (!isPlaced) {\r\n setPlacingFile(file)\r\n setMoveFileId(file.id)\r\n return\r\n }\r\n\r\n // Placed file: attach/detach gizmo\r\n if (!bimComponents || !modelManager) return\r\n\r\n const world = bimComponents.get(CurrentWorld).world\r\n if (!world) return\r\n\r\n const modelInfo = modelManager.getModelByName(file.name)\r\n if (!modelInfo) return\r\n\r\n const existing = gizmoControllersRef.current.get(file.name)\r\n if (existing) {\r\n existing.dispose()\r\n gizmoControllersRef.current.delete(file.name)\r\n } else {\r\n const gizmo = new GizmoController(world)\r\n const cleanupGizmo = (savePosition: boolean) => {\r\n if (savePosition) {\r\n const { x, y, z } = modelInfo.model.position\r\n const rotation = modelInfo.model.rotation.y\r\n updateFileRef.current({ x, y, z, rotation } as any)\r\n .catch((err: unknown) => console.error(`Failed to save position for \"${file.name}\":`, err))\r\n file.x = x\r\n file.y = y\r\n file.z = z\r\n file.rotation = rotation\r\n }\r\n gizmoControllersRef.current.delete(file.name)\r\n setMoveFileId(null)\r\n }\r\n gizmo.onAccept = () => cleanupGizmo(true)\r\n gizmo.onCancel = () => cleanupGizmo(false)\r\n setMoveFileId(file.id)\r\n gizmo.attach(modelInfo.model)\r\n gizmoControllersRef.current.set(file.name, gizmo)\r\n }\r\n }, [bimComponents, modelManager])\r\n\r\n const { handleAction, deleteDialog } = useFileActions({\r\n files: localFiles,\r\n setFiles: setLocalFiles,\r\n buildingId,\r\n handleDeleteFile,\r\n onView: handleBimView,\r\n onMove: handleBimMove,\r\n })\r\n\r\n const { handleAddFile } = useCommonFileUpload({\r\n buildingId,\r\n acceptedFileTypes: '*',\r\n handleFileUpload: async (domFile: globalThis.File) => {\r\n await handleFileUpload(domFile)\r\n },\r\n onUploadSuccess: () => {\r\n console.log('File uploaded successfully')\r\n },\r\n onUploadError: (error) => {\r\n console.error('Error uploading file:', error)\r\n },\r\n })\r\n\r\n const filteredFiles = React.useMemo(() => {\r\n if (!query.trim()) return localFiles\r\n return localFiles.filter(file =>\r\n file.name.toLowerCase().includes(query.toLowerCase())\r\n )\r\n }, [localFiles, query])\r\n\r\n const areAllHidden = localFiles.every(f => !f.isVisible)\r\n\r\n const handleSwitchVariant = () => ({\r\n checked: !areAllHidden,\r\n onCheckedChange: async (checked: boolean) => {\r\n setLocalFiles(prev => prev.map(f => ({ ...f, isVisible: checked })))\r\n if (modelManager) {\r\n for (const f of localFiles) {\r\n if (!is3DFile(f.extension)) continue\r\n const existingModel = modelManager.getModelByName(f.name)\r\n if (checked) {\r\n if (existingModel) {\r\n existingModel.model.visible = true\r\n } else {\r\n try {\r\n const res = await fetch(`/api/presignedUrlDownload/${f.id}`)\r\n if (res.ok) {\r\n const { presignedUrl } = await res.json()\r\n const position = (f.x != null && f.y != null && f.z != null)\r\n ? new THREE.Vector3(f.x as number, f.y as number, f.z as number)\r\n : new THREE.Vector3(0, 0, 0)\r\n await modelManager.load(presignedUrl, f.id.toString(), f.name, {\r\n position,\r\n extension: f.extension ?? undefined,\r\n })\r\n }\r\n } catch (err) {\r\n console.error(`[FilesSection] Failed to load model \"${f.name}\":`, err)\r\n }\r\n }\r\n } else {\r\n if (existingModel) existingModel.model.visible = false\r\n }\r\n }\r\n if (fragments) fragments.core.update(true)\r\n }\r\n },\r\n })\r\n\r\n return (\r\n <>\r\n <CollapsibleSection\r\n title={t('filesTitle')}\r\n icon={LR.FileText}\r\n className=\"max-h-40 overflow-y-auto\"\r\n itemCount={filteredFiles.length}\r\n switchVariant={handleSwitchVariant()}\r\n onAddItem={handleAddFile}\r\n addItemTitle={t('addFileTitle')}\r\n >\r\n <div className=\"space-y-1\">\r\n {filteredFiles.map((item) => (\r\n <FileItemComponent\r\n key={item.id}\r\n file={item}\r\n onAction={handleAction}\r\n options={is3DFile(item.extension) ? OPTIONS_3D : OPTIONS_NON_3D}\r\n translationKey=\"FileSelection\"\r\n confirmDelete={false}\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 />\r\n </>\r\n )\r\n}\r\n"],"mappings":"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","names":["t"]}
1
+ {"version":3,"sources":["../../../../../../../../../../src/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/FilesSection.tsx"],"sourcesContent":["import * as React from 'react'\r\nimport * as LR from 'lucide-react'\r\nimport { BimContext, BuildingsContext, MenusContext } from '../../../../../../../../store'\r\nimport { ModelManager } from '../../../../ModelManager'\r\nimport { DXFManager } from '../../../../DXFLoader'\r\nimport * as THREE from 'three'\r\nimport { GizmoController } from '../../../../../utils/GizmoController'\r\nimport { CurrentWorld } from '../../../../CurrentWorld'\r\nimport { Cursor } from '../../../../Cursor'\r\nimport { Highlighter } from '../../../../Highlighter'\r\nimport { CollapsibleSection } from '../../../../../../../ui/CollapsibleSection'\r\nimport { useTranslations } from 'next-intl'\r\nimport ConfirmDialog from '../../../../../../../ConfirmDialog'\r\nimport { useUploadFileToBuilding, useDeleteFile, useFile } from '../../../../../../../../hooks/files/files'\r\nimport { useFileUploadHandler, useFileDeleteHandler, FileItemComponent, useFileActions, useCommonFileUpload } from '../../../../../../../ui/FilesManager'\r\nimport { IDSManager } from '../../../../IDSManager'\r\nimport { BCFTopicsManager } from '../../../../BCFTopicsManager'\r\nimport { createFileMarker, removeMarker, type AddedFile } from '../../../../tools/AddToBim/src/FileMarkerUtils'\r\nimport type { CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js'\r\nimport { DbFile as IFile } from '../../../../../../../../types/dbTypes'\r\n\r\n// Hoist options arrays so the array identity is stable across renders.\r\n// Inline `options={[...]}` defeats React.memo on FileItemComponent.\r\ntype FileAction = import('../../../../../../../../types/global').FileAction\r\nconst OPTIONS_3D: FileAction[] = ['download', 'view', 'move', 'info', 'delete']\r\nconst OPTIONS_NON_3D: FileAction[] = ['download', 'view', 'delete']\r\n\r\ninterface FilesSectionProps {\r\n files: IFile[]\r\n query?: string\r\n}\r\n\r\nconst is3DFile = (ext?: string | null): boolean => {\r\n if (!ext) return false\r\n return ['glb', 'gltf', 'fbx', 'obj', 'collada'].includes(ext.toLowerCase())\r\n}\r\n\r\n// Files that live in the 3D scene and can be moved/scaled (3D models + DXF drawings).\r\nconst isPlaceable = (ext?: string | null): boolean => is3DFile(ext) || ext?.toLowerCase() === 'dxf'\r\n\r\nexport function FilesSection({ files, query = '' }: FilesSectionProps) {\r\n const t = useTranslations('FileSelection')\r\n\r\n const { state: bimState, dispatch: bimDispatch } = React.useContext(BimContext)\r\n const { bimComponents, fragments } = bimState.bim\r\n const { state: buildingsState } = React.useContext(BuildingsContext)\r\n const { building } = buildingsState.buildings\r\n const buildingId = building?.id || -1\r\n const { dispatch: menusDispatch } = React.useContext(MenusContext)\r\n\r\n const { uploadFile } = useUploadFileToBuilding(buildingId)\r\n const { deleteFile } = useDeleteFile(buildingId)\r\n\r\n const { handleFileUpload } = useFileUploadHandler({\r\n buildingId,\r\n tag: 'file',\r\n uploadFile,\r\n })\r\n\r\n const { handleDeleteFile } = useFileDeleteHandler({\r\n deleteFile,\r\n onDeleteSuccess: () => {\r\n console.log('File deleted successfully')\r\n },\r\n })\r\n\r\n // Local state for file management with isVisible property\r\n const [localFiles, setLocalFiles] = React.useState<(IFile & { isVisible?: boolean })[]>([])\r\n const [activeIDSFileId, setActiveIDSFileId] = React.useState<number | null>(null)\r\n\r\n // Initialize and sync files\r\n React.useEffect(() => {\r\n setLocalFiles(prevFiles => {\r\n const visibilityMap = new Map(\r\n prevFiles.map(f => [f.id, f.isVisible ?? false])\r\n )\r\n return files\r\n .filter(file => file.tag !== 'user')\r\n .filter(file => (file as any).type !== 'map-file')\r\n .map(file => {\r\n // Preserve the user's toggle state for already-tracked files; otherwise honor\r\n // the persisted visibility so files added in-session show as added (not disabled).\r\n let isVisible = visibilityMap.has(file.id) ? visibilityMap.get(file.id)! : (file.isVisible ?? false)\r\n if (file.extension === 'ids' && activeIDSFileId === file.id) {\r\n isVisible = true\r\n } else if (file.extension === 'ids' && activeIDSFileId !== null && activeIDSFileId !== file.id) {\r\n isVisible = false\r\n }\r\n return { ...file, isVisible }\r\n })\r\n .sort((a, b) => a.name.localeCompare(b.name))\r\n })\r\n }, [files, activeIDSFileId])\r\n\r\n // Listen to IDS reset events\r\n React.useEffect(() => {\r\n if (!bimComponents) return\r\n try {\r\n const idsManager = bimComponents.get(IDSManager)\r\n const handleIDSReset = () => {\r\n setActiveIDSFileId(null)\r\n setLocalFiles(prevFiles =>\r\n prevFiles.map(file =>\r\n file.extension === 'ids' ? { ...file, isVisible: false } : file\r\n )\r\n )\r\n }\r\n idsManager.onReset.add(handleIDSReset)\r\n return () => { idsManager.onReset.remove(handleIDSReset) }\r\n } catch {\r\n return\r\n }\r\n }, [bimComponents])\r\n\r\n const modelManager = React.useMemo(() => {\r\n if (!bimComponents) return null\r\n try { return bimComponents.get(ModelManager) } catch { return null }\r\n }, [bimComponents])\r\n const modelManagerRef = React.useRef(modelManager)\r\n React.useEffect(() => { modelManagerRef.current = modelManager }, [modelManager])\r\n\r\n const dxfManager = React.useMemo(() => {\r\n if (!bimComponents) return null\r\n try { return bimComponents.get(DXFManager) } catch { return null }\r\n }, [bimComponents])\r\n // Loaded DXF groups keyed by file id, so visibility toggles can show/hide them.\r\n const dxfGroupsRef = React.useRef<Map<string, THREE.Group>>(new Map())\r\n\r\n // Floating scene markers (pin + actions card) for visible placeable files.\r\n const markersRef = React.useRef<Map<string, { marker: CSS2DObject; file: IFile }>>(new Map())\r\n // Bumped after an object finishes loading so the marker reconcile effect re-runs.\r\n const [loadedTick, setLoadedTick] = React.useState(0)\r\n\r\n const toggleDxfVisibility = React.useCallback(async (file: IFile, visible: boolean) => {\r\n if (!dxfManager || !bimComponents) return\r\n const world = bimComponents.get(CurrentWorld).world\r\n if (!world) return\r\n\r\n const key = file.id.toString()\r\n const existing = dxfGroupsRef.current.get(key)\r\n if (visible) {\r\n if (existing) { existing.visible = true; return }\r\n try {\r\n const res = await fetch(`/api/presignedUrlDownload/${file.id}`)\r\n if (!res.ok) throw new Error(`Failed to get download URL: ${res.status}`)\r\n const { presignedUrl } = await res.json()\r\n const group = await dxfManager.parse(presignedUrl)\r\n group.name = key\r\n const placed = file.x != null && file.y != null && file.z != null\r\n group.position.copy(placed\r\n ? new THREE.Vector3(file.x as number, file.y as number, file.z as number)\r\n : new THREE.Vector3())\r\n group.scale.setScalar(0.001)\r\n if (file.rotation != null) group.rotation.y = file.rotation as number\r\n world.scene.three.add(group)\r\n dxfGroupsRef.current.set(key, group)\r\n setLoadedTick(t => t + 1)\r\n } catch (err) {\r\n console.error(`[FilesSection] Failed to load DXF \"${file.name}\":`, err)\r\n }\r\n } else if (existing) {\r\n existing.visible = false\r\n }\r\n }, [dxfManager, bimComponents])\r\n\r\n // Gizmo controllers keyed by file name (one gizmo per file at most)\r\n const gizmoControllersRef = React.useRef<Map<string, GizmoController>>(new Map())\r\n\r\n // Track the file ID currently being repositioned so useFile can provide updateFile\r\n const [moveFileId, setMoveFileId] = React.useState<number | null>(null)\r\n const { updateFile } = useFile(moveFileId)\r\n const updateFileRef = React.useRef(updateFile)\r\n React.useEffect(() => { updateFileRef.current = updateFile }, [updateFile])\r\n\r\n const fetchDbFileAsFile = async (file: IFile): Promise<globalThis.File> => {\r\n const response = await fetch(file.url)\r\n const blob = await response.blob()\r\n const mimeType = file.extension === 'ids' ? 'application/xml' : 'application/octet-stream'\r\n return new globalThis.File([blob], file.name, { type: mimeType })\r\n }\r\n\r\n // View handler: IDS, BCF, and 3D file visibility\r\n const handleBimView = React.useCallback(async (file: IFile & { isVisible?: boolean }, newVisibility: boolean) => {\r\n // IDS files\r\n if (file.extension === 'ids') {\r\n const idsManager = bimComponents?.get(IDSManager)\r\n if (!idsManager) return\r\n idsManager.enabled = newVisibility\r\n if (newVisibility) {\r\n setActiveIDSFileId(file.id)\r\n try {\r\n const dbFile = await fetchDbFileAsFile(file)\r\n await idsManager.loadFromFile(dbFile)\r\n await idsManager.loadAndTestIDS()\r\n } catch (error) {\r\n console.error('Error loading IDS file:', error)\r\n }\r\n } else {\r\n setActiveIDSFileId(null)\r\n await idsManager.reset()\r\n }\r\n }\r\n\r\n // BCF files\r\n if (file.extension === 'bcf') {\r\n menusDispatch({ type: 'SET_SIDEBAR_SELECTED_TAB', payload: { selectedTab: 'communication' } })\r\n const bcfManager = bimComponents?.get(BCFTopicsManager)\r\n if (!bcfManager) return\r\n try {\r\n const { topics } = await bcfManager.loadBCFFromUrl(file.url)\r\n if (topics?.length) {\r\n topics.forEach((topic) => {\r\n const exists = bimState.bim.bcfTopics.find(t => t.guid === topic.guid)\r\n if (!exists) {\r\n bimDispatch({ type: 'ADD_BCF_TOPIC', payload: { bcfTopic: topic } })\r\n }\r\n })\r\n }\r\n } catch (error) {\r\n console.error('Failed to load BCF from URL:', error)\r\n }\r\n }\r\n\r\n // 3D model files (GLB/GLTF/FBX/OBJ) managed by ModelManager\r\n if (is3DFile(file.extension) && modelManager) {\r\n const existingModel = modelManager.getModelByName(file.name)\r\n if (newVisibility) {\r\n if (existingModel) {\r\n // Already in scene — just show it\r\n existingModel.model.visible = true\r\n } else {\r\n // Not yet loaded — get a fresh presigned download URL then load\r\n try {\r\n const res = await fetch(`/api/presignedUrlDownload/${file.id}`)\r\n if (!res.ok) throw new Error(`Failed to get download URL: ${res.status}`)\r\n const { presignedUrl } = await res.json()\r\n const position = (file.x != null && file.y != null && file.z != null)\r\n ? new THREE.Vector3(file.x as number, file.y as number, file.z as number)\r\n : new THREE.Vector3(0, 0, 0)\r\n const rotation = file.rotation != null\r\n ? new THREE.Euler(0, file.rotation, 0)\r\n : undefined\r\n await modelManager.load(presignedUrl, file.id.toString(), file.name, {\r\n position,\r\n rotation,\r\n extension: file.extension ?? undefined,\r\n })\r\n } catch (err) {\r\n console.error(`[FilesSection] Failed to load model \"${file.name}\":`, err)\r\n }\r\n }\r\n } else {\r\n if (existingModel) {\r\n existingModel.model.visible = false\r\n }\r\n }\r\n if (fragments) fragments.core.update(true)\r\n }\r\n\r\n // DXF files managed via DXFManager\r\n if (file.extension === 'dxf') {\r\n await toggleDxfVisibility(file, newVisibility)\r\n if (fragments) fragments.core.update(true)\r\n }\r\n setLoadedTick(t => t + 1)\r\n }, [bimComponents, menusDispatch, bimState, bimDispatch, modelManager, fragments, toggleDxfVisibility])\r\n\r\n const highlighter = React.useMemo(() => {\r\n if (!bimComponents) return null\r\n try { return bimComponents.get(Highlighter) } catch { return null }\r\n }, [bimComponents])\r\n\r\n // Raycast into fragments (same logic as useFilePlacement)\r\n const raycast = React.useCallback(async (data: {\r\n camera: THREE.PerspectiveCamera | THREE.OrthographicCamera\r\n mouse: THREE.Vector2\r\n dom: HTMLCanvasElement\r\n }) => {\r\n if (!fragments || !highlighter) return null\r\n const results = []\r\n for (const [modelName, model] of fragments.core.models.list) {\r\n if (highlighter.isModelDisabled(modelName)) continue\r\n const result = await model.raycast(data)\r\n if (result) results.push(result)\r\n }\r\n await Promise.all(results)\r\n if (results.length === 0) return null\r\n let closest = results[0]\r\n for (let i = 1; i < results.length; i++) {\r\n if (results[i].distance < closest.distance) closest = results[i]\r\n }\r\n return closest\r\n }, [fragments, highlighter])\r\n\r\n // Track the file currently being placed (unplaced file → click-to-place)\r\n const [placingFile, setPlacingFile] = React.useState<IFile | null>(null)\r\n\r\n // Click-to-place effect: crosshair + double-click raycast for unplaced files\r\n React.useEffect(() => {\r\n if (!placingFile || !bimComponents) return\r\n\r\n const world = bimComponents.get(CurrentWorld).world\r\n if (!world) return\r\n\r\n const cursor = bimComponents.get(Cursor)\r\n if (cursor) cursor.cursor = 'crosshair'\r\n\r\n const mouse = new THREE.Vector2()\r\n\r\n const handleDblClick = async (e: MouseEvent) => {\r\n mouse.x = e.clientX\r\n mouse.y = e.clientY\r\n\r\n const result = await raycast({\r\n camera: world.camera.three,\r\n mouse,\r\n dom: world.renderer!.three.domElement!,\r\n })\r\n\r\n if (result?.point && (result.point.x !== 0 || result.point.y !== 0 || result.point.z !== 0)) {\r\n const { x, y, z } = result.point\r\n setMoveFileId(placingFile.id)\r\n // Save coordinates to DB\r\n setTimeout(() => {\r\n updateFileRef.current({ x, y, z } as any)\r\n .catch((err: unknown) => console.error(`Failed to save placement for \"${placingFile.name}\":`, err))\r\n }, 50)\r\n // Load model into scene at the placed position (for 3D files)\r\n if (is3DFile(placingFile.extension) && modelManagerRef.current) {\r\n const existing = modelManagerRef.current.getModelByName(placingFile.name)\r\n if (!existing) {\r\n fetch(`/api/presignedUrlDownload/${placingFile.id}`)\r\n .then(res => res.ok ? res.json() : Promise.reject(res.status))\r\n .then(({ presignedUrl }) =>\r\n modelManagerRef.current!.load(\r\n presignedUrl,\r\n placingFile.id.toString(),\r\n placingFile.name,\r\n { position: new THREE.Vector3(x, y, z), extension: placingFile.extension ?? undefined },\r\n )\r\n )\r\n .catch((err: unknown) => console.error(`Failed to load model \"${placingFile.name}\":`, err))\r\n } else {\r\n existing.model.position.set(x, y, z)\r\n existing.model.visible = true\r\n }\r\n }\r\n // Update local state so it shows as placed and visible\r\n placingFile.x = x\r\n placingFile.y = y\r\n placingFile.z = z\r\n setLocalFiles(prev => prev.map(f => f.id === placingFile.id ? { ...f, x, y, z, isVisible: true } : f))\r\n setPlacingFile(null)\r\n if (cursor) cursor.cursor = ''\r\n }\r\n }\r\n\r\n const handleKeyDown = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape') {\r\n setPlacingFile(null)\r\n if (cursor) cursor.cursor = ''\r\n }\r\n }\r\n\r\n document.addEventListener('dblclick', handleDblClick)\r\n document.addEventListener('keydown', handleKeyDown)\r\n\r\n return () => {\r\n document.removeEventListener('dblclick', handleDblClick)\r\n document.removeEventListener('keydown', handleKeyDown)\r\n if (cursor) cursor.cursor = ''\r\n }\r\n }, [placingFile, bimComponents, raycast])\r\n\r\n // Resolve the scene object for a file (loaded 3D model or DXF group), if present.\r\n const getSceneObject = React.useCallback((file: IFile): THREE.Object3D | null => {\r\n if (file.extension === 'dxf') return dxfGroupsRef.current.get(file.id.toString()) ?? null\r\n return modelManager?.getModelByName(file.name)?.model ?? null\r\n }, [modelManager])\r\n\r\n // Attach a transform gizmo to a placed object (or re-set its mode); saves on accept.\r\n const editObject = React.useCallback((file: IFile, mode: 'translate' | 'rotate' | 'scale' = 'translate') => {\r\n if (!bimComponents) return\r\n const world = bimComponents.get(CurrentWorld).world\r\n if (!world) return\r\n const obj = getSceneObject(file)\r\n if (!obj) return\r\n\r\n const key = file.id.toString()\r\n const existing = gizmoControllersRef.current.get(key)\r\n if (existing) { existing.setMode(mode); return }\r\n\r\n const gizmo = new GizmoController(world)\r\n const cleanup = (save: boolean) => {\r\n if (save) {\r\n const { x, y, z } = obj.position\r\n const rotation = obj.rotation.y\r\n updateFileRef.current({ x, y, z, rotation } as any)\r\n .catch((err: unknown) => console.error(`Failed to save position for \"${file.name}\":`, err))\r\n file.x = x; file.y = y; file.z = z; file.rotation = rotation\r\n }\r\n gizmoControllersRef.current.delete(key)\r\n setMoveFileId(null)\r\n }\r\n gizmo.onAccept = () => cleanup(true)\r\n gizmo.onCancel = () => cleanup(false)\r\n gizmo.setMode(mode)\r\n setMoveFileId(file.id)\r\n gizmo.attach(obj)\r\n gizmoControllersRef.current.set(key, gizmo)\r\n }, [bimComponents, getSceneObject])\r\n\r\n // Move handler: unplaced files → click-to-place; placed files → gizmo (load DXF first if needed)\r\n const handleBimMove = React.useCallback((file: IFile) => {\r\n const isPlaced = file.x != null && file.y != null && file.z != null\r\n if (!isPlaced) {\r\n setPlacingFile(file)\r\n setMoveFileId(file.id)\r\n return\r\n }\r\n if (file.extension === 'dxf' && !dxfGroupsRef.current.has(file.id.toString())) {\r\n void toggleDxfVisibility(file, true).then(() => editObject(file, 'translate'))\r\n return\r\n }\r\n editObject(file, 'translate')\r\n }, [editObject, toggleDxfVisibility])\r\n\r\n const { handleAction, deleteDialog } = useFileActions({\r\n files: localFiles,\r\n setFiles: setLocalFiles,\r\n buildingId,\r\n handleDeleteFile,\r\n onView: handleBimView,\r\n onMove: handleBimMove,\r\n })\r\n\r\n const { handleAddFile } = useCommonFileUpload({\r\n buildingId,\r\n acceptedFileTypes: '*',\r\n handleFileUpload: async (domFile: globalThis.File) => {\r\n await handleFileUpload(domFile)\r\n },\r\n onUploadSuccess: () => {\r\n console.log('File uploaded successfully')\r\n },\r\n onUploadError: (error) => {\r\n console.error('Error uploading file:', error)\r\n },\r\n })\r\n\r\n const filteredFiles = React.useMemo(() => {\r\n if (!query.trim()) return localFiles\r\n return localFiles.filter(file =>\r\n file.name.toLowerCase().includes(query.toLowerCase())\r\n )\r\n }, [localFiles, query])\r\n\r\n const areAllHidden = localFiles.every(f => !f.isVisible)\r\n\r\n const handleSwitchVariant = () => ({\r\n checked: !areAllHidden,\r\n onCheckedChange: async (checked: boolean) => {\r\n setLocalFiles(prev => prev.map(f => ({ ...f, isVisible: checked })))\r\n for (const f of localFiles) {\r\n if (is3DFile(f.extension) && modelManager) {\r\n const existingModel = modelManager.getModelByName(f.name)\r\n if (checked) {\r\n if (existingModel) {\r\n existingModel.model.visible = true\r\n } else {\r\n try {\r\n const res = await fetch(`/api/presignedUrlDownload/${f.id}`)\r\n if (res.ok) {\r\n const { presignedUrl } = await res.json()\r\n const position = (f.x != null && f.y != null && f.z != null)\r\n ? new THREE.Vector3(f.x as number, f.y as number, f.z as number)\r\n : new THREE.Vector3(0, 0, 0)\r\n await modelManager.load(presignedUrl, f.id.toString(), f.name, {\r\n position,\r\n extension: f.extension ?? undefined,\r\n })\r\n }\r\n } catch (err) {\r\n console.error(`[FilesSection] Failed to load model \"${f.name}\":`, err)\r\n }\r\n }\r\n } else if (existingModel) {\r\n existingModel.model.visible = false\r\n }\r\n } else if (f.extension === 'dxf') {\r\n await toggleDxfVisibility(f, checked)\r\n }\r\n }\r\n if (fragments) fragments.core.update(true)\r\n setLoadedTick(t => t + 1)\r\n },\r\n })\r\n\r\n // createFileMarker expects an AddedFile; build a lightweight one from the DB file.\r\n const makeMarkerInput = React.useCallback((file: IFile, position: THREE.Vector3): AddedFile => ({\r\n id: file.id.toString(),\r\n file: new File([], file.name, { type: (file as any).mimeType ?? '' }),\r\n position,\r\n }), [])\r\n\r\n // Reconcile floating markers with the visible + loaded placeable files.\r\n React.useEffect(() => {\r\n if (!bimComponents) return\r\n const world = bimComponents.get(CurrentWorld).world\r\n if (!world) return\r\n\r\n const wanted = new Map(\r\n localFiles\r\n .filter(f => f.isVisible && isPlaceable(f.extension))\r\n .map(f => [f.id.toString(), f] as const),\r\n )\r\n\r\n for (const [key, entry] of markersRef.current) {\r\n if (!wanted.has(key)) {\r\n removeMarker(entry.marker, world)\r\n markersRef.current.delete(key)\r\n }\r\n }\r\n\r\n for (const [key, file] of wanted) {\r\n if (markersRef.current.has(key)) continue\r\n const obj = getSceneObject(file)\r\n if (!obj) continue // not loaded yet — picked up once loadedTick bumps\r\n const marker = createFileMarker(makeMarkerInput(file, obj.position.clone()), obj, world, (action) => {\r\n if (action === 'delete') { handleAction('delete', file); return }\r\n editObject(file, action === 'move' ? 'translate' : action)\r\n })\r\n if (marker) markersRef.current.set(key, { marker, file })\r\n }\r\n }, [localFiles, loadedTick, bimComponents, getSceneObject, editObject, handleAction, makeMarkerInput])\r\n\r\n // Markers follow their object each frame and hide while that object's gizmo is active.\r\n React.useEffect(() => {\r\n if (!bimComponents) return\r\n let raf = 0\r\n const worldPos = new THREE.Vector3()\r\n const tick = () => {\r\n markersRef.current.forEach(({ marker, file }, key) => {\r\n const obj = getSceneObject(file)\r\n if (!obj) { marker.visible = false; return }\r\n obj.getWorldPosition(worldPos)\r\n marker.position.set(worldPos.x, worldPos.y + 0.2, worldPos.z)\r\n marker.visible = !gizmoControllersRef.current.has(key)\r\n })\r\n raf = requestAnimationFrame(tick)\r\n }\r\n raf = requestAnimationFrame(tick)\r\n return () => cancelAnimationFrame(raf)\r\n }, [bimComponents, getSceneObject])\r\n\r\n // Clean up all markers on unmount so their DOM/React roots don't leak.\r\n const markersCleanupRef = React.useRef(markersRef.current)\r\n React.useEffect(() => {\r\n const markers = markersCleanupRef.current\r\n return () => {\r\n markers.forEach(({ marker }) => removeMarker(marker))\r\n markers.clear()\r\n }\r\n }, [])\r\n\r\n return (\r\n <>\r\n <CollapsibleSection\r\n title={t('filesTitle')}\r\n icon={LR.FileText}\r\n className=\"max-h-40 overflow-y-auto\"\r\n itemCount={filteredFiles.length}\r\n switchVariant={handleSwitchVariant()}\r\n onAddItem={handleAddFile}\r\n addItemTitle={t('addFileTitle')}\r\n >\r\n <div className=\"space-y-1\">\r\n {filteredFiles.map((item) => (\r\n <FileItemComponent\r\n key={item.id}\r\n file={item}\r\n onAction={handleAction}\r\n options={isPlaceable(item.extension) ? OPTIONS_3D : OPTIONS_NON_3D}\r\n translationKey=\"FileSelection\"\r\n confirmDelete={false}\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 />\r\n </>\r\n )\r\n}\r\n"],"mappings":"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","names":["t"]}
@@ -1 +1 @@
1
- {"version":3,"file":"ModelsSection.d.ts","sourceRoot":"","sources":["../../../../../../../../../../src/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/ModelsSection.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAc9B,OAAO,KAAK,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,uCAAuC,CAAA;AAM7E,UAAU,kBAAkB;IAC1B,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,KAAU,EAAE,EAAE,kBAAkB,qBAwTtE"}
1
+ {"version":3,"file":"ModelsSection.d.ts","sourceRoot":"","sources":["../../../../../../../../../../src/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/ModelsSection.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAc9B,OAAO,KAAK,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,uCAAuC,CAAA;AAI7E,UAAU,kBAAkB;IAC1B,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,KAAU,EAAE,EAAE,kBAAkB,qBAwTtE"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../../../../src/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/ModelsSection.tsx"],"sourcesContent":["'use client'\r\n\r\nimport * as React from 'react'\r\nimport { useTranslations } from 'next-intl'\r\nimport ConfirmDialog from '../../../../../../../ConfirmDialog'\r\nimport * as LR from 'lucide-react'\r\nimport { BimContext, BuildingsContext } from '../../../../../../../../store'\r\nimport { ModelManager } from '../../../../ModelManager'\r\nimport { BIMManager } from '../../../../BIMManager'\r\nimport { GhostMode } from '../../../../GhostMode'\r\nimport { GizmoController } from '../../../../../utils/GizmoController'\r\nimport { CurrentWorld } from '../../../../CurrentWorld'\r\nimport { Highlighter } from '../../../../Highlighter'\r\nimport { CollapsibleSection } from '../../../../../../../ui/CollapsibleSection'\r\nimport { useUploadFileToBuilding, useDeleteFile, useFile } from '../../../../../../../../hooks/files/files'\r\nimport { useFileUploadHandler, useFileDeleteHandler, FileItemComponent, useFileActions, useCommonFileUpload } from '../../../../../../../ui/FilesManager'\r\nimport type { DbFile as DbFile } from '../../../../../../../../types/dbTypes'\r\n\r\n// Audit Phase 1.C (F-19): hoist out of JSX so React.memo on FileItemComponent\r\n// isn't defeated by per-render array identity churn.\r\nconst BIM_MODEL_OPTIONS: import('../../../../../../../../types/global').FileAction[] = ['view', 'ghost', 'move', 'info', 'delete']\r\n\r\ninterface ModelsSectionProps {\r\n files: DbFile[]\r\n query?: string\r\n}\r\n\r\nexport function ModelsSection({ files, query = '' }: ModelsSectionProps) {\r\n // Translation\r\n const t = useTranslations('FileItemComponent')\r\n\r\n // Get BIM context\r\n const { state: bimState, dispatch: bimDispatch } = React.useContext(BimContext)\r\n const { bimComponents, fragments, modelId, modelUIState } = bimState.bim\r\n \r\n // Get Buildings context for buildingId\r\n const { state: buildingsState } = React.useContext(BuildingsContext)\r\n const { building } = buildingsState.buildings\r\n const buildingId = building?.id || 0\r\n\r\n // Upload file hook and session\r\n const { uploadFile } = useUploadFileToBuilding(buildingId)\r\n const { deleteFile } = useDeleteFile(buildingId)\r\n\r\n // Use the reusable upload handler\r\n const { handleFileUpload } = useFileUploadHandler({\r\n buildingId,\r\n tag: 'bim-file',\r\n isVisible: true,\r\n uploadFile,\r\n })\r\n\r\n // Use the reusable delete handler\r\n const { handleDeleteFile } = useFileDeleteHandler({\r\n deleteFile,\r\n \r\n })\r\n\r\n // Local state for file management with isVisible property\r\n const [loadedModels, setLoadedModels] = React.useState<(DbFile & { isVisible?: boolean })[]>(\r\n files.map(file => ({\r\n ...file,\r\n isVisible: modelUIState[file.id]?.isVisible ?? (file as any).isVisible,\r\n isGhost: modelUIState[file.id]?.isGhost ?? false,\r\n }))\r\n )\r\n\r\n // Keep local list in sync with incoming props and store UI state changes\r\n React.useEffect(() => {\r\n setLoadedModels(prev => {\r\n const prevMap = new Map(prev.map(f => [f.id, f as any]))\r\n return files.map(file => ({\r\n ...file,\r\n isVisible: modelUIState[file.id]?.isVisible ?? (file as any).isVisible,\r\n isGhost: modelUIState[file.id]?.isGhost ?? prevMap.get(file.id)?.isGhost ?? false,\r\n }))\r\n })\r\n }, [files, modelUIState])\r\n\r\n // Get ModelManager from BIM components\r\n const modelManager = React.useMemo(() => {\r\n if (!bimComponents) return null\r\n try {\r\n return bimComponents.get(ModelManager)\r\n }\r\n catch {\r\n return null\r\n }\r\n }, [bimComponents])\r\n\r\n // Get BIMManager from BIM components\r\n const bimManager = React.useMemo(() => {\r\n if (!bimComponents) return null\r\n try {\r\n return bimComponents.get(BIMManager)\r\n }\r\n catch {\r\n return null\r\n }\r\n }, [bimComponents])\r\n\r\n // Get GhostMode from BIM components\r\n const ghostMode = React.useMemo(() => {\r\n if (!bimComponents) return null\r\n try {\r\n return bimComponents.get(GhostMode)\r\n }\r\n catch {\r\n return null\r\n }\r\n }, [bimComponents])\r\n\r\n // Gizmo controllers keyed by model's file.name (one gizmo per model at most)\r\n const gizmoControllersRef = React.useRef<Map<string, GizmoController>>(new Map())\r\n\r\n // Track the file ID currently being repositioned so useFile can provide updateFile\r\n const [moveFileId, setMoveFileId] = React.useState<number | null>(null)\r\n const { updateFile } = useFile(moveFileId)\r\n const updateFileRef = React.useRef(updateFile)\r\n React.useEffect(() => { updateFileRef.current = updateFile }, [updateFile])\r\n\r\n // Get Highlighter from BIM components\r\n const highlighter = React.useMemo(() => {\r\n if (!bimComponents) return null\r\n try {\r\n return bimComponents.get(Highlighter)\r\n }\r\n catch {\r\n return null\r\n }\r\n }, [bimComponents])\r\n\r\n // Custom handlers for BIM-specific actions (view and delete only - download uses default)\r\n const handleBimView = React.useCallback((file: DbFile, newVisibility: boolean) => {\r\n bimDispatch({ type: 'SET_MODEL_UI_STATE', payload: { fileId: file.id, isVisible: newVisibility } })\r\n\r\n // Disable highlighting for hidden models; re-enable only when visible and not ghosted\r\n if (highlighter) {\r\n const isGhosted = modelUIState[file.id]?.isGhost ?? false\r\n if (!newVisibility || isGhosted) {\r\n highlighter.disableModel(file.name)\r\n } else {\r\n highlighter.enableModel(file.name)\r\n }\r\n }\r\n\r\n // Non-fragment models (gltf/obj/fbx) managed by ModelManager\r\n if (modelManager) {\r\n const modelInfo = modelManager.getModel(file.id.toString())\r\n if (modelInfo) {\r\n modelInfo.model.visible = newVisibility\r\n if (fragments) fragments.core.update(true)\r\n return\r\n }\r\n }\r\n\r\n // Fragment (IFC/FRAG) models — look up directly from fragments list by file.name\r\n if (fragments) {\r\n const fragModel = fragments.core.models.list.get(file.name)\r\n if (fragModel) {\r\n fragModel.object.visible = newVisibility\r\n fragments.core.update(true)\r\n } else {\r\n }\r\n }\r\n }, [modelManager, fragments, highlighter, modelUIState])\r\n\r\n const handleBimDelete = React.useCallback((file: DbFile) => {\r\n // Remove from ModelManager if it exists (gltf/obj/fbx models)\r\n if (modelManager) {\r\n const modelIdStr = file.id.toString()\r\n const model = modelManager.getModel(modelIdStr)\r\n console.log('Attempting to remove model', model, modelIdStr)\r\n const success = modelManager.remove(modelIdStr)\r\n if (success) {\r\n console.log(`Model ${modelIdStr} removed from BIM scene`)\r\n }\r\n }\r\n\r\n // Remove fragment model from scene if it exists (ifc/frag models)\r\n if (fragments) {\r\n const fragModel = fragments.core.models.list.get(file.name)\r\n if (fragModel) {\r\n fragments.core.disposeModel(fragModel.modelId).catch((err: unknown) => {\r\n console.error(`Failed to dispose fragment model \"${file.name}\":`, err)\r\n })\r\n // Also clean up BIMManager tracking\r\n bimManager?.remove(file.name)\r\n }\r\n }\r\n }, [modelManager, bimComponents, fragments, bimManager])\r\n\r\n const handleBimMove = React.useCallback((file: DbFile) => {\r\n if (!bimComponents || !fragments) return\r\n\r\n const world = bimComponents.get(CurrentWorld).world\r\n if (!world) return\r\n\r\n const fragModel = fragments.core.models.list.get(file.name)\r\n if (!fragModel) {\r\n console.warn(`[BimMove] Model not found: \"${file.name}\"`)\r\n return\r\n }\r\n\r\n const existing = gizmoControllersRef.current.get(file.name)\r\n if (existing) {\r\n // Toggle off: destroy the gizmo\r\n existing.dispose()\r\n gizmoControllersRef.current.delete(file.name)\r\n if (gizmoControllersRef.current.size === 0 && highlighter) highlighter.enabled = true\r\n } else {\r\n // Toggle on: create a new gizmo attached to the model's root object\r\n const gizmo = new GizmoController(world)\r\n const cleanupGizmo = (savePosition: boolean) => {\r\n if (savePosition) {\r\n const { x, y, z } = fragModel.object.position\r\n const rotation = fragModel.object.rotation.y\r\n updateFileRef.current({ x, y, z, rotation } as any)\r\n .catch((err: unknown) => console.error(`[BimMove] Failed to save position for \"${file.name}\":`, err))\r\n file.x = x\r\n file.y = y\r\n file.z = z\r\n file.rotation = rotation\r\n }\r\n gizmoControllersRef.current.delete(file.name)\r\n if (gizmoControllersRef.current.size === 0 && highlighter) highlighter.enabled = true\r\n setMoveFileId(null)\r\n }\r\n gizmo.onAccept = () => cleanupGizmo(true)\r\n gizmo.onCancel = () => cleanupGizmo(false)\r\n setMoveFileId(file.id)\r\n if (highlighter) highlighter.enabled = false\r\n gizmo.attach(fragModel.object)\r\n gizmoControllersRef.current.set(file.name, gizmo)\r\n }\r\n }, [bimComponents, fragments, highlighter])\r\n\r\n const handleBimGhost = React.useCallback((file: DbFile, ghostState: boolean) => {\r\n if (!fragments || !ghostMode) return\r\n\r\n const fragModel = fragments.core.models.list.get(file.name)\r\n if (!fragModel) {\r\n console.warn(`[BimGhost] Model not found: \"${file.name}\"`)\r\n return\r\n }\r\n\r\n ghostMode.setModelGhost(fragModel, ghostState)\r\n bimDispatch({ type: 'SET_MODEL_UI_STATE', payload: { fileId: file.id, isGhost: ghostState } })\r\n\r\n // Disable highlighting for ghosted models; re-enable only when visible and not ghosted\r\n if (highlighter) {\r\n const isVisible = modelUIState[file.id]?.isVisible ?? true\r\n if (ghostState || !isVisible) {\r\n highlighter.disableModel(file.name)\r\n } else {\r\n highlighter.enableModel(file.name)\r\n }\r\n }\r\n }, [fragments, ghostMode, bimDispatch, highlighter, modelUIState])\r\n\r\n // Use the common file actions hook (no custom download handler - use default for all files)\r\n const { handleAction, deleteDialog } = useFileActions({\r\n files: loadedModels,\r\n setFiles: setLoadedModels,\r\n buildingId,\r\n handleDeleteFile,\r\n onView: handleBimView,\r\n onDelete: handleBimDelete,\r\n onMove: handleBimMove,\r\n onGhost: handleBimGhost\r\n })\r\n\r\n // Use the common file upload hook\r\n const { handleAddFile } = useCommonFileUpload({\r\n buildingId,\r\n acceptedFileTypes: '.ifc,.frag',\r\n handleFileUpload,\r\n onUploadSuccess: () => {\r\n console.log('Model uploaded successfully')\r\n },\r\n onUploadError: (error) => {\r\n console.error('Error uploading model:', error)\r\n }\r\n })\r\n\r\n // Filter models based on search query\r\n const filteredModels = React.useMemo(() => {\r\n if (!query.trim()) return loadedModels\r\n return loadedModels.filter(file =>\r\n file.name.toLowerCase().includes(query.toLowerCase())\r\n )\r\n }, [loadedModels, query])\r\n\r\n const areAllHidden = loadedModels.every(f => !f.isVisible)\r\n\r\n const handleSwitchVariant = () => ({\r\n checked: !areAllHidden,\r\n onCheckedChange: (checked: boolean) => {\r\n setLoadedModels(prev => prev.map(f => ({ ...f, isVisible: checked })))\r\n // Toggle visibility in 3D scene for all models\r\n for (const file of loadedModels) {\r\n handleBimView(file, checked)\r\n }\r\n },\r\n })\r\n\r\n return (\r\n <>\r\n <CollapsibleSection\r\n title={t('modelsTitles')}\r\n icon={LR.Box}\r\n className=\"max-h-40 overflow-y-auto\"\r\n itemCount={filteredModels.length}\r\n onAddItem={handleAddFile}\r\n addItemTitle={t('addBimTitle')}\r\n switchVariant={handleSwitchVariant()}\r\n >\r\n <div className=\"space-y-1\">\r\n {filteredModels.map((file) => (\r\n <FileItemComponent\r\n key={file.id}\r\n file={file}\r\n onAction={handleAction}\r\n options={BIM_MODEL_OPTIONS}\r\n confirmDelete={false}\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 />\r\n </>\r\n )\r\n}\r\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../../../../../../../src/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/ModelsSection.tsx"],"sourcesContent":["'use client'\r\n\r\nimport * as React from 'react'\r\nimport { useTranslations } from 'next-intl'\r\nimport ConfirmDialog from '../../../../../../../ConfirmDialog'\r\nimport * as LR from 'lucide-react'\r\nimport { BimContext, BuildingsContext } from '../../../../../../../../store'\r\nimport { ModelManager } from '../../../../ModelManager'\r\nimport { BIMManager } from '../../../../BIMManager'\r\nimport { GhostMode } from '../../../../GhostMode'\r\nimport { GizmoController } from '../../../../../utils/GizmoController'\r\nimport { CurrentWorld } from '../../../../CurrentWorld'\r\nimport { Highlighter } from '../../../../Highlighter'\r\nimport { CollapsibleSection } from '../../../../../../../ui/CollapsibleSection'\r\nimport { useUploadFileToBuilding, useDeleteFile, useFile } from '../../../../../../../../hooks/files/files'\r\nimport { useFileUploadHandler, useFileDeleteHandler, FileItemComponent, useFileActions, useCommonFileUpload } from '../../../../../../../ui/FilesManager'\r\nimport type { DbFile as DbFile } from '../../../../../../../../types/dbTypes'\r\n\r\nconst BIM_MODEL_OPTIONS: import('../../../../../../../../types/global').FileAction[] = ['view', 'ghost', 'move', 'info', 'delete']\r\n\r\ninterface ModelsSectionProps {\r\n files: DbFile[]\r\n query?: string\r\n}\r\n\r\nexport function ModelsSection({ files, query = '' }: ModelsSectionProps) {\r\n // Translation\r\n const t = useTranslations('FileItemComponent')\r\n\r\n // Get BIM context\r\n const { state: bimState, dispatch: bimDispatch } = React.useContext(BimContext)\r\n const { bimComponents, fragments, modelId, modelUIState } = bimState.bim\r\n \r\n // Get Buildings context for buildingId\r\n const { state: buildingsState } = React.useContext(BuildingsContext)\r\n const { building } = buildingsState.buildings\r\n const buildingId = building?.id || 0\r\n\r\n // Upload file hook and session\r\n const { uploadFile } = useUploadFileToBuilding(buildingId)\r\n const { deleteFile } = useDeleteFile(buildingId)\r\n\r\n // Use the reusable upload handler\r\n const { handleFileUpload } = useFileUploadHandler({\r\n buildingId,\r\n tag: 'bim-file',\r\n isVisible: true,\r\n uploadFile,\r\n })\r\n\r\n // Use the reusable delete handler\r\n const { handleDeleteFile } = useFileDeleteHandler({\r\n deleteFile,\r\n \r\n })\r\n\r\n // Local state for file management with isVisible property\r\n const [loadedModels, setLoadedModels] = React.useState<(DbFile & { isVisible?: boolean })[]>(\r\n files.map(file => ({\r\n ...file,\r\n isVisible: modelUIState[file.id]?.isVisible ?? (file as any).isVisible,\r\n isGhost: modelUIState[file.id]?.isGhost ?? false,\r\n }))\r\n )\r\n\r\n // Keep local list in sync with incoming props and store UI state changes\r\n React.useEffect(() => {\r\n setLoadedModels(prev => {\r\n const prevMap = new Map(prev.map(f => [f.id, f as any]))\r\n return files.map(file => ({\r\n ...file,\r\n isVisible: modelUIState[file.id]?.isVisible ?? (file as any).isVisible,\r\n isGhost: modelUIState[file.id]?.isGhost ?? prevMap.get(file.id)?.isGhost ?? false,\r\n }))\r\n })\r\n }, [files, modelUIState])\r\n\r\n // Get ModelManager from BIM components\r\n const modelManager = React.useMemo(() => {\r\n if (!bimComponents) return null\r\n try {\r\n return bimComponents.get(ModelManager)\r\n }\r\n catch {\r\n return null\r\n }\r\n }, [bimComponents])\r\n\r\n // Get BIMManager from BIM components\r\n const bimManager = React.useMemo(() => {\r\n if (!bimComponents) return null\r\n try {\r\n return bimComponents.get(BIMManager)\r\n }\r\n catch {\r\n return null\r\n }\r\n }, [bimComponents])\r\n\r\n // Get GhostMode from BIM components\r\n const ghostMode = React.useMemo(() => {\r\n if (!bimComponents) return null\r\n try {\r\n return bimComponents.get(GhostMode)\r\n }\r\n catch {\r\n return null\r\n }\r\n }, [bimComponents])\r\n\r\n // Gizmo controllers keyed by model's file.name (one gizmo per model at most)\r\n const gizmoControllersRef = React.useRef<Map<string, GizmoController>>(new Map())\r\n\r\n // Track the file ID currently being repositioned so useFile can provide updateFile\r\n const [moveFileId, setMoveFileId] = React.useState<number | null>(null)\r\n const { updateFile } = useFile(moveFileId)\r\n const updateFileRef = React.useRef(updateFile)\r\n React.useEffect(() => { updateFileRef.current = updateFile }, [updateFile])\r\n\r\n // Get Highlighter from BIM components\r\n const highlighter = React.useMemo(() => {\r\n if (!bimComponents) return null\r\n try {\r\n return bimComponents.get(Highlighter)\r\n }\r\n catch {\r\n return null\r\n }\r\n }, [bimComponents])\r\n\r\n // Custom handlers for BIM-specific actions (view and delete only - download uses default)\r\n const handleBimView = React.useCallback((file: DbFile, newVisibility: boolean) => {\r\n bimDispatch({ type: 'SET_MODEL_UI_STATE', payload: { fileId: file.id, isVisible: newVisibility } })\r\n\r\n // Disable highlighting for hidden models; re-enable only when visible and not ghosted\r\n if (highlighter) {\r\n const isGhosted = modelUIState[file.id]?.isGhost ?? false\r\n if (!newVisibility || isGhosted) {\r\n highlighter.disableModel(file.name)\r\n } else {\r\n highlighter.enableModel(file.name)\r\n }\r\n }\r\n\r\n // Non-fragment models (gltf/obj/fbx) managed by ModelManager\r\n if (modelManager) {\r\n const modelInfo = modelManager.getModel(file.id.toString())\r\n if (modelInfo) {\r\n modelInfo.model.visible = newVisibility\r\n if (fragments) fragments.core.update(true)\r\n return\r\n }\r\n }\r\n\r\n // Fragment (IFC/FRAG) models — look up directly from fragments list by file.name\r\n if (fragments) {\r\n const fragModel = fragments.core.models.list.get(file.name)\r\n if (fragModel) {\r\n fragModel.object.visible = newVisibility\r\n fragments.core.update(true)\r\n } else {\r\n }\r\n }\r\n }, [modelManager, fragments, highlighter, modelUIState])\r\n\r\n const handleBimDelete = React.useCallback((file: DbFile) => {\r\n // Remove from ModelManager if it exists (gltf/obj/fbx models)\r\n if (modelManager) {\r\n const modelIdStr = file.id.toString()\r\n const model = modelManager.getModel(modelIdStr)\r\n console.log('Attempting to remove model', model, modelIdStr)\r\n const success = modelManager.remove(modelIdStr)\r\n if (success) {\r\n console.log(`Model ${modelIdStr} removed from BIM scene`)\r\n }\r\n }\r\n\r\n // Remove fragment model from scene if it exists (ifc/frag models)\r\n if (fragments) {\r\n const fragModel = fragments.core.models.list.get(file.name)\r\n if (fragModel) {\r\n fragments.core.disposeModel(fragModel.modelId).catch((err: unknown) => {\r\n console.error(`Failed to dispose fragment model \"${file.name}\":`, err)\r\n })\r\n // Also clean up BIMManager tracking\r\n bimManager?.remove(file.name)\r\n }\r\n }\r\n }, [modelManager, bimComponents, fragments, bimManager])\r\n\r\n const handleBimMove = React.useCallback((file: DbFile) => {\r\n if (!bimComponents || !fragments) return\r\n\r\n const world = bimComponents.get(CurrentWorld).world\r\n if (!world) return\r\n\r\n const fragModel = fragments.core.models.list.get(file.name)\r\n if (!fragModel) {\r\n console.warn(`[BimMove] Model not found: \"${file.name}\"`)\r\n return\r\n }\r\n\r\n const existing = gizmoControllersRef.current.get(file.name)\r\n if (existing) {\r\n // Toggle off: destroy the gizmo\r\n existing.dispose()\r\n gizmoControllersRef.current.delete(file.name)\r\n if (gizmoControllersRef.current.size === 0 && highlighter) highlighter.enabled = true\r\n } else {\r\n // Toggle on: create a new gizmo attached to the model's root object\r\n const gizmo = new GizmoController(world)\r\n const cleanupGizmo = (savePosition: boolean) => {\r\n if (savePosition) {\r\n const { x, y, z } = fragModel.object.position\r\n const rotation = fragModel.object.rotation.y\r\n updateFileRef.current({ x, y, z, rotation } as any)\r\n .catch((err: unknown) => console.error(`[BimMove] Failed to save position for \"${file.name}\":`, err))\r\n file.x = x\r\n file.y = y\r\n file.z = z\r\n file.rotation = rotation\r\n }\r\n gizmoControllersRef.current.delete(file.name)\r\n if (gizmoControllersRef.current.size === 0 && highlighter) highlighter.enabled = true\r\n setMoveFileId(null)\r\n }\r\n gizmo.onAccept = () => cleanupGizmo(true)\r\n gizmo.onCancel = () => cleanupGizmo(false)\r\n setMoveFileId(file.id)\r\n if (highlighter) highlighter.enabled = false\r\n gizmo.attach(fragModel.object)\r\n gizmoControllersRef.current.set(file.name, gizmo)\r\n }\r\n }, [bimComponents, fragments, highlighter])\r\n\r\n const handleBimGhost = React.useCallback((file: DbFile, ghostState: boolean) => {\r\n if (!fragments || !ghostMode) return\r\n\r\n const fragModel = fragments.core.models.list.get(file.name)\r\n if (!fragModel) {\r\n console.warn(`[BimGhost] Model not found: \"${file.name}\"`)\r\n return\r\n }\r\n\r\n ghostMode.setModelGhost(fragModel, ghostState)\r\n bimDispatch({ type: 'SET_MODEL_UI_STATE', payload: { fileId: file.id, isGhost: ghostState } })\r\n\r\n // Disable highlighting for ghosted models; re-enable only when visible and not ghosted\r\n if (highlighter) {\r\n const isVisible = modelUIState[file.id]?.isVisible ?? true\r\n if (ghostState || !isVisible) {\r\n highlighter.disableModel(file.name)\r\n } else {\r\n highlighter.enableModel(file.name)\r\n }\r\n }\r\n }, [fragments, ghostMode, bimDispatch, highlighter, modelUIState])\r\n\r\n // Use the common file actions hook (no custom download handler - use default for all files)\r\n const { handleAction, deleteDialog } = useFileActions({\r\n files: loadedModels,\r\n setFiles: setLoadedModels,\r\n buildingId,\r\n handleDeleteFile,\r\n onView: handleBimView,\r\n onDelete: handleBimDelete,\r\n onMove: handleBimMove,\r\n onGhost: handleBimGhost\r\n })\r\n\r\n // Use the common file upload hook\r\n const { handleAddFile } = useCommonFileUpload({\r\n buildingId,\r\n acceptedFileTypes: '.ifc,.frag',\r\n handleFileUpload,\r\n onUploadSuccess: () => {\r\n console.log('Model uploaded successfully')\r\n },\r\n onUploadError: (error) => {\r\n console.error('Error uploading model:', error)\r\n }\r\n })\r\n\r\n // Filter models based on search query\r\n const filteredModels = React.useMemo(() => {\r\n if (!query.trim()) return loadedModels\r\n return loadedModels.filter(file =>\r\n file.name.toLowerCase().includes(query.toLowerCase())\r\n )\r\n }, [loadedModels, query])\r\n\r\n const areAllHidden = loadedModels.every(f => !f.isVisible)\r\n\r\n const handleSwitchVariant = () => ({\r\n checked: !areAllHidden,\r\n onCheckedChange: (checked: boolean) => {\r\n setLoadedModels(prev => prev.map(f => ({ ...f, isVisible: checked })))\r\n // Toggle visibility in 3D scene for all models\r\n for (const file of loadedModels) {\r\n handleBimView(file, checked)\r\n }\r\n },\r\n })\r\n\r\n return (\r\n <>\r\n <CollapsibleSection\r\n title={t('modelsTitles')}\r\n icon={LR.Box}\r\n className=\"max-h-40 overflow-y-auto\"\r\n itemCount={filteredModels.length}\r\n onAddItem={handleAddFile}\r\n addItemTitle={t('addBimTitle')}\r\n switchVariant={handleSwitchVariant()}\r\n >\r\n <div className=\"space-y-1\">\r\n {filteredModels.map((file) => (\r\n <FileItemComponent\r\n key={file.id}\r\n file={file}\r\n onAction={handleAction}\r\n options={BIM_MODEL_OPTIONS}\r\n confirmDelete={false}\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 />\r\n </>\r\n )\r\n}\r\n"],"mappings":"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","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"FloorplanSection.d.ts","sourceRoot":"","sources":["../../../../../../../../../../src/core/components/viewers/bim/src/BimSidebar/src/LayersTab/src/FloorplanSection.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAmB9B,UAAU,qBAAqB;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAID,wBAAgB,gBAAgB,CAAC,EAAE,KAAU,EAAE,EAAE,qBAAqB,qBAiLrE"}
1
+ {"version":3,"file":"FloorplanSection.d.ts","sourceRoot":"","sources":["../../../../../../../../../../src/core/components/viewers/bim/src/BimSidebar/src/LayersTab/src/FloorplanSection.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAmB9B,UAAU,qBAAqB;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAID,wBAAgB,gBAAgB,CAAC,EAAE,KAAU,EAAE,EAAE,qBAAqB,qBAmLrE"}
@@ -96,7 +96,7 @@ function FloorplanSection({ query = "" }) {
96
96
  const fpEntry = entries.find((e) => e.id === entry.id);
97
97
  if (!(fpEntry == null ? void 0 : fpEntry.drawing)) return;
98
98
  const fileName = `${buildingName(fpEntry.modelId)}-${fpEntry.name}`;
99
- exportDrawingToDxf(bimComponents, fpEntry.drawing, fileName, northAngle);
99
+ exportDrawingToDxf(bimComponents, fpEntry.drawing, fileName, -northAngle);
100
100
  };
101
101
  const handleToggleLayer = (className, visible) => {
102
102
  if (!bimComponents || !activeId) return;