@collabdt/core 0.3.1 → 0.3.3

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 (300) hide show
  1. package/dist/core/components/authentication/ForgotPassword.d.ts.map +1 -1
  2. package/dist/core/components/authentication/ForgotPassword.js +0 -1
  3. package/dist/core/components/authentication/ForgotPassword.js.map +1 -1
  4. package/dist/core/components/ui/Comments/CollapsibleCommentItem.d.ts +12 -2
  5. package/dist/core/components/ui/Comments/CollapsibleCommentItem.d.ts.map +1 -1
  6. package/dist/core/components/ui/Comments/CollapsibleCommentItem.js +137 -139
  7. package/dist/core/components/ui/Comments/CollapsibleCommentItem.js.map +1 -1
  8. package/dist/core/components/ui/Comments/Comment.d.ts +18 -1
  9. package/dist/core/components/ui/Comments/Comment.d.ts.map +1 -1
  10. package/dist/core/components/ui/Comments/Comment.js +94 -23
  11. package/dist/core/components/ui/Comments/Comment.js.map +1 -1
  12. package/dist/core/components/ui/Comments/CommentActionButtons.d.ts +38 -0
  13. package/dist/core/components/ui/Comments/CommentActionButtons.d.ts.map +1 -0
  14. package/dist/core/components/ui/Comments/CommentActionButtons.js +134 -0
  15. package/dist/core/components/ui/Comments/CommentActionButtons.js.map +1 -0
  16. package/dist/core/components/ui/Comments/CommentInput.d.ts.map +1 -1
  17. package/dist/core/components/ui/Comments/CommentInput.js +5 -2
  18. package/dist/core/components/ui/Comments/CommentInput.js.map +1 -1
  19. package/dist/core/components/ui/Comments/CommentsSection.d.ts.map +1 -1
  20. package/dist/core/components/ui/Comments/CommentsSection.js +86 -42
  21. package/dist/core/components/ui/Comments/CommentsSection.js.map +1 -1
  22. package/dist/core/components/ui/Comments/commentUtils.d.ts.map +1 -1
  23. package/dist/core/components/ui/Comments/commentUtils.js +2 -1
  24. package/dist/core/components/ui/Comments/commentUtils.js.map +1 -1
  25. package/dist/core/components/ui/FilesManager/src/useFileUploadWithProgress.d.ts.map +1 -1
  26. package/dist/core/components/ui/FilesManager/src/useFileUploadWithProgress.js +0 -1
  27. package/dist/core/components/ui/FilesManager/src/useFileUploadWithProgress.js.map +1 -1
  28. package/dist/core/components/ui/InfoSidebar/Container.d.ts.map +1 -1
  29. package/dist/core/components/ui/InfoSidebar/Container.js +16 -12
  30. package/dist/core/components/ui/InfoSidebar/Container.js.map +1 -1
  31. package/dist/core/components/ui/Sensors/CollapsibleSensorItem.d.ts +1 -2
  32. package/dist/core/components/ui/Sensors/CollapsibleSensorItem.d.ts.map +1 -1
  33. package/dist/core/components/ui/Sensors/CollapsibleSensorItem.js +66 -94
  34. package/dist/core/components/ui/Sensors/CollapsibleSensorItem.js.map +1 -1
  35. package/dist/core/components/ui/Sensors/Sensor.d.ts +16 -3
  36. package/dist/core/components/ui/Sensors/Sensor.d.ts.map +1 -1
  37. package/dist/core/components/ui/Sensors/Sensor.js +76 -37
  38. package/dist/core/components/ui/Sensors/Sensor.js.map +1 -1
  39. package/dist/core/components/ui/Sensors/SensorChart.d.ts +12 -2
  40. package/dist/core/components/ui/Sensors/SensorChart.d.ts.map +1 -1
  41. package/dist/core/components/ui/Sensors/SensorChart.js +49 -12
  42. package/dist/core/components/ui/Sensors/SensorChart.js.map +1 -1
  43. package/dist/core/components/ui/Sensors/SensorDetailDialog.d.ts +9 -0
  44. package/dist/core/components/ui/Sensors/SensorDetailDialog.d.ts.map +1 -0
  45. package/dist/core/components/ui/Sensors/SensorDetailDialog.js +128 -0
  46. package/dist/core/components/ui/Sensors/SensorDetailDialog.js.map +1 -0
  47. package/dist/core/components/ui/Sensors/SensorInput.d.ts +6 -1
  48. package/dist/core/components/ui/Sensors/SensorInput.d.ts.map +1 -1
  49. package/dist/core/components/ui/Sensors/SensorInput.js +94 -9
  50. package/dist/core/components/ui/Sensors/SensorInput.js.map +1 -1
  51. package/dist/core/components/ui/Sensors/SensorTagsSection.d.ts +3 -1
  52. package/dist/core/components/ui/Sensors/SensorTagsSection.d.ts.map +1 -1
  53. package/dist/core/components/ui/Sensors/SensorTagsSection.js +4 -1
  54. package/dist/core/components/ui/Sensors/SensorTagsSection.js.map +1 -1
  55. package/dist/core/components/ui/Sensors/SensorsSection.d.ts +1 -3
  56. package/dist/core/components/ui/Sensors/SensorsSection.d.ts.map +1 -1
  57. package/dist/core/components/ui/Sensors/SensorsSection.js +33 -10
  58. package/dist/core/components/ui/Sensors/SensorsSection.js.map +1 -1
  59. package/dist/core/components/ui/Sensors/TimeZoneSelect.d.ts +7 -0
  60. package/dist/core/components/ui/Sensors/TimeZoneSelect.d.ts.map +1 -0
  61. package/dist/core/components/ui/Sensors/TimeZoneSelect.js +56 -0
  62. package/dist/core/components/ui/Sensors/TimeZoneSelect.js.map +1 -0
  63. package/dist/core/components/ui/Sensors/sensorData.d.ts +42 -0
  64. package/dist/core/components/ui/Sensors/sensorData.d.ts.map +1 -0
  65. package/dist/core/components/ui/Sensors/sensorData.js +118 -0
  66. package/dist/core/components/ui/Sensors/sensorData.js.map +1 -0
  67. package/dist/core/components/ui/Sensors/sensorRange.d.ts +24 -0
  68. package/dist/core/components/ui/Sensors/sensorRange.d.ts.map +1 -0
  69. package/dist/core/components/ui/Sensors/sensorRange.js +34 -0
  70. package/dist/core/components/ui/Sensors/sensorRange.js.map +1 -0
  71. package/dist/core/components/ui/Sensors/useSensorSeries.d.ts +15 -0
  72. package/dist/core/components/ui/Sensors/useSensorSeries.d.ts.map +1 -0
  73. package/dist/core/components/ui/Sensors/useSensorSeries.js +63 -0
  74. package/dist/core/components/ui/Sensors/useSensorSeries.js.map +1 -0
  75. package/dist/core/components/ui/Sidebar.d.ts.map +1 -1
  76. package/dist/core/components/ui/Sidebar.js +27 -4
  77. package/dist/core/components/ui/Sidebar.js.map +1 -1
  78. package/dist/core/components/ui/ToolbarButton.d.ts.map +1 -1
  79. package/dist/core/components/ui/ToolbarButton.js +0 -1
  80. package/dist/core/components/ui/ToolbarButton.js.map +1 -1
  81. package/dist/core/components/viewers/Data/advancedFilter/FiltersDialog.d.ts.map +1 -1
  82. package/dist/core/components/viewers/Data/advancedFilter/FiltersDialog.js +0 -2
  83. package/dist/core/components/viewers/Data/advancedFilter/FiltersDialog.js.map +1 -1
  84. package/dist/core/components/viewers/Data/details/EnergySourcesGrid.d.ts.map +1 -1
  85. package/dist/core/components/viewers/Data/details/EnergySourcesGrid.js +0 -10
  86. package/dist/core/components/viewers/Data/details/EnergySourcesGrid.js.map +1 -1
  87. package/dist/core/components/viewers/Data/files/DatatableFileAdder.d.ts.map +1 -1
  88. package/dist/core/components/viewers/Data/files/DatatableFileAdder.js +0 -1
  89. package/dist/core/components/viewers/Data/files/DatatableFileAdder.js.map +1 -1
  90. package/dist/core/components/viewers/Data/files/utils/fuzzySearch.d.ts.map +1 -1
  91. package/dist/core/components/viewers/Data/files/utils/fuzzySearch.js +0 -1
  92. package/dist/core/components/viewers/Data/files/utils/fuzzySearch.js.map +1 -1
  93. package/dist/core/components/viewers/Data/userDetails/UserMoreOptions.d.ts.map +1 -1
  94. package/dist/core/components/viewers/Data/userDetails/UserMoreOptions.js +0 -1
  95. package/dist/core/components/viewers/Data/userDetails/UserMoreOptions.js.map +1 -1
  96. package/dist/core/components/viewers/Data/utils/filterHelper.d.ts.map +1 -1
  97. package/dist/core/components/viewers/Data/utils/filterHelper.js +0 -2
  98. package/dist/core/components/viewers/Data/utils/filterHelper.js.map +1 -1
  99. package/dist/core/components/viewers/Viewer.js +1 -1
  100. package/dist/core/components/viewers/Viewer.js.map +1 -1
  101. package/dist/core/components/viewers/bim/src/BimSidebar/src/CommunicationTab/src/TopicsSection.d.ts.map +1 -1
  102. package/dist/core/components/viewers/bim/src/BimSidebar/src/CommunicationTab/src/TopicsSection.js +0 -3
  103. package/dist/core/components/viewers/bim/src/BimSidebar/src/CommunicationTab/src/TopicsSection.js.map +1 -1
  104. package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/FilesSection.d.ts.map +1 -1
  105. package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/FilesSection.js +1 -7
  106. package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/FilesSection.js.map +1 -1
  107. package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/ModelsSection.d.ts.map +1 -1
  108. package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/ModelsSection.js +1 -9
  109. package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/ModelsSection.js.map +1 -1
  110. package/dist/core/components/viewers/bim/src/BimSidebar/src/SensorsTab/index.d.ts +1 -3
  111. package/dist/core/components/viewers/bim/src/BimSidebar/src/SensorsTab/index.d.ts.map +1 -1
  112. package/dist/core/components/viewers/bim/src/BimSidebar/src/SensorsTab/index.js +2 -2
  113. package/dist/core/components/viewers/bim/src/BimSidebar/src/SensorsTab/index.js.map +1 -1
  114. package/dist/core/components/viewers/bim/src/BimSidebar/src/TabSelector.d.ts.map +1 -1
  115. package/dist/core/components/viewers/bim/src/BimSidebar/src/TabSelector.js +4 -3
  116. package/dist/core/components/viewers/bim/src/BimSidebar/src/TabSelector.js.map +1 -1
  117. package/dist/core/components/viewers/bim/src/BimSidebar/src/index.js +1 -1
  118. package/dist/core/components/viewers/bim/src/BimSidebar/src/index.js.map +1 -1
  119. package/dist/core/components/viewers/bim/src/ClippingPlane.d.ts.map +1 -1
  120. package/dist/core/components/viewers/bim/src/ClippingPlane.js +0 -1
  121. package/dist/core/components/viewers/bim/src/ClippingPlane.js.map +1 -1
  122. package/dist/core/components/viewers/bim/src/tools/AddToBim/index.d.ts +1 -2
  123. package/dist/core/components/viewers/bim/src/tools/AddToBim/index.d.ts.map +1 -1
  124. package/dist/core/components/viewers/bim/src/tools/AddToBim/index.js +25 -2
  125. package/dist/core/components/viewers/bim/src/tools/AddToBim/index.js.map +1 -1
  126. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimComment.d.ts +16 -10
  127. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimComment.d.ts.map +1 -1
  128. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimComment.js +26 -6
  129. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimComment.js.map +1 -1
  130. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimCommentCluster.d.ts +2 -0
  131. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimCommentCluster.d.ts.map +1 -0
  132. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimCommentCluster.js +5 -0
  133. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimCommentCluster.js.map +1 -0
  134. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimSensor.d.ts +8 -1
  135. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimSensor.d.ts.map +1 -1
  136. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimSensor.js +15 -3
  137. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimSensor.js.map +1 -1
  138. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/clusterMarkersByScreenSpace.d.ts +44 -0
  139. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/clusterMarkersByScreenSpace.d.ts.map +1 -0
  140. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/clusterMarkersByScreenSpace.js +77 -0
  141. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/clusterMarkersByScreenSpace.js.map +1 -0
  142. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/commentCameraUtils.d.ts +3 -0
  143. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/commentCameraUtils.d.ts.map +1 -0
  144. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/commentCameraUtils.js +5 -0
  145. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/commentCameraUtils.js.map +1 -0
  146. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/commentMarkerConfig.d.ts +33 -0
  147. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/commentMarkerConfig.d.ts.map +1 -0
  148. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/commentMarkerConfig.js +90 -0
  149. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/commentMarkerConfig.js.map +1 -0
  150. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/renderCSS2DMarkers.d.ts.map +1 -1
  151. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/renderCSS2DMarkers.js +2 -2
  152. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/renderCSS2DMarkers.js.map +1 -1
  153. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useCommentMarkers.d.ts +7 -1
  154. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useCommentMarkers.d.ts.map +1 -1
  155. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useCommentMarkers.js +50 -73
  156. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useCommentMarkers.js.map +1 -1
  157. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useSensorMarkers.d.ts +7 -1
  158. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useSensorMarkers.d.ts.map +1 -1
  159. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useSensorMarkers.js +39 -11
  160. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useSensorMarkers.js.map +1 -1
  161. package/dist/core/components/viewers/bim/src/tools/ClippingTool/ClippingTool.d.ts.map +1 -1
  162. package/dist/core/components/viewers/bim/src/tools/ClippingTool/ClippingTool.js +1 -5
  163. package/dist/core/components/viewers/bim/src/tools/ClippingTool/ClippingTool.js.map +1 -1
  164. package/dist/core/components/viewers/bim/src/tools/ExplodeByLevelTool.d.ts.map +1 -1
  165. package/dist/core/components/viewers/bim/src/tools/ExplodeByLevelTool.js +0 -1
  166. package/dist/core/components/viewers/bim/src/tools/ExplodeByLevelTool.js.map +1 -1
  167. package/dist/core/components/viewers/bim/src/tools/measureBimTool.d.ts.map +1 -1
  168. package/dist/core/components/viewers/bim/src/tools/measureBimTool.js +1 -2
  169. package/dist/core/components/viewers/bim/src/tools/measureBimTool.js.map +1 -1
  170. package/dist/core/components/viewers/map/MapViewer.d.ts +1 -2
  171. package/dist/core/components/viewers/map/MapViewer.d.ts.map +1 -1
  172. package/dist/core/components/viewers/map/MapViewer.js +2 -2
  173. package/dist/core/components/viewers/map/MapViewer.js.map +1 -1
  174. package/dist/core/components/viewers/map/datasets/src/arcGISDatasets.d.ts.map +1 -1
  175. package/dist/core/components/viewers/map/datasets/src/arcGISDatasets.js +11 -14
  176. package/dist/core/components/viewers/map/datasets/src/arcGISDatasets.js.map +1 -1
  177. package/dist/core/components/viewers/map/datasets/src/ckanDatasets.d.ts.map +1 -1
  178. package/dist/core/components/viewers/map/datasets/src/ckanDatasets.js +2 -5
  179. package/dist/core/components/viewers/map/datasets/src/ckanDatasets.js.map +1 -1
  180. package/dist/core/components/viewers/map/datasets/src/localDatasets.d.ts.map +1 -1
  181. package/dist/core/components/viewers/map/datasets/src/localDatasets.js +0 -3
  182. package/dist/core/components/viewers/map/datasets/src/localDatasets.js.map +1 -1
  183. package/dist/core/components/viewers/map/datasets/src/opendatasoftDatasets.d.ts.map +1 -1
  184. package/dist/core/components/viewers/map/datasets/src/opendatasoftDatasets.js +0 -11
  185. package/dist/core/components/viewers/map/datasets/src/opendatasoftDatasets.js.map +1 -1
  186. package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/DatabaseBuildingPopover/src/BuildingsTools.d.ts.map +1 -1
  187. package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/DatabaseBuildingPopover/src/BuildingsTools.js +0 -1
  188. package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/DatabaseBuildingPopover/src/BuildingsTools.js.map +1 -1
  189. package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/NonDatabaseBuildingPopover.d.ts.map +1 -1
  190. package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/NonDatabaseBuildingPopover.js +0 -1
  191. package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/NonDatabaseBuildingPopover.js.map +1 -1
  192. package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/OpenDataFeaturePopover.d.ts.map +1 -1
  193. package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/OpenDataFeaturePopover.js +0 -1
  194. package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/OpenDataFeaturePopover.js.map +1 -1
  195. package/dist/core/components/viewers/map/src/MapLayers/index.d.ts +1 -2
  196. package/dist/core/components/viewers/map/src/MapLayers/index.d.ts.map +1 -1
  197. package/dist/core/components/viewers/map/src/MapLayers/index.js +2 -2
  198. package/dist/core/components/viewers/map/src/MapLayers/index.js.map +1 -1
  199. package/dist/core/components/viewers/map/src/MapLayers/src/CommentLayer/index.d.ts.map +1 -1
  200. package/dist/core/components/viewers/map/src/MapLayers/src/CommentLayer/index.js +174 -53
  201. package/dist/core/components/viewers/map/src/MapLayers/src/CommentLayer/index.js.map +1 -1
  202. package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/components/MapFileManager.d.ts.map +1 -1
  203. package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/components/MapFileManager.js +2 -1
  204. package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/components/MapFileManager.js.map +1 -1
  205. package/dist/core/components/viewers/map/src/MapLayers/src/SensorsLayer/index.d.ts +1 -3
  206. package/dist/core/components/viewers/map/src/MapLayers/src/SensorsLayer/index.d.ts.map +1 -1
  207. package/dist/core/components/viewers/map/src/MapLayers/src/SensorsLayer/index.js +74 -42
  208. package/dist/core/components/viewers/map/src/MapLayers/src/SensorsLayer/index.js.map +1 -1
  209. package/dist/core/components/viewers/map/src/MapSidebar/TabSelector.d.ts.map +1 -1
  210. package/dist/core/components/viewers/map/src/MapSidebar/TabSelector.js +4 -3
  211. package/dist/core/components/viewers/map/src/MapSidebar/TabSelector.js.map +1 -1
  212. package/dist/core/components/viewers/map/src/MapSidebar/index.js +1 -1
  213. package/dist/core/components/viewers/map/src/MapSidebar/index.js.map +1 -1
  214. package/dist/core/components/viewers/map/src/MapSidebar/src/FileTab/src/FilesSection.d.ts.map +1 -1
  215. package/dist/core/components/viewers/map/src/MapSidebar/src/FileTab/src/FilesSection.js +0 -1
  216. package/dist/core/components/viewers/map/src/MapSidebar/src/FileTab/src/FilesSection.js.map +1 -1
  217. package/dist/core/components/viewers/map/src/MapSidebar/src/FileTab/src/ModelsSection.d.ts.map +1 -1
  218. package/dist/core/components/viewers/map/src/MapSidebar/src/FileTab/src/ModelsSection.js +1 -5
  219. package/dist/core/components/viewers/map/src/MapSidebar/src/FileTab/src/ModelsSection.js.map +1 -1
  220. package/dist/core/components/viewers/map/src/MapSidebar/src/SensorsTab/index.d.ts +1 -3
  221. package/dist/core/components/viewers/map/src/MapSidebar/src/SensorsTab/index.d.ts.map +1 -1
  222. package/dist/core/components/viewers/map/src/MapSidebar/src/SensorsTab/index.js +2 -2
  223. package/dist/core/components/viewers/map/src/MapSidebar/src/SensorsTab/index.js.map +1 -1
  224. package/dist/core/components/viewers/map/src/tools/AddTools/AddFile/utils/uploadToPresignedURLS.d.ts.map +1 -1
  225. package/dist/core/components/viewers/map/src/tools/AddTools/AddFile/utils/uploadToPresignedURLS.js +1 -3
  226. package/dist/core/components/viewers/map/src/tools/AddTools/AddFile/utils/uploadToPresignedURLS.js.map +1 -1
  227. package/dist/core/components/viewers/map/utils/MapEventManager/MapClickManager.d.ts.map +1 -1
  228. package/dist/core/components/viewers/map/utils/MapEventManager/MapClickManager.js +0 -1
  229. package/dist/core/components/viewers/map/utils/MapEventManager/MapClickManager.js.map +1 -1
  230. package/dist/core/components/viewers/map/utils/flyToEach.d.ts.map +1 -1
  231. package/dist/core/components/viewers/map/utils/flyToEach.js +0 -1
  232. package/dist/core/components/viewers/map/utils/flyToEach.js.map +1 -1
  233. package/dist/core/components/viewers/map/utils/getOsmIdbyCoordinates.d.ts.map +1 -1
  234. package/dist/core/components/viewers/map/utils/getOsmIdbyCoordinates.js +0 -2
  235. package/dist/core/components/viewers/map/utils/getOsmIdbyCoordinates.js.map +1 -1
  236. package/dist/core/components/viewers/shared/markers/BimMarkerCluster.d.ts +19 -0
  237. package/dist/core/components/viewers/shared/markers/BimMarkerCluster.d.ts.map +1 -0
  238. package/dist/core/components/viewers/shared/markers/BimMarkerCluster.js +108 -0
  239. package/dist/core/components/viewers/shared/markers/BimMarkerCluster.js.map +1 -0
  240. package/dist/core/components/viewers/shared/markers/computeMarkerLookAt.d.ts +24 -0
  241. package/dist/core/components/viewers/shared/markers/computeMarkerLookAt.d.ts.map +1 -0
  242. package/dist/core/components/viewers/shared/markers/computeMarkerLookAt.js +27 -0
  243. package/dist/core/components/viewers/shared/markers/computeMarkerLookAt.js.map +1 -0
  244. package/dist/core/components/viewers/shared/markers/types.d.ts +66 -0
  245. package/dist/core/components/viewers/shared/markers/types.d.ts.map +1 -0
  246. package/dist/core/components/viewers/shared/markers/types.js +1 -0
  247. package/dist/core/components/viewers/shared/markers/types.js.map +1 -0
  248. package/dist/core/components/viewers/shared/markers/useMarkerLayerBim.d.ts +22 -0
  249. package/dist/core/components/viewers/shared/markers/useMarkerLayerBim.d.ts.map +1 -0
  250. package/dist/core/components/viewers/shared/markers/useMarkerLayerBim.js +233 -0
  251. package/dist/core/components/viewers/shared/markers/useMarkerLayerBim.js.map +1 -0
  252. package/dist/core/hooks/comments/comments.d.ts +11 -0
  253. package/dist/core/hooks/comments/comments.d.ts.map +1 -1
  254. package/dist/core/hooks/comments/comments.js +3 -1
  255. package/dist/core/hooks/comments/comments.js.map +1 -1
  256. package/dist/core/hooks/comments/createCommentHooks.d.ts +11 -0
  257. package/dist/core/hooks/comments/createCommentHooks.d.ts.map +1 -1
  258. package/dist/core/hooks/comments/createCommentHooks.js +30 -1
  259. package/dist/core/hooks/comments/createCommentHooks.js.map +1 -1
  260. package/dist/core/hooks/files/files.d.ts.map +1 -1
  261. package/dist/core/hooks/files/files.js +0 -1
  262. package/dist/core/hooks/files/files.js.map +1 -1
  263. package/dist/core/hooks/ui/useResizableSidebarWidth.d.ts +30 -0
  264. package/dist/core/hooks/ui/useResizableSidebarWidth.d.ts.map +1 -0
  265. package/dist/core/hooks/ui/useResizableSidebarWidth.js +75 -0
  266. package/dist/core/hooks/ui/useResizableSidebarWidth.js.map +1 -0
  267. package/dist/core/i18n/messages/en.json +10 -1
  268. package/dist/core/i18n/messages/es.json +11 -2
  269. package/dist/core/i18n/messages/fr.json +11 -2
  270. package/dist/core/store/AppConfig/context.d.ts.map +1 -1
  271. package/dist/core/store/AppConfig/context.js +4 -1
  272. package/dist/core/store/AppConfig/context.js.map +1 -1
  273. package/dist/core/store/AppConfig/reducer.d.ts +10 -0
  274. package/dist/core/store/AppConfig/reducer.d.ts.map +1 -1
  275. package/dist/core/store/AppConfig/reducer.js +10 -0
  276. package/dist/core/store/AppConfig/reducer.js.map +1 -1
  277. package/dist/core/store/Datasets/reducer.d.ts.map +1 -1
  278. package/dist/core/store/Datasets/reducer.js +0 -2
  279. package/dist/core/store/Datasets/reducer.js.map +1 -1
  280. package/dist/core/store/Files/reducer.js +0 -1
  281. package/dist/core/store/Files/reducer.js.map +1 -1
  282. package/dist/core/store/Menus/context.d.ts.map +1 -1
  283. package/dist/core/store/Menus/context.js +8 -2
  284. package/dist/core/store/Menus/context.js.map +1 -1
  285. package/dist/core/store/Menus/reducer.d.ts +65 -1
  286. package/dist/core/store/Menus/reducer.d.ts.map +1 -1
  287. package/dist/core/store/Menus/reducer.js +39 -3
  288. package/dist/core/store/Menus/reducer.js.map +1 -1
  289. package/dist/core/utils/markerUtils.d.ts +10 -0
  290. package/dist/core/utils/markerUtils.d.ts.map +1 -1
  291. package/dist/core/utils/markerUtils.js +9 -1
  292. package/dist/core/utils/markerUtils.js.map +1 -1
  293. package/dist/core/utils/memcache.d.ts.map +1 -1
  294. package/dist/core/utils/memcache.js +0 -7
  295. package/dist/core/utils/memcache.js.map +1 -1
  296. package/dist/core/utils/timeUtils.d.ts +24 -1
  297. package/dist/core/utils/timeUtils.d.ts.map +1 -1
  298. package/dist/core/utils/timeUtils.js +52 -3
  299. package/dist/core/utils/timeUtils.js.map +1 -1
  300. package/package.json +4 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ForgotPassword.d.ts","sourceRoot":"","sources":["../../../../src/core/components/authentication/ForgotPassword.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAU9B,wBAAgB,cAAc,sBAkK7B"}
1
+ {"version":3,"file":"ForgotPassword.d.ts","sourceRoot":"","sources":["../../../../src/core/components/authentication/ForgotPassword.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAU9B,wBAAgB,cAAc,sBAiK7B"}
@@ -9,7 +9,6 @@ import { Input } from "../ui/Input";
9
9
  import { AuthPage } from "./AuthPage";
10
10
  import { PasswordError } from "./PasswordError";
11
11
  function ForgotPassword() {
12
- console.log("Executing ForgotPassword()");
13
12
  const [password, setPassword] = React.useState("");
14
13
  const [confirmPassword, setConfirmPassword] = React.useState("");
15
14
  const [error, setError] = React.useState("");
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/core/components/authentication/ForgotPassword.tsx"],"sourcesContent":["'use client'\r\n\r\n// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\nimport { Eye, EyeClosed } from 'lucide-react'\r\nimport Link from 'next/link'\r\nimport { useTranslations } from 'next-intl'\r\nimport * as React from 'react'\r\n\r\n// Direct file imports (not the ui barrel) — see Signin.tsx for rationale.\r\nimport { Button } from '../ui/Button'\r\nimport { Input } from '../ui/Input'\r\n\r\n\r\nimport { AuthPage } from './AuthPage'\r\nimport { PasswordError } from './PasswordError'\r\n\r\nexport function ForgotPassword() {\r\n console.log('Executing ForgotPassword()')\r\n const [password, setPassword] = React.useState('')\r\n const [confirmPassword, setConfirmPassword] = React.useState('')\r\n const [error, setError] = React.useState('')\r\n const [isLoading, setIsLoading] = React.useState(false)\r\n const t = useTranslations('forgotPassword')\r\n\r\n const [showPassword, setShowPassword] = React.useState(false)\r\n const [showConfirmPassword, setShowConfirmPassword] = React.useState(false)\r\n const [passwordErrors, setPasswordErrors] = React.useState<string[]>([])\r\n const [confirmPasswordError, setConfirmPasswordError] = React.useState('')\r\n const [hasAttemptedSubmit, setHasAttemptedSubmit] = React.useState(false)\r\n\r\n const validatePassword = (password: string): string[] => {\r\n const errors: string[] = []\r\n if (password.length < 12) errors.push('Password must be at least 12 characters')\r\n if (password.length > 65) errors.push('Password must be less than 65 characters')\r\n return errors\r\n }\r\n\r\n const handlePasswordChange = (e) => {\r\n const newPassword = e.target.value\r\n setPassword(newPassword)\r\n if (newPassword) setPasswordErrors(validatePassword(newPassword))\r\n else setPasswordErrors([])\r\n if (confirmPassword) {\r\n setConfirmPasswordError(newPassword === confirmPassword ? '' : 'Passwords do not match')\r\n }\r\n }\r\n\r\n const handleConfirmPasswordChange = (e) => {\r\n const newConfirmPassword = e.target.value\r\n setConfirmPassword(newConfirmPassword)\r\n if (newConfirmPassword && password) {\r\n setConfirmPasswordError(newConfirmPassword === password ? '' : 'Passwords do not match')\r\n } else {\r\n setConfirmPasswordError('')\r\n }\r\n }\r\n\r\n const handleSubmit = async (e) => {\r\n e.preventDefault()\r\n setHasAttemptedSubmit(true)\r\n const errors = validatePassword(password)\r\n setPasswordErrors(errors)\r\n if (password === confirmPassword) setConfirmPasswordError('')\r\n else setConfirmPasswordError('Passwords do not match')\r\n if (errors.length > 0 || password !== confirmPassword) return\r\n setError('')\r\n setIsLoading(true)\r\n // password reset logic here\r\n }\r\n\r\n return (\r\n <AuthPage>\r\n {/* Header */}\r\n <div className=\"space-y-2 text-left\">\r\n <h1\r\n className=\"font-display font-bold\"\r\n style={{\r\n fontSize: '1.75rem',\r\n lineHeight: '1.1',\r\n letterSpacing: '-0.02em',\r\n color: 'var(--hp-on-surface)',\r\n fontFamily: \"'Space Grotesk', sans-serif\",\r\n }}\r\n >\r\n {t('h1')}\r\n </h1>\r\n <p style={{ color: 'var(--hp-on-surface-variant)', fontSize: '0.9rem' }}>\r\n {t('subHeader')}\r\n </p>\r\n </div>\r\n\r\n {/* Form */}\r\n <form id=\"resetForm\" onSubmit={handleSubmit} className=\"space-y-4\">\r\n {/* Password */}\r\n <div className=\"space-y-2\">\r\n <div className=\"flex items-center gap-1\">\r\n <label htmlFor=\"password\" className=\"auth-label\">{t('inputLabel')}</label>\r\n {hasAttemptedSubmit && passwordErrors.length > 0 && (\r\n <div className=\"w-1.5 h-1.5 rounded-full\" style={{ background: '#ff6b6b' }} />\r\n )}\r\n </div>\r\n <div className=\"relative\">\r\n <Input\r\n id=\"password\"\r\n type={showPassword ? 'text' : 'password'}\r\n placeholder={t('placeholder1')}\r\n value={password}\r\n onChange={handlePasswordChange}\r\n required\r\n className={`auth-input pr-10 ${hasAttemptedSubmit && passwordErrors.length > 0 ? 'border-destructive' : ''}`}\r\n />\r\n <Button\r\n type=\"button\"\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n onClick={() => setShowPassword(!showPassword)}\r\n className=\"absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4\"\r\n style={{ color: 'var(--hp-on-surface-variant)' }}\r\n >\r\n {showPassword ? <EyeClosed className=\"h-4 w-4\" /> : <Eye className=\"h-4 w-4\" />}\r\n </Button>\r\n </div>\r\n {hasAttemptedSubmit && passwordErrors.map((err, i) => (\r\n <PasswordError key={i} message={err} />\r\n ))}\r\n {(!hasAttemptedSubmit || passwordErrors.length === 0) && (\r\n <p className=\"text-xs\" style={{ color: 'var(--hp-on-surface-variant)' }}>{t('lenError')}</p>\r\n )}\r\n </div>\r\n\r\n {/* Confirm Password */}\r\n <div className=\"space-y-2\">\r\n <div className=\"flex items-center gap-1\">\r\n <label htmlFor=\"confirmPassword\" className=\"auth-label\">{t('confirmInputLabel')}</label>\r\n {hasAttemptedSubmit && confirmPasswordError && (\r\n <div className=\"w-1.5 h-1.5 rounded-full\" style={{ background: '#ff6b6b' }} />\r\n )}\r\n </div>\r\n <div className=\"relative\">\r\n <Input\r\n id=\"confirmPassword\"\r\n type={showConfirmPassword ? 'text' : 'password'}\r\n placeholder={t('placeholder2')}\r\n value={confirmPassword}\r\n onChange={handleConfirmPasswordChange}\r\n required\r\n className={`auth-input pr-10 ${hasAttemptedSubmit && confirmPasswordError ? 'border-destructive' : ''}`}\r\n />\r\n <Button\r\n type=\"button\"\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n onClick={() => setShowConfirmPassword(!showConfirmPassword)}\r\n className=\"absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4\"\r\n style={{ color: 'var(--hp-on-surface-variant)' }}\r\n >\r\n {showConfirmPassword ? <EyeClosed className=\"h-4 w-4\" /> : <Eye className=\"h-4 w-4\" />}\r\n </Button>\r\n </div>\r\n {hasAttemptedSubmit && confirmPasswordError && (\r\n <PasswordError message={confirmPasswordError} />\r\n )}\r\n </div>\r\n </form>\r\n\r\n {/* Submit + link */}\r\n <div className=\"space-y-4 pt-2\">\r\n <Button type=\"submit\" form=\"resetForm\" className=\"auth-btn-primary w-full h-10\">\r\n {t('submit')}\r\n </Button>\r\n <p className=\"text-sm text-center\" style={{ color: 'var(--hp-on-surface-variant)' }}>\r\n <Link className=\"underline\" href=\"/cdt/auth/Signin\" style={{ color: 'var(--hp-primary-container)' }}>\r\n {t('linkSignin')}\r\n </Link>\r\n </p>\r\n </div>\r\n </AuthPage>\r\n )\r\n}\r\n"],"mappings":"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","names":["password"]}
1
+ {"version":3,"sources":["../../../../src/core/components/authentication/ForgotPassword.tsx"],"sourcesContent":["'use client'\r\n\r\n// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\nimport { Eye, EyeClosed } from 'lucide-react'\r\nimport Link from 'next/link'\r\nimport { useTranslations } from 'next-intl'\r\nimport * as React from 'react'\r\n\r\n// Direct file imports (not the ui barrel) — see Signin.tsx for rationale.\r\nimport { Button } from '../ui/Button'\r\nimport { Input } from '../ui/Input'\r\n\r\n\r\nimport { AuthPage } from './AuthPage'\r\nimport { PasswordError } from './PasswordError'\r\n\r\nexport function ForgotPassword() {\r\n const [password, setPassword] = React.useState('')\r\n const [confirmPassword, setConfirmPassword] = React.useState('')\r\n const [error, setError] = React.useState('')\r\n const [isLoading, setIsLoading] = React.useState(false)\r\n const t = useTranslations('forgotPassword')\r\n\r\n const [showPassword, setShowPassword] = React.useState(false)\r\n const [showConfirmPassword, setShowConfirmPassword] = React.useState(false)\r\n const [passwordErrors, setPasswordErrors] = React.useState<string[]>([])\r\n const [confirmPasswordError, setConfirmPasswordError] = React.useState('')\r\n const [hasAttemptedSubmit, setHasAttemptedSubmit] = React.useState(false)\r\n\r\n const validatePassword = (password: string): string[] => {\r\n const errors: string[] = []\r\n if (password.length < 12) errors.push('Password must be at least 12 characters')\r\n if (password.length > 65) errors.push('Password must be less than 65 characters')\r\n return errors\r\n }\r\n\r\n const handlePasswordChange = (e) => {\r\n const newPassword = e.target.value\r\n setPassword(newPassword)\r\n if (newPassword) setPasswordErrors(validatePassword(newPassword))\r\n else setPasswordErrors([])\r\n if (confirmPassword) {\r\n setConfirmPasswordError(newPassword === confirmPassword ? '' : 'Passwords do not match')\r\n }\r\n }\r\n\r\n const handleConfirmPasswordChange = (e) => {\r\n const newConfirmPassword = e.target.value\r\n setConfirmPassword(newConfirmPassword)\r\n if (newConfirmPassword && password) {\r\n setConfirmPasswordError(newConfirmPassword === password ? '' : 'Passwords do not match')\r\n } else {\r\n setConfirmPasswordError('')\r\n }\r\n }\r\n\r\n const handleSubmit = async (e) => {\r\n e.preventDefault()\r\n setHasAttemptedSubmit(true)\r\n const errors = validatePassword(password)\r\n setPasswordErrors(errors)\r\n if (password === confirmPassword) setConfirmPasswordError('')\r\n else setConfirmPasswordError('Passwords do not match')\r\n if (errors.length > 0 || password !== confirmPassword) return\r\n setError('')\r\n setIsLoading(true)\r\n // password reset logic here\r\n }\r\n\r\n return (\r\n <AuthPage>\r\n {/* Header */}\r\n <div className=\"space-y-2 text-left\">\r\n <h1\r\n className=\"font-display font-bold\"\r\n style={{\r\n fontSize: '1.75rem',\r\n lineHeight: '1.1',\r\n letterSpacing: '-0.02em',\r\n color: 'var(--hp-on-surface)',\r\n fontFamily: \"'Space Grotesk', sans-serif\",\r\n }}\r\n >\r\n {t('h1')}\r\n </h1>\r\n <p style={{ color: 'var(--hp-on-surface-variant)', fontSize: '0.9rem' }}>\r\n {t('subHeader')}\r\n </p>\r\n </div>\r\n\r\n {/* Form */}\r\n <form id=\"resetForm\" onSubmit={handleSubmit} className=\"space-y-4\">\r\n {/* Password */}\r\n <div className=\"space-y-2\">\r\n <div className=\"flex items-center gap-1\">\r\n <label htmlFor=\"password\" className=\"auth-label\">{t('inputLabel')}</label>\r\n {hasAttemptedSubmit && passwordErrors.length > 0 && (\r\n <div className=\"w-1.5 h-1.5 rounded-full\" style={{ background: '#ff6b6b' }} />\r\n )}\r\n </div>\r\n <div className=\"relative\">\r\n <Input\r\n id=\"password\"\r\n type={showPassword ? 'text' : 'password'}\r\n placeholder={t('placeholder1')}\r\n value={password}\r\n onChange={handlePasswordChange}\r\n required\r\n className={`auth-input pr-10 ${hasAttemptedSubmit && passwordErrors.length > 0 ? 'border-destructive' : ''}`}\r\n />\r\n <Button\r\n type=\"button\"\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n onClick={() => setShowPassword(!showPassword)}\r\n className=\"absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4\"\r\n style={{ color: 'var(--hp-on-surface-variant)' }}\r\n >\r\n {showPassword ? <EyeClosed className=\"h-4 w-4\" /> : <Eye className=\"h-4 w-4\" />}\r\n </Button>\r\n </div>\r\n {hasAttemptedSubmit && passwordErrors.map((err, i) => (\r\n <PasswordError key={i} message={err} />\r\n ))}\r\n {(!hasAttemptedSubmit || passwordErrors.length === 0) && (\r\n <p className=\"text-xs\" style={{ color: 'var(--hp-on-surface-variant)' }}>{t('lenError')}</p>\r\n )}\r\n </div>\r\n\r\n {/* Confirm Password */}\r\n <div className=\"space-y-2\">\r\n <div className=\"flex items-center gap-1\">\r\n <label htmlFor=\"confirmPassword\" className=\"auth-label\">{t('confirmInputLabel')}</label>\r\n {hasAttemptedSubmit && confirmPasswordError && (\r\n <div className=\"w-1.5 h-1.5 rounded-full\" style={{ background: '#ff6b6b' }} />\r\n )}\r\n </div>\r\n <div className=\"relative\">\r\n <Input\r\n id=\"confirmPassword\"\r\n type={showConfirmPassword ? 'text' : 'password'}\r\n placeholder={t('placeholder2')}\r\n value={confirmPassword}\r\n onChange={handleConfirmPasswordChange}\r\n required\r\n className={`auth-input pr-10 ${hasAttemptedSubmit && confirmPasswordError ? 'border-destructive' : ''}`}\r\n />\r\n <Button\r\n type=\"button\"\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n onClick={() => setShowConfirmPassword(!showConfirmPassword)}\r\n className=\"absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4\"\r\n style={{ color: 'var(--hp-on-surface-variant)' }}\r\n >\r\n {showConfirmPassword ? <EyeClosed className=\"h-4 w-4\" /> : <Eye className=\"h-4 w-4\" />}\r\n </Button>\r\n </div>\r\n {hasAttemptedSubmit && confirmPasswordError && (\r\n <PasswordError message={confirmPasswordError} />\r\n )}\r\n </div>\r\n </form>\r\n\r\n {/* Submit + link */}\r\n <div className=\"space-y-4 pt-2\">\r\n <Button type=\"submit\" form=\"resetForm\" className=\"auth-btn-primary w-full h-10\">\r\n {t('submit')}\r\n </Button>\r\n <p className=\"text-sm text-center\" style={{ color: 'var(--hp-on-surface-variant)' }}>\r\n <Link className=\"underline\" href=\"/cdt/auth/Signin\" style={{ color: 'var(--hp-primary-container)' }}>\r\n {t('linkSignin')}\r\n </Link>\r\n </p>\r\n </div>\r\n </AuthPage>\r\n )\r\n}\r\n"],"mappings":"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","names":["password"]}
@@ -1,11 +1,18 @@
1
1
  import * as React from 'react';
2
2
  import type { Comment } from '../../../types/dbTypes';
3
3
  type CommentAction = 'view' | 'edit' | 'delete' | 'reply';
4
+ /** Request from a 3D/map marker to auto-open a comment's editor or reply box. */
5
+ export interface PendingCommentAction {
6
+ commentId: number;
7
+ action: 'edit' | 'reply';
8
+ requestId: number;
9
+ }
4
10
  interface CollapsibleCommentItemProps {
5
11
  comment: Comment;
6
12
  onAction?: (action: CommentAction, id: number) => void;
7
13
  replies?: Comment[];
8
- onReply?: (id: number, replyText: string | number) => void;
14
+ onReply?: (comment: Comment, replyText: string) => void;
15
+ onEdit?: (id: number, text: string) => void;
9
16
  onFileUpload?: (id: number, files: FileList) => void;
10
17
  attachments?: Array<{
11
18
  name: string;
@@ -14,9 +21,12 @@ interface CollapsibleCommentItemProps {
14
21
  }>;
15
22
  depth?: number;
16
23
  isVisible?: boolean;
24
+ focused?: boolean;
25
+ onFocus?: () => void;
26
+ pendingAction?: PendingCommentAction;
17
27
  onMouseEnter?: () => void;
18
28
  onMouseLeave?: () => void;
19
29
  }
20
- export declare function CollapsibleCommentItem({ comment, onAction, replies, onReply, onFileUpload, attachments, depth, isVisible, onMouseEnter, onMouseLeave }: CollapsibleCommentItemProps): React.JSX.Element;
30
+ export declare function CollapsibleCommentItem({ comment, onAction, replies, onReply, onEdit, onFileUpload, depth, isVisible, focused, onFocus, pendingAction, onMouseEnter, onMouseLeave, }: CollapsibleCommentItemProps): React.JSX.Element;
21
31
  export {};
22
32
  //# sourceMappingURL=CollapsibleCommentItem.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CollapsibleCommentItem.d.ts","sourceRoot":"","sources":["../../../../../src/core/components/ui/Comments/CollapsibleCommentItem.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAW9B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAA;AAIrD,KAAK,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAA;AAEzD,UAAU,2BAA2B;IACnC,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IACtD,OAAO,CAAC,EAAE,OAAO,EAAE,CAAA;IACnB,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI,CAAA;IAC1D,YAAY,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAA;IACpD,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAChE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAA;IACzB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAA;CAC1B;AAED,wBAAgB,sBAAsB,CAAC,EACrC,OAAO,EACP,QAAQ,EACR,OAAY,EACZ,OAAO,EACP,YAAY,EACZ,WAAgB,EAChB,KAAS,EACT,SAAgB,EAChB,YAAY,EACZ,YAAY,EACb,EAAE,2BAA2B,qBA4N7B"}
1
+ {"version":3,"file":"CollapsibleCommentItem.d.ts","sourceRoot":"","sources":["../../../../../src/core/components/ui/Comments/CollapsibleCommentItem.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAe9B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAA;AAErD,KAAK,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAA;AAEzD,iFAAiF;AACjF,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,GAAG,OAAO,CAAA;IACxB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,UAAU,2BAA2B;IACnC,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IACtD,OAAO,CAAC,EAAE,OAAO,EAAE,CAAA;IACnB,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;IACvD,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAC3C,YAAY,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAA;IACpD,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAChE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,aAAa,CAAC,EAAE,oBAAoB,CAAA;IACpC,YAAY,CAAC,EAAE,MAAM,IAAI,CAAA;IACzB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAA;CAC1B;AAED,wBAAgB,sBAAsB,CAAC,EACrC,OAAO,EACP,QAAQ,EACR,OAAY,EACZ,OAAO,EACP,MAAM,EACN,YAAY,EACZ,KAAS,EACT,SAAgB,EAChB,OAAe,EACf,OAAO,EACP,aAAa,EACb,YAAY,EACZ,YAAY,GACb,EAAE,2BAA2B,qBAsM7B"}
@@ -1,203 +1,201 @@
1
1
  "use client";
2
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
- import { format } from "date-fns";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
4
3
  import * as LR from "lucide-react";
5
4
  import { useSession } from "next-auth/react";
6
5
  import { useTranslations } from "next-intl";
7
6
  import * as React from "react";
8
7
  import { useUser } from "../../../hooks/users/users";
9
8
  import { usePermissions } from "../../../store";
9
+ import { commentRingShadow } from "../../../utils/markerUtils";
10
+ import { formatTimestamp } from "../../../utils/timeUtils";
10
11
  import { cn } from "../../../utils/utils";
11
12
  import { Avatar } from "../Avatar";
12
13
  import { Badge } from "../Badge";
13
14
  import { Button } from "../Button";
14
15
  import { Input } from "../Input";
15
16
  import { UserAvatar } from "../UserAvatar";
17
+ import { CommentActionButtons } from "./CommentActionButtons";
16
18
  function CollapsibleCommentItem({
17
19
  comment,
18
20
  onAction,
19
21
  replies = [],
20
22
  onReply,
23
+ onEdit,
21
24
  onFileUpload,
22
- attachments = [],
23
25
  depth = 0,
24
26
  isVisible = true,
27
+ focused = false,
28
+ onFocus,
29
+ pendingAction,
25
30
  onMouseEnter,
26
31
  onMouseLeave
27
32
  }) {
28
33
  var _a, _b;
29
34
  const t = useTranslations("CommentsSection");
30
35
  const { ability } = usePermissions();
36
+ const isReply = depth > 0;
31
37
  const [isExpanded, setIsExpanded] = React.useState(false);
32
- const [showReplyInput, setShowReplyInput] = React.useState(false);
33
38
  const [replyText, setReplyText] = React.useState("");
34
- const fileInputRef = React.useRef(null);
39
+ const [isEditing, setIsEditing] = React.useState(false);
40
+ const [editText, setEditText] = React.useState(comment.text);
41
+ const containerRef = React.useRef(null);
42
+ const replyInputRef = React.useRef(null);
35
43
  const prevVisibleRef = React.useRef(isVisible);
36
44
  const user = (_a = useSession().data) == null ? void 0 : _a.user;
45
+ const isAuthor = (user == null ? void 0 : user.id) === String(comment.authorId);
46
+ const canReply = ability.can("create", "Comment");
47
+ const canEdit = ability.can("update", "Comment");
48
+ const canDelete = ability.can("delete", "Comment");
49
+ const { user: author } = useUser(String(comment.authorId));
50
+ const authorName = (_b = author == null ? void 0 : author.name) != null ? _b : "Unknown User";
37
51
  React.useEffect(() => {
38
- const prevVisible = prevVisibleRef.current;
39
- if (prevVisible && !isVisible) {
40
- setIsExpanded(false);
41
- }
52
+ if (prevVisibleRef.current && !isVisible) setIsExpanded(false);
42
53
  prevVisibleRef.current = isVisible;
43
54
  }, [isVisible]);
55
+ const handleEditStart = React.useCallback(() => {
56
+ setEditText(comment.text);
57
+ setIsEditing(true);
58
+ }, [comment.text]);
59
+ const openReply = React.useCallback(() => {
60
+ setIsExpanded(true);
61
+ requestAnimationFrame(() => {
62
+ var _a2;
63
+ return (_a2 = replyInputRef.current) == null ? void 0 : _a2.focus();
64
+ });
65
+ }, []);
66
+ React.useEffect(() => {
67
+ var _a2;
68
+ if (!pendingAction) return;
69
+ const matchesSelf = pendingAction.commentId === comment.id;
70
+ const matchesReply = replies.some((r) => r.id === pendingAction.commentId);
71
+ if (matchesSelf) {
72
+ if (pendingAction.action === "edit") handleEditStart();
73
+ else openReply();
74
+ (_a2 = containerRef.current) == null ? void 0 : _a2.scrollIntoView({ behavior: "smooth", block: "nearest" });
75
+ }
76
+ if (matchesReply) setIsExpanded(true);
77
+ }, [pendingAction == null ? void 0 : pendingAction.requestId]);
44
78
  const handleReplySubmit = () => {
45
79
  if (replyText.trim() && onReply) {
46
- onReply(comment.id, replyText);
80
+ onReply(comment, replyText);
47
81
  setReplyText("");
48
- setShowReplyInput(false);
49
82
  }
50
83
  };
51
- const handleFileSelect = (event) => {
52
- if (event.target.files && event.target.files.length > 0 && onFileUpload) {
53
- onFileUpload(comment.id, event.target.files);
54
- event.target.value = "";
55
- }
84
+ const handleEditSubmit = () => {
85
+ const next = editText.trim();
86
+ if (next && next !== comment.text && onEdit) onEdit(comment.id, next);
87
+ setIsEditing(false);
56
88
  };
57
- const indentClass = depth > 0 ? `ml-${Math.min(depth * 4, 12)}` : "";
58
- const { user: author } = useUser(String(comment.authorId));
59
- const authorName = (_b = author == null ? void 0 : author.name) != null ? _b : "Unknown User";
60
89
  return /* @__PURE__ */ jsxs(
61
90
  "div",
62
91
  {
92
+ ref: containerRef,
63
93
  className: cn(
64
- "border rounded-md overflow-hidden transition-opacity",
65
- indentClass
66
- // !isVisible && "opacity-50"
94
+ "transition-colors",
95
+ !isReply && "rounded-md border",
96
+ isReply && "pt-2"
67
97
  ),
98
+ style: focused ? { boxShadow: commentRingShadow({ focused: true }), borderColor: "transparent" } : void 0,
68
99
  onMouseEnter,
69
100
  onMouseLeave,
101
+ onDoubleClick: (e) => {
102
+ e.stopPropagation();
103
+ onFocus == null ? void 0 : onFocus();
104
+ },
105
+ title: onFocus ? t("doubleClickZoom") : void 0,
70
106
  children: [
71
- /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between p-3 hover:bg-accent/50 transition-colors", children: [
72
- /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3 flex-1 min-w-0", children: [
107
+ /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-1.5 p-3", !isReply && "hover:bg-accent/50 transition-colors rounded-md", onFocus && "cursor-pointer"), children: [
108
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2", children: [
109
+ /* @__PURE__ */ jsx(Avatar, { className: cn("mt-0.5 rounded-full overflow-hidden shrink-0", isReply ? "h-6 w-6" : "h-8 w-8"), children: /* @__PURE__ */ jsx(UserAvatar, { imageFileId: author == null ? void 0 : author.imageFileId, name: authorName }) }),
110
+ /* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
111
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-foreground truncate", children: authorName }),
112
+ comment.updatedAt !== comment.createdAt && /* @__PURE__ */ jsx(Badge, { variant: "outline", className: "text-xs", children: t("edited") }),
113
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground ml-auto whitespace-nowrap", children: formatTimestamp(comment.createdAt) })
114
+ ] }) }),
115
+ onAction && /* @__PURE__ */ jsx(
116
+ CommentActionButtons,
117
+ {
118
+ onReply: !isReply && onReply ? openReply : void 0,
119
+ onEdit: isAuthor ? handleEditStart : void 0,
120
+ onDelete: isAuthor ? () => onAction("delete", comment.id) : void 0,
121
+ canReply,
122
+ canEdit,
123
+ canDelete,
124
+ labels: { reply: t("replyToComment"), edit: t("editComment"), delete: t("deleteComment") }
125
+ }
126
+ )
127
+ ] }),
128
+ isEditing ? /* @__PURE__ */ jsxs("div", { className: "flex gap-2", onDoubleClick: (e) => e.stopPropagation(), children: [
73
129
  /* @__PURE__ */ jsx(
74
- Button,
130
+ Input,
75
131
  {
76
- variant: "ghost",
77
- size: "sm",
78
- className: cn("h-6 w-6 p-0 mt-1"),
79
- onClick: () => setIsExpanded(!isExpanded),
80
- children: /* @__PURE__ */ jsx(
81
- LR.ChevronRight,
82
- {
83
- className: cn(
84
- "h-4 w-4 transition-transform",
85
- isExpanded && "rotate-90"
86
- )
132
+ value: editText,
133
+ onChange: (e) => setEditText(e.target.value),
134
+ className: "flex-1 h-8",
135
+ autoFocus: true,
136
+ onKeyDown: (e) => {
137
+ if (e.key === "Enter" && !e.shiftKey) {
138
+ e.preventDefault();
139
+ handleEditSubmit();
87
140
  }
88
- )
141
+ if (e.key === "Escape") setIsEditing(false);
142
+ },
143
+ disabled: !canEdit
89
144
  }
90
145
  ),
91
- /* @__PURE__ */ jsx(Avatar, { className: cn("h-8 w-8 mt-1 rounded-full overflow-hidden"), children: /* @__PURE__ */ jsx(UserAvatar, { imageFileId: author == null ? void 0 : author.imageFileId, name: authorName }) }),
92
- /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
93
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
94
- /* @__PURE__ */ jsx("span", { className: cn("text-sm font-medium text-foreground "), children: authorName }),
95
- comment.updatedAt !== comment.createdAt && /* @__PURE__ */ jsx(Badge, { variant: "outline", className: "text-xs", children: t("edited") })
96
- ] }),
97
- /* @__PURE__ */ jsx("p", { className: cn("text-sm mt-1 line-clamp-1 text-foreground"), children: comment.text }),
98
- replies.length > 0 && !isExpanded && /* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground mt-1", children: [
146
+ /* @__PURE__ */ jsx(Button, { size: "icon", className: "h-8 w-8 p-0", onClick: handleEditSubmit, disabled: !editText.trim() || !canEdit, children: /* @__PURE__ */ jsx(LR.Check, { className: "h-4 w-4" }) }),
147
+ /* @__PURE__ */ jsx(Button, { size: "icon", variant: "ghost", className: "h-8 w-8 p-0", onClick: () => setIsEditing(false), children: /* @__PURE__ */ jsx(LR.X, { className: "h-4 w-4" }) })
148
+ ] }) : /* @__PURE__ */ jsx("p", { className: "text-sm text-foreground whitespace-pre-wrap break-words", children: comment.text }),
149
+ !isReply && replies.length > 0 && /* @__PURE__ */ jsxs(
150
+ "button",
151
+ {
152
+ type: "button",
153
+ className: "flex items-center gap-1 w-fit text-xs text-muted-foreground hover:text-foreground transition-colors",
154
+ onClick: () => setIsExpanded((v) => !v),
155
+ children: [
156
+ /* @__PURE__ */ jsx(LR.ChevronRight, { className: cn("h-3.5 w-3.5 transition-transform", isExpanded && "rotate-90") }),
99
157
  replies.length,
100
158
  " ",
101
159
  replies.length === 1 ? t("reply") : t("replies")
102
- ] })
103
- ] })
104
- ] }),
105
- onAction && /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-0 flex-shrink-0"), children: [
160
+ ]
161
+ }
162
+ )
163
+ ] }),
164
+ !isReply && isExpanded && /* @__PURE__ */ jsxs("div", { className: "ml-5 border-l border-border pl-1 pr-2 pb-2", children: [
165
+ replies.map((reply) => /* @__PURE__ */ jsx(
166
+ CollapsibleCommentItem,
167
+ {
168
+ comment: reply,
169
+ onAction,
170
+ onReply,
171
+ onEdit,
172
+ onFileUpload,
173
+ depth: depth + 1,
174
+ pendingAction
175
+ },
176
+ reply.id
177
+ )),
178
+ onReply && /* @__PURE__ */ jsxs("div", { className: "flex gap-2 px-1 pt-2", onDoubleClick: (e) => e.stopPropagation(), children: [
106
179
  /* @__PURE__ */ jsx(
107
- Button,
180
+ Input,
108
181
  {
109
- variant: "ghost",
110
- size: "icon",
111
- className: "h-8 w-8 p-0",
112
- onClick: () => setShowReplyInput(!showReplyInput),
113
- title: t("replyToComment"),
114
- disabled: !ability.can("create", "Comment"),
115
- children: /* @__PURE__ */ jsx(LR.Reply, { className: "h-4 w-4" })
182
+ ref: replyInputRef,
183
+ value: replyText,
184
+ onChange: (e) => setReplyText(e.target.value),
185
+ placeholder: t("writeReply"),
186
+ className: "flex-1 h-8",
187
+ onKeyDown: (e) => {
188
+ if (e.key === "Enter" && !e.shiftKey) {
189
+ e.preventDefault();
190
+ handleReplySubmit();
191
+ }
192
+ },
193
+ disabled: !canReply
116
194
  }
117
195
  ),
118
- (user == null ? void 0 : user.id) === String(comment.authorId) && /* @__PURE__ */ jsxs(Fragment, { children: [
119
- /* @__PURE__ */ jsx(
120
- Button,
121
- {
122
- variant: "ghost",
123
- size: "icon",
124
- className: "h-8 w-8 p-0",
125
- onClick: () => onAction("edit", comment.id),
126
- title: t("editComment"),
127
- disabled: !ability.can("update", "Comment"),
128
- children: /* @__PURE__ */ jsx(LR.Pencil, { className: "h-4 w-4" })
129
- }
130
- ),
131
- /* @__PURE__ */ jsx(
132
- Button,
133
- {
134
- variant: "ghost",
135
- size: "icon",
136
- className: "h-8 w-8 p-0",
137
- onClick: () => onAction("delete", comment.id),
138
- title: t("deleteComment"),
139
- disabled: !ability.can("delete", "Comment"),
140
- children: /* @__PURE__ */ jsx(LR.Trash2, { className: "h-4 w-4" })
141
- }
142
- )
143
- ] })
196
+ /* @__PURE__ */ jsx(Button, { size: "icon", className: "h-8 w-8 p-0", onClick: handleReplySubmit, disabled: !replyText.trim() || !canReply, children: /* @__PURE__ */ jsx(LR.Send, { className: "h-4 w-4" }) })
144
197
  ] })
145
- ] }),
146
- isExpanded && /* @__PURE__ */ jsx("div", { className: "border-t bg-muted/30", children: /* @__PURE__ */ jsxs("div", { className: "p-4 space-y-4", children: [
147
- /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: format(new Date(comment.createdAt), "PPp") }),
148
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx("p", { className: "text-sm text-foreground whitespace-pre-wrap", children: comment.text }) })
149
- ] }) }),
150
- showReplyInput && onReply && /* @__PURE__ */ jsx("div", { className: "border-t p-3 bg-muted/20", children: /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
151
- /* @__PURE__ */ jsx(
152
- Input,
153
- {
154
- value: replyText,
155
- onChange: (e) => setReplyText(e.target.value),
156
- placeholder: t("writeReply"),
157
- className: "flex-1",
158
- onKeyDown: (e) => {
159
- if (e.key === "Enter" && !e.shiftKey) {
160
- e.preventDefault();
161
- handleReplySubmit();
162
- }
163
- },
164
- disabled: !ability.can("create", "Comment")
165
- }
166
- ),
167
- /* @__PURE__ */ jsx(
168
- Button,
169
- {
170
- size: "sm",
171
- onClick: handleReplySubmit,
172
- disabled: !replyText.trim() || !ability.can("create", "Comment"),
173
- children: /* @__PURE__ */ jsx(LR.Send, { className: "h-4 w-4" })
174
- }
175
- ),
176
- /* @__PURE__ */ jsx(
177
- Button,
178
- {
179
- size: "sm",
180
- variant: "ghost",
181
- onClick: () => {
182
- setShowReplyInput(false);
183
- setReplyText("");
184
- },
185
- disabled: !ability.can("create", "Comment"),
186
- children: /* @__PURE__ */ jsx(LR.X, { className: "h-4 w-4" })
187
- }
188
- )
189
- ] }) }),
190
- isExpanded && replies.length > 0 && /* @__PURE__ */ jsx("div", { className: "border-t", children: replies.map((reply) => /* @__PURE__ */ jsx(
191
- CollapsibleCommentItem,
192
- {
193
- comment: reply,
194
- onAction,
195
- onReply,
196
- onFileUpload,
197
- depth: depth + 1
198
- },
199
- reply.id
200
- )) })
198
+ ] })
201
199
  ]
202
200
  }
203
201
  );
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/core/components/ui/Comments/CollapsibleCommentItem.tsx"],"sourcesContent":["'use client'\r\n\r\n// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\nimport { format } from 'date-fns'\r\nimport * as LR from 'lucide-react'\r\nimport { useSession } from 'next-auth/react'\r\nimport { useTranslations } from 'next-intl'\r\nimport * as React from 'react'\r\n\r\nimport { useUser } from '../../../hooks/users/users'\r\nimport { usePermissions } from '../../../store'\r\nimport { cn } from '../../../utils/utils'\r\nimport { Avatar } from '../Avatar'\r\nimport { Badge } from '../Badge'\r\nimport { Button } from '../Button'\r\nimport { Input } from '../Input'\r\nimport { UserAvatar } from '../UserAvatar'\r\n\r\nimport type { Comment } from '../../../types/dbTypes'\r\n\r\n\r\n\r\ntype CommentAction = 'view' | 'edit' | 'delete' | 'reply'\r\n\r\ninterface CollapsibleCommentItemProps {\r\n comment: Comment\r\n onAction?: (action: CommentAction, id: number) => void\r\n replies?: Comment[]\r\n onReply?: (id: number, replyText: string | number) => void\r\n onFileUpload?: (id: number, files: FileList) => void\r\n attachments?: Array<{ name: string; url: string; size: number }>\r\n depth?: number\r\n isVisible?: boolean\r\n onMouseEnter?: () => void\r\n onMouseLeave?: () => void\r\n}\r\n\r\nexport function CollapsibleCommentItem({\r\n comment,\r\n onAction,\r\n replies = [],\r\n onReply,\r\n onFileUpload,\r\n attachments = [],\r\n depth = 0,\r\n isVisible = true,\r\n onMouseEnter,\r\n onMouseLeave\r\n}: CollapsibleCommentItemProps) {\r\n const t = useTranslations('CommentsSection')\r\n // Permissions\r\n const { ability } = usePermissions()\r\n\r\n const [isExpanded, setIsExpanded] = React.useState(false)\r\n const [showReplyInput, setShowReplyInput] = React.useState(false)\r\n const [replyText, setReplyText] = React.useState('')\r\n const fileInputRef = React.useRef<HTMLInputElement>(null)\r\n const prevVisibleRef = React.useRef(isVisible)\r\n\r\n const user = useSession().data?.user\r\n\r\n // Auto-collapse when visibility turns off\r\n React.useEffect(() => {\r\n const prevVisible = prevVisibleRef.current\r\n\r\n if (prevVisible && !isVisible) {\r\n // Just turned invisible - collapse\r\n setIsExpanded(false)\r\n }\r\n\r\n prevVisibleRef.current = isVisible\r\n }, [isVisible])\r\n\r\n const handleReplySubmit = () => {\r\n if (replyText.trim() && onReply) {\r\n onReply(comment.id, replyText)\r\n setReplyText('')\r\n setShowReplyInput(false)\r\n }\r\n }\r\n\r\n const handleFileSelect = (event: React.ChangeEvent<HTMLInputElement>) => {\r\n if (event.target.files && event.target.files.length > 0 && onFileUpload) {\r\n onFileUpload(comment.id, event.target.files)\r\n event.target.value = ''\r\n }\r\n }\r\n\r\n const indentClass = depth > 0 ? `ml-${Math.min(depth * 4, 12)}` : ''\r\n\r\n const { user: author } = useUser(String(comment.authorId))\r\n const authorName: string | undefined = author?.name ?? 'Unknown User'\r\n\r\n return (\r\n <div\r\n className={cn(\r\n \"border rounded-md overflow-hidden transition-opacity\",\r\n indentClass,\r\n // !isVisible && \"opacity-50\"\r\n )}\r\n onMouseEnter={onMouseEnter}\r\n onMouseLeave={onMouseLeave}\r\n >\r\n {/* Comment Header */}\r\n <div className=\"flex items-start justify-between p-3 hover:bg-accent/50 transition-colors\">\r\n <div className=\"flex items-start gap-3 flex-1 min-w-0\">\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n className={cn(\"h-6 w-6 p-0 mt-1\")}\r\n onClick={() => setIsExpanded(!isExpanded)}\r\n >\r\n <LR.ChevronRight\r\n className={cn(\r\n \"h-4 w-4 transition-transform\",\r\n isExpanded && \"rotate-90\"\r\n )}\r\n />\r\n </Button>\r\n\r\n <Avatar className={cn(\"h-8 w-8 mt-1 rounded-full overflow-hidden\")}>\r\n <UserAvatar imageFileId={author?.imageFileId} name={authorName} />\r\n </Avatar>\r\n\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"flex items-center gap-2\">\r\n <span className={cn(\"text-sm font-medium text-foreground \")}>\r\n {authorName}\r\n </span>\r\n {comment.updatedAt !== comment.createdAt && (\r\n <Badge variant=\"outline\" className=\"text-xs\">\r\n {t('edited')}\r\n </Badge>\r\n )}\r\n </div>\r\n <p className={cn(\"text-sm mt-1 line-clamp-1 text-foreground\")}>\r\n {comment.text}\r\n </p>\r\n {replies.length > 0 && !isExpanded && (\r\n <span className=\"text-xs text-muted-foreground mt-1\">\r\n {replies.length} {replies.length === 1 ? t('reply') : t('replies')}\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Action Buttons */}\r\n {onAction && (\r\n <div className={cn(\"flex items-center gap-0 flex-shrink-0\")}>\r\n <Button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n className=\"h-8 w-8 p-0\"\r\n onClick={() => setShowReplyInput(!showReplyInput)}\r\n title={t('replyToComment')}\r\n disabled={!ability.can('create', 'Comment')}\r\n >\r\n <LR.Reply className=\"h-4 w-4\" />\r\n </Button>\r\n {user?.id === String(comment.authorId) && (\r\n <>\r\n <Button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n className=\"h-8 w-8 p-0\"\r\n onClick={() => onAction('edit', comment.id)}\r\n title={t('editComment')}\r\n disabled={!ability.can('update', 'Comment')}\r\n >\r\n <LR.Pencil className=\"h-4 w-4\" />\r\n </Button>\r\n {/* TODO: Need 2-step confirmation dialog for DELETE COMMENT */}\r\n <Button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n className=\"h-8 w-8 p-0\"\r\n onClick={() => onAction('delete', comment.id)}\r\n title={t('deleteComment')}\r\n disabled={!ability.can('delete', 'Comment')}\r\n\r\n >\r\n <LR.Trash2 className=\"h-4 w-4\" />\r\n </Button>\r\n </>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Expanded Content */ }\r\n {\r\n isExpanded && (\r\n <div className=\"border-t bg-muted/30\">\r\n <div className=\"p-4 space-y-4\">\r\n {/* Full Comment Text */}\r\n <span className=\"text-xs text-muted-foreground\">\r\n {format(new Date(comment.createdAt), 'PPp')}\r\n </span>\r\n <div>\r\n <p className=\"text-sm text-foreground whitespace-pre-wrap\">\r\n {comment.text}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n )\r\n }\r\n\r\n {/* Reply Input */ }\r\n {\r\n showReplyInput && onReply && (\r\n <div className=\"border-t p-3 bg-muted/20\">\r\n <div className=\"flex gap-2\">\r\n <Input\r\n value={replyText}\r\n onChange={(e) => setReplyText(e.target.value)}\r\n placeholder={t('writeReply')}\r\n className=\"flex-1\"\r\n onKeyDown={(e) => {\r\n if (e.key === 'Enter' && !e.shiftKey) {\r\n e.preventDefault()\r\n handleReplySubmit()\r\n }\r\n }}\r\n disabled={!ability.can('create', 'Comment')}\r\n />\r\n <Button\r\n size=\"sm\"\r\n onClick={handleReplySubmit}\r\n disabled={!replyText.trim() || !ability.can('create', 'Comment')}\r\n >\r\n <LR.Send className=\"h-4 w-4\" />\r\n </Button>\r\n <Button\r\n size=\"sm\"\r\n variant=\"ghost\"\r\n onClick={() => {\r\n setShowReplyInput(false)\r\n setReplyText('')\r\n }}\r\n disabled={!ability.can('create', 'Comment')}\r\n >\r\n <LR.X className=\"h-4 w-4\" />\r\n </Button>\r\n </div>\r\n </div>\r\n )\r\n }\r\n\r\n {/* Nested Replies */ }\r\n {\r\n isExpanded && replies.length > 0 && (\r\n <div className=\"border-t\">\r\n {replies.map((reply) => (\r\n <CollapsibleCommentItem\r\n key={reply.id}\r\n comment={reply}\r\n onAction={onAction}\r\n onReply={onReply}\r\n onFileUpload={onFileUpload}\r\n depth={depth + 1}\r\n />\r\n ))}\r\n </div>\r\n )\r\n }\r\n </div >\r\n )\r\n}\r\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../../src/core/components/ui/Comments/CollapsibleCommentItem.tsx"],"sourcesContent":["'use client'\r\n\r\n// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\nimport * as LR from 'lucide-react'\r\nimport { useSession } from 'next-auth/react'\r\nimport { useTranslations } from 'next-intl'\r\nimport * as React from 'react'\r\n\r\nimport { useUser } from '../../../hooks/users/users'\r\nimport { usePermissions } from '../../../store'\r\nimport { commentRingShadow } from '../../../utils/markerUtils'\r\nimport { formatTimestamp } from '../../../utils/timeUtils'\r\nimport { cn } from '../../../utils/utils'\r\nimport { Avatar } from '../Avatar'\r\nimport { Badge } from '../Badge'\r\nimport { Button } from '../Button'\r\nimport { Input } from '../Input'\r\nimport { UserAvatar } from '../UserAvatar'\r\n\r\nimport { CommentActionButtons } from './CommentActionButtons'\r\n\r\nimport type { Comment } from '../../../types/dbTypes'\r\n\r\ntype CommentAction = 'view' | 'edit' | 'delete' | 'reply'\r\n\r\n/** Request from a 3D/map marker to auto-open a comment's editor or reply box. */\r\nexport interface PendingCommentAction {\r\n commentId: number\r\n action: 'edit' | 'reply'\r\n requestId: number\r\n}\r\n\r\ninterface CollapsibleCommentItemProps {\r\n comment: Comment\r\n onAction?: (action: CommentAction, id: number) => void\r\n replies?: Comment[]\r\n onReply?: (comment: Comment, replyText: string) => void\r\n onEdit?: (id: number, text: string) => void\r\n onFileUpload?: (id: number, files: FileList) => void\r\n attachments?: Array<{ name: string; url: string; size: number }>\r\n depth?: number\r\n isVisible?: boolean\r\n focused?: boolean\r\n onFocus?: () => void\r\n pendingAction?: PendingCommentAction\r\n onMouseEnter?: () => void\r\n onMouseLeave?: () => void\r\n}\r\n\r\nexport function CollapsibleCommentItem({\r\n comment,\r\n onAction,\r\n replies = [],\r\n onReply,\r\n onEdit,\r\n onFileUpload,\r\n depth = 0,\r\n isVisible = true,\r\n focused = false,\r\n onFocus,\r\n pendingAction,\r\n onMouseEnter,\r\n onMouseLeave,\r\n}: CollapsibleCommentItemProps) {\r\n const t = useTranslations('CommentsSection')\r\n const { ability } = usePermissions()\r\n\r\n const isReply = depth > 0\r\n const [isExpanded, setIsExpanded] = React.useState(false)\r\n const [replyText, setReplyText] = React.useState('')\r\n const [isEditing, setIsEditing] = React.useState(false)\r\n const [editText, setEditText] = React.useState(comment.text)\r\n const containerRef = React.useRef<HTMLDivElement>(null)\r\n const replyInputRef = React.useRef<HTMLInputElement>(null)\r\n const prevVisibleRef = React.useRef(isVisible)\r\n\r\n const user = useSession().data?.user\r\n const isAuthor = user?.id === String(comment.authorId)\r\n const canReply = ability.can('create', 'Comment')\r\n const canEdit = ability.can('update', 'Comment')\r\n const canDelete = ability.can('delete', 'Comment')\r\n\r\n const { user: author } = useUser(String(comment.authorId))\r\n const authorName: string = author?.name ?? 'Unknown User'\r\n\r\n // Auto-collapse when visibility turns off\r\n React.useEffect(() => {\r\n if (prevVisibleRef.current && !isVisible) setIsExpanded(false)\r\n prevVisibleRef.current = isVisible\r\n }, [isVisible])\r\n\r\n const handleEditStart = React.useCallback(() => {\r\n setEditText(comment.text)\r\n setIsEditing(true)\r\n }, [comment.text])\r\n\r\n // Reply happens in one place: the input at the end of the thread. The reply button just\r\n // expands the thread and focuses that input, so users never hunt for a per-comment control.\r\n const openReply = React.useCallback(() => {\r\n setIsExpanded(true)\r\n requestAnimationFrame(() => replyInputRef.current?.focus())\r\n }, [])\r\n\r\n // Open the editor / reply box when a marker requests it, then scroll into view.\r\n React.useEffect(() => {\r\n if (!pendingAction) return\r\n const matchesSelf = pendingAction.commentId === comment.id\r\n const matchesReply = replies.some((r) => r.id === pendingAction.commentId)\r\n if (matchesSelf) {\r\n if (pendingAction.action === 'edit') handleEditStart()\r\n else openReply()\r\n containerRef.current?.scrollIntoView({ behavior: 'smooth', block: 'nearest' })\r\n }\r\n if (matchesReply) setIsExpanded(true)\r\n }, [pendingAction?.requestId])\r\n\r\n const handleReplySubmit = () => {\r\n if (replyText.trim() && onReply) {\r\n onReply(comment, replyText)\r\n setReplyText('')\r\n }\r\n }\r\n\r\n const handleEditSubmit = () => {\r\n const next = editText.trim()\r\n if (next && next !== comment.text && onEdit) onEdit(comment.id, next)\r\n setIsEditing(false)\r\n }\r\n\r\n return (\r\n <div\r\n ref={containerRef}\r\n className={cn(\r\n 'transition-colors',\r\n !isReply && 'rounded-md border',\r\n isReply && 'pt-2'\r\n )}\r\n style={focused ? { boxShadow: commentRingShadow({ focused: true }), borderColor: 'transparent' } : undefined}\r\n onMouseEnter={onMouseEnter}\r\n onMouseLeave={onMouseLeave}\r\n onDoubleClick={(e) => {\r\n e.stopPropagation()\r\n onFocus?.()\r\n }}\r\n title={onFocus ? t('doubleClickZoom') : undefined}\r\n >\r\n <div className={cn('flex flex-col gap-1.5 p-3', !isReply && 'hover:bg-accent/50 transition-colors rounded-md', onFocus && 'cursor-pointer')}>\r\n {/* Header: avatar, author, timestamp, actions */}\r\n <div className=\"flex items-start gap-2\">\r\n <Avatar className={cn('mt-0.5 rounded-full overflow-hidden shrink-0', isReply ? 'h-6 w-6' : 'h-8 w-8')}>\r\n <UserAvatar imageFileId={author?.imageFileId} name={authorName} />\r\n </Avatar>\r\n\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"text-sm font-medium text-foreground truncate\">{authorName}</span>\r\n {comment.updatedAt !== comment.createdAt && (\r\n <Badge variant=\"outline\" className=\"text-xs\">{t('edited')}</Badge>\r\n )}\r\n <span className=\"text-xs text-muted-foreground ml-auto whitespace-nowrap\">\r\n {formatTimestamp(comment.createdAt)}\r\n </span>\r\n </div>\r\n </div>\r\n\r\n {onAction && (\r\n <CommentActionButtons\r\n // Replies are single-level, so only top-level comments expose a reply control.\r\n onReply={!isReply && onReply ? openReply : undefined}\r\n onEdit={isAuthor ? handleEditStart : undefined}\r\n onDelete={isAuthor ? () => onAction('delete', comment.id) : undefined}\r\n canReply={canReply}\r\n canEdit={canEdit}\r\n canDelete={canDelete}\r\n labels={{ reply: t('replyToComment'), edit: t('editComment'), delete: t('deleteComment') }}\r\n />\r\n )}\r\n </div>\r\n\r\n {/* Body: full text (shown once) or inline editor */}\r\n {isEditing ? (\r\n <div className=\"flex gap-2\" onDoubleClick={(e) => e.stopPropagation()}>\r\n <Input\r\n value={editText}\r\n onChange={(e) => setEditText(e.target.value)}\r\n className=\"flex-1 h-8\"\r\n autoFocus\r\n onKeyDown={(e) => {\r\n if (e.key === 'Enter' && !e.shiftKey) {\r\n e.preventDefault()\r\n handleEditSubmit()\r\n }\r\n if (e.key === 'Escape') setIsEditing(false)\r\n }}\r\n disabled={!canEdit}\r\n />\r\n <Button size=\"icon\" className=\"h-8 w-8 p-0\" onClick={handleEditSubmit} disabled={!editText.trim() || !canEdit}>\r\n <LR.Check className=\"h-4 w-4\" />\r\n </Button>\r\n <Button size=\"icon\" variant=\"ghost\" className=\"h-8 w-8 p-0\" onClick={() => setIsEditing(false)}>\r\n <LR.X className=\"h-4 w-4\" />\r\n </Button>\r\n </div>\r\n ) : (\r\n <p className=\"text-sm text-foreground whitespace-pre-wrap break-words\">{comment.text}</p>\r\n )}\r\n\r\n {/* Replies toggle (top-level only) */}\r\n {!isReply && replies.length > 0 && (\r\n <button\r\n type=\"button\"\r\n className=\"flex items-center gap-1 w-fit text-xs text-muted-foreground hover:text-foreground transition-colors\"\r\n onClick={() => setIsExpanded((v) => !v)}\r\n >\r\n <LR.ChevronRight className={cn('h-3.5 w-3.5 transition-transform', isExpanded && 'rotate-90')} />\r\n {replies.length} {replies.length === 1 ? t('reply') : t('replies')}\r\n </button>\r\n )}\r\n </div>\r\n\r\n {/* Nested replies thread + single reply input at the end */}\r\n {!isReply && isExpanded && (\r\n <div className=\"ml-5 border-l border-border pl-1 pr-2 pb-2\">\r\n {replies.map((reply) => (\r\n <CollapsibleCommentItem\r\n key={reply.id}\r\n comment={reply}\r\n onAction={onAction}\r\n onReply={onReply}\r\n onEdit={onEdit}\r\n onFileUpload={onFileUpload}\r\n depth={depth + 1}\r\n pendingAction={pendingAction}\r\n />\r\n ))}\r\n\r\n {onReply && (\r\n <div className=\"flex gap-2 px-1 pt-2\" onDoubleClick={(e) => e.stopPropagation()}>\r\n <Input\r\n ref={replyInputRef}\r\n value={replyText}\r\n onChange={(e) => setReplyText(e.target.value)}\r\n placeholder={t('writeReply')}\r\n className=\"flex-1 h-8\"\r\n onKeyDown={(e) => {\r\n if (e.key === 'Enter' && !e.shiftKey) {\r\n e.preventDefault()\r\n handleReplySubmit()\r\n }\r\n }}\r\n disabled={!canReply}\r\n />\r\n <Button size=\"icon\" className=\"h-8 w-8 p-0\" onClick={handleReplySubmit} disabled={!replyText.trim() || !canReply}>\r\n <LR.Send className=\"h-4 w-4\" />\r\n </Button>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n )\r\n}\r\n"],"mappings":"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","names":["_a"]}
@@ -1,4 +1,5 @@
1
1
  import * as React from 'react';
2
+ import { type CommentActionLabels } from './CommentActionButtons';
2
3
  export type CommentProps = {
3
4
  userName: string;
4
5
  userImage: number | null;
@@ -8,10 +9,26 @@ export type CommentProps = {
8
9
  createdAt: string | Date;
9
10
  onRemove?: () => void;
10
11
  onClose?: () => void;
12
+ /** Called when the collapsed avatar is single-clicked (select the comment). */
13
+ onSelect?: () => void;
14
+ /** Called on double-click — used to zoom/focus the comment in the viewer. */
15
+ onFocus?: () => void;
16
+ /** Reply to the comment (in-viewer card opens the reply box in the sidebar). */
17
+ onReply?: () => void;
18
+ /** Edit the comment (in-viewer card opens the editor in the sidebar). */
19
+ onEdit?: () => void;
11
20
  enableCollapse?: boolean;
12
21
  defaultCollapsed?: boolean;
13
22
  isPending?: boolean;
14
23
  highlight?: boolean;
24
+ /** Double-clicked/zoomed comment: renders the thicker focus ring. */
25
+ focused?: boolean;
26
+ /** Render the close/reply/edit/delete action row (used by the in-viewer BIM card). */
27
+ showActions?: boolean;
28
+ canReply?: boolean;
29
+ canEdit?: boolean;
30
+ canDelete?: boolean;
31
+ actionLabels?: CommentActionLabels;
15
32
  };
16
- export default function Comment({ text, createdAt, userName, userImage, userImageFileId, onRemove, onClose, enableCollapse, defaultCollapsed, isPending, highlight, }: CommentProps): React.JSX.Element;
33
+ export default function Comment({ text, createdAt, userName, userImage, userImageFileId, onRemove, onClose, onSelect, onFocus, onReply, onEdit, enableCollapse, defaultCollapsed, isPending, highlight, focused, showActions, canReply, canEdit, canDelete, actionLabels, }: CommentProps): React.JSX.Element;
17
34
  //# sourceMappingURL=Comment.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Comment.d.ts","sourceRoot":"","sources":["../../../../../src/core/components/ui/Comments/Comment.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAU9B,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,CAAA;AAED,MAAM,CAAC,OAAO,UAAU,OAAO,CAAC,EAC9B,IAAI,EACJ,SAAS,EACT,QAAQ,EACR,SAAS,EACT,eAAe,EACf,QAAQ,EACR,OAAO,EACP,cAAsB,EACtB,gBAAwB,EACxB,SAAiB,EACjB,SAAiB,GAClB,EAAE,YAAY,qBA6Gd"}
1
+ {"version":3,"file":"Comment.d.ts","sourceRoot":"","sources":["../../../../../src/core/components/ui/Comments/Comment.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAU9B,OAAO,EAAwB,KAAK,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAEvF,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,6EAA6E;IAC7E,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,gFAAgF;IAChF,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;IACnB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,qEAAqE;IACrE,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,sFAAsF;IACtF,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,YAAY,CAAC,EAAE,mBAAmB,CAAA;CACnC,CAAA;AAED,MAAM,CAAC,OAAO,UAAU,OAAO,CAAC,EAC9B,IAAI,EACJ,SAAS,EACT,QAAQ,EACR,SAAS,EACT,eAAe,EACf,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,OAAO,EACP,OAAO,EACP,MAAM,EACN,cAAsB,EACtB,gBAAwB,EACxB,SAAiB,EACjB,SAAiB,EACjB,OAAe,EACf,WAAmB,EACnB,QAAe,EACf,OAAc,EACd,SAAgB,EAChB,YAAY,GACb,EAAE,YAAY,qBAgKd"}