@geode/opengeodeweb-front 10.34.0-rc.8 → 10.34.0
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/{server → .build/server}/utils/app_config.js +10 -9
- package/{server → .build/server}/utils/cleanup.js +31 -17
- package/{server → .build/server}/utils/cloud.js +1 -4
- package/{server → .build/server}/utils/microservices.js +21 -9
- package/{server → .build/server}/utils/path.js +4 -4
- package/{server → .build/server}/utils/scripts.js +9 -9
- package/.build/server/utils/server_config.js +51 -0
- package/.build/server/utils/stream.js +6 -0
- package/{server → .build/server}/utils/ws_client.js +18 -3
- package/{shared → .build/shared}/scripts.js +10 -10
- package/.build/shared/utils/call_raw.js +31 -0
- package/{shared → .build/shared}/utils/call_schema.js +2 -2
- package/.build/shared/utils/fetch_raw.js +52 -0
- package/{shared → .build/shared}/utils/fetch_schema.js +2 -2
- package/{shared → .build/shared}/utils/file.js +3 -1
- package/{shared → .build/shared}/utils/response_handlers/load.js +10 -7
- package/{shared → .build/shared}/utils/validate_schema.js +1 -1
- package/app/components/ActionButton.vue +6 -6
- package/app/components/CameraManager/List.vue +5 -5
- package/app/components/CameraManager/Saver.vue +3 -5
- package/app/components/CameraManager.vue +6 -4
- package/app/components/CameraOrientation.vue +12 -12
- package/app/components/ClippingPlaneCard.vue +4 -2
- package/app/components/ClippingPlanes.vue +8 -8
- package/app/components/CrsSelector.vue +9 -10
- package/app/components/DeleteDialog.vue +4 -2
- package/app/components/DragAndDrop.vue +10 -12
- package/app/components/DragAndDropInternal/DragAndDropInline.vue +4 -2
- package/app/components/ExtensionSelector.vue +4 -4
- package/app/components/FeedBack/ErrorBanner.vue +3 -1
- package/app/components/FeedBack/Snackers.vue +4 -3
- package/app/components/FileSelector.vue +10 -8
- package/app/components/FileUploader.vue +11 -11
- package/app/components/GlassCard.vue +1 -1
- package/app/components/HybridRenderingView.vue +7 -5
- package/app/components/HybridViewerTooltip.vue +7 -7
- package/app/components/Launcher.vue +1 -1
- package/app/components/Loading/EcoMessages.vue +9 -3
- package/app/components/Loading.vue +2 -2
- package/app/components/MissingFilesSelector.vue +12 -10
- package/app/components/ObjectSelector.vue +10 -9
- package/app/components/PackagesVersions.vue +6 -5
- package/app/components/Recaptcha.vue +3 -3
- package/app/components/RemoteRenderingView.vue +6 -7
- package/app/components/Ruler.vue +3 -3
- package/app/components/Screenshot.vue +6 -6
- package/app/components/SearchBar.vue +4 -2
- package/app/components/ShrinkFilter.vue +7 -7
- package/app/components/Step.vue +6 -5
- package/app/components/Stepper.vue +4 -3
- package/app/components/ToolPanel.vue +6 -3
- package/app/components/ViewToolbar.vue +25 -28
- package/app/components/Viewer/ContextMenu/CenterButton.vue +7 -5
- package/app/components/Viewer/ContextMenu/CircularItems.vue +3 -3
- package/app/components/Viewer/ContextMenu/ContextMenu.vue +22 -19
- package/app/components/Viewer/ContextMenu/ContextMenuItem.vue +10 -8
- package/app/components/Viewer/ContextMenu/InfoCard.vue +11 -12
- package/app/components/Viewer/EdgedCurve/SpecificEdgesOptions.vue +13 -17
- package/app/components/Viewer/Generic/Mesh/CellsOptions.vue +11 -15
- package/app/components/Viewer/Generic/Mesh/EdgesOptions.vue +12 -16
- package/app/components/Viewer/Generic/Mesh/PointsOptions.vue +8 -12
- package/app/components/Viewer/Generic/Mesh/PolygonsOptions.vue +11 -15
- package/app/components/Viewer/Generic/Mesh/PolyhedraOptions.vue +11 -15
- package/app/components/Viewer/Generic/Model/BlocksOptions.vue +67 -38
- package/app/components/Viewer/Generic/Model/CornersOptions.vue +53 -23
- package/app/components/Viewer/Generic/Model/EdgesOptions.vue +1 -3
- package/app/components/Viewer/Generic/Model/LinesOptions.vue +67 -38
- package/app/components/Viewer/Generic/Model/ModelStyleCard.vue +31 -15
- package/app/components/Viewer/Generic/Model/ModelStyleOptions.vue +2 -3
- package/app/components/Viewer/Generic/Model/PointsOptions.vue +6 -6
- package/app/components/Viewer/Generic/Model/SurfacesOptions.vue +69 -38
- package/app/components/Viewer/ObjectTree/Base/CommonTreeView.vue +64 -46
- package/app/components/Viewer/ObjectTree/Base/Controls.vue +5 -5
- package/app/components/Viewer/ObjectTree/Base/ItemLabel.vue +13 -9
- package/app/components/Viewer/ObjectTree/Base/StickyHeader.vue +5 -5
- package/app/components/Viewer/ObjectTree/Base/TreeRow.vue +10 -10
- package/app/components/Viewer/ObjectTree/Box.vue +6 -4
- package/app/components/Viewer/ObjectTree/Layout.vue +23 -21
- package/app/components/Viewer/ObjectTree/Views/GlobalObjects.vue +14 -14
- package/app/components/Viewer/ObjectTree/Views/{ModelCollections.vue → ModelTree.vue} +59 -24
- package/app/components/Viewer/Options/AttributeColorBar.vue +4 -2
- package/app/components/Viewer/Options/AttributeRangeSelector.vue +4 -2
- package/app/components/Viewer/Options/AttributeSelector.vue +7 -9
- package/app/components/Viewer/Options/ColorMapList.vue +15 -13
- package/app/components/Viewer/Options/ColorMapPicker.vue +4 -4
- package/app/components/Viewer/Options/ColorPicker.vue +223 -41
- package/app/components/Viewer/Options/ColoringTypeSelector.vue +16 -16
- package/app/components/Viewer/Options/ColormapQuickPicker.vue +7 -5
- package/app/components/Viewer/Options/OptionsSection.vue +1 -1
- package/app/components/Viewer/Options/TextureItem.vue +8 -6
- package/app/components/Viewer/Options/TexturesSelector.vue +1 -1
- package/app/components/Viewer/OverlappingObjectsPicker.vue +8 -9
- package/app/components/Viewer/PointSet/SpecificPointsOptions.vue +2 -6
- package/app/components/Viewer/Solid/SpecificPolyhedraOptions.vue +12 -16
- package/app/components/Viewer/Surface/PolygonsOptions.vue +12 -16
- package/app/components/Viewer/Ui.vue +2 -2
- package/app/components/Wrapper.vue +1 -4
- package/app/components/ZScaling.vue +5 -3
- package/app/components/csv-preview/CsvPreviewer.vue +38 -37
- package/app/components/csv-preview/CsvSettings.vue +6 -4
- package/app/components/csv-preview/CsvTable.vue +1 -1
- package/app/composables/batch_style.ts +5 -6
- package/app/composables/clipping_planes_widget.ts +73 -181
- 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 +163 -83
- package/app/composables/hover_highlight.ts +46 -14
- package/app/composables/model_collections.ts +26 -13
- package/app/composables/model_components.ts +26 -13
- package/app/composables/project_manager.ts +76 -19
- package/app/composables/responsive_middle_truncate.ts +13 -13
- package/app/composables/stepper_tree.ts +34 -11
- package/app/composables/tree_filter.ts +66 -44
- package/app/composables/tree_keyboard_nav.ts +25 -11
- package/app/composables/tree_scroll.ts +44 -14
- package/app/composables/use_adaptive_styles.ts +66 -23
- package/app/composables/use_overlapping_picker.ts +66 -16
- package/app/composables/use_quick_colormap.ts +16 -5
- package/app/composables/virtual_tree.ts +75 -43
- package/app/composables/vtk_implicit_plane_widget.d.ts +2 -0
- package/app/plugins/auto_store_register.ts +2 -7
- package/app/plugins/click_outside_ignore_snackbars.client.ts +39 -0
- package/app/stores/app.ts +57 -192
- package/app/stores/app_helpers/extension.ts +179 -0
- package/app/stores/back.ts +37 -21
- package/app/stores/camera_manager.ts +22 -20
- package/app/stores/cloud.ts +17 -13
- package/app/stores/data.ts +88 -47
- package/app/stores/data_helpers/collections.ts +36 -38
- package/app/stores/data_helpers/mesh.ts +45 -36
- package/app/stores/data_style.ts +50 -28
- package/app/stores/feedback.ts +6 -6
- package/app/stores/hybrid_viewer.ts +41 -52
- package/app/stores/infra.ts +39 -37
- package/app/stores/menu.ts +23 -14
- package/app/stores/treeview.ts +72 -42
- package/app/stores/viewer.ts +39 -27
- package/app/utils/attributes.ts +3 -3
- package/app/utils/clipping_planes.ts +111 -14
- package/app/utils/color_picker.ts +57 -0
- package/app/utils/colormap.ts +58 -35
- package/app/utils/default_styles/index.ts +2 -2
- package/app/utils/default_styles/meshes.ts +107 -13
- package/app/utils/default_styles/models.ts +83 -14
- package/app/utils/extension.ts +47 -20
- package/app/utils/import_workflow.ts +21 -13
- package/app/utils/name_cleaner.ts +1 -1
- package/app/utils/string.ts +1 -1
- package/app/utils/treeview.ts +2 -2
- package/internal/database/base_database.ts +7 -3
- package/internal/database/database.ts +36 -26
- package/internal/database/extended_database.ts +1 -1
- package/internal/stores/data_style/mesh/cells/cell.ts +70 -34
- package/internal/stores/data_style/mesh/cells/color.ts +12 -6
- package/internal/stores/data_style/mesh/cells/common.ts +18 -8
- package/internal/stores/data_style/mesh/cells/index.ts +122 -42
- package/internal/stores/data_style/mesh/cells/textures.ts +12 -6
- package/internal/stores/data_style/mesh/cells/vertex.ts +75 -34
- package/internal/stores/data_style/mesh/cells/visibility.ts +15 -4
- package/internal/stores/data_style/mesh/edges/color.ts +12 -6
- package/internal/stores/data_style/mesh/edges/common.ts +14 -6
- package/internal/stores/data_style/mesh/edges/edge.ts +71 -39
- package/internal/stores/data_style/mesh/edges/index.ts +117 -42
- package/internal/stores/data_style/mesh/edges/vertex.ts +76 -39
- package/internal/stores/data_style/mesh/edges/visibility.ts +15 -4
- package/internal/stores/data_style/mesh/edges/width.ts +12 -4
- package/internal/stores/data_style/mesh/index.ts +30 -11
- package/internal/stores/data_style/mesh/points/color.ts +12 -6
- package/internal/stores/data_style/mesh/points/common.ts +21 -8
- package/internal/stores/data_style/mesh/points/index.ts +101 -50
- package/internal/stores/data_style/mesh/points/size.ts +12 -4
- package/internal/stores/data_style/mesh/points/vertex.ts +75 -34
- package/internal/stores/data_style/mesh/points/visibility.ts +17 -7
- package/internal/stores/data_style/mesh/polygons/color.ts +12 -6
- package/internal/stores/data_style/mesh/polygons/common.ts +23 -6
- package/internal/stores/data_style/mesh/polygons/index.ts +130 -70
- package/internal/stores/data_style/mesh/polygons/polygon.ts +77 -43
- package/internal/stores/data_style/mesh/polygons/textures.ts +12 -6
- package/internal/stores/data_style/mesh/polygons/vertex.ts +79 -39
- package/internal/stores/data_style/mesh/polygons/visibility.ts +16 -6
- package/internal/stores/data_style/mesh/polyhedra/color.ts +12 -6
- package/internal/stores/data_style/mesh/polyhedra/common.ts +14 -6
- package/internal/stores/data_style/mesh/polyhedra/index.ts +115 -56
- package/internal/stores/data_style/mesh/polyhedra/polyhedron.ts +80 -39
- package/internal/stores/data_style/mesh/polyhedra/vertex.ts +79 -39
- package/internal/stores/data_style/mesh/polyhedra/visibility.ts +16 -6
- package/internal/stores/data_style/model/blocks/color.ts +43 -13
- package/internal/stores/data_style/model/blocks/common.ts +21 -6
- package/internal/stores/data_style/model/blocks/index.ts +89 -59
- package/internal/stores/data_style/model/blocks/polyhedron.ts +101 -44
- package/internal/stores/data_style/model/blocks/vertex.ts +107 -42
- package/internal/stores/data_style/model/blocks/visibility.ts +17 -4
- package/internal/stores/data_style/model/color.ts +171 -83
- package/internal/stores/data_style/model/common.ts +70 -21
- package/internal/stores/data_style/model/corners/color.ts +43 -11
- package/internal/stores/data_style/model/corners/common.ts +25 -6
- package/internal/stores/data_style/model/corners/index.ts +66 -41
- package/internal/stores/data_style/model/corners/vertex.ts +105 -74
- package/internal/stores/data_style/model/corners/visibility.ts +19 -4
- package/internal/stores/data_style/model/edges/common.ts +12 -4
- package/internal/stores/data_style/model/edges/index.ts +2 -1
- package/internal/stores/data_style/model/edges/visibility.ts +24 -7
- package/internal/stores/data_style/model/index.ts +24 -11
- package/internal/stores/data_style/model/lines/color.ts +41 -11
- package/internal/stores/data_style/model/lines/common.ts +17 -6
- package/internal/stores/data_style/model/lines/edge.ts +105 -42
- package/internal/stores/data_style/model/lines/index.ts +86 -59
- package/internal/stores/data_style/model/lines/vertex.ts +105 -42
- package/internal/stores/data_style/model/lines/visibility.ts +17 -4
- package/internal/stores/data_style/model/points/common.ts +8 -4
- package/internal/stores/data_style/model/points/index.ts +10 -3
- package/internal/stores/data_style/model/points/size.ts +12 -4
- package/internal/stores/data_style/model/points/visibility.ts +16 -6
- package/internal/stores/data_style/model/selection.ts +80 -58
- package/internal/stores/data_style/model/surfaces/color.ts +41 -11
- package/internal/stores/data_style/model/surfaces/common.ts +23 -6
- package/internal/stores/data_style/model/surfaces/index.ts +89 -59
- package/internal/stores/data_style/model/surfaces/polygon.ts +107 -67
- package/internal/stores/data_style/model/surfaces/vertex.ts +111 -67
- package/internal/stores/data_style/model/surfaces/visibility.ts +18 -5
- package/internal/stores/data_style/model/visibility.ts +82 -20
- package/internal/stores/data_style/state.ts +77 -65
- package/internal/stores/hybrid_viewer/brightness.ts +49 -31
- package/internal/stores/hybrid_viewer/camera.ts +191 -177
- package/internal/stores/hybrid_viewer/camera_animation.ts +11 -10
- package/internal/stores/hybrid_viewer/core.ts +64 -0
- package/internal/stores/hybrid_viewer/filters.ts +10 -16
- package/internal/stores/hybrid_viewer/highlight.ts +91 -130
- package/internal/stores/hybrid_viewer/ruler.ts +24 -15
- package/internal/stores/hybrid_viewer/scene.ts +96 -117
- package/internal/stores/hybrid_viewer/viewport.ts +74 -65
- package/internal/stores/hybrid_viewer/vtk_types.ts +13 -29
- package/internal/utils/api_fetch.ts +54 -23
- package/internal/utils/upload_file.ts +74 -53
- package/internal/utils/viewer_call.ts +22 -13
- package/internal/utils/ws_client.ts +24 -13
- package/nuxt.config.ts +58 -1
- package/package.json +20 -8
- package/server/api/cloud/extensions/run.post.ts +6 -10
- package/server/api/local/app/project_folder_path.post.ts +4 -4
- package/server/api/local/app/run_back.post.ts +5 -7
- package/server/api/local/app/run_viewer.post.ts +5 -7
- package/server/api/local/extensions/kill.post.ts +4 -3
- package/server/api/local/extensions/run.post.ts +7 -10
- package/server/api/local/extensions/upload.put.ts +44 -54
- package/server/api/microservice/app/get_is_app_ready.get.ts +4 -5
- package/server/api/microservice/app/set_app_base_url.post.ts +5 -6
- package/server/api/microservice/app/set_back_base_url.post.ts +5 -6
- package/server/api/microservice/app/set_is_app_ready.post.ts +5 -6
- package/server/api/microservice/app/set_viewer_base_url.post.ts +5 -6
- package/server/api/microservice/extensions/download.post.ts +5 -4
- package/server/api/serverless/run_cloud.post.ts +53 -11
- package/server/utils/app_config.ts +29 -22
- package/server/utils/cleanup.ts +60 -30
- package/server/utils/cloud.ts +9 -8
- package/server/utils/extension.ts +23 -9
- package/server/utils/microservices.ts +33 -24
- package/server/utils/path.ts +4 -4
- package/server/utils/scripts.ts +26 -23
- package/server/utils/server.ts +2 -2
- package/server/utils/server_config.ts +41 -27
- package/server/utils/stream.ts +6 -0
- package/server/utils/ws_client.ts +42 -8
- package/shared/scripts.ts +15 -10
- package/shared/utils/call_raw.ts +23 -16
- package/shared/utils/call_schema.ts +5 -8
- package/shared/utils/fetch_raw.ts +87 -47
- package/shared/utils/fetch_schema.ts +6 -9
- package/shared/utils/file.ts +8 -2
- package/shared/utils/response_handlers/load.ts +26 -11
- package/shared/utils/types.ts +9 -9
- package/shared/utils/validate_schema.ts +1 -1
- package/app/components/Viewer/ObjectTree/Views/ModelComponents.vue +0 -276
- package/server/types/vendor.d.ts +0 -64
- package/server/utils/server_config.js +0 -43
- package/shared/utils/call_raw.js +0 -30
- package/shared/utils/fetch_raw.js +0 -40
- /package/{opengeodeweb_front_schemas.js → .build/opengeodeweb_front_schemas.js} +0 -0
- /package/{server → .build/server}/utils/server.js +0 -0
- /package/{shared → .build/shared}/app_mode.js +0 -0
- /package/{shared → .build/shared}/utils/parse_boolean.js +0 -0
- /package/{shared → .build/shared}/utils/types.js +0 -0
|
@@ -1,8 +1,5 @@
|
|
|
1
|
+
import type { JsonRpcSchema } from "@ogw_shared/utils/types";
|
|
1
2
|
import back_schemas from "@geode/opengeodeweb-back/opengeodeweb_back_schemas.json";
|
|
2
|
-
import { computed } from "vue";
|
|
3
|
-
// oxlint-disable-next-line eslint/no-duplicate-imports
|
|
4
|
-
import type { Ref } from "vue";
|
|
5
|
-
|
|
6
3
|
import { getAttributeRange } from "@ogw_front/utils/attributes";
|
|
7
4
|
import { useBackStore } from "@ogw_front/stores/back";
|
|
8
5
|
import { useDataStyleStore } from "@ogw_front/stores/data_style";
|
|
@@ -19,26 +16,67 @@ interface ActiveComponent extends ComponentNameEntry {
|
|
|
19
16
|
attributeType: string;
|
|
20
17
|
}
|
|
21
18
|
|
|
22
|
-
// This composable resolves a batch of dynamically-named getter/setter methods on the data style store (e.g. "meshPointsVertexAttributeRange", "setMeshPointsVertexAttributeRange", ...) - the store's real, fully-typed surface has no index signature for this, so dynamic lookups
|
|
23
|
-
type
|
|
19
|
+
// This composable resolves a batch of dynamically-named getter/setter methods on the data style store (e.g. "meshPointsVertexAttributeRange", "setMeshPointsVertexAttributeRange", ...) - the store's real, fully-typed surface has no index signature for this, so dynamic lookups go through this type guard instead of an unsafe cast of the whole store (which mixes these methods with state refs and other members), matching how these methods are actually shaped (getters take an id and return a value, setters take an id plus arbitrary arguments).
|
|
20
|
+
type DynamicStoreMethod = (...args: readonly unknown[]) => unknown;
|
|
21
|
+
|
|
22
|
+
function isDynamicStoreMethod(value: unknown): value is DynamicStoreMethod {
|
|
23
|
+
return typeof value === "function";
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function getDynamicStoreMethod(store: object, key: string): DynamicStoreMethod | undefined {
|
|
27
|
+
const value: unknown = Reflect.get(store, key);
|
|
28
|
+
return isDynamicStoreMethod(value) ? value : undefined;
|
|
29
|
+
}
|
|
24
30
|
|
|
25
31
|
interface AttributeStyleComponent {
|
|
26
32
|
coloring?: { active?: string };
|
|
27
33
|
}
|
|
28
34
|
|
|
29
35
|
interface AttributeResponse {
|
|
30
|
-
attributes?: {
|
|
31
|
-
attribute_name?: string;
|
|
32
|
-
min_values?: number[];
|
|
33
|
-
max_values?: number[];
|
|
34
|
-
min_value?: number;
|
|
35
|
-
max_value?: number;
|
|
36
|
+
readonly attributes?: readonly {
|
|
37
|
+
readonly attribute_name?: string;
|
|
38
|
+
readonly min_values?: readonly number[];
|
|
39
|
+
readonly max_values?: readonly number[];
|
|
40
|
+
readonly min_value?: number;
|
|
41
|
+
readonly max_value?: number;
|
|
36
42
|
}[];
|
|
37
43
|
}
|
|
38
44
|
|
|
39
|
-
|
|
45
|
+
function isColoringValue(
|
|
46
|
+
value: unknown,
|
|
47
|
+
): value is NonNullable<AttributeStyleComponent["coloring"]> {
|
|
48
|
+
return typeof value === "object" && value !== null;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function isJsonRpcSchema(value: unknown): value is JsonRpcSchema {
|
|
52
|
+
return (
|
|
53
|
+
typeof value === "object" && value !== null && "$id" in value && typeof value.$id === "string"
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function isAttributeResponse(value: unknown): value is AttributeResponse {
|
|
58
|
+
return typeof value === "object" && value !== null;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function isNumberArray(value: unknown): value is number[] {
|
|
62
|
+
return Array.isArray(value) && value.every((item) => typeof item === "number");
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function isStringOrUndefined(value: unknown): value is string | undefined {
|
|
66
|
+
return value === undefined || typeof value === "string";
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function isNumberOrUndefined(value: unknown): value is number | undefined {
|
|
70
|
+
return value === undefined || typeof value === "number";
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function useGlobalAttributeStyle(dataIdRef: Ref<string | undefined>): {
|
|
74
|
+
currentColormap: typeof currentColormap;
|
|
75
|
+
currentRange: typeof currentRange;
|
|
76
|
+
applyGlobalColormap: typeof applyGlobalColormap;
|
|
77
|
+
resetGlobalRange: typeof resetGlobalRange;
|
|
78
|
+
} {
|
|
40
79
|
const dataStyleStore = useDataStyleStore();
|
|
41
|
-
const dynamicDataStyleStore = dataStyleStore as unknown as DynamicStore;
|
|
42
80
|
const hybridViewerStore = useHybridViewerStore();
|
|
43
81
|
const backStore = useBackStore();
|
|
44
82
|
|
|
@@ -51,23 +89,47 @@ export function useGlobalAttributeStyle(dataIdRef: Ref<string | undefined>) {
|
|
|
51
89
|
];
|
|
52
90
|
|
|
53
91
|
function getActiveComponents(targetId: string): ActiveComponent[] {
|
|
54
|
-
const style = dataStyleStore.getStyle(targetId)
|
|
55
|
-
string,
|
|
56
|
-
AttributeStyleComponent | undefined
|
|
57
|
-
>;
|
|
92
|
+
const style = dataStyleStore.getStyle(targetId);
|
|
58
93
|
const activeComponents: ActiveComponent[] = [];
|
|
59
|
-
if (!style) {
|
|
60
|
-
return activeComponents;
|
|
61
|
-
}
|
|
62
94
|
for (const { key, getterKey, setterKey } of componentNames) {
|
|
63
|
-
|
|
64
|
-
|
|
95
|
+
let componentStyle: Record<string, unknown> | undefined = undefined;
|
|
96
|
+
switch (key) {
|
|
97
|
+
case "points": {
|
|
98
|
+
componentStyle = style.points;
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
case "edges": {
|
|
102
|
+
componentStyle = style.edges;
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
case "polygons": {
|
|
106
|
+
componentStyle = style.polygons;
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
case "cells": {
|
|
110
|
+
componentStyle = style.cells;
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
case "polyhedra": {
|
|
114
|
+
componentStyle = style.polyhedra;
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
default: {
|
|
118
|
+
componentStyle = undefined;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (componentStyle === undefined) {
|
|
65
122
|
continue;
|
|
66
123
|
}
|
|
67
124
|
|
|
68
|
-
const
|
|
125
|
+
const { coloring } = componentStyle;
|
|
126
|
+
if (!isColoringValue(coloring)) {
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const { active: activeColoring } = coloring;
|
|
69
131
|
if (
|
|
70
|
-
|
|
132
|
+
activeColoring === undefined ||
|
|
71
133
|
!["vertex", "edge", "polygon", "cell", "polyhedron"].includes(activeColoring)
|
|
72
134
|
) {
|
|
73
135
|
continue;
|
|
@@ -79,19 +141,19 @@ export function useGlobalAttributeStyle(dataIdRef: Ref<string | undefined>) {
|
|
|
79
141
|
return activeComponents;
|
|
80
142
|
}
|
|
81
143
|
|
|
82
|
-
const currentColormap = computed(() => {
|
|
144
|
+
const currentColormap = computed((): string => {
|
|
83
145
|
const targetId = dataIdRef.value;
|
|
84
|
-
if (
|
|
146
|
+
if (targetId === undefined || targetId === "") {
|
|
85
147
|
return "batlow";
|
|
86
148
|
}
|
|
87
149
|
|
|
88
150
|
for (const comp of getActiveComponents(targetId)) {
|
|
89
151
|
const getterName = `${comp.getterKey}${comp.attributeType}ColorMap`;
|
|
90
|
-
const getter =
|
|
152
|
+
const getter = getDynamicStoreMethod(dataStyleStore, getterName);
|
|
91
153
|
if (getter) {
|
|
92
154
|
const colorMap = getter(targetId);
|
|
93
|
-
if (colorMap) {
|
|
94
|
-
return colorMap
|
|
155
|
+
if (typeof colorMap === "string" && colorMap.length > 0) {
|
|
156
|
+
return colorMap;
|
|
95
157
|
}
|
|
96
158
|
}
|
|
97
159
|
}
|
|
@@ -99,18 +161,39 @@ export function useGlobalAttributeStyle(dataIdRef: Ref<string | undefined>) {
|
|
|
99
161
|
return "batlow";
|
|
100
162
|
});
|
|
101
163
|
|
|
102
|
-
|
|
103
|
-
|
|
164
|
+
async function applyCurrentRange(newValue: readonly [number, number]): Promise<void> {
|
|
165
|
+
const targetId = dataIdRef.value;
|
|
166
|
+
if (targetId === undefined || targetId === "") {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
let updated = false;
|
|
171
|
+
for (const comp of getActiveComponents(targetId)) {
|
|
172
|
+
const setterName = `set${comp.setterKey}${comp.attributeType}Range`;
|
|
173
|
+
const setter = getDynamicStoreMethod(dataStyleStore, setterName);
|
|
174
|
+
if (setter) {
|
|
175
|
+
setter(targetId, newValue[0], newValue[1]);
|
|
176
|
+
updated = true;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
if (updated) {
|
|
180
|
+
await hybridViewerStore.remoteRender();
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const currentRange = computed<readonly [number, number]>({
|
|
185
|
+
get(): readonly [number, number] {
|
|
104
186
|
const targetId = dataIdRef.value;
|
|
105
|
-
if (
|
|
187
|
+
if (targetId === undefined || targetId === "") {
|
|
106
188
|
return [0, 1];
|
|
107
189
|
}
|
|
108
190
|
|
|
109
191
|
for (const comp of getActiveComponents(targetId)) {
|
|
110
192
|
const getterName = `${comp.getterKey}${comp.attributeType}Range`;
|
|
111
|
-
const getter =
|
|
193
|
+
const getter = getDynamicStoreMethod(dataStyleStore, getterName);
|
|
112
194
|
if (getter) {
|
|
113
|
-
const
|
|
195
|
+
const rawRange = getter(targetId);
|
|
196
|
+
const range = isNumberArray(rawRange) ? rawRange : undefined;
|
|
114
197
|
if (range && range.length === 2) {
|
|
115
198
|
return [range[0] ?? 0, range[1] ?? 1];
|
|
116
199
|
}
|
|
@@ -118,30 +201,16 @@ export function useGlobalAttributeStyle(dataIdRef: Ref<string | undefined>) {
|
|
|
118
201
|
}
|
|
119
202
|
return [0, 1];
|
|
120
203
|
},
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
let updated = false;
|
|
128
|
-
for (const comp of getActiveComponents(targetId)) {
|
|
129
|
-
const setterName = `set${comp.setterKey}${comp.attributeType}Range`;
|
|
130
|
-
const setter = dynamicDataStyleStore[setterName];
|
|
131
|
-
if (setter) {
|
|
132
|
-
setter(targetId, newValue[0], newValue[1]);
|
|
133
|
-
updated = true;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
if (updated) {
|
|
137
|
-
hybridViewerStore.remoteRender();
|
|
138
|
-
}
|
|
204
|
+
// Vue's WritableComputedOptions setter is strictly `(v: T) => void`, so the async render call is delegated to a helper (see the same trade-off in `app/composables/hover_highlight.ts`'s `onHoverEnter`).
|
|
205
|
+
set: (newValue: readonly [number, number]): void => {
|
|
206
|
+
/* oxlint-disable-next-line promise/prefer-await-to-then -- setter cannot be async; see comment above. */
|
|
207
|
+
applyCurrentRange(newValue).catch(() => undefined);
|
|
139
208
|
},
|
|
140
209
|
});
|
|
141
210
|
|
|
142
211
|
async function applyGlobalColormap(newMap: string): Promise<void> {
|
|
143
212
|
const targetId = dataIdRef.value;
|
|
144
|
-
if (
|
|
213
|
+
if (targetId === undefined || targetId === "") {
|
|
145
214
|
return;
|
|
146
215
|
}
|
|
147
216
|
|
|
@@ -149,7 +218,7 @@ export function useGlobalAttributeStyle(dataIdRef: Ref<string | undefined>) {
|
|
|
149
218
|
|
|
150
219
|
for (const comp of getActiveComponents(targetId)) {
|
|
151
220
|
const setterName = `set${comp.setterKey}${comp.attributeType}ColorMap`;
|
|
152
|
-
const setter =
|
|
221
|
+
const setter = getDynamicStoreMethod(dataStyleStore, setterName);
|
|
153
222
|
|
|
154
223
|
if (setter) {
|
|
155
224
|
promises.push(Promise.resolve(setter(targetId, newMap)));
|
|
@@ -157,61 +226,72 @@ export function useGlobalAttributeStyle(dataIdRef: Ref<string | undefined>) {
|
|
|
157
226
|
}
|
|
158
227
|
|
|
159
228
|
await Promise.all(promises);
|
|
160
|
-
hybridViewerStore.remoteRender();
|
|
229
|
+
await hybridViewerStore.remoteRender();
|
|
161
230
|
}
|
|
162
231
|
|
|
163
|
-
function resetGlobalRange(): void {
|
|
232
|
+
async function resetGlobalRange(): Promise<void> {
|
|
164
233
|
const targetId = dataIdRef.value;
|
|
165
|
-
if (
|
|
234
|
+
if (targetId === undefined || targetId === "") {
|
|
166
235
|
return;
|
|
167
236
|
}
|
|
168
237
|
|
|
238
|
+
const requestPromises: Promise<unknown>[] = [];
|
|
239
|
+
|
|
169
240
|
for (const comp of getActiveComponents(targetId)) {
|
|
170
241
|
const { activeColoring, attributeType, getterKey, setterKey } = comp;
|
|
171
242
|
|
|
172
|
-
const nameGetter =
|
|
173
|
-
const itemGetter =
|
|
243
|
+
const nameGetter = getDynamicStoreMethod(dataStyleStore, `${getterKey}${attributeType}Name`);
|
|
244
|
+
const itemGetter = getDynamicStoreMethod(dataStyleStore, `${getterKey}${attributeType}Item`);
|
|
174
245
|
if (!nameGetter || !itemGetter) {
|
|
175
246
|
continue;
|
|
176
247
|
}
|
|
177
248
|
|
|
178
|
-
const
|
|
179
|
-
const
|
|
249
|
+
const rawAttrName = nameGetter(targetId);
|
|
250
|
+
const attrName = isStringOrUndefined(rawAttrName) ? rawAttrName : undefined;
|
|
251
|
+
const rawAttrItem = itemGetter(targetId);
|
|
252
|
+
const attrItem = (isNumberOrUndefined(rawAttrItem) ? rawAttrItem : undefined) ?? 0;
|
|
180
253
|
|
|
181
|
-
if (
|
|
254
|
+
if (attrName === undefined || attrName === "") {
|
|
182
255
|
continue;
|
|
183
256
|
}
|
|
184
257
|
|
|
185
258
|
const schemaName = `${activeColoring}_attribute_names`;
|
|
186
259
|
const backSchemas = back_schemas.opengeodeweb_back as Record<string, unknown>;
|
|
187
260
|
const schema = backSchemas[schemaName];
|
|
188
|
-
if (!schema) {
|
|
261
|
+
if (schema === undefined || !isJsonRpcSchema(schema)) {
|
|
189
262
|
continue;
|
|
190
263
|
}
|
|
191
264
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
const
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
265
|
+
requestPromises.push(
|
|
266
|
+
backStore.request(
|
|
267
|
+
{
|
|
268
|
+
schema,
|
|
269
|
+
params: { id: targetId },
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
response_function: async (response: unknown): Promise<void> => {
|
|
273
|
+
if (!isAttributeResponse(response)) {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
const attributes = response.attributes ?? [];
|
|
277
|
+
const currentAttribute = attributes.find((attr) => attr.attribute_name === attrName);
|
|
278
|
+
if (currentAttribute) {
|
|
279
|
+
const { min, max } = getAttributeRange(currentAttribute, attrItem);
|
|
280
|
+
|
|
281
|
+
const setterName = `set${setterKey}${attributeType}Range`;
|
|
282
|
+
const setter = getDynamicStoreMethod(dataStyleStore, setterName);
|
|
283
|
+
if (setter) {
|
|
284
|
+
setter(targetId, min, max);
|
|
285
|
+
await hybridViewerStore.remoteRender();
|
|
286
|
+
}
|
|
209
287
|
}
|
|
210
|
-
}
|
|
288
|
+
},
|
|
211
289
|
},
|
|
212
|
-
|
|
290
|
+
),
|
|
213
291
|
);
|
|
214
292
|
}
|
|
293
|
+
|
|
294
|
+
await Promise.all(requestPromises);
|
|
215
295
|
}
|
|
216
296
|
|
|
217
297
|
return {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { JsonRpcSchema } from "@ogw_shared/utils/types";
|
|
1
2
|
import { useDataStore } from "@ogw_front/stores/data";
|
|
2
3
|
import { useViewerStore } from "@ogw_front/stores/viewer";
|
|
3
4
|
import vtk_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json";
|
|
@@ -5,9 +6,12 @@ import vtk_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.
|
|
|
5
6
|
const HOVER_DELAY = 200;
|
|
6
7
|
|
|
7
8
|
type HighlightType = "mesh" | "model";
|
|
8
|
-
type BlockIdsProvider = number[] | (() => number[] | Promise<number[]>);
|
|
9
|
+
type BlockIdsProvider = readonly number[] | (() => readonly number[] | Promise<readonly number[]>);
|
|
9
10
|
|
|
10
|
-
export function useHoverhighlight() {
|
|
11
|
+
export function useHoverhighlight(): {
|
|
12
|
+
onHoverEnter: typeof onHoverEnter;
|
|
13
|
+
onHoverLeave: typeof onHoverLeave;
|
|
14
|
+
} {
|
|
11
15
|
const viewerStore = useViewerStore();
|
|
12
16
|
const dataStore = useDataStore();
|
|
13
17
|
let timer: ReturnType<typeof setTimeout> | undefined = undefined;
|
|
@@ -26,7 +30,7 @@ export function useHoverhighlight() {
|
|
|
26
30
|
}
|
|
27
31
|
const schema = vtk_schemas.opengeodeweb_viewer[type].highlight;
|
|
28
32
|
|
|
29
|
-
async function highlightAction() {
|
|
33
|
+
async function highlightAction(): Promise<void> {
|
|
30
34
|
currentId = id;
|
|
31
35
|
currentType = type;
|
|
32
36
|
|
|
@@ -34,11 +38,14 @@ export function useHoverhighlight() {
|
|
|
34
38
|
return;
|
|
35
39
|
}
|
|
36
40
|
|
|
37
|
-
let block_ids: number[] =
|
|
38
|
-
typeof block_ids_provider === "function"
|
|
41
|
+
let block_ids: number[] = [
|
|
42
|
+
...(typeof block_ids_provider === "function"
|
|
43
|
+
? await block_ids_provider()
|
|
44
|
+
: block_ids_provider),
|
|
45
|
+
];
|
|
39
46
|
|
|
40
47
|
block_ids = (Array.isArray(block_ids) ? block_ids : [])
|
|
41
|
-
.map((blockId) => Math.trunc(
|
|
48
|
+
.map((blockId) => Math.trunc(blockId))
|
|
42
49
|
.filter((blockId) => !Number.isNaN(blockId));
|
|
43
50
|
|
|
44
51
|
if (currentId !== id) {
|
|
@@ -57,10 +64,38 @@ export function useHoverhighlight() {
|
|
|
57
64
|
}
|
|
58
65
|
}
|
|
59
66
|
|
|
67
|
+
async function runHighlightAction(): Promise<void> {
|
|
68
|
+
try {
|
|
69
|
+
await highlightAction();
|
|
70
|
+
} catch {
|
|
71
|
+
// Ignore
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
60
75
|
if (immediate) {
|
|
61
|
-
|
|
76
|
+
// oxlint-disable-next-line typescript/no-floating-promises -- runHighlightAction catches its own errors internally.
|
|
77
|
+
runHighlightAction();
|
|
62
78
|
} else {
|
|
63
|
-
timer = setTimeout(
|
|
79
|
+
timer = setTimeout(() => {
|
|
80
|
+
// oxlint-disable-next-line typescript/no-floating-promises -- runHighlightAction catches its own errors internally.
|
|
81
|
+
runHighlightAction();
|
|
82
|
+
}, HOVER_DELAY);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async function unhighlightAction(
|
|
87
|
+
type: HighlightType,
|
|
88
|
+
id: string,
|
|
89
|
+
request: {
|
|
90
|
+
schema: JsonRpcSchema;
|
|
91
|
+
params?: Record<string, unknown>;
|
|
92
|
+
timeout?: number;
|
|
93
|
+
},
|
|
94
|
+
): Promise<void> {
|
|
95
|
+
try {
|
|
96
|
+
await viewerStore.request(request);
|
|
97
|
+
} catch (error) {
|
|
98
|
+
console.error(`Unhighlight failed for ${type} ${id}:`, error);
|
|
64
99
|
}
|
|
65
100
|
}
|
|
66
101
|
|
|
@@ -76,16 +111,13 @@ export function useHoverhighlight() {
|
|
|
76
111
|
visibility: false,
|
|
77
112
|
...(currentType === "model" && { block_ids: [] }),
|
|
78
113
|
};
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
} catch (error) {
|
|
82
|
-
console.error(`Unhighlight failed for ${currentType} ${id}:`, error);
|
|
83
|
-
}
|
|
114
|
+
// oxlint-disable-next-line typescript/no-floating-promises -- unhighlightAction catches its own errors internally.
|
|
115
|
+
unhighlightAction(currentType, id, { schema, params });
|
|
84
116
|
currentId = undefined;
|
|
85
117
|
currentType = undefined;
|
|
86
118
|
}
|
|
87
119
|
|
|
88
|
-
if (
|
|
120
|
+
if (currentId === undefined) {
|
|
89
121
|
currentId = undefined;
|
|
90
122
|
currentType = undefined;
|
|
91
123
|
}
|
|
@@ -1,15 +1,26 @@
|
|
|
1
|
-
// Not auto-fixable (eslint's sort-imports core rule has no autofixer) and this file's import order doesn't match its syntax-kind-then-alphabetical requirement - left as-is rather than manually reordered across the codebase for a purely cosmetic rule.
|
|
2
|
-
// oxlint-disable eslint/sort-imports
|
|
3
|
-
import { compareSelections } from "@ogw_front/utils/treeview";
|
|
4
|
-
import { useDataStore } from "@ogw_front/stores/data";
|
|
5
|
-
import { useDataStyleStore } from "@ogw_front/stores/data_style";
|
|
6
|
-
import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
|
|
7
1
|
import type {
|
|
8
2
|
CollectionComponent,
|
|
9
3
|
CollectionComponentGroup,
|
|
10
4
|
} from "@ogw_front/stores/data_helpers/collections";
|
|
5
|
+
import { compareSelections } from "@ogw_front/utils/treeview";
|
|
6
|
+
import { useDataStore } from "@ogw_front/stores/data";
|
|
7
|
+
import { useDataStyleStore } from "@ogw_front/stores/data_style";
|
|
8
|
+
import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
|
|
9
|
+
|
|
10
|
+
// The `watch` callback receives the freshly-fetched collection groups purely for reading (matching against and copying into `localCategories`, never mutated in place), so it's typed with its own fully-readonly mirror of `CollectionComponentGroup` rather than that (intentionally mutable, see `existing.title` below) store type directly.
|
|
11
|
+
interface ReadonlyCollectionComponentGroup {
|
|
12
|
+
readonly id: string;
|
|
13
|
+
readonly title: string;
|
|
14
|
+
readonly children: readonly CollectionComponent[];
|
|
15
|
+
}
|
|
11
16
|
|
|
12
|
-
export function useModelCollections(viewId: string) {
|
|
17
|
+
export function useModelCollections(viewId: string): {
|
|
18
|
+
items: typeof items;
|
|
19
|
+
collectionsCache: typeof collectionsCache;
|
|
20
|
+
localCategories: typeof localCategories;
|
|
21
|
+
selection: typeof selection;
|
|
22
|
+
updateVisibility: typeof updateVisibility;
|
|
23
|
+
} {
|
|
13
24
|
const dataStore = useDataStore();
|
|
14
25
|
const dataStyleStore = useDataStyleStore();
|
|
15
26
|
const hybridViewerStore = useHybridViewerStore();
|
|
@@ -25,7 +36,7 @@ export function useModelCollections(viewId: string) {
|
|
|
25
36
|
|
|
26
37
|
watch(
|
|
27
38
|
items,
|
|
28
|
-
async (newItems) => {
|
|
39
|
+
async (newItems: readonly ReadonlyCollectionComponentGroup[] | undefined) => {
|
|
29
40
|
if (!newItems) {
|
|
30
41
|
localCategories.value = [];
|
|
31
42
|
return;
|
|
@@ -34,8 +45,10 @@ export function useModelCollections(viewId: string) {
|
|
|
34
45
|
const data = await dataStore.fetchAllCollectionComponents(viewId);
|
|
35
46
|
collectionsCache.value = markRaw(data);
|
|
36
47
|
|
|
37
|
-
localCategories.value = newItems.map((newCategory) => {
|
|
38
|
-
const existing = localCategories.value.find(
|
|
48
|
+
localCategories.value = newItems.map((newCategory: ReadonlyCollectionComponentGroup) => {
|
|
49
|
+
const existing = localCategories.value.find(
|
|
50
|
+
(category: ReadonlyCollectionComponentGroup) => category.id === newCategory.id,
|
|
51
|
+
);
|
|
39
52
|
if (existing) {
|
|
40
53
|
existing.title = newCategory.title || newCategory.id;
|
|
41
54
|
return existing;
|
|
@@ -51,9 +64,9 @@ export function useModelCollections(viewId: string) {
|
|
|
51
64
|
|
|
52
65
|
const selection = dataStyleStore.visibleMeshComponents(viewId);
|
|
53
66
|
|
|
54
|
-
async function updateVisibility(current: string[]) {
|
|
67
|
+
async function updateVisibility(current: readonly string[]): Promise<void> {
|
|
55
68
|
const previous = selection.value;
|
|
56
|
-
const { added, removed } = compareSelections(current, previous);
|
|
69
|
+
const { added, removed } = compareSelections([...current], previous);
|
|
57
70
|
|
|
58
71
|
if (added.length === 0 && removed.length === 0) {
|
|
59
72
|
return;
|
|
@@ -65,7 +78,7 @@ export function useModelCollections(viewId: string) {
|
|
|
65
78
|
if (removed.length > 0) {
|
|
66
79
|
await dataStyleStore.setModelComponentsVisibility(viewId, removed, false);
|
|
67
80
|
}
|
|
68
|
-
hybridViewerStore.remoteRender();
|
|
81
|
+
await hybridViewerStore.remoteRender();
|
|
69
82
|
}
|
|
70
83
|
|
|
71
84
|
return {
|
|
@@ -1,15 +1,26 @@
|
|
|
1
|
-
// Not auto-fixable (eslint's sort-imports core rule has no autofixer) and this file's import order doesn't match its syntax-kind-then-alphabetical requirement - left as-is rather than manually reordered across the codebase for a purely cosmetic rule.
|
|
2
|
-
// oxlint-disable eslint/sort-imports
|
|
3
|
-
import { compareSelections } from "@ogw_front/utils/treeview";
|
|
4
|
-
import { useDataStore } from "@ogw_front/stores/data";
|
|
5
|
-
import { useDataStyleStore } from "@ogw_front/stores/data_style";
|
|
6
|
-
import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
|
|
7
1
|
import type {
|
|
8
2
|
FormattedComponent,
|
|
9
3
|
FormattedComponentGroup,
|
|
10
4
|
} from "@ogw_front/stores/data_helpers/mesh";
|
|
5
|
+
import { compareSelections } from "@ogw_front/utils/treeview";
|
|
6
|
+
import { useDataStore } from "@ogw_front/stores/data";
|
|
7
|
+
import { useDataStyleStore } from "@ogw_front/stores/data_style";
|
|
8
|
+
import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
|
|
9
|
+
|
|
10
|
+
// The `watch` callback receives the freshly-fetched component groups purely for reading (matching against and copying into `localCategories`, never mutated in place), so it's typed with its own fully-readonly mirror of `FormattedComponentGroup` rather than that (intentionally mutable, see `existing.title` below) store type directly.
|
|
11
|
+
interface ReadonlyFormattedComponentGroup {
|
|
12
|
+
readonly id: string;
|
|
13
|
+
readonly title: string;
|
|
14
|
+
readonly children: readonly FormattedComponent[];
|
|
15
|
+
}
|
|
11
16
|
|
|
12
|
-
export function useModelComponents(viewId: string) {
|
|
17
|
+
export function useModelComponents(viewId: string): {
|
|
18
|
+
items: typeof items;
|
|
19
|
+
componentsCache: typeof componentsCache;
|
|
20
|
+
localCategories: typeof localCategories;
|
|
21
|
+
selection: typeof selection;
|
|
22
|
+
updateVisibility: typeof updateVisibility;
|
|
23
|
+
} {
|
|
13
24
|
const dataStore = useDataStore();
|
|
14
25
|
const dataStyleStore = useDataStyleStore();
|
|
15
26
|
const hybridViewerStore = useHybridViewerStore();
|
|
@@ -25,7 +36,7 @@ export function useModelComponents(viewId: string) {
|
|
|
25
36
|
|
|
26
37
|
watch(
|
|
27
38
|
items,
|
|
28
|
-
async (newItems) => {
|
|
39
|
+
async (newItems: readonly ReadonlyFormattedComponentGroup[] | undefined) => {
|
|
29
40
|
if (!newItems) {
|
|
30
41
|
localCategories.value = [];
|
|
31
42
|
return;
|
|
@@ -34,8 +45,10 @@ export function useModelComponents(viewId: string) {
|
|
|
34
45
|
const data = await dataStore.fetchAllMeshComponents(viewId);
|
|
35
46
|
componentsCache.value = markRaw(data);
|
|
36
47
|
|
|
37
|
-
localCategories.value = newItems.map((newCategory) => {
|
|
38
|
-
const existing = localCategories.value.find(
|
|
48
|
+
localCategories.value = newItems.map((newCategory: ReadonlyFormattedComponentGroup) => {
|
|
49
|
+
const existing = localCategories.value.find(
|
|
50
|
+
(category: ReadonlyFormattedComponentGroup) => category.id === newCategory.id,
|
|
51
|
+
);
|
|
39
52
|
if (existing) {
|
|
40
53
|
existing.title = newCategory.title || newCategory.id;
|
|
41
54
|
return existing;
|
|
@@ -51,9 +64,9 @@ export function useModelComponents(viewId: string) {
|
|
|
51
64
|
|
|
52
65
|
const selection = dataStyleStore.visibleMeshComponents(viewId);
|
|
53
66
|
|
|
54
|
-
async function updateVisibility(current: string[]) {
|
|
67
|
+
async function updateVisibility(current: readonly string[]): Promise<void> {
|
|
55
68
|
const previous = selection.value;
|
|
56
|
-
const { added, removed } = compareSelections(current, previous);
|
|
69
|
+
const { added, removed } = compareSelections([...current], previous);
|
|
57
70
|
|
|
58
71
|
if (added.length === 0 && removed.length === 0) {
|
|
59
72
|
return;
|
|
@@ -65,7 +78,7 @@ export function useModelComponents(viewId: string) {
|
|
|
65
78
|
if (removed.length > 0) {
|
|
66
79
|
await dataStyleStore.setModelComponentsVisibility(viewId, removed, false);
|
|
67
80
|
}
|
|
68
|
-
hybridViewerStore.remoteRender();
|
|
81
|
+
await hybridViewerStore.remoteRender();
|
|
69
82
|
}
|
|
70
83
|
|
|
71
84
|
return {
|