@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.
- package/.build/opengeodeweb_front_schemas.js +175 -0
- package/.build/server/utils/app_config.js +57 -0
- package/.build/server/utils/cleanup.js +135 -0
- package/.build/server/utils/cloud.js +156 -0
- package/.build/server/utils/microservices.js +153 -0
- package/.build/server/utils/path.js +108 -0
- package/.build/server/utils/scripts.js +134 -0
- package/.build/server/utils/server.js +44 -0
- package/.build/server/utils/server_config.js +51 -0
- package/.build/server/utils/stream.js +6 -0
- package/.build/server/utils/ws_client.js +100 -0
- package/.build/shared/app_mode.js +8 -0
- package/.build/shared/scripts.js +49 -0
- package/.build/shared/utils/call_raw.js +31 -0
- package/.build/shared/utils/call_schema.js +28 -0
- package/.build/shared/utils/fetch_raw.js +52 -0
- package/.build/shared/utils/fetch_schema.js +32 -0
- package/.build/shared/utils/file.js +14 -0
- package/.build/shared/utils/parse_boolean.js +23 -0
- package/.build/shared/utils/response_handlers/load.js +50 -0
- package/.build/shared/utils/types.js +1 -0
- package/.build/shared/utils/validate_schema.js +17 -0
- package/README.md +8 -0
- package/app/assets/{geode_objects.js → geode_objects.ts} +8 -1
- package/app/components/ActionButton.vue +28 -12
- package/app/components/Basic/Slider.vue +2 -2
- package/app/components/Basic/Switch.vue +2 -2
- package/app/components/CameraManager/List.vue +11 -11
- package/app/components/CameraManager/Saver.vue +8 -4
- package/app/components/CameraManager.vue +24 -12
- package/app/components/CameraOrientation.vue +31 -17
- package/app/components/ClippingPlaneCard.vue +13 -12
- package/app/components/ClippingPlanes.vue +31 -21
- package/app/components/CrsSelector.vue +26 -18
- package/app/components/DeleteDialog.vue +18 -16
- package/app/components/DragAndDrop.vue +55 -37
- package/app/components/DragAndDropInternal/DragAndDropInline.vue +31 -16
- package/app/components/DragAndDropInternal/DragAndDropOverlay.vue +32 -19
- package/app/components/ExtensionSelector.vue +34 -18
- package/app/components/FeedBack/ErrorBanner.vue +4 -3
- package/app/components/FeedBack/Snackers.vue +6 -5
- package/app/components/FetchingData.vue +8 -12
- package/app/components/FileSelector.vue +27 -17
- package/app/components/FileUploader.vue +51 -30
- package/app/components/GlassCard.vue +17 -13
- package/app/components/HybridRenderingView.vue +25 -12
- package/app/components/HybridViewerTooltip.vue +28 -26
- package/app/components/InfraConnected.vue +1 -1
- package/app/components/Launcher.vue +12 -10
- package/app/components/Loading/EcoMessages.vue +24 -13
- package/app/components/Loading/Header.vue +6 -7
- package/app/components/Loading/Progress.vue +6 -7
- package/app/components/Loading.vue +10 -14
- package/app/components/MissingFilesSelector.vue +35 -19
- package/app/components/ObjectSelector.vue +37 -21
- package/app/components/PackagesVersions.vue +16 -8
- package/app/components/Recaptcha.vue +17 -23
- package/app/components/RemoteRenderingView.vue +21 -15
- package/app/components/Ruler.vue +11 -9
- package/app/components/Screenshot.vue +25 -19
- package/app/components/SearchBar.vue +12 -6
- package/app/components/ShrinkFilter.vue +19 -14
- package/app/components/Step.vue +32 -12
- package/app/components/Stepper.vue +19 -7
- package/app/components/ToolPanel.vue +29 -13
- package/app/components/ViewToolbar.vue +53 -44
- package/app/components/Viewer/ContextMenu/CenterButton.vue +16 -9
- package/app/components/Viewer/ContextMenu/CircularItems.vue +13 -10
- package/app/components/Viewer/ContextMenu/ContextMenu.vue +40 -32
- package/app/components/Viewer/ContextMenu/ContextMenuItem.vue +31 -17
- package/app/components/Viewer/ContextMenu/InfoCard.vue +38 -22
- package/app/components/Viewer/EdgedCurve/PointsOptions.vue +8 -5
- package/app/components/Viewer/EdgedCurve/SpecificEdgesOptions.vue +67 -48
- package/app/components/Viewer/Generic/Mesh/CellsOptions.vue +74 -50
- package/app/components/Viewer/Generic/Mesh/EdgesOptions.vue +69 -50
- package/app/components/Viewer/Generic/Mesh/PointsOptions.vue +47 -35
- package/app/components/Viewer/Generic/Mesh/PolygonsOptions.vue +91 -51
- package/app/components/Viewer/Generic/Mesh/PolyhedraOptions.vue +74 -49
- package/app/components/Viewer/Generic/Model/BlocksOptions.vue +115 -53
- package/app/components/Viewer/Generic/Model/CornersOptions.vue +75 -37
- package/app/components/Viewer/Generic/Model/EdgesOptions.vue +13 -9
- package/app/components/Viewer/Generic/Model/LinesOptions.vue +110 -61
- package/app/components/Viewer/Generic/Model/ModelStyleCard.vue +32 -21
- package/app/components/Viewer/Generic/Model/ModelStyleOptions.vue +9 -5
- package/app/components/Viewer/Generic/Model/PointsOptions.vue +19 -13
- package/app/components/Viewer/Generic/Model/SurfacesOptions.vue +119 -49
- package/app/components/Viewer/Grid/2D/CellsOptions.vue +8 -5
- package/app/components/Viewer/Grid/2D/EdgesOptions.vue +8 -5
- package/app/components/Viewer/Grid/2D/PointsOptions.vue +8 -5
- package/app/components/Viewer/Grid/3D/CellsOptions.vue +8 -5
- package/app/components/Viewer/Grid/3D/EdgesOptions.vue +8 -5
- package/app/components/Viewer/Grid/3D/FacetsOptions.vue +8 -5
- package/app/components/Viewer/Grid/3D/PointsOptions.vue +8 -5
- package/app/components/Viewer/ObjectTree/Base/CommonTreeView.vue +120 -76
- package/app/components/Viewer/ObjectTree/Base/Controls.vue +25 -10
- package/app/components/Viewer/ObjectTree/Base/ItemLabel.vue +42 -17
- package/app/components/Viewer/ObjectTree/Base/StickyHeader.vue +22 -9
- package/app/components/Viewer/ObjectTree/Base/TreeRow.vue +29 -14
- package/app/components/Viewer/ObjectTree/Box.vue +32 -15
- package/app/components/Viewer/ObjectTree/Layout.vue +55 -35
- package/app/components/Viewer/ObjectTree/Views/GlobalObjects.vue +63 -34
- package/app/components/Viewer/ObjectTree/Views/{ModelCollections.vue → ModelTree.vue} +101 -39
- package/app/components/Viewer/Options/AttributeColorBar.vue +14 -6
- package/app/components/Viewer/Options/AttributeRangeSelector.vue +8 -4
- package/app/components/Viewer/Options/AttributeSelector.vue +64 -33
- package/app/components/Viewer/Options/ColorMapList.vue +52 -24
- package/app/components/Viewer/Options/ColorMapPicker.vue +15 -11
- package/app/components/Viewer/Options/ColorPicker.vue +239 -50
- package/app/components/Viewer/Options/ColoringTypeSelector.vue +87 -67
- package/app/components/Viewer/Options/ColormapQuickPicker.vue +16 -12
- package/app/components/Viewer/Options/OptionsSection.vue +7 -5
- package/app/components/Viewer/Options/Sliders/Size.vue +3 -3
- package/app/components/Viewer/Options/Sliders/Slider.vue +9 -6
- package/app/components/Viewer/Options/Sliders/Width.vue +3 -3
- package/app/components/Viewer/Options/TextureItem.vue +29 -22
- package/app/components/Viewer/Options/TexturesSelector.vue +23 -12
- package/app/components/Viewer/Options/VisibilitySwitch.vue +3 -3
- package/app/components/Viewer/OverlappingObjectsPicker.vue +27 -12
- package/app/components/Viewer/PointSet/SpecificPointsOptions.vue +38 -26
- package/app/components/Viewer/Solid/EdgesOptions.vue +8 -5
- package/app/components/Viewer/Solid/PointsOptions.vue +8 -5
- package/app/components/Viewer/Solid/PolygonsOptions.vue +8 -5
- package/app/components/Viewer/Solid/SpecificPolyhedraOptions.vue +73 -48
- package/app/components/Viewer/Surface/EdgesOptions.vue +8 -5
- package/app/components/Viewer/Surface/PointsOptions.vue +8 -5
- package/app/components/Viewer/Surface/PolygonsOptions.vue +79 -49
- package/app/components/Viewer/Surface/Triangulated/TrianglesOptions.vue +8 -5
- package/app/components/Viewer/TetrahedralSolid/TetrahedraOptions.vue +8 -5
- package/app/components/Viewer/TetrahedralSolid/TrianglesOptions.vue +8 -5
- package/app/components/Viewer/Ui.vue +19 -14
- package/app/components/Wrapper.vue +16 -10
- package/app/components/ZScaling.vue +18 -10
- package/app/components/csv-preview/CsvPreviewer.vue +72 -50
- package/app/components/csv-preview/CsvSettings.vue +30 -50
- package/app/components/csv-preview/CsvTable.vue +34 -14
- package/app/composables/{batch_style.js → batch_style.ts} +9 -7
- package/app/composables/clipping_planes_widget.ts +204 -0
- package/app/composables/clipping_planes_widget_entries.ts +189 -0
- package/app/composables/copy_to_clipboard.ts +7 -0
- package/app/composables/global_attribute_style.ts +303 -0
- package/app/composables/hover_highlight.ts +127 -0
- package/app/composables/{model_collections.js → model_collections.ts} +28 -9
- package/app/composables/{model_components.js → model_components.ts} +28 -9
- package/app/composables/{project_manager.js → project_manager.ts} +77 -20
- package/app/composables/responsive_middle_truncate.ts +48 -0
- package/app/composables/{run_function_when_microservices_connected.js → run_function_when_microservices_connected.ts} +1 -1
- package/app/composables/stepper_tree.ts +79 -0
- package/app/composables/tree_filter.ts +194 -0
- package/app/composables/{tree_keyboard_nav.js → tree_keyboard_nav.ts} +62 -20
- package/app/composables/{tree_scroll.js → tree_scroll.ts} +61 -12
- package/app/composables/use_adaptive_styles.ts +186 -0
- package/app/composables/use_overlapping_picker.ts +263 -0
- package/app/composables/use_quick_colormap.ts +55 -0
- package/app/composables/virtual_tree.ts +271 -0
- package/app/composables/vtk_implicit_plane_widget.d.ts +2 -0
- package/app/plugins/{auto_store_register.js → auto_store_register.ts} +3 -5
- package/app/plugins/click_outside_ignore_snackbars.client.ts +36 -0
- package/app/stores/app.ts +252 -0
- package/app/stores/app_helpers/extension.ts +179 -0
- package/app/stores/{back.js → back.ts} +54 -28
- package/app/stores/camera_manager.ts +80 -0
- package/app/stores/{cloud.js → cloud.ts} +18 -13
- package/app/stores/data.ts +392 -0
- package/app/stores/data_helpers/collections.ts +138 -0
- package/app/stores/data_helpers/mesh.ts +169 -0
- package/app/stores/data_style.ts +167 -0
- package/app/stores/{feedback.js → feedback.ts} +19 -8
- package/app/stores/{hybrid_viewer.js → hybrid_viewer.ts} +49 -45
- package/app/stores/infra.ts +106 -0
- package/app/stores/{menu.js → menu.ts} +67 -36
- package/app/stores/treeview.ts +383 -0
- package/app/stores/{viewer.js → viewer.ts} +75 -42
- package/app/utils/attributes.ts +40 -0
- package/app/utils/clipping_planes.ts +222 -0
- package/app/utils/color_picker.js +54 -0
- package/app/utils/colormap.ts +102 -0
- package/app/utils/default_styles/{constants.js → constants.ts} +25 -12
- package/app/utils/default_styles/{index.js → index.ts} +4 -3
- package/app/utils/default_styles/meshes.ts +264 -0
- package/app/utils/default_styles/{models.js → models.ts} +106 -52
- package/app/utils/{extension.js → extension.ts} +63 -19
- package/app/utils/{import_workflow.js → import_workflow.ts} +39 -22
- package/app/utils/{log.js → log.ts} +12 -2
- package/app/utils/{name_cleaner.js → name_cleaner.ts} +6 -6
- package/app/utils/status.ts +19 -0
- package/app/utils/{stores.js → stores.ts} +5 -5
- package/app/utils/{string.js → string.ts} +6 -6
- package/app/utils/{treeview.js → treeview.ts} +4 -1
- package/internal/database/{base_database.js → base_database.ts} +7 -3
- package/internal/database/database.ts +102 -0
- package/internal/database/{extended_database.js → extended_database.ts} +5 -1
- package/internal/database/tables/camera_positions.ts +6 -0
- package/internal/database/tables/{data.js → data.ts} +3 -1
- package/internal/database/tables/data_style.ts +6 -0
- package/internal/database/tables/model_component_datastyle.ts +6 -0
- package/internal/database/tables/model_component_type_datastyle.ts +6 -0
- package/internal/database/tables/model_components.ts +6 -0
- package/internal/database/tables/model_components_relation.ts +6 -0
- package/internal/database/tables/table_definition.ts +5 -0
- package/internal/stores/data_style/mesh/cells/cell.ts +279 -0
- package/internal/stores/data_style/mesh/cells/{color.js → color.ts} +13 -7
- package/internal/stores/data_style/mesh/cells/common.ts +50 -0
- package/internal/stores/data_style/mesh/cells/index.ts +161 -0
- package/internal/stores/data_style/mesh/cells/{textures.js → textures.ts} +14 -8
- package/internal/stores/data_style/mesh/cells/vertex.ts +285 -0
- package/internal/stores/data_style/mesh/cells/visibility.ts +46 -0
- package/internal/stores/data_style/mesh/edges/{color.js → color.ts} +13 -7
- package/internal/stores/data_style/mesh/edges/common.ts +41 -0
- package/internal/stores/data_style/mesh/edges/edge.ts +279 -0
- package/internal/stores/data_style/mesh/edges/index.ts +155 -0
- package/internal/stores/data_style/mesh/edges/vertex.ts +285 -0
- package/internal/stores/data_style/mesh/edges/visibility.ts +45 -0
- package/internal/stores/data_style/mesh/edges/width.ts +42 -0
- package/internal/stores/data_style/mesh/{index.js → index.ts} +34 -14
- package/internal/stores/data_style/mesh/points/{color.js → color.ts} +13 -7
- package/internal/stores/data_style/mesh/points/common.ts +51 -0
- package/internal/stores/data_style/mesh/points/index.ts +133 -0
- package/internal/stores/data_style/mesh/points/size.ts +43 -0
- package/internal/stores/data_style/mesh/points/vertex.ts +285 -0
- package/internal/stores/data_style/mesh/points/visibility.ts +49 -0
- package/internal/stores/data_style/mesh/polygons/{color.js → color.ts} +13 -7
- package/internal/stores/data_style/mesh/polygons/common.ts +50 -0
- package/internal/stores/data_style/mesh/polygons/index.ts +167 -0
- package/internal/stores/data_style/mesh/polygons/polygon.ts +282 -0
- package/internal/stores/data_style/mesh/polygons/{textures.js → textures.ts} +14 -8
- package/internal/stores/data_style/mesh/polygons/vertex.ts +288 -0
- package/internal/stores/data_style/mesh/polygons/visibility.ts +48 -0
- package/internal/stores/data_style/mesh/polyhedra/{color.js → color.ts} +13 -7
- package/internal/stores/data_style/mesh/polyhedra/common.ts +41 -0
- package/internal/stores/data_style/mesh/polyhedra/index.ts +157 -0
- package/internal/stores/data_style/mesh/polyhedra/polyhedron.ts +294 -0
- package/internal/stores/data_style/mesh/polyhedra/vertex.ts +288 -0
- package/internal/stores/data_style/mesh/polyhedra/visibility.ts +48 -0
- package/internal/stores/data_style/model/blocks/{color.js → color.ts} +50 -13
- package/internal/stores/data_style/model/blocks/common.ts +67 -0
- package/internal/stores/data_style/model/blocks/{index.js → index.ts} +111 -66
- package/internal/stores/data_style/model/blocks/polyhedron.ts +363 -0
- package/internal/stores/data_style/model/blocks/vertex.ts +349 -0
- package/internal/stores/data_style/model/blocks/visibility.ts +37 -0
- package/internal/stores/data_style/model/color.ts +348 -0
- package/internal/stores/data_style/model/common.ts +262 -0
- package/internal/stores/data_style/model/corners/{color.js → color.ts} +49 -10
- package/internal/stores/data_style/model/corners/common.ts +71 -0
- package/internal/stores/data_style/model/corners/{index.js → index.ts} +86 -47
- package/internal/stores/data_style/model/corners/vertex.ts +315 -0
- package/internal/stores/data_style/model/corners/visibility.ts +39 -0
- package/internal/stores/data_style/model/edges/common.ts +29 -0
- package/internal/stores/data_style/model/edges/{index.js → index.ts} +2 -7
- package/internal/stores/data_style/model/edges/visibility.ts +55 -0
- package/internal/stores/data_style/model/{index.js → index.ts} +24 -11
- package/internal/stores/data_style/model/lines/{color.js → color.ts} +47 -10
- package/internal/stores/data_style/model/lines/common.ts +63 -0
- package/internal/stores/data_style/model/lines/edge.ts +343 -0
- package/internal/stores/data_style/model/lines/{index.js → index.ts} +108 -66
- package/internal/stores/data_style/model/lines/vertex.ts +344 -0
- package/internal/stores/data_style/model/lines/visibility.ts +37 -0
- package/internal/stores/data_style/model/points/common.ts +25 -0
- package/internal/stores/data_style/model/points/index.ts +35 -0
- package/internal/stores/data_style/model/points/size.ts +44 -0
- package/internal/stores/data_style/model/points/visibility.ts +46 -0
- package/internal/stores/data_style/model/selection.ts +138 -0
- package/internal/stores/data_style/model/surfaces/{color.js → color.ts} +47 -10
- package/internal/stores/data_style/model/surfaces/common.ts +69 -0
- package/internal/stores/data_style/model/surfaces/{index.js → index.ts} +113 -66
- package/internal/stores/data_style/model/surfaces/polygon.ts +347 -0
- package/internal/stores/data_style/model/surfaces/vertex.ts +351 -0
- package/internal/stores/data_style/model/surfaces/visibility.ts +37 -0
- package/internal/stores/data_style/model/{visibility.js → visibility.ts} +112 -32
- package/internal/stores/data_style/state.ts +281 -0
- package/internal/stores/data_style/types.ts +30 -0
- package/internal/stores/hybrid_viewer/brightness.ts +124 -0
- package/internal/stores/hybrid_viewer/camera.ts +326 -0
- package/internal/stores/hybrid_viewer/{camera_animation.js → camera_animation.ts} +30 -12
- package/internal/stores/hybrid_viewer/{constants.js → constants.ts} +2 -2
- package/internal/stores/hybrid_viewer/core.ts +64 -0
- package/internal/stores/hybrid_viewer/{filters.js → filters.ts} +10 -13
- package/internal/stores/hybrid_viewer/highlight.ts +183 -0
- package/internal/stores/hybrid_viewer/{ruler.js → ruler.ts} +50 -22
- package/internal/stores/hybrid_viewer/scene.ts +125 -0
- package/internal/stores/hybrid_viewer/viewport.ts +177 -0
- package/internal/stores/hybrid_viewer/vtk_types.ts +58 -0
- package/internal/utils/api_fetch.ts +133 -0
- package/internal/utils/upload_file.ts +115 -0
- package/internal/utils/viewer_call.ts +99 -0
- package/internal/utils/ws_client.ts +54 -0
- package/nuxt.config.ts +168 -0
- package/opengeodeweb_front_schemas.json +2 -2
- package/package.json +49 -13
- package/server/api/cloud/extensions/{run.post.js → run.post.ts} +16 -12
- package/server/api/local/app/project_folder_path.post.ts +33 -0
- package/server/api/local/app/run_back.post.ts +39 -0
- package/server/api/local/app/run_viewer.post.ts +39 -0
- package/server/api/local/extensions/{kill.post.js → kill.post.ts} +15 -8
- package/server/api/local/extensions/{run.post.js → run.post.ts} +17 -12
- package/server/api/local/extensions/upload.put.ts +71 -0
- package/server/api/microservice/app/{get_is_app_ready.get.js → get_is_app_ready.get.ts} +5 -5
- package/server/api/microservice/app/schemas/get_is_app_ready.json +1 -1
- package/server/api/microservice/app/set_app_base_url.post.ts +29 -0
- package/server/api/microservice/app/set_back_base_url.post.ts +26 -0
- package/server/api/microservice/app/set_is_app_ready.post.ts +29 -0
- package/server/api/microservice/app/set_viewer_base_url.post.ts +26 -0
- package/server/api/microservice/extensions/{download.post.js → download.post.ts} +13 -6
- package/server/api/serverless/run_cloud.post.ts +92 -0
- package/server/utils/{app_config.js → app_config.ts} +40 -18
- package/server/utils/{cleanup.js → cleanup.ts} +76 -29
- package/server/utils/{cloud.js → cloud.ts} +33 -17
- package/server/utils/{extension.js → extension.ts} +31 -4
- package/server/utils/{microservices.js → microservices.ts} +68 -27
- package/server/utils/{path.js → path.ts} +36 -17
- package/server/utils/{scripts.js → scripts.ts} +49 -33
- package/server/utils/{server.js → server.ts} +13 -6
- package/server/utils/server_config.ts +74 -0
- package/server/utils/stream.ts +6 -0
- package/server/utils/ws_client.ts +165 -0
- package/shared/{scripts.js → scripts.ts} +15 -10
- package/shared/utils/call_raw.ts +73 -0
- package/shared/utils/{call_schema.js → call_schema.ts} +15 -6
- package/shared/utils/fetch_raw.ts +125 -0
- package/shared/utils/{fetch_schema.js → fetch_schema.ts} +16 -7
- package/shared/utils/file.ts +22 -0
- package/shared/utils/{parse_boolean.js → parse_boolean.ts} +1 -1
- package/shared/utils/response_handlers/load.ts +109 -0
- package/shared/utils/types.ts +27 -0
- package/shared/utils/{validate_schema.js → validate_schema.ts} +3 -1
- package/.github/workflows/config.json +0 -5
- package/.github/workflows/deploy.yml +0 -15
- package/.github/workflows/manual_release.yml +0 -11
- package/.github/workflows/merge_request.yml +0 -9
- package/.github/workflows/pr_update.yml +0 -11
- package/.github/workflows/prepare_deploy.yml +0 -9
- package/.github/workflows/schedule.yml +0 -18
- package/.github/workflows/test.yml +0 -14
- package/.github/workflows/test_pr.yml +0 -12
- package/.oxlintrc.json +0 -150
- package/.releaserc +0 -11
- package/app/components/Viewer/ObjectTree/Views/ModelComponents.vue +0 -224
- package/app/composables/clipping_planes_widget.js +0 -249
- package/app/composables/global_attribute_style.js +0 -181
- package/app/composables/hover_highlight.js +0 -91
- package/app/composables/responsive_middle_truncate.js +0 -34
- package/app/composables/stepper_tree.js +0 -56
- package/app/composables/tree_filter.js +0 -138
- package/app/composables/use_adaptive_styles.js +0 -120
- package/app/composables/use_overlapping_picker.js +0 -169
- package/app/composables/use_quick_colormap.js +0 -32
- package/app/composables/virtual_tree.js +0 -191
- package/app/stores/app.js +0 -326
- package/app/stores/camera_manager.js +0 -57
- package/app/stores/data.js +0 -278
- package/app/stores/data_helpers/collections.js +0 -96
- package/app/stores/data_helpers/mesh.js +0 -122
- package/app/stores/data_style.js +0 -116
- package/app/stores/infra.js +0 -95
- package/app/stores/treeview.js +0 -290
- package/app/utils/attributes.js +0 -23
- package/app/utils/clipping_planes.js +0 -110
- package/app/utils/colormap.js +0 -64
- package/app/utils/default_styles/meshes.js +0 -191
- package/app/utils/status.js +0 -10
- package/commitlint.config.js +0 -20
- package/internal/database/database.js +0 -80
- package/internal/database/tables/camera_positions.js +0 -4
- package/internal/database/tables/data_style.js +0 -4
- package/internal/database/tables/model_component_datastyle.js +0 -4
- package/internal/database/tables/model_component_type_datastyle.js +0 -4
- package/internal/database/tables/model_components.js +0 -4
- package/internal/database/tables/model_components_relation.js +0 -4
- package/internal/stores/data_style/mesh/cells/cell.js +0 -196
- package/internal/stores/data_style/mesh/cells/common.js +0 -39
- package/internal/stores/data_style/mesh/cells/index.js +0 -81
- package/internal/stores/data_style/mesh/cells/vertex.js +0 -193
- package/internal/stores/data_style/mesh/cells/visibility.js +0 -35
- package/internal/stores/data_style/mesh/edges/common.js +0 -32
- package/internal/stores/data_style/mesh/edges/edge.js +0 -195
- package/internal/stores/data_style/mesh/edges/index.js +0 -81
- package/internal/stores/data_style/mesh/edges/vertex.js +0 -196
- package/internal/stores/data_style/mesh/edges/visibility.js +0 -34
- package/internal/stores/data_style/mesh/edges/width.js +0 -34
- package/internal/stores/data_style/mesh/points/common.js +0 -37
- package/internal/stores/data_style/mesh/points/index.js +0 -82
- package/internal/stores/data_style/mesh/points/size.js +0 -35
- package/internal/stores/data_style/mesh/points/vertex.js +0 -193
- package/internal/stores/data_style/mesh/points/visibility.js +0 -37
- package/internal/stores/data_style/mesh/polygons/common.js +0 -32
- package/internal/stores/data_style/mesh/polygons/index.js +0 -107
- package/internal/stores/data_style/mesh/polygons/polygon.js +0 -196
- package/internal/stores/data_style/mesh/polygons/vertex.js +0 -196
- package/internal/stores/data_style/mesh/polygons/visibility.js +0 -38
- package/internal/stores/data_style/mesh/polyhedra/common.js +0 -32
- package/internal/stores/data_style/mesh/polyhedra/index.js +0 -98
- package/internal/stores/data_style/mesh/polyhedra/polyhedron.js +0 -196
- package/internal/stores/data_style/mesh/polyhedra/vertex.js +0 -196
- package/internal/stores/data_style/mesh/polyhedra/visibility.js +0 -38
- package/internal/stores/data_style/model/blocks/common.js +0 -51
- package/internal/stores/data_style/model/blocks/polyhedron.js +0 -215
- package/internal/stores/data_style/model/blocks/vertex.js +0 -204
- package/internal/stores/data_style/model/blocks/visibility.js +0 -20
- package/internal/stores/data_style/model/color.js +0 -218
- package/internal/stores/data_style/model/common.js +0 -141
- package/internal/stores/data_style/model/corners/common.js +0 -51
- package/internal/stores/data_style/model/corners/vertex.js +0 -204
- package/internal/stores/data_style/model/corners/visibility.js +0 -20
- package/internal/stores/data_style/model/edges/common.js +0 -20
- package/internal/stores/data_style/model/edges/visibility.js +0 -38
- package/internal/stores/data_style/model/lines/common.js +0 -51
- package/internal/stores/data_style/model/lines/edge.js +0 -203
- package/internal/stores/data_style/model/lines/vertex.js +0 -204
- package/internal/stores/data_style/model/lines/visibility.js +0 -20
- package/internal/stores/data_style/model/points/common.js +0 -20
- package/internal/stores/data_style/model/points/index.js +0 -25
- package/internal/stores/data_style/model/points/size.js +0 -36
- package/internal/stores/data_style/model/points/visibility.js +0 -36
- package/internal/stores/data_style/model/selection.js +0 -89
- package/internal/stores/data_style/model/surfaces/common.js +0 -51
- package/internal/stores/data_style/model/surfaces/polygon.js +0 -215
- package/internal/stores/data_style/model/surfaces/vertex.js +0 -215
- package/internal/stores/data_style/model/surfaces/visibility.js +0 -20
- package/internal/stores/data_style/state.js +0 -197
- package/internal/stores/hybrid_viewer/brightness.js +0 -82
- package/internal/stores/hybrid_viewer/camera.js +0 -274
- package/internal/stores/hybrid_viewer/highlight.js +0 -170
- package/internal/stores/hybrid_viewer/scene.js +0 -136
- package/internal/stores/hybrid_viewer/viewport.js +0 -140
- package/internal/utils/api_fetch.js +0 -52
- package/internal/utils/upload_file.js +0 -57
- package/internal/utils/viewer_call.js +0 -49
- package/internal/utils/ws_client.js +0 -29
- package/nuxt.config.js +0 -106
- package/scripts/generate_geode_objects.js +0 -24
- package/server/api/local/app/project_folder_path.post.js +0 -29
- package/server/api/local/app/run_back.post.js +0 -33
- package/server/api/local/app/run_viewer.post.js +0 -33
- package/server/api/local/extensions/upload.put.js +0 -72
- package/server/api/microservice/app/set_app_base_url.post.js +0 -25
- package/server/api/microservice/app/set_back_base_url.post.js +0 -22
- package/server/api/microservice/app/set_is_app_ready.post.js +0 -25
- package/server/api/microservice/app/set_viewer_base_url.post.js +0 -22
- package/server/api/serverless/run_cloud.post.js +0 -44
- package/server/utils/server_config.js +0 -58
- package/server/utils/ws_client.js +0 -112
- package/shared/utils/call_raw.js +0 -46
- package/shared/utils/fetch_raw.js +0 -61
- package/shared/utils/file.js +0 -16
- package/shared/utils/response_handlers/load.js +0 -74
- package/tests/integration/data/uploads/test.og_brep +0 -0
- package/tests/integration/data/uploads/test.og_edc2d +0 -0
- package/tests/integration/data/uploads/test.og_edc3d +0 -0
- package/tests/integration/data/uploads/test.og_psf3d +0 -0
- package/tests/integration/data/uploads/test.og_rgd2d +0 -0
- package/tests/integration/data/uploads/test.og_rgd3d +0 -0
- package/tests/integration/data/uploads/test.vtu +0 -22
- package/tests/integration/setup.js +0 -92
- package/tests/integration/stores/data_style/mesh/cells.nuxt.test.js +0 -343
- package/tests/integration/stores/data_style/mesh/edges.nuxt.test.js +0 -254
- package/tests/integration/stores/data_style/mesh/index.nuxt.test.js +0 -62
- package/tests/integration/stores/data_style/mesh/points.nuxt.test.js +0 -201
- package/tests/integration/stores/data_style/mesh/polygons.nuxt.test.js +0 -260
- package/tests/integration/stores/data_style/mesh/polyhedra.nuxt.test.js +0 -267
- package/tests/integration/stores/data_style/model/blocks.nuxt.test.js +0 -397
- package/tests/integration/stores/data_style/model/corners.nuxt.test.js +0 -264
- package/tests/integration/stores/data_style/model/edges.nuxt.test.js +0 -71
- package/tests/integration/stores/data_style/model/index.nuxt.test.js +0 -92
- package/tests/integration/stores/data_style/model/lines.nuxt.test.js +0 -379
- package/tests/integration/stores/data_style/model/points.nuxt.test.js +0 -95
- package/tests/integration/stores/data_style/model/surfaces.nuxt.test.js +0 -574
- package/tests/integration/stores/viewer.nuxt.test.js +0 -69
- package/tests/setup_indexeddb.js +0 -4
- package/tests/unit/components/CrsSelector.nuxt.test.js +0 -55
- package/tests/unit/components/DragAndDrop.nuxt.test.js +0 -89
- package/tests/unit/components/ExtensionSelector.nuxt.test.js +0 -65
- package/tests/unit/components/FeedBack/ErrorsBanner.nuxt.test.js +0 -41
- package/tests/unit/components/FeedBack/Snackers.nuxt.test.js +0 -49
- package/tests/unit/components/FileSelector.nuxt.test.js +0 -124
- package/tests/unit/components/FileUploader.nuxt.test.js +0 -69
- package/tests/unit/components/MissingFilesSelector.nuxt.test.js +0 -77
- package/tests/unit/components/ObjectSelector.nuxt.test.js +0 -118
- package/tests/unit/components/PackagesVersions.nuxt.test.js +0 -42
- package/tests/unit/components/Step.nuxt.test.js +0 -51
- package/tests/unit/components/Stepper.nuxt.test.js +0 -41
- package/tests/unit/components/ToolPanel.nuxt.test.js +0 -66
- package/tests/unit/composables/api_fetch.nuxt.test.js +0 -75
- package/tests/unit/composables/project_manager.nuxt.test.js +0 -299
- package/tests/unit/composables/run_function_when_microservices_connected.nuxt.test.js +0 -57
- package/tests/unit/composables/upload_file.nuxt.test.js +0 -45
- package/tests/unit/composables/virtual_tree.nuxt.test.js +0 -63
- package/tests/unit/plugins/project_load.nuxt.test.js +0 -98
- package/tests/unit/stores/app.nuxt.test.js +0 -189
- package/tests/unit/stores/back.nuxt.test.js +0 -147
- package/tests/unit/stores/cloud.nuxt.test.js +0 -90
- package/tests/unit/stores/data.nuxt.test.js +0 -162
- package/tests/unit/stores/feedback.nuxt.test.js +0 -90
- package/tests/unit/stores/infra.nuxt.test.js +0 -313
- package/tests/unit/stores/treeview.nuxt.test.js +0 -63
- package/tests/unit/stores/viewer.nuxt.test.js +0 -161
- package/tests/unit/utils/validate_schema.nuxt.test.js +0 -38
- package/tests/utils.js +0 -20
- package/tests/vitest.config.js +0 -67
- /package/server/api/local/app/{kill.post.js → kill.post.ts} +0 -0
- /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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
129
|
+
const snapshot = (isImportSnapshotResponse(result) ? result.snapshot : undefined) ?? {};
|
|
74
130
|
|
|
75
131
|
treeviewStore.isImporting = true;
|
|
76
132
|
|
|
77
|
-
|
|
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
|
-
|
|
83
|
-
|
|
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
|
|
141
|
+
const items = snapshot.data?.items ?? [];
|
|
87
142
|
await importWorkflowFromSnapshot(items);
|
|
88
143
|
await hybridViewerStore.importStores(snapshot.hybridViewer);
|
|
89
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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
|
-
|
|
172
|
+
if (item) {
|
|
173
|
+
handleItemClick(item, focusedIndex.value);
|
|
174
|
+
}
|
|
133
175
|
}
|
|
134
176
|
}
|
|
135
177
|
}
|