@geode/opengeodeweb-front 10.34.0-rc.2 → 10.34.0-rc.21

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 (499) hide show
  1. package/.build/opengeodeweb_front_schemas.js +175 -0
  2. package/.build/server/utils/app_config.js +57 -0
  3. package/.build/server/utils/cleanup.js +135 -0
  4. package/.build/server/utils/cloud.js +156 -0
  5. package/.build/server/utils/microservices.js +153 -0
  6. package/.build/server/utils/path.js +108 -0
  7. package/.build/server/utils/scripts.js +134 -0
  8. package/.build/server/utils/server.js +44 -0
  9. package/.build/server/utils/server_config.js +51 -0
  10. package/.build/server/utils/stream.js +6 -0
  11. package/.build/server/utils/ws_client.js +100 -0
  12. package/.build/shared/app_mode.js +8 -0
  13. package/.build/shared/scripts.js +49 -0
  14. package/.build/shared/utils/call_raw.js +31 -0
  15. package/.build/shared/utils/call_schema.js +28 -0
  16. package/.build/shared/utils/fetch_raw.js +52 -0
  17. package/.build/shared/utils/fetch_schema.js +32 -0
  18. package/.build/shared/utils/file.js +14 -0
  19. package/.build/shared/utils/parse_boolean.js +23 -0
  20. package/.build/shared/utils/response_handlers/load.js +50 -0
  21. package/.build/shared/utils/types.js +1 -0
  22. package/.build/shared/utils/validate_schema.js +17 -0
  23. package/README.md +8 -0
  24. package/app/assets/{geode_objects.js → geode_objects.ts} +8 -1
  25. package/app/components/ActionButton.vue +28 -12
  26. package/app/components/Basic/Slider.vue +2 -2
  27. package/app/components/Basic/Switch.vue +2 -2
  28. package/app/components/CameraManager/List.vue +11 -11
  29. package/app/components/CameraManager/Saver.vue +8 -4
  30. package/app/components/CameraManager.vue +24 -12
  31. package/app/components/CameraOrientation.vue +31 -17
  32. package/app/components/ClippingPlaneCard.vue +13 -12
  33. package/app/components/ClippingPlanes.vue +31 -21
  34. package/app/components/CrsSelector.vue +26 -18
  35. package/app/components/DeleteDialog.vue +18 -16
  36. package/app/components/DragAndDrop.vue +55 -37
  37. package/app/components/DragAndDropInternal/DragAndDropInline.vue +31 -16
  38. package/app/components/DragAndDropInternal/DragAndDropOverlay.vue +32 -19
  39. package/app/components/ExtensionSelector.vue +34 -18
  40. package/app/components/FeedBack/ErrorBanner.vue +4 -3
  41. package/app/components/FeedBack/Snackers.vue +6 -5
  42. package/app/components/FetchingData.vue +8 -12
  43. package/app/components/FileSelector.vue +27 -17
  44. package/app/components/FileUploader.vue +51 -30
  45. package/app/components/GlassCard.vue +17 -13
  46. package/app/components/HybridRenderingView.vue +25 -12
  47. package/app/components/HybridViewerTooltip.vue +28 -26
  48. package/app/components/InfraConnected.vue +1 -1
  49. package/app/components/Launcher.vue +12 -10
  50. package/app/components/Loading/EcoMessages.vue +24 -13
  51. package/app/components/Loading/Header.vue +6 -7
  52. package/app/components/Loading/Progress.vue +6 -7
  53. package/app/components/Loading.vue +10 -14
  54. package/app/components/MissingFilesSelector.vue +35 -19
  55. package/app/components/ObjectSelector.vue +37 -21
  56. package/app/components/PackagesVersions.vue +16 -8
  57. package/app/components/Recaptcha.vue +17 -23
  58. package/app/components/RemoteRenderingView.vue +21 -15
  59. package/app/components/Ruler.vue +11 -9
  60. package/app/components/Screenshot.vue +25 -19
  61. package/app/components/SearchBar.vue +12 -6
  62. package/app/components/ShrinkFilter.vue +19 -14
  63. package/app/components/Step.vue +32 -12
  64. package/app/components/Stepper.vue +19 -7
  65. package/app/components/ToolPanel.vue +29 -13
  66. package/app/components/ViewToolbar.vue +53 -44
  67. package/app/components/Viewer/ContextMenu/CenterButton.vue +16 -9
  68. package/app/components/Viewer/ContextMenu/CircularItems.vue +13 -10
  69. package/app/components/Viewer/ContextMenu/ContextMenu.vue +40 -32
  70. package/app/components/Viewer/ContextMenu/ContextMenuItem.vue +31 -17
  71. package/app/components/Viewer/ContextMenu/InfoCard.vue +38 -22
  72. package/app/components/Viewer/EdgedCurve/PointsOptions.vue +8 -5
  73. package/app/components/Viewer/EdgedCurve/SpecificEdgesOptions.vue +67 -48
  74. package/app/components/Viewer/Generic/Mesh/CellsOptions.vue +74 -50
  75. package/app/components/Viewer/Generic/Mesh/EdgesOptions.vue +69 -50
  76. package/app/components/Viewer/Generic/Mesh/PointsOptions.vue +47 -35
  77. package/app/components/Viewer/Generic/Mesh/PolygonsOptions.vue +91 -51
  78. package/app/components/Viewer/Generic/Mesh/PolyhedraOptions.vue +74 -49
  79. package/app/components/Viewer/Generic/Model/BlocksOptions.vue +115 -53
  80. package/app/components/Viewer/Generic/Model/CornersOptions.vue +75 -37
  81. package/app/components/Viewer/Generic/Model/EdgesOptions.vue +13 -9
  82. package/app/components/Viewer/Generic/Model/LinesOptions.vue +110 -61
  83. package/app/components/Viewer/Generic/Model/ModelStyleCard.vue +32 -21
  84. package/app/components/Viewer/Generic/Model/ModelStyleOptions.vue +9 -5
  85. package/app/components/Viewer/Generic/Model/PointsOptions.vue +19 -13
  86. package/app/components/Viewer/Generic/Model/SurfacesOptions.vue +119 -49
  87. package/app/components/Viewer/Grid/2D/CellsOptions.vue +8 -5
  88. package/app/components/Viewer/Grid/2D/EdgesOptions.vue +8 -5
  89. package/app/components/Viewer/Grid/2D/PointsOptions.vue +8 -5
  90. package/app/components/Viewer/Grid/3D/CellsOptions.vue +8 -5
  91. package/app/components/Viewer/Grid/3D/EdgesOptions.vue +8 -5
  92. package/app/components/Viewer/Grid/3D/FacetsOptions.vue +8 -5
  93. package/app/components/Viewer/Grid/3D/PointsOptions.vue +8 -5
  94. package/app/components/Viewer/ObjectTree/Base/CommonTreeView.vue +120 -76
  95. package/app/components/Viewer/ObjectTree/Base/Controls.vue +25 -10
  96. package/app/components/Viewer/ObjectTree/Base/ItemLabel.vue +42 -17
  97. package/app/components/Viewer/ObjectTree/Base/StickyHeader.vue +22 -9
  98. package/app/components/Viewer/ObjectTree/Base/TreeRow.vue +29 -14
  99. package/app/components/Viewer/ObjectTree/Box.vue +32 -15
  100. package/app/components/Viewer/ObjectTree/Layout.vue +55 -35
  101. package/app/components/Viewer/ObjectTree/Views/GlobalObjects.vue +63 -34
  102. package/app/components/Viewer/ObjectTree/Views/{ModelCollections.vue → ModelTree.vue} +101 -39
  103. package/app/components/Viewer/Options/AttributeColorBar.vue +14 -6
  104. package/app/components/Viewer/Options/AttributeRangeSelector.vue +8 -4
  105. package/app/components/Viewer/Options/AttributeSelector.vue +64 -33
  106. package/app/components/Viewer/Options/ColorMapList.vue +52 -24
  107. package/app/components/Viewer/Options/ColorMapPicker.vue +15 -11
  108. package/app/components/Viewer/Options/ColorPicker.vue +239 -50
  109. package/app/components/Viewer/Options/ColoringTypeSelector.vue +87 -67
  110. package/app/components/Viewer/Options/ColormapQuickPicker.vue +16 -12
  111. package/app/components/Viewer/Options/OptionsSection.vue +7 -5
  112. package/app/components/Viewer/Options/Sliders/Size.vue +3 -3
  113. package/app/components/Viewer/Options/Sliders/Slider.vue +9 -6
  114. package/app/components/Viewer/Options/Sliders/Width.vue +3 -3
  115. package/app/components/Viewer/Options/TextureItem.vue +29 -22
  116. package/app/components/Viewer/Options/TexturesSelector.vue +23 -12
  117. package/app/components/Viewer/Options/VisibilitySwitch.vue +3 -3
  118. package/app/components/Viewer/OverlappingObjectsPicker.vue +27 -12
  119. package/app/components/Viewer/PointSet/SpecificPointsOptions.vue +38 -26
  120. package/app/components/Viewer/Solid/EdgesOptions.vue +8 -5
  121. package/app/components/Viewer/Solid/PointsOptions.vue +8 -5
  122. package/app/components/Viewer/Solid/PolygonsOptions.vue +8 -5
  123. package/app/components/Viewer/Solid/SpecificPolyhedraOptions.vue +73 -48
  124. package/app/components/Viewer/Surface/EdgesOptions.vue +8 -5
  125. package/app/components/Viewer/Surface/PointsOptions.vue +8 -5
  126. package/app/components/Viewer/Surface/PolygonsOptions.vue +79 -49
  127. package/app/components/Viewer/Surface/Triangulated/TrianglesOptions.vue +8 -5
  128. package/app/components/Viewer/TetrahedralSolid/TetrahedraOptions.vue +8 -5
  129. package/app/components/Viewer/TetrahedralSolid/TrianglesOptions.vue +8 -5
  130. package/app/components/Viewer/Ui.vue +19 -14
  131. package/app/components/Wrapper.vue +16 -10
  132. package/app/components/ZScaling.vue +18 -10
  133. package/app/components/csv-preview/CsvPreviewer.vue +72 -50
  134. package/app/components/csv-preview/CsvSettings.vue +30 -50
  135. package/app/components/csv-preview/CsvTable.vue +34 -14
  136. package/app/composables/{batch_style.js → batch_style.ts} +9 -7
  137. package/app/composables/clipping_planes_widget.ts +204 -0
  138. package/app/composables/clipping_planes_widget_entries.ts +189 -0
  139. package/app/composables/copy_to_clipboard.ts +7 -0
  140. package/app/composables/global_attribute_style.ts +303 -0
  141. package/app/composables/hover_highlight.ts +127 -0
  142. package/app/composables/{model_collections.js → model_collections.ts} +28 -9
  143. package/app/composables/{model_components.js → model_components.ts} +28 -9
  144. package/app/composables/{project_manager.js → project_manager.ts} +77 -20
  145. package/app/composables/responsive_middle_truncate.ts +48 -0
  146. package/app/composables/{run_function_when_microservices_connected.js → run_function_when_microservices_connected.ts} +1 -1
  147. package/app/composables/stepper_tree.ts +79 -0
  148. package/app/composables/tree_filter.ts +194 -0
  149. package/app/composables/{tree_keyboard_nav.js → tree_keyboard_nav.ts} +62 -20
  150. package/app/composables/{tree_scroll.js → tree_scroll.ts} +61 -12
  151. package/app/composables/use_adaptive_styles.ts +186 -0
  152. package/app/composables/use_overlapping_picker.ts +263 -0
  153. package/app/composables/use_quick_colormap.ts +55 -0
  154. package/app/composables/virtual_tree.ts +271 -0
  155. package/app/composables/vtk_implicit_plane_widget.d.ts +2 -0
  156. package/app/plugins/{auto_store_register.js → auto_store_register.ts} +3 -5
  157. package/app/plugins/click_outside_ignore_snackbars.client.ts +36 -0
  158. package/app/stores/app.ts +252 -0
  159. package/app/stores/app_helpers/extension.ts +179 -0
  160. package/app/stores/{back.js → back.ts} +54 -28
  161. package/app/stores/camera_manager.ts +80 -0
  162. package/app/stores/{cloud.js → cloud.ts} +18 -13
  163. package/app/stores/data.ts +392 -0
  164. package/app/stores/data_helpers/collections.ts +138 -0
  165. package/app/stores/data_helpers/mesh.ts +169 -0
  166. package/app/stores/data_style.ts +167 -0
  167. package/app/stores/{feedback.js → feedback.ts} +19 -8
  168. package/app/stores/{hybrid_viewer.js → hybrid_viewer.ts} +49 -45
  169. package/app/stores/infra.ts +106 -0
  170. package/app/stores/{menu.js → menu.ts} +67 -36
  171. package/app/stores/treeview.ts +383 -0
  172. package/app/stores/{viewer.js → viewer.ts} +75 -42
  173. package/app/utils/attributes.ts +40 -0
  174. package/app/utils/clipping_planes.ts +222 -0
  175. package/app/utils/color_picker.js +54 -0
  176. package/app/utils/colormap.ts +102 -0
  177. package/app/utils/default_styles/{constants.js → constants.ts} +25 -12
  178. package/app/utils/default_styles/{index.js → index.ts} +4 -3
  179. package/app/utils/default_styles/meshes.ts +264 -0
  180. package/app/utils/default_styles/{models.js → models.ts} +106 -52
  181. package/app/utils/{extension.js → extension.ts} +63 -19
  182. package/app/utils/{import_workflow.js → import_workflow.ts} +39 -22
  183. package/app/utils/{log.js → log.ts} +12 -2
  184. package/app/utils/{name_cleaner.js → name_cleaner.ts} +6 -6
  185. package/app/utils/status.ts +19 -0
  186. package/app/utils/{stores.js → stores.ts} +5 -5
  187. package/app/utils/{string.js → string.ts} +6 -6
  188. package/app/utils/{treeview.js → treeview.ts} +4 -1
  189. package/internal/database/{base_database.js → base_database.ts} +7 -3
  190. package/internal/database/database.ts +102 -0
  191. package/internal/database/{extended_database.js → extended_database.ts} +5 -1
  192. package/internal/database/tables/camera_positions.ts +6 -0
  193. package/internal/database/tables/{data.js → data.ts} +3 -1
  194. package/internal/database/tables/data_style.ts +6 -0
  195. package/internal/database/tables/model_component_datastyle.ts +6 -0
  196. package/internal/database/tables/model_component_type_datastyle.ts +6 -0
  197. package/internal/database/tables/model_components.ts +6 -0
  198. package/internal/database/tables/model_components_relation.ts +6 -0
  199. package/internal/database/tables/table_definition.ts +5 -0
  200. package/internal/stores/data_style/mesh/cells/cell.ts +279 -0
  201. package/internal/stores/data_style/mesh/cells/{color.js → color.ts} +13 -7
  202. package/internal/stores/data_style/mesh/cells/common.ts +50 -0
  203. package/internal/stores/data_style/mesh/cells/index.ts +161 -0
  204. package/internal/stores/data_style/mesh/cells/{textures.js → textures.ts} +14 -8
  205. package/internal/stores/data_style/mesh/cells/vertex.ts +285 -0
  206. package/internal/stores/data_style/mesh/cells/visibility.ts +46 -0
  207. package/internal/stores/data_style/mesh/edges/{color.js → color.ts} +13 -7
  208. package/internal/stores/data_style/mesh/edges/common.ts +41 -0
  209. package/internal/stores/data_style/mesh/edges/edge.ts +279 -0
  210. package/internal/stores/data_style/mesh/edges/index.ts +155 -0
  211. package/internal/stores/data_style/mesh/edges/vertex.ts +285 -0
  212. package/internal/stores/data_style/mesh/edges/visibility.ts +45 -0
  213. package/internal/stores/data_style/mesh/edges/width.ts +42 -0
  214. package/internal/stores/data_style/mesh/{index.js → index.ts} +34 -14
  215. package/internal/stores/data_style/mesh/points/{color.js → color.ts} +13 -7
  216. package/internal/stores/data_style/mesh/points/common.ts +51 -0
  217. package/internal/stores/data_style/mesh/points/index.ts +133 -0
  218. package/internal/stores/data_style/mesh/points/size.ts +43 -0
  219. package/internal/stores/data_style/mesh/points/vertex.ts +285 -0
  220. package/internal/stores/data_style/mesh/points/visibility.ts +49 -0
  221. package/internal/stores/data_style/mesh/polygons/{color.js → color.ts} +13 -7
  222. package/internal/stores/data_style/mesh/polygons/common.ts +50 -0
  223. package/internal/stores/data_style/mesh/polygons/index.ts +167 -0
  224. package/internal/stores/data_style/mesh/polygons/polygon.ts +282 -0
  225. package/internal/stores/data_style/mesh/polygons/{textures.js → textures.ts} +14 -8
  226. package/internal/stores/data_style/mesh/polygons/vertex.ts +288 -0
  227. package/internal/stores/data_style/mesh/polygons/visibility.ts +48 -0
  228. package/internal/stores/data_style/mesh/polyhedra/{color.js → color.ts} +13 -7
  229. package/internal/stores/data_style/mesh/polyhedra/common.ts +41 -0
  230. package/internal/stores/data_style/mesh/polyhedra/index.ts +157 -0
  231. package/internal/stores/data_style/mesh/polyhedra/polyhedron.ts +294 -0
  232. package/internal/stores/data_style/mesh/polyhedra/vertex.ts +288 -0
  233. package/internal/stores/data_style/mesh/polyhedra/visibility.ts +48 -0
  234. package/internal/stores/data_style/model/blocks/{color.js → color.ts} +50 -13
  235. package/internal/stores/data_style/model/blocks/common.ts +67 -0
  236. package/internal/stores/data_style/model/blocks/{index.js → index.ts} +111 -66
  237. package/internal/stores/data_style/model/blocks/polyhedron.ts +363 -0
  238. package/internal/stores/data_style/model/blocks/vertex.ts +349 -0
  239. package/internal/stores/data_style/model/blocks/visibility.ts +37 -0
  240. package/internal/stores/data_style/model/color.ts +348 -0
  241. package/internal/stores/data_style/model/common.ts +262 -0
  242. package/internal/stores/data_style/model/corners/{color.js → color.ts} +49 -10
  243. package/internal/stores/data_style/model/corners/common.ts +71 -0
  244. package/internal/stores/data_style/model/corners/{index.js → index.ts} +86 -47
  245. package/internal/stores/data_style/model/corners/vertex.ts +315 -0
  246. package/internal/stores/data_style/model/corners/visibility.ts +39 -0
  247. package/internal/stores/data_style/model/edges/common.ts +29 -0
  248. package/internal/stores/data_style/model/edges/{index.js → index.ts} +2 -7
  249. package/internal/stores/data_style/model/edges/visibility.ts +55 -0
  250. package/internal/stores/data_style/model/{index.js → index.ts} +24 -11
  251. package/internal/stores/data_style/model/lines/{color.js → color.ts} +47 -10
  252. package/internal/stores/data_style/model/lines/common.ts +63 -0
  253. package/internal/stores/data_style/model/lines/edge.ts +343 -0
  254. package/internal/stores/data_style/model/lines/{index.js → index.ts} +108 -66
  255. package/internal/stores/data_style/model/lines/vertex.ts +344 -0
  256. package/internal/stores/data_style/model/lines/visibility.ts +37 -0
  257. package/internal/stores/data_style/model/points/common.ts +25 -0
  258. package/internal/stores/data_style/model/points/index.ts +35 -0
  259. package/internal/stores/data_style/model/points/size.ts +44 -0
  260. package/internal/stores/data_style/model/points/visibility.ts +46 -0
  261. package/internal/stores/data_style/model/selection.ts +138 -0
  262. package/internal/stores/data_style/model/surfaces/{color.js → color.ts} +47 -10
  263. package/internal/stores/data_style/model/surfaces/common.ts +69 -0
  264. package/internal/stores/data_style/model/surfaces/{index.js → index.ts} +113 -66
  265. package/internal/stores/data_style/model/surfaces/polygon.ts +347 -0
  266. package/internal/stores/data_style/model/surfaces/vertex.ts +351 -0
  267. package/internal/stores/data_style/model/surfaces/visibility.ts +37 -0
  268. package/internal/stores/data_style/model/{visibility.js → visibility.ts} +112 -32
  269. package/internal/stores/data_style/state.ts +281 -0
  270. package/internal/stores/data_style/types.ts +30 -0
  271. package/internal/stores/hybrid_viewer/brightness.ts +124 -0
  272. package/internal/stores/hybrid_viewer/camera.ts +326 -0
  273. package/internal/stores/hybrid_viewer/{camera_animation.js → camera_animation.ts} +30 -12
  274. package/internal/stores/hybrid_viewer/{constants.js → constants.ts} +2 -2
  275. package/internal/stores/hybrid_viewer/core.ts +64 -0
  276. package/internal/stores/hybrid_viewer/{filters.js → filters.ts} +10 -13
  277. package/internal/stores/hybrid_viewer/highlight.ts +183 -0
  278. package/internal/stores/hybrid_viewer/{ruler.js → ruler.ts} +50 -22
  279. package/internal/stores/hybrid_viewer/scene.ts +125 -0
  280. package/internal/stores/hybrid_viewer/viewport.ts +177 -0
  281. package/internal/stores/hybrid_viewer/vtk_types.ts +58 -0
  282. package/internal/utils/api_fetch.ts +133 -0
  283. package/internal/utils/upload_file.ts +115 -0
  284. package/internal/utils/viewer_call.ts +99 -0
  285. package/internal/utils/ws_client.ts +54 -0
  286. package/nuxt.config.ts +168 -0
  287. package/opengeodeweb_front_schemas.json +2 -2
  288. package/package.json +49 -13
  289. package/server/api/cloud/extensions/{run.post.js → run.post.ts} +16 -12
  290. package/server/api/local/app/project_folder_path.post.ts +33 -0
  291. package/server/api/local/app/run_back.post.ts +39 -0
  292. package/server/api/local/app/run_viewer.post.ts +39 -0
  293. package/server/api/local/extensions/{kill.post.js → kill.post.ts} +15 -8
  294. package/server/api/local/extensions/{run.post.js → run.post.ts} +17 -12
  295. package/server/api/local/extensions/upload.put.ts +71 -0
  296. package/server/api/microservice/app/{get_is_app_ready.get.js → get_is_app_ready.get.ts} +5 -5
  297. package/server/api/microservice/app/schemas/get_is_app_ready.json +1 -1
  298. package/server/api/microservice/app/set_app_base_url.post.ts +29 -0
  299. package/server/api/microservice/app/set_back_base_url.post.ts +26 -0
  300. package/server/api/microservice/app/set_is_app_ready.post.ts +29 -0
  301. package/server/api/microservice/app/set_viewer_base_url.post.ts +26 -0
  302. package/server/api/microservice/extensions/{download.post.js → download.post.ts} +13 -6
  303. package/server/api/serverless/run_cloud.post.ts +92 -0
  304. package/server/utils/{app_config.js → app_config.ts} +40 -18
  305. package/server/utils/{cleanup.js → cleanup.ts} +76 -29
  306. package/server/utils/{cloud.js → cloud.ts} +33 -17
  307. package/server/utils/{extension.js → extension.ts} +31 -4
  308. package/server/utils/{microservices.js → microservices.ts} +68 -27
  309. package/server/utils/{path.js → path.ts} +36 -17
  310. package/server/utils/{scripts.js → scripts.ts} +49 -33
  311. package/server/utils/{server.js → server.ts} +13 -6
  312. package/server/utils/server_config.ts +74 -0
  313. package/server/utils/stream.ts +6 -0
  314. package/server/utils/ws_client.ts +165 -0
  315. package/shared/{scripts.js → scripts.ts} +15 -10
  316. package/shared/utils/call_raw.ts +73 -0
  317. package/shared/utils/{call_schema.js → call_schema.ts} +15 -6
  318. package/shared/utils/fetch_raw.ts +125 -0
  319. package/shared/utils/{fetch_schema.js → fetch_schema.ts} +16 -7
  320. package/shared/utils/file.ts +22 -0
  321. package/shared/utils/{parse_boolean.js → parse_boolean.ts} +1 -1
  322. package/shared/utils/response_handlers/load.ts +109 -0
  323. package/shared/utils/types.ts +27 -0
  324. package/shared/utils/{validate_schema.js → validate_schema.ts} +3 -1
  325. package/.github/workflows/config.json +0 -5
  326. package/.github/workflows/deploy.yml +0 -15
  327. package/.github/workflows/manual_release.yml +0 -11
  328. package/.github/workflows/merge_request.yml +0 -9
  329. package/.github/workflows/pr_update.yml +0 -11
  330. package/.github/workflows/prepare_deploy.yml +0 -9
  331. package/.github/workflows/schedule.yml +0 -18
  332. package/.github/workflows/test.yml +0 -14
  333. package/.github/workflows/test_pr.yml +0 -12
  334. package/.oxlintrc.json +0 -150
  335. package/.releaserc +0 -11
  336. package/app/components/Viewer/ObjectTree/Views/ModelComponents.vue +0 -224
  337. package/app/composables/clipping_planes_widget.js +0 -249
  338. package/app/composables/global_attribute_style.js +0 -181
  339. package/app/composables/hover_highlight.js +0 -91
  340. package/app/composables/responsive_middle_truncate.js +0 -34
  341. package/app/composables/stepper_tree.js +0 -56
  342. package/app/composables/tree_filter.js +0 -138
  343. package/app/composables/use_adaptive_styles.js +0 -120
  344. package/app/composables/use_overlapping_picker.js +0 -169
  345. package/app/composables/use_quick_colormap.js +0 -32
  346. package/app/composables/virtual_tree.js +0 -191
  347. package/app/stores/app.js +0 -326
  348. package/app/stores/camera_manager.js +0 -57
  349. package/app/stores/data.js +0 -278
  350. package/app/stores/data_helpers/collections.js +0 -96
  351. package/app/stores/data_helpers/mesh.js +0 -122
  352. package/app/stores/data_style.js +0 -116
  353. package/app/stores/infra.js +0 -95
  354. package/app/stores/treeview.js +0 -290
  355. package/app/utils/attributes.js +0 -23
  356. package/app/utils/clipping_planes.js +0 -110
  357. package/app/utils/colormap.js +0 -64
  358. package/app/utils/default_styles/meshes.js +0 -191
  359. package/app/utils/status.js +0 -10
  360. package/commitlint.config.js +0 -20
  361. package/internal/database/database.js +0 -80
  362. package/internal/database/tables/camera_positions.js +0 -4
  363. package/internal/database/tables/data_style.js +0 -4
  364. package/internal/database/tables/model_component_datastyle.js +0 -4
  365. package/internal/database/tables/model_component_type_datastyle.js +0 -4
  366. package/internal/database/tables/model_components.js +0 -4
  367. package/internal/database/tables/model_components_relation.js +0 -4
  368. package/internal/stores/data_style/mesh/cells/cell.js +0 -196
  369. package/internal/stores/data_style/mesh/cells/common.js +0 -39
  370. package/internal/stores/data_style/mesh/cells/index.js +0 -81
  371. package/internal/stores/data_style/mesh/cells/vertex.js +0 -193
  372. package/internal/stores/data_style/mesh/cells/visibility.js +0 -35
  373. package/internal/stores/data_style/mesh/edges/common.js +0 -32
  374. package/internal/stores/data_style/mesh/edges/edge.js +0 -195
  375. package/internal/stores/data_style/mesh/edges/index.js +0 -81
  376. package/internal/stores/data_style/mesh/edges/vertex.js +0 -196
  377. package/internal/stores/data_style/mesh/edges/visibility.js +0 -34
  378. package/internal/stores/data_style/mesh/edges/width.js +0 -34
  379. package/internal/stores/data_style/mesh/points/common.js +0 -37
  380. package/internal/stores/data_style/mesh/points/index.js +0 -82
  381. package/internal/stores/data_style/mesh/points/size.js +0 -35
  382. package/internal/stores/data_style/mesh/points/vertex.js +0 -193
  383. package/internal/stores/data_style/mesh/points/visibility.js +0 -37
  384. package/internal/stores/data_style/mesh/polygons/common.js +0 -32
  385. package/internal/stores/data_style/mesh/polygons/index.js +0 -107
  386. package/internal/stores/data_style/mesh/polygons/polygon.js +0 -196
  387. package/internal/stores/data_style/mesh/polygons/vertex.js +0 -196
  388. package/internal/stores/data_style/mesh/polygons/visibility.js +0 -38
  389. package/internal/stores/data_style/mesh/polyhedra/common.js +0 -32
  390. package/internal/stores/data_style/mesh/polyhedra/index.js +0 -98
  391. package/internal/stores/data_style/mesh/polyhedra/polyhedron.js +0 -196
  392. package/internal/stores/data_style/mesh/polyhedra/vertex.js +0 -196
  393. package/internal/stores/data_style/mesh/polyhedra/visibility.js +0 -38
  394. package/internal/stores/data_style/model/blocks/common.js +0 -51
  395. package/internal/stores/data_style/model/blocks/polyhedron.js +0 -215
  396. package/internal/stores/data_style/model/blocks/vertex.js +0 -204
  397. package/internal/stores/data_style/model/blocks/visibility.js +0 -20
  398. package/internal/stores/data_style/model/color.js +0 -218
  399. package/internal/stores/data_style/model/common.js +0 -141
  400. package/internal/stores/data_style/model/corners/common.js +0 -51
  401. package/internal/stores/data_style/model/corners/vertex.js +0 -204
  402. package/internal/stores/data_style/model/corners/visibility.js +0 -20
  403. package/internal/stores/data_style/model/edges/common.js +0 -20
  404. package/internal/stores/data_style/model/edges/visibility.js +0 -38
  405. package/internal/stores/data_style/model/lines/common.js +0 -51
  406. package/internal/stores/data_style/model/lines/edge.js +0 -203
  407. package/internal/stores/data_style/model/lines/vertex.js +0 -204
  408. package/internal/stores/data_style/model/lines/visibility.js +0 -20
  409. package/internal/stores/data_style/model/points/common.js +0 -20
  410. package/internal/stores/data_style/model/points/index.js +0 -25
  411. package/internal/stores/data_style/model/points/size.js +0 -36
  412. package/internal/stores/data_style/model/points/visibility.js +0 -36
  413. package/internal/stores/data_style/model/selection.js +0 -89
  414. package/internal/stores/data_style/model/surfaces/common.js +0 -51
  415. package/internal/stores/data_style/model/surfaces/polygon.js +0 -215
  416. package/internal/stores/data_style/model/surfaces/vertex.js +0 -215
  417. package/internal/stores/data_style/model/surfaces/visibility.js +0 -20
  418. package/internal/stores/data_style/state.js +0 -197
  419. package/internal/stores/hybrid_viewer/brightness.js +0 -82
  420. package/internal/stores/hybrid_viewer/camera.js +0 -274
  421. package/internal/stores/hybrid_viewer/highlight.js +0 -170
  422. package/internal/stores/hybrid_viewer/scene.js +0 -136
  423. package/internal/stores/hybrid_viewer/viewport.js +0 -140
  424. package/internal/utils/api_fetch.js +0 -52
  425. package/internal/utils/upload_file.js +0 -57
  426. package/internal/utils/viewer_call.js +0 -49
  427. package/internal/utils/ws_client.js +0 -29
  428. package/nuxt.config.js +0 -106
  429. package/scripts/generate_geode_objects.js +0 -24
  430. package/server/api/local/app/project_folder_path.post.js +0 -29
  431. package/server/api/local/app/run_back.post.js +0 -33
  432. package/server/api/local/app/run_viewer.post.js +0 -33
  433. package/server/api/local/extensions/upload.put.js +0 -72
  434. package/server/api/microservice/app/set_app_base_url.post.js +0 -25
  435. package/server/api/microservice/app/set_back_base_url.post.js +0 -22
  436. package/server/api/microservice/app/set_is_app_ready.post.js +0 -25
  437. package/server/api/microservice/app/set_viewer_base_url.post.js +0 -22
  438. package/server/api/serverless/run_cloud.post.js +0 -44
  439. package/server/utils/server_config.js +0 -58
  440. package/server/utils/ws_client.js +0 -112
  441. package/shared/utils/call_raw.js +0 -46
  442. package/shared/utils/fetch_raw.js +0 -61
  443. package/shared/utils/file.js +0 -16
  444. package/shared/utils/response_handlers/load.js +0 -74
  445. package/tests/integration/data/uploads/test.og_brep +0 -0
  446. package/tests/integration/data/uploads/test.og_edc2d +0 -0
  447. package/tests/integration/data/uploads/test.og_edc3d +0 -0
  448. package/tests/integration/data/uploads/test.og_psf3d +0 -0
  449. package/tests/integration/data/uploads/test.og_rgd2d +0 -0
  450. package/tests/integration/data/uploads/test.og_rgd3d +0 -0
  451. package/tests/integration/data/uploads/test.vtu +0 -22
  452. package/tests/integration/setup.js +0 -92
  453. package/tests/integration/stores/data_style/mesh/cells.nuxt.test.js +0 -343
  454. package/tests/integration/stores/data_style/mesh/edges.nuxt.test.js +0 -254
  455. package/tests/integration/stores/data_style/mesh/index.nuxt.test.js +0 -62
  456. package/tests/integration/stores/data_style/mesh/points.nuxt.test.js +0 -201
  457. package/tests/integration/stores/data_style/mesh/polygons.nuxt.test.js +0 -260
  458. package/tests/integration/stores/data_style/mesh/polyhedra.nuxt.test.js +0 -267
  459. package/tests/integration/stores/data_style/model/blocks.nuxt.test.js +0 -397
  460. package/tests/integration/stores/data_style/model/corners.nuxt.test.js +0 -264
  461. package/tests/integration/stores/data_style/model/edges.nuxt.test.js +0 -71
  462. package/tests/integration/stores/data_style/model/index.nuxt.test.js +0 -92
  463. package/tests/integration/stores/data_style/model/lines.nuxt.test.js +0 -379
  464. package/tests/integration/stores/data_style/model/points.nuxt.test.js +0 -95
  465. package/tests/integration/stores/data_style/model/surfaces.nuxt.test.js +0 -574
  466. package/tests/integration/stores/viewer.nuxt.test.js +0 -69
  467. package/tests/setup_indexeddb.js +0 -4
  468. package/tests/unit/components/CrsSelector.nuxt.test.js +0 -55
  469. package/tests/unit/components/DragAndDrop.nuxt.test.js +0 -89
  470. package/tests/unit/components/ExtensionSelector.nuxt.test.js +0 -65
  471. package/tests/unit/components/FeedBack/ErrorsBanner.nuxt.test.js +0 -41
  472. package/tests/unit/components/FeedBack/Snackers.nuxt.test.js +0 -49
  473. package/tests/unit/components/FileSelector.nuxt.test.js +0 -124
  474. package/tests/unit/components/FileUploader.nuxt.test.js +0 -69
  475. package/tests/unit/components/MissingFilesSelector.nuxt.test.js +0 -77
  476. package/tests/unit/components/ObjectSelector.nuxt.test.js +0 -118
  477. package/tests/unit/components/PackagesVersions.nuxt.test.js +0 -42
  478. package/tests/unit/components/Step.nuxt.test.js +0 -51
  479. package/tests/unit/components/Stepper.nuxt.test.js +0 -41
  480. package/tests/unit/components/ToolPanel.nuxt.test.js +0 -66
  481. package/tests/unit/composables/api_fetch.nuxt.test.js +0 -75
  482. package/tests/unit/composables/project_manager.nuxt.test.js +0 -299
  483. package/tests/unit/composables/run_function_when_microservices_connected.nuxt.test.js +0 -57
  484. package/tests/unit/composables/upload_file.nuxt.test.js +0 -45
  485. package/tests/unit/composables/virtual_tree.nuxt.test.js +0 -63
  486. package/tests/unit/plugins/project_load.nuxt.test.js +0 -98
  487. package/tests/unit/stores/app.nuxt.test.js +0 -189
  488. package/tests/unit/stores/back.nuxt.test.js +0 -147
  489. package/tests/unit/stores/cloud.nuxt.test.js +0 -90
  490. package/tests/unit/stores/data.nuxt.test.js +0 -162
  491. package/tests/unit/stores/feedback.nuxt.test.js +0 -90
  492. package/tests/unit/stores/infra.nuxt.test.js +0 -313
  493. package/tests/unit/stores/treeview.nuxt.test.js +0 -63
  494. package/tests/unit/stores/viewer.nuxt.test.js +0 -161
  495. package/tests/unit/utils/validate_schema.nuxt.test.js +0 -38
  496. package/tests/utils.js +0 -20
  497. package/tests/vitest.config.js +0 -67
  498. /package/server/api/local/app/{kill.post.js → kill.post.ts} +0 -0
  499. /package/shared/{app_mode.js → app_mode.ts} +0 -0
@@ -2,18 +2,50 @@ import back_schemas from "@geode/opengeodeweb-back/opengeodeweb_back_schemas.jso
2
2
  import fileDownload from "js-file-download";
3
3
  import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json";
4
4
 
5
+ import { type DataStyleSnapshot, useDataStyleStore } from "@ogw_front/stores/data_style";
6
+ import { type NewDataItem, useDataStore } from "@ogw_front/stores/data";
7
+ import { type TreeviewSnapshot, useTreeviewStore } from "@ogw_front/stores/treeview";
8
+ import type { CameraSnapshot } from "@ogw_internal/stores/hybrid_viewer/camera";
9
+ import type { ModelComponentRecord } from "@ogw_front/stores/data_helpers/mesh.js";
10
+ import type { ModelComponentRelationRecord } from "@ogw_front/stores/data.js";
5
11
  import { fetchRaw } from "@ogw_shared/utils/fetch_raw";
6
12
  import { importWorkflowFromSnapshot } from "@ogw_front/utils/import_workflow";
7
13
  import { useAppStore } from "@ogw_front/stores/app";
8
14
  import { useBackStore } from "@ogw_front/stores/back";
9
- import { useDataStore } from "@ogw_front/stores/data";
10
- import { useDataStyleStore } from "@ogw_front/stores/data_style";
11
15
  import { useFeedbackStore } from "@ogw_front/stores/feedback";
12
16
  import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
13
- import { useTreeviewStore } from "@ogw_front/stores/treeview";
14
17
  import { useViewerStore } from "@ogw_front/stores/viewer";
15
18
 
16
- async function exportProject() {
19
+ interface ProjectDataSnapshot {
20
+ items: NewDataItem[];
21
+ modelComponents: ModelComponentRecord[];
22
+ modelComponentsRelations: ModelComponentRelationRecord[];
23
+ }
24
+
25
+ interface ProjectSnapshot {
26
+ treeview?: TreeviewSnapshot;
27
+ data?: ProjectDataSnapshot;
28
+ hybridViewer?: CameraSnapshot;
29
+ dataStyle?: DataStyleSnapshot;
30
+ }
31
+
32
+ // The backend response is an untyped network payload; this is the one place its shape is asserted.
33
+ function isImportSnapshotResponse(value: unknown): value is { snapshot?: ProjectSnapshot } {
34
+ return typeof value === "object" && value !== null;
35
+ }
36
+
37
+ function isFileDownloadData(
38
+ value: unknown,
39
+ ): value is string | ArrayBuffer | ArrayBufferView | Blob {
40
+ return (
41
+ typeof value === "string" ||
42
+ value instanceof ArrayBuffer ||
43
+ ArrayBuffer.isView(value) ||
44
+ value instanceof Blob
45
+ );
46
+ }
47
+
48
+ async function exportProject(): Promise<{ result: unknown }> {
17
49
  console.log("[export triggered]");
18
50
  const appStore = useAppStore();
19
51
  const backStore = useBackStore();
@@ -29,12 +61,39 @@ async function exportProject() {
29
61
  baseURL: backStore.base_url,
30
62
  });
31
63
 
64
+ if (!isFileDownloadData(result)) {
65
+ throw new Error("Unexpected export_project response type");
66
+ }
32
67
  fileDownload(result, defaultName);
33
68
  feedbackStore.add_success("Project exported successfully");
34
69
  return { result };
35
70
  }
36
71
 
37
- async function importProject(file) {
72
+ async function releaseViewerDatabase(
73
+ client: ReturnType<typeof useViewerStore>["client"],
74
+ ): Promise<void> {
75
+ if (
76
+ client !== undefined &&
77
+ client.getConnection !== undefined &&
78
+ client.getConnection().getSession !== undefined
79
+ ) {
80
+ await client.getConnection().getSession().call("opengeodeweb_viewer.release_database", [{}]);
81
+ }
82
+ }
83
+
84
+ async function importProjectToViewer(
85
+ client: ReturnType<typeof useViewerStore>["client"],
86
+ ): Promise<void> {
87
+ if (
88
+ client !== undefined &&
89
+ client.getConnection !== undefined &&
90
+ client.getConnection().getSession !== undefined
91
+ ) {
92
+ await client.getConnection().getSession().call("opengeodeweb_viewer.import_project", [{}]);
93
+ }
94
+ }
95
+
96
+ async function importProject(file: File): Promise<void> {
38
97
  const backStore = useBackStore();
39
98
  const dataStyleStore = useDataStyleStore();
40
99
  const viewerStore = useViewerStore();
@@ -44,21 +103,18 @@ async function importProject(file) {
44
103
 
45
104
  await viewerStore.ws_connect();
46
105
 
47
- const { client } = viewerStore;
48
- if (client && client.getConnection && client.getConnection().getSession) {
49
- await client.getConnection().getSession().call("opengeodeweb_viewer.release_database", [{}]);
50
- }
106
+ await releaseViewerDatabase(viewerStore.client);
51
107
  const resetVisualizationSchema = viewer_schemas.opengeodeweb_viewer.viewer.reset_visualization;
52
108
  const timeout = undefined;
53
109
  await viewerStore.request({ schema: resetVisualizationSchema, timeout });
54
110
 
55
111
  treeviewStore.clear();
56
- dataStore.clear();
112
+ await dataStore.clear();
57
113
  hybridViewerStore.clear();
58
114
 
59
115
  const importProjectSchema = back_schemas.opengeodeweb_back.import_project;
60
116
  const form = new FormData();
61
- const originalFileName = file && file.name ? file.name : "project.vease";
117
+ const originalFileName = file.name.length > 0 ? file.name : "project.vease";
62
118
  if (!originalFileName.toLowerCase().endsWith(".vease")) {
63
119
  throw new Error("Uploaded file must be a .vease");
64
120
  }
@@ -70,23 +126,24 @@ async function importProject(file) {
70
126
  method: importProjectSchema.methods[0],
71
127
  baseURL: backStore.base_url,
72
128
  });
73
- const snapshot = result && result.snapshot ? result.snapshot : {};
129
+ const snapshot = (isImportSnapshotResponse(result) ? result.snapshot : undefined) ?? {};
74
130
 
75
131
  treeviewStore.isImporting = true;
76
132
 
77
- const { client: client2 } = viewerStore;
78
- if (client2 && client2.getConnection && client2.getConnection().getSession) {
79
- await client2.getConnection().getSession().call("opengeodeweb_viewer.import_project", [{}]);
80
- }
133
+ await importProjectToViewer(viewerStore.client);
81
134
 
82
- await treeviewStore.importStores(snapshot.treeview);
83
- await dataStore.importStores(snapshot.data);
135
+ treeviewStore.importStores(snapshot.treeview);
136
+ if (snapshot.data !== undefined) {
137
+ await dataStore.importStores(snapshot.data);
138
+ }
84
139
  await hybridViewerStore.initHybridViewer();
85
140
 
86
- const items = snapshot?.data?.items || [];
141
+ const items = snapshot.data?.items ?? [];
87
142
  await importWorkflowFromSnapshot(items);
88
143
  await hybridViewerStore.importStores(snapshot.hybridViewer);
89
- await dataStyleStore.importStores(snapshot.dataStyle);
144
+ if (snapshot.dataStyle !== undefined) {
145
+ await dataStyleStore.importStores(snapshot.dataStyle);
146
+ }
90
147
  await dataStyleStore.applyAllStylesFromState();
91
148
 
92
149
  treeviewStore.finalizeImportSelection();
@@ -0,0 +1,48 @@
1
+ import { middleTruncate } from "@ogw_front/utils/string";
2
+
3
+ const UUID_END_CHARS = 12;
4
+ const ELLIPSIS_LENGTH = 3;
5
+ const MIN_START_CHARS = 4;
6
+ const DEFAULT_ESTIMATED_CHAR_WIDTH = 8.5;
7
+
8
+ interface ResponsiveMiddleTruncateOptions {
9
+ readonly estimatedCharWidth?: number;
10
+ readonly uuidEndChars?: number;
11
+ readonly ellipsisLength?: number;
12
+ readonly minStartChars?: number;
13
+ }
14
+
15
+ // Same shape as Vue's MaybeRefOrGetter<T>, kept as a local alias for readability at call sites.
16
+ type ReadonlyMaybeRefOrGetter<Value> = Value | Ref<Value> | (() => Value);
17
+
18
+ export function useResponsiveMiddleTruncate(
19
+ textRef: ReadonlyMaybeRefOrGetter<string | undefined | null>,
20
+ containerWidthRef: ReadonlyMaybeRefOrGetter<number | undefined>,
21
+ options: ResponsiveMiddleTruncateOptions = {},
22
+ ): ComputedRef<string> {
23
+ const {
24
+ estimatedCharWidth = DEFAULT_ESTIMATED_CHAR_WIDTH,
25
+ uuidEndChars = UUID_END_CHARS,
26
+ ellipsisLength = ELLIPSIS_LENGTH,
27
+ minStartChars = MIN_START_CHARS,
28
+ } = options;
29
+
30
+ return computed(() => {
31
+ const text = toValue(textRef);
32
+ if (text === undefined || text === null || text === "") {
33
+ return "";
34
+ }
35
+
36
+ const width = toValue(containerWidthRef) ?? 0;
37
+ const maxChars = Math.floor(width / estimatedCharWidth);
38
+
39
+ if (maxChars <= 0 || text.length <= maxChars) {
40
+ return text;
41
+ }
42
+
43
+ const endChars = Math.min(uuidEndChars, Math.floor(maxChars / ellipsisLength));
44
+ const startChars = Math.max(minStartChars, maxChars - endChars - ellipsisLength);
45
+
46
+ return middleTruncate(text, maxChars, startChars, endChars) ?? "";
47
+ });
48
+ }
@@ -1,6 +1,6 @@
1
1
  import { useInfraStore } from "@ogw_front/stores/infra";
2
2
 
3
- export function runFunctionWhenMicroservicesConnected(functionToRun) {
3
+ export function runFunctionWhenMicroservicesConnected(functionToRun: () => void): void {
4
4
  const infraStore = useInfraStore();
5
5
  const { microservices_connected } = storeToRefs(infraStore);
6
6
  console.log("inside microservices_connected", microservices_connected.value);
@@ -0,0 +1,79 @@
1
+ interface StepperTreeApi {
2
+ state: Record<string, unknown>;
3
+ update_values: (keys_values_object: Record<string, unknown>) => void;
4
+ increment_step: () => void;
5
+ decrement_step: () => void;
6
+ reset_values: () => void;
7
+ }
8
+
9
+ function isUnknownArray(value: unknown): value is unknown[] {
10
+ return Array.isArray(value);
11
+ }
12
+
13
+ function get_current_step_index(state: Record<string, unknown>): number {
14
+ const value = state.current_step_index;
15
+ return typeof value === "number" ? value : 0;
16
+ }
17
+
18
+ function build_initial_state_unref(
19
+ initial_state: Record<string, unknown>,
20
+ ): Record<string, unknown> {
21
+ const initial_state_unref: Record<string, unknown> = {};
22
+ for (const [key, value] of Object.entries(initial_state)) {
23
+ const unref_val: unknown = unref(value);
24
+ initial_state_unref[key] = isUnknownArray(unref_val) ? [...unref_val] : unref_val;
25
+ }
26
+ return initial_state_unref;
27
+ }
28
+
29
+ export function useStepperTree(
30
+ steps: readonly unknown[],
31
+ initial_state: Record<string, unknown> = {},
32
+ ): StepperTreeApi {
33
+ const initial_state_unref = build_initial_state_unref(initial_state);
34
+ const state = reactive<Record<string, unknown>>({
35
+ current_step_index: 0,
36
+ navigating_back: false,
37
+ steps,
38
+ ...initial_state,
39
+ });
40
+
41
+ watch(
42
+ () => get_current_step_index(state),
43
+ (newVal, oldVal) => {
44
+ if (newVal < oldVal) {
45
+ state.navigating_back = true;
46
+ }
47
+ },
48
+ );
49
+
50
+ function update_values(keys_values_object: Record<string, unknown>): void {
51
+ for (const [key, value] of Object.entries(keys_values_object)) {
52
+ state[key] = value;
53
+ }
54
+ }
55
+
56
+ function increment_step(): void {
57
+ state.current_step_index = get_current_step_index(state) + 1;
58
+ }
59
+
60
+ function decrement_step(): void {
61
+ state.current_step_index = get_current_step_index(state) - 1;
62
+ }
63
+
64
+ function reset_values(): void {
65
+ state.current_step_index = 0;
66
+ state.navigating_back = false;
67
+ for (const [key, initial_val] of Object.entries(initial_state_unref)) {
68
+ state[key] = isUnknownArray(initial_val) ? [...initial_val] : initial_val;
69
+ }
70
+ }
71
+
72
+ return {
73
+ state,
74
+ update_values,
75
+ increment_step,
76
+ decrement_step,
77
+ reset_values,
78
+ };
79
+ }
@@ -0,0 +1,194 @@
1
+ import type { Ref } from "vue";
2
+
3
+ // Same shape as Vue's MaybeRefOrGetter<T>, kept as a local alias for readability at call sites.
4
+ type ReadonlyMaybeRefOrGetter<Value> = Value | Ref<Value> | (() => Value);
5
+
6
+ // This composable filters/sorts different flavors of "category with children" trees (treeview groups, model component/collection groups, ...); this shape captures just the fields it reads/writes, generically, across all of them.
7
+ interface FilterableItem {
8
+ readonly id: unknown;
9
+ readonly title?: string;
10
+ readonly children?: readonly FilterableItem[];
11
+ }
12
+
13
+ interface FilterContext {
14
+ readonly raw?: FilterableItem;
15
+ }
16
+
17
+ interface TreeFilterOptions {
18
+ readonly recursiveSort?: boolean;
19
+ readonly defaultSort?: string;
20
+ readonly defaultFilters?: Record<string, boolean>;
21
+ }
22
+
23
+ interface UseTreeFilterReturn {
24
+ search: Ref<string>;
25
+ sortType: Ref<string>;
26
+ filterOptions: Ref<Record<string, boolean>>;
27
+ processedItems: ComputedRef<FilterableItem[]>;
28
+ availableFilterOptions: ComputedRef<string[]>;
29
+ toggleSort: () => void;
30
+ customFilter: typeof customFilter;
31
+ applySearchFilter: (
32
+ newSelection: readonly unknown[],
33
+ previousSelection?: readonly unknown[],
34
+ ) => unknown[];
35
+ }
36
+
37
+ function customFilter(
38
+ value: unknown,
39
+ searchQuery: string | undefined,
40
+ item: FilterContext,
41
+ ): boolean {
42
+ if (searchQuery === undefined || searchQuery === "") {
43
+ return true;
44
+ }
45
+ if (!item.raw) {
46
+ return false;
47
+ }
48
+ const query = searchQuery.toLowerCase();
49
+ const { title = "", id = value } = item.raw;
50
+ return [title, id].some((field) => String(field).toLowerCase().includes(query));
51
+ }
52
+
53
+ // Extracted so we never call String() directly on a value typed as `unknown`/`any`.
54
+ // The `id` field can be anything at runtime, so only stringify primitives that have a sane toString.
55
+ // Anything else falls back to "" instead of risking "[object Object]".
56
+ function toSortKey(item: FilterableItem, field: "title" | "id"): string {
57
+ const raw = item[field] ?? item.id ?? "";
58
+ if (typeof raw === "string" || typeof raw === "number" || typeof raw === "boolean") {
59
+ return String(raw);
60
+ }
61
+ return "";
62
+ }
63
+
64
+ function sortAndFormatItems(
65
+ itemList: readonly FilterableItem[] | undefined | null,
66
+ sortType: string,
67
+ options: TreeFilterOptions = {},
68
+ ): FilterableItem[] {
69
+ if (!itemList) {
70
+ return [];
71
+ }
72
+ const field: "title" | "id" = sortType === "name" ? "title" : "id";
73
+ const localeOptions: Intl.CollatorOptions = { numeric: true, sensitivity: "base" };
74
+
75
+ // Copy into a plain mutable array up front: chaining .filter()/.toSorted() straight off the
76
+ // Readonly-typed parameter (previously combined with an Array.isArray guard here) has been
77
+ // Observed to make oxlint's type-aware analysis silently widen the result to `any[]`.
78
+ const items: FilterableItem[] = [...itemList];
79
+ const sorted = items
80
+ .filter((item) => item !== null && item !== undefined)
81
+ .toSorted((itemA, itemB) =>
82
+ toSortKey(itemA, field).localeCompare(toSortKey(itemB, field), undefined, localeOptions),
83
+ );
84
+
85
+ if (options.recursiveSort === true) {
86
+ return sorted.map((item) => {
87
+ if (item.children && item.children.length > 0) {
88
+ return {
89
+ ...item,
90
+ children: sortAndFormatItems(item.children, sortType, options),
91
+ };
92
+ }
93
+ return item;
94
+ });
95
+ }
96
+ return sorted;
97
+ }
98
+
99
+ function useTreeFilter(
100
+ itemsIn: ReadonlyMaybeRefOrGetter<readonly FilterableItem[]>,
101
+ options: TreeFilterOptions = {},
102
+ ): UseTreeFilterReturn {
103
+ const rawItems = typeof itemsIn === "function" ? computed(itemsIn) : toRef(itemsIn);
104
+ const search = ref("");
105
+ const sortType = ref(options.defaultSort ?? "name");
106
+ const filterOptions = ref<Record<string, boolean>>({ ...options.defaultFilters });
107
+
108
+ const availableFilterOptions = computed(() =>
109
+ rawItems.value.map((category) => String(category.title ?? category.id)),
110
+ );
111
+
112
+ watch(
113
+ availableFilterOptions,
114
+ (newOptions: readonly string[]) => {
115
+ for (const option of newOptions) {
116
+ filterOptions.value[option] ??= true;
117
+ }
118
+ },
119
+ { immediate: true },
120
+ );
121
+
122
+ const processedItems = computed(() => {
123
+ const filteredByCategory = rawItems.value.filter((category) => {
124
+ const key = String(category.title ?? category.id);
125
+ return filterOptions.value[key] !== false;
126
+ });
127
+
128
+ const sorted = sortAndFormatItems(filteredByCategory, sortType.value, options);
129
+
130
+ if (!search.value) {
131
+ return sorted;
132
+ }
133
+
134
+ const result: FilterableItem[] = [];
135
+ for (const category of sorted) {
136
+ const children = (category.children ?? []).filter((child) =>
137
+ customFilter(child.id, search.value, { raw: child }),
138
+ );
139
+ if (children.length > 0 || customFilter(category.id, search.value, { raw: category })) {
140
+ result.push({ ...category, children });
141
+ }
142
+ }
143
+ return result;
144
+ });
145
+
146
+ function toggleSort(): void {
147
+ sortType.value = sortType.value === "name" ? "id" : "name";
148
+ }
149
+
150
+ const allItems = computed(() => {
151
+ const map = new Map<unknown, FilterableItem>();
152
+ function traverse(items: readonly FilterableItem[]): void {
153
+ for (const item of items) {
154
+ map.set(item.id, item);
155
+ if (item.children) {
156
+ traverse(item.children);
157
+ }
158
+ }
159
+ }
160
+ traverse(rawItems.value);
161
+ return map;
162
+ });
163
+
164
+ function applySearchFilter(
165
+ newSelection: readonly unknown[],
166
+ previousSelection: readonly unknown[] = [],
167
+ ): unknown[] {
168
+ if (!search.value) {
169
+ return [...newSelection];
170
+ }
171
+ const allItemsMap = allItems.value;
172
+ function matches(id: unknown): boolean {
173
+ const item = allItemsMap.get(id);
174
+ return Boolean(item && customFilter(id, search.value, { raw: item }));
175
+ }
176
+ const hidden = previousSelection.filter((id) => !matches(id));
177
+ const visible = newSelection.filter((id) => matches(id));
178
+ return [...new Set([...hidden, ...visible])];
179
+ }
180
+
181
+ return {
182
+ search,
183
+ sortType,
184
+ filterOptions,
185
+ processedItems,
186
+ availableFilterOptions,
187
+ toggleSort,
188
+ customFilter,
189
+ applySearchFilter,
190
+ };
191
+ }
192
+
193
+ export { customFilter, useTreeFilter, sortAndFormatItems };
194
+ export type { FilterableItem };
@@ -1,4 +1,36 @@
1
- function getBaseIndex(currentIndex, lastIndex, bounds, key) {
1
+ import type { DisplayItem, EmitFn } from "./virtual_tree";
2
+
3
+ interface VisibleBounds {
4
+ firstVisible: number;
5
+ lastVisible: number;
6
+ }
7
+
8
+ interface ScrollInfo {
9
+ scrollTop: number;
10
+ containerHeight: number;
11
+ itemHeight: number;
12
+ }
13
+
14
+ type ReadonlyDisplayItem = Omit<DisplayItem, "raw"> & {
15
+ readonly raw: Record<string, unknown>;
16
+ };
17
+
18
+ interface KeyboardEventLike {
19
+ readonly key: string;
20
+ preventDefault: () => void;
21
+ }
22
+
23
+ interface UseTreeKeyboardNavReturn {
24
+ focusedIndex: Ref<number>;
25
+ handleKeyDown: (event: KeyboardEventLike) => void;
26
+ }
27
+
28
+ function getBaseIndex(
29
+ currentIndex: number,
30
+ lastIndex: number,
31
+ bounds: VisibleBounds | undefined,
32
+ key: string,
33
+ ): number {
2
34
  if (currentIndex < 0 || currentIndex > lastIndex) {
3
35
  if (bounds) {
4
36
  return key === "End" ? lastIndex : bounds.firstVisible;
@@ -17,26 +49,27 @@ function getBaseIndex(currentIndex, lastIndex, bounds, key) {
17
49
  }
18
50
 
19
51
  export function useTreeKeyboardNav(
20
- displayItems,
21
- emit,
22
- scrollToIndex,
23
- toggleOpen,
24
- handleItemClick,
25
- getScrollInfo,
26
- externalFocusedIndex,
27
- ) {
28
- const focusedIndex = externalFocusedIndex || ref(-1);
29
-
30
- function findParentIndex(item, currentIndex) {
52
+ displayItems: Ref<readonly ReadonlyDisplayItem[]>,
53
+ emit: EmitFn,
54
+ scrollToIndex: (index: number) => void,
55
+ toggleOpen: (raw: Record<string, unknown>) => void,
56
+ handleItemClick: (item: ReadonlyDisplayItem, index: number) => void,
57
+ getScrollInfo: (() => ScrollInfo | undefined) | undefined,
58
+ externalFocusedIndex: Ref<number> | undefined,
59
+ ): UseTreeKeyboardNavReturn {
60
+ const focusedIndex = externalFocusedIndex ?? ref(-1);
61
+
62
+ function findParentIndex(item: ReadonlyDisplayItem, currentIndex: number): number {
31
63
  for (let index = currentIndex - 1; index >= 0; index -= 1) {
32
- if (displayItems.value[index] && displayItems.value[index].depth < item.depth) {
64
+ const candidate = displayItems.value[index];
65
+ if (candidate && candidate.depth < item.depth) {
33
66
  return index;
34
67
  }
35
68
  }
36
69
  return -1;
37
70
  }
38
71
 
39
- function getVisibleBounds() {
72
+ function getVisibleBounds(): VisibleBounds | undefined {
40
73
  if (!getScrollInfo) {
41
74
  return undefined;
42
75
  }
@@ -51,7 +84,11 @@ export function useTreeKeyboardNav(
51
84
  return { firstVisible, lastVisible };
52
85
  }
53
86
 
54
- function handleExpandOrNext(item, currentIndex, lastIndex) {
87
+ function handleExpandOrNext(
88
+ item: ReadonlyDisplayItem | undefined,
89
+ currentIndex: number,
90
+ lastIndex: number,
91
+ ): number {
55
92
  if (item && !item.isLeaf && !item.isOpen) {
56
93
  toggleOpen(item.raw);
57
94
  return currentIndex;
@@ -59,7 +96,10 @@ export function useTreeKeyboardNav(
59
96
  return Math.min(currentIndex + 1, lastIndex);
60
97
  }
61
98
 
62
- function handleCollapseOrParent(item, currentIndex) {
99
+ function handleCollapseOrParent(
100
+ item: ReadonlyDisplayItem | undefined,
101
+ currentIndex: number,
102
+ ): number {
63
103
  if (item && !item.isLeaf && item.isOpen) {
64
104
  toggleOpen(item.raw);
65
105
  return currentIndex;
@@ -71,7 +111,7 @@ export function useTreeKeyboardNav(
71
111
  return currentIndex;
72
112
  }
73
113
 
74
- function getNextIndex(key) {
114
+ function getNextIndex(key: string): number {
75
115
  const total = displayItems.value.length;
76
116
  if (total === 0) {
77
117
  return -1;
@@ -103,7 +143,7 @@ export function useTreeKeyboardNav(
103
143
  return currentIndex;
104
144
  }
105
145
 
106
- function handleKeyDown(event) {
146
+ function handleKeyDown(event: KeyboardEventLike): void {
107
147
  if (displayItems.value.length === 0) {
108
148
  return;
109
149
  }
@@ -111,7 +151,7 @@ export function useTreeKeyboardNav(
111
151
  if (["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "Home", "End"].includes(event.key)) {
112
152
  event.preventDefault();
113
153
  const prevIndex = focusedIndex.value;
114
- focusedIndex.value = getNextIndex(event.key);
154
+ (focusedIndex as Ref<number>).value = getNextIndex(event.key);
115
155
 
116
156
  if (focusedIndex.value !== prevIndex) {
117
157
  if (prevIndex >= 0 && prevIndex < displayItems.value.length) {
@@ -129,7 +169,9 @@ export function useTreeKeyboardNav(
129
169
  event.preventDefault();
130
170
  if (focusedIndex.value >= 0 && focusedIndex.value < displayItems.value.length) {
131
171
  const item = displayItems.value[focusedIndex.value];
132
- handleItemClick(item, focusedIndex.value);
172
+ if (item) {
173
+ handleItemClick(item, focusedIndex.value);
174
+ }
133
175
  }
134
176
  }
135
177
  }