@geode/opengeodeweb-front 10.37.0-rc.1 → 10.38.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/README.md +0 -1
  2. package/app/components/Viewer/ContextMenu/ContextMenu.vue +2 -0
  3. package/app/components/Viewer/EdgedCurve/SpecificEdgesOptions.vue +21 -1
  4. package/app/components/Viewer/Generic/Mesh/CellsOptions.vue +21 -1
  5. package/app/components/Viewer/Generic/Mesh/EdgesOptions.vue +21 -1
  6. package/app/components/Viewer/Generic/Mesh/PointsOptions.vue +13 -1
  7. package/app/components/Viewer/Generic/Mesh/PolygonsOptions.vue +21 -1
  8. package/app/components/Viewer/Generic/Mesh/PolyhedraOptions.vue +21 -1
  9. package/app/components/Viewer/Generic/Model/ModelStyleCard.vue +29 -31
  10. package/app/components/Viewer/ObjectTree/Layout.vue +2 -1
  11. package/app/components/Viewer/ObjectTree/Views/GlobalObjects.vue +24 -10
  12. package/app/components/Viewer/ObjectTree/Views/ModelTree.vue +5 -15
  13. package/app/components/Viewer/Options/AttributeColorBar.vue +7 -0
  14. package/app/components/Viewer/Options/AttributeSelector.vue +71 -21
  15. package/app/components/Viewer/Options/ColoringTypeSelector.vue +16 -0
  16. package/app/components/Viewer/Options/TextureItem.vue +15 -11
  17. package/app/components/Viewer/PointSet/SpecificPointsOptions.vue +13 -1
  18. package/app/components/Viewer/Solid/SpecificPolyhedraOptions.vue +21 -1
  19. package/app/components/Viewer/Surface/PolygonsOptions.vue +21 -1
  20. package/app/components/Viewer/Ui.vue +7 -3
  21. package/app/composables/batch_style.ts +64 -1
  22. package/app/composables/tree_filter.ts +8 -8
  23. package/app/composables/use_overlapping_picker.ts +2 -0
  24. package/app/composables/viewer_context_menu.ts +123 -0
  25. package/app/stores/menu.ts +3 -0
  26. package/app/utils/attributes.ts +38 -1
  27. package/app/utils/request_for_targets.ts +24 -0
  28. package/app/utils/treeview.ts +30 -0
  29. package/package.json +4 -6
package/README.md CHANGED
@@ -6,6 +6,5 @@ OpenSource Vue/Vuetify framework for web applications.
6
6
 
7
7
  This codebase is written in TypeScript (`strict` mode, `noUncheckedIndexedAccess`).
8
8
 
9
- - `npm run typecheck` — type-checks the app/server/shared code (via `nuxt typecheck`) and the tests/scripts code (via `tsc -p tsconfig.tests.json`), which live under separate `tsconfig.json` projects since Nuxt's own generated config only covers the former.
10
9
  - `npm run lint` — runs [oxlint](https://oxc.rs/docs/guide/usage/linter.html) with autofix. The project's `.oxlintrc.json` must stay in sync with the shared [`Geode-solutions/actions`](https://github.com/Geode-solutions/actions) config, which CI re-downloads and enforces on every run.
11
10
  - `npm run test:unit` / `npm run test:integration` — run the Vitest suites under `tests/`.
@@ -3,6 +3,7 @@ import CenterButton from "@ogw_front/components/Viewer/ContextMenu/CenterButton.
3
3
  import CircularItems from "@ogw_front/components/Viewer/ContextMenu/CircularItems.vue";
4
4
  import type { Component } from "vue";
5
5
  import InfoCard from "@ogw_front/components/Viewer/ContextMenu/InfoCard.vue";
6
+ import { provideBatchGroup } from "@ogw_front/composables/batch_style";
6
7
  import { useEventListener } from "@vueuse/core";
7
8
  import { useMenuStore } from "@ogw_front/stores/menu";
8
9
  import { useTreeviewStore } from "@ogw_front/stores/treeview";
@@ -30,6 +31,7 @@ const menuStore = useMenuStore();
30
31
  const treeviewStore = useTreeviewStore();
31
32
 
32
33
  const meta_data = computed(() => menuStore.current_meta_data || {});
34
+ provideBatchGroup(() => meta_data.value.targetIds ?? []);
33
35
 
34
36
  const show_menu = ref<boolean>(true);
35
37
  const showName = ref<boolean>(false);
@@ -1,4 +1,9 @@
1
1
  <script setup lang="ts">
2
+ import {
3
+ type RangesPerData,
4
+ applyRangesPerData,
5
+ useBatchStyle,
6
+ } from "@ogw_front/composables/batch_style";
2
7
  import ViewerContextMenuItem, {
3
8
  type ItemProps,
4
9
  } from "@ogw_front/components/Viewer/ContextMenu/ContextMenuItem.vue";
@@ -7,7 +12,6 @@ import type { RGBAColor } from "@ogw_front/utils/default_styles/constants";
7
12
  import ViewerOptionsColoringTypeSelector from "@ogw_front/components/Viewer/Options/ColoringTypeSelector.vue";
8
13
  import ViewerOptionsVisibilitySwitch from "@ogw_front/components/Viewer/Options/VisibilitySwitch.vue";
9
14
  import ViewerOptionsWidthSlider from "@ogw_front/components/Viewer/Options/Sliders/Width.vue";
10
- import { useBatchStyle } from "@ogw_front/composables/batch_style";
11
15
  import { useDataStyleStore } from "@ogw_front/stores/data_style";
12
16
  import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
13
17
 
@@ -166,6 +170,20 @@ const edge_attribute_no_data_color = computed<RGBAColor>({
166
170
  hybridViewerStore.remoteRender();
167
171
  },
168
172
  });
173
+
174
+ async function setVertexAttributeRangesPerData(ranges: RangesPerData): Promise<void> {
175
+ await applyRangesPerData(ranges, (targetId, minimum, maximum) =>
176
+ dataStyleStore.setMeshEdgesVertexAttributeRange(targetId, minimum, maximum),
177
+ );
178
+ hybridViewerStore.remoteRender();
179
+ }
180
+
181
+ async function setEdgeAttributeRangesPerData(ranges: RangesPerData): Promise<void> {
182
+ await applyRangesPerData(ranges, (targetId, minimum, maximum) =>
183
+ dataStyleStore.setMeshEdgesEdgeAttributeRange(targetId, minimum, maximum),
184
+ );
185
+ hybridViewerStore.remoteRender();
186
+ }
169
187
  </script>
170
188
 
171
189
  <template>
@@ -188,11 +206,13 @@ const edge_attribute_no_data_color = computed<RGBAColor>({
188
206
  v-model:vertex_attribute_name="vertex_attribute_name"
189
207
  v-model:vertex_attribute_item="vertex_attribute_item"
190
208
  v-model:vertex_attribute_range="vertex_attribute_range"
209
+ @vertex_attribute_ranges_per_data="setVertexAttributeRangesPerData"
191
210
  v-model:vertex_attribute_color_map="vertex_attribute_color_map"
192
211
  v-model:vertex_attribute_no_data_color="vertex_attribute_no_data_color"
193
212
  v-model:edge_attribute_name="edge_attribute_name"
194
213
  v-model:edge_attribute_item="edge_attribute_item"
195
214
  v-model:edge_attribute_range="edge_attribute_range"
215
+ @edge_attribute_ranges_per_data="setEdgeAttributeRangesPerData"
196
216
  v-model:edge_attribute_color_map="edge_attribute_color_map"
197
217
  v-model:edge_attribute_no_data_color="edge_attribute_no_data_color"
198
218
  />
@@ -1,11 +1,15 @@
1
1
  <script setup lang="ts">
2
+ import {
3
+ type RangesPerData,
4
+ applyRangesPerData,
5
+ useBatchStyle,
6
+ } from "@ogw_front/composables/batch_style";
2
7
  import ViewerContextMenuItem, {
3
8
  type ItemProps,
4
9
  } from "@ogw_front/components/Viewer/ContextMenu/ContextMenuItem.vue";
5
10
  import type { RGBAColor } from "@ogw_front/utils/default_styles/constants";
6
11
  import ViewerOptionsColoringTypeSelector from "@ogw_front/components/Viewer/Options/ColoringTypeSelector.vue";
7
12
  import ViewerOptionsVisibilitySwitch from "@ogw_front/components/Viewer/Options/VisibilitySwitch.vue";
8
- import { useBatchStyle } from "@ogw_front/composables/batch_style";
9
13
  import { useDataStyleStore } from "@ogw_front/stores/data_style";
10
14
  import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
11
15
 
@@ -175,6 +179,20 @@ const cell_attribute_no_data_color = computed<RGBAColor>({
175
179
  hybridViewerStore.remoteRender();
176
180
  },
177
181
  });
182
+
183
+ async function setVertexAttributeRangesPerData(ranges: RangesPerData): Promise<void> {
184
+ await applyRangesPerData(ranges, (targetId, minimum, maximum) =>
185
+ dataStyleStore.setMeshCellsVertexAttributeRange(targetId, minimum, maximum),
186
+ );
187
+ hybridViewerStore.remoteRender();
188
+ }
189
+
190
+ async function setCellAttributeRangesPerData(ranges: RangesPerData): Promise<void> {
191
+ await applyRangesPerData(ranges, (targetId, minimum, maximum) =>
192
+ dataStyleStore.setMeshCellsCellAttributeRange(targetId, minimum, maximum),
193
+ );
194
+ hybridViewerStore.remoteRender();
195
+ }
178
196
  </script>
179
197
 
180
198
  <template>
@@ -197,11 +215,13 @@ const cell_attribute_no_data_color = computed<RGBAColor>({
197
215
  v-model:vertex_attribute_name="vertex_attribute_name"
198
216
  v-model:vertex_attribute_item="vertex_attribute_item"
199
217
  v-model:vertex_attribute_range="vertex_attribute_range"
218
+ @vertex_attribute_ranges_per_data="setVertexAttributeRangesPerData"
200
219
  v-model:vertex_attribute_color_map="vertex_attribute_color_map"
201
220
  v-model:vertex_attribute_no_data_color="vertex_attribute_no_data_color"
202
221
  v-model:cell_attribute_name="cell_attribute_name"
203
222
  v-model:cell_attribute_item="cell_attribute_item"
204
223
  v-model:cell_attribute_range="cell_attribute_range"
224
+ @cell_attribute_ranges_per_data="setCellAttributeRangesPerData"
205
225
  v-model:cell_attribute_color_map="cell_attribute_color_map"
206
226
  v-model:cell_attribute_no_data_color="cell_attribute_no_data_color"
207
227
  />
@@ -1,4 +1,9 @@
1
1
  <script setup lang="ts">
2
+ import {
3
+ type RangesPerData,
4
+ applyRangesPerData,
5
+ useBatchStyle,
6
+ } from "@ogw_front/composables/batch_style";
2
7
  import ViewerContextMenuItem, {
3
8
  type ItemProps,
4
9
  } from "@ogw_front/components/Viewer/ContextMenu/ContextMenuItem.vue";
@@ -6,7 +11,6 @@ import type { RGBAColor } from "@ogw_front/utils/default_styles/constants";
6
11
  import ViewerOptionsColoringTypeSelector from "@ogw_front/components/Viewer/Options/ColoringTypeSelector.vue";
7
12
  import ViewerOptionsVisibilitySwitch from "@ogw_front/components/Viewer/Options/VisibilitySwitch.vue";
8
13
  import ViewerOptionsWidthSlider from "@ogw_front/components/Viewer/Options/Sliders/Width.vue";
9
- import { useBatchStyle } from "@ogw_front/composables/batch_style";
10
14
  import { useDataStyleStore } from "@ogw_front/stores/data_style";
11
15
  import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
12
16
 
@@ -167,6 +171,20 @@ const edge_attribute_no_data_color = computed<RGBAColor>({
167
171
  hybridViewerStore.remoteRender();
168
172
  },
169
173
  });
174
+
175
+ async function setVertexAttributeRangesPerData(ranges: RangesPerData): Promise<void> {
176
+ await applyRangesPerData(ranges, (targetId, minimum, maximum) =>
177
+ dataStyleStore.setMeshEdgesVertexAttributeRange(targetId, minimum, maximum),
178
+ );
179
+ hybridViewerStore.remoteRender();
180
+ }
181
+
182
+ async function setEdgeAttributeRangesPerData(ranges: RangesPerData): Promise<void> {
183
+ await applyRangesPerData(ranges, (targetId, minimum, maximum) =>
184
+ dataStyleStore.setMeshEdgesEdgeAttributeRange(targetId, minimum, maximum),
185
+ );
186
+ hybridViewerStore.remoteRender();
187
+ }
170
188
  </script>
171
189
 
172
190
  <template>
@@ -196,11 +214,13 @@ const edge_attribute_no_data_color = computed<RGBAColor>({
196
214
  v-model:vertex_attribute_name="vertex_attribute_name"
197
215
  v-model:vertex_attribute_item="vertex_attribute_item"
198
216
  v-model:vertex_attribute_range="vertex_attribute_range"
217
+ @vertex_attribute_ranges_per_data="setVertexAttributeRangesPerData"
199
218
  v-model:vertex_attribute_color_map="vertex_attribute_color_map"
200
219
  v-model:vertex_attribute_no_data_color="vertex_attribute_no_data_color"
201
220
  v-model:edge_attribute_name="edge_attribute_name"
202
221
  v-model:edge_attribute_item="edge_attribute_item"
203
222
  v-model:edge_attribute_range="edge_attribute_range"
223
+ @edge_attribute_ranges_per_data="setEdgeAttributeRangesPerData"
204
224
  v-model:edge_attribute_color_map="edge_attribute_color_map"
205
225
  v-model:edge_attribute_no_data_color="edge_attribute_no_data_color"
206
226
  />
@@ -1,4 +1,9 @@
1
1
  <script setup lang="ts">
2
+ import {
3
+ type RangesPerData,
4
+ applyRangesPerData,
5
+ useBatchStyle,
6
+ } from "@ogw_front/composables/batch_style";
2
7
  import ViewerContextMenuItem, {
3
8
  type ItemProps,
4
9
  } from "@ogw_front/components/Viewer/ContextMenu/ContextMenuItem.vue";
@@ -6,7 +11,6 @@ import type { RGBAColor } from "@ogw_front/utils/default_styles/constants";
6
11
  import ViewerOptionsColoringTypeSelector from "@ogw_front/components/Viewer/Options/ColoringTypeSelector.vue";
7
12
  import ViewerOptionsSizeSlider from "@ogw_front/components/Viewer/Options/Sliders/Size.vue";
8
13
  import ViewerOptionsVisibilitySwitch from "@ogw_front/components/Viewer/Options/VisibilitySwitch.vue";
9
- import { useBatchStyle } from "@ogw_front/composables/batch_style";
10
14
  import { useDataStyleStore } from "@ogw_front/stores/data_style";
11
15
  import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
12
16
 
@@ -115,6 +119,13 @@ const vertex_attribute_no_data_color = computed<RGBAColor>({
115
119
  hybridViewerStore.remoteRender();
116
120
  },
117
121
  });
122
+
123
+ async function setVertexAttributeRangesPerData(ranges: RangesPerData): Promise<void> {
124
+ await applyRangesPerData(ranges, (targetId, minimum, maximum) =>
125
+ dataStyleStore.setMeshPointsVertexAttributeRange(targetId, minimum, maximum),
126
+ );
127
+ hybridViewerStore.remoteRender();
128
+ }
118
129
  </script>
119
130
 
120
131
  <template>
@@ -144,6 +155,7 @@ const vertex_attribute_no_data_color = computed<RGBAColor>({
144
155
  v-model:vertex_attribute_name="vertex_attribute_name"
145
156
  v-model:vertex_attribute_item="vertex_attribute_item"
146
157
  v-model:vertex_attribute_range="vertex_attribute_range"
158
+ @vertex_attribute_ranges_per_data="setVertexAttributeRangesPerData"
147
159
  v-model:vertex_attribute_color_map="vertex_attribute_color_map"
148
160
  v-model:vertex_attribute_no_data_color="vertex_attribute_no_data_color"
149
161
  :capabilities="{ vertex: { available: false } }"
@@ -1,11 +1,15 @@
1
1
  <script setup lang="ts">
2
+ import {
3
+ type RangesPerData,
4
+ applyRangesPerData,
5
+ useBatchStyle,
6
+ } from "@ogw_front/composables/batch_style";
2
7
  import ViewerContextMenuItem, {
3
8
  type ItemProps,
4
9
  } from "@ogw_front/components/Viewer/ContextMenu/ContextMenuItem.vue";
5
10
  import type { RGBAColor } from "@ogw_front/utils/default_styles/constants";
6
11
  import ViewerOptionsColoringTypeSelector from "@ogw_front/components/Viewer/Options/ColoringTypeSelector.vue";
7
12
  import ViewerOptionsVisibilitySwitch from "@ogw_front/components/Viewer/Options/VisibilitySwitch.vue";
8
- import { useBatchStyle } from "@ogw_front/composables/batch_style";
9
13
  import { useDataStyleStore } from "@ogw_front/stores/data_style";
10
14
  import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
11
15
 
@@ -190,6 +194,20 @@ const polygon_attribute_no_data_color = computed<RGBAColor>({
190
194
  hybridViewerStore.remoteRender();
191
195
  },
192
196
  });
197
+
198
+ async function setVertexAttributeRangesPerData(ranges: RangesPerData): Promise<void> {
199
+ await applyRangesPerData(ranges, (targetId, minimum, maximum) =>
200
+ dataStyleStore.setMeshPolygonsVertexAttributeRange(targetId, minimum, maximum),
201
+ );
202
+ hybridViewerStore.remoteRender();
203
+ }
204
+
205
+ async function setPolygonAttributeRangesPerData(ranges: RangesPerData): Promise<void> {
206
+ await applyRangesPerData(ranges, (targetId, minimum, maximum) =>
207
+ dataStyleStore.setMeshPolygonsPolygonAttributeRange(targetId, minimum, maximum),
208
+ );
209
+ hybridViewerStore.remoteRender();
210
+ }
193
211
  </script>
194
212
 
195
213
  <template>
@@ -215,11 +233,13 @@ const polygon_attribute_no_data_color = computed<RGBAColor>({
215
233
  v-model:vertex_attribute_name="vertex_attribute_name"
216
234
  v-model:vertex_attribute_item="vertex_attribute_item"
217
235
  v-model:vertex_attribute_range="vertex_attribute_range"
236
+ @vertex_attribute_ranges_per_data="setVertexAttributeRangesPerData"
218
237
  v-model:vertex_attribute_color_map="vertex_attribute_color_map"
219
238
  v-model:vertex_attribute_no_data_color="vertex_attribute_no_data_color"
220
239
  v-model:polygon_attribute_name="polygon_attribute_name"
221
240
  v-model:polygon_attribute_item="polygon_attribute_item"
222
241
  v-model:polygon_attribute_range="polygon_attribute_range"
242
+ @polygon_attribute_ranges_per_data="setPolygonAttributeRangesPerData"
223
243
  v-model:polygon_attribute_color_map="polygon_attribute_color_map"
224
244
  v-model:polygon_attribute_no_data_color="polygon_attribute_no_data_color"
225
245
  :capabilities="capabilities"
@@ -1,11 +1,15 @@
1
1
  <script setup lang="ts">
2
+ import {
3
+ type RangesPerData,
4
+ applyRangesPerData,
5
+ useBatchStyle,
6
+ } from "@ogw_front/composables/batch_style";
2
7
  import ViewerContextMenuItem, {
3
8
  type ItemProps,
4
9
  } from "@ogw_front/components/Viewer/ContextMenu/ContextMenuItem.vue";
5
10
  import type { RGBAColor } from "@ogw_front/utils/default_styles/constants";
6
11
  import ViewerOptionsColoringTypeSelector from "@ogw_front/components/Viewer/Options/ColoringTypeSelector.vue";
7
12
  import ViewerOptionsVisibilitySwitch from "@ogw_front/components/Viewer/Options/VisibilitySwitch.vue";
8
- import { useBatchStyle } from "@ogw_front/composables/batch_style";
9
13
  import { useDataStyleStore } from "@ogw_front/stores/data_style";
10
14
  import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
11
15
 
@@ -163,6 +167,20 @@ const polyhedron_attribute_no_data_color = computed<RGBAColor>({
163
167
  hybridViewerStore.remoteRender();
164
168
  },
165
169
  });
170
+
171
+ async function setVertexAttributeRangesPerData(ranges: RangesPerData): Promise<void> {
172
+ await applyRangesPerData(ranges, (targetId, minimum, maximum) =>
173
+ dataStyleStore.setMeshPolyhedraVertexAttributeRange(targetId, minimum, maximum),
174
+ );
175
+ hybridViewerStore.remoteRender();
176
+ }
177
+
178
+ async function setPolyhedronAttributeRangesPerData(ranges: RangesPerData): Promise<void> {
179
+ await applyRangesPerData(ranges, (targetId, minimum, maximum) =>
180
+ dataStyleStore.setMeshPolyhedraPolyhedronAttributeRange(targetId, minimum, maximum),
181
+ );
182
+ hybridViewerStore.remoteRender();
183
+ }
166
184
  </script>
167
185
 
168
186
  <template>
@@ -187,11 +205,13 @@ const polyhedron_attribute_no_data_color = computed<RGBAColor>({
187
205
  v-model:vertex_attribute_name="vertex_attribute_name"
188
206
  v-model:vertex_attribute_item="vertex_attribute_item"
189
207
  v-model:vertex_attribute_range="vertex_attribute_range"
208
+ @vertex_attribute_ranges_per_data="setVertexAttributeRangesPerData"
190
209
  v-model:vertex_attribute_color_map="vertex_attribute_color_map"
191
210
  v-model:vertex_attribute_no_data_color="vertex_attribute_no_data_color"
192
211
  v-model:polyhedron_attribute_name="polyhedron_attribute_name"
193
212
  v-model:polyhedron_attribute_item="polyhedron_attribute_item"
194
213
  v-model:polyhedron_attribute_range="polyhedron_attribute_range"
214
+ @polyhedron_attribute_ranges_per_data="setPolyhedronAttributeRangesPerData"
195
215
  v-model:polyhedron_attribute_color_map="polyhedron_attribute_color_map"
196
216
  v-model:polyhedron_attribute_no_data_color="polyhedron_attribute_no_data_color"
197
217
  :capabilities="{
@@ -9,23 +9,15 @@ import type { RGBAColor } from "@ogw_front/utils/default_styles/constants";
9
9
  import SurfacesOptions from "./SurfacesOptions.vue";
10
10
  import ViewerOptionsColoringTypeSelector from "@ogw_front/components/Viewer/Options/ColoringTypeSelector.vue";
11
11
  import VisibilitySwitch from "@ogw_front/components/Viewer/Options/VisibilitySwitch.vue";
12
+ import { useBatchStyle } from "@ogw_front/composables/batch_style";
12
13
  import { useDataStore } from "@ogw_front/stores/data";
13
14
  import { useDataStyleStore } from "@ogw_front/stores/data_style";
14
15
  import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
15
- import { useTreeviewStore } from "@ogw_front/stores/treeview";
16
16
 
17
17
  const dataStyleStore = useDataStyleStore();
18
18
  const hybridViewerStore = useHybridViewerStore();
19
19
  const dataStore = useDataStore();
20
- const treeviewStore = useTreeviewStore();
21
-
22
- function getBatchComponentIds(currentId: string): string[] {
23
- const { activeItems } = treeviewStore;
24
- if (activeItems.includes(currentId) && activeItems.length > 1) {
25
- return activeItems;
26
- }
27
- return [currentId];
28
- }
20
+ const { applyBatchStyle } = useBatchStyle();
29
21
 
30
22
  interface Props {
31
23
  itemProps: Record<string, unknown>;
@@ -35,9 +27,9 @@ const { itemProps } = defineProps<Props>();
35
27
 
36
28
  const modelId = computed<string>(() => itemProps.meta_data.modelId || itemProps.id);
37
29
  const componentId = computed<string | undefined>(() => itemProps.meta_data.pickedComponentId);
38
- const selection = computed<string[]>(
39
- () => dataStyleStore.visibleMeshComponents(modelId.value).value || [],
40
- );
30
+ function visibleComponents(targetId: string): string[] {
31
+ return dataStyleStore.visibleMeshComponents(targetId).value || [];
32
+ }
41
33
  const componentType = ref<string | undefined>(undefined);
42
34
  const collections = ref<CollectionComponent[] | undefined>(undefined);
43
35
 
@@ -105,7 +97,9 @@ const modelVisibility = computed<boolean | undefined>({
105
97
  if (newValue === undefined) {
106
98
  return;
107
99
  }
108
- await dataStyleStore.setModelVisibility(modelId.value, newValue);
100
+ await applyBatchStyle(modelId.value, (targetId: string) =>
101
+ dataStyleStore.setModelVisibility(targetId, newValue),
102
+ );
109
103
  hybridViewerStore.remoteRender();
110
104
  },
111
105
  });
@@ -113,16 +107,18 @@ const modelVisibility = computed<boolean | undefined>({
113
107
  const modelComponentsColor = computed<RGBAColor | undefined>({
114
108
  get: () => dataStyleStore.getModelColor(modelId.value) as RGBAColor | undefined,
115
109
  set: async (color) => {
116
- await dataStyleStore.mutateStyle(modelId.value, {
117
- coloring: { constant: color },
110
+ await applyBatchStyle(modelId.value, async (targetId: string) => {
111
+ await dataStyleStore.mutateStyle(targetId, {
112
+ coloring: { constant: color },
113
+ });
114
+ const activeColoring = dataStyleStore.getModelActiveColoring(targetId);
115
+ await dataStyleStore.setModelComponentsColor(
116
+ targetId,
117
+ visibleComponents(targetId),
118
+ color,
119
+ typeof activeColoring === "string" ? activeColoring : undefined,
120
+ );
118
121
  });
119
- const activeColoring = dataStyleStore.getModelActiveColoring(modelId.value);
120
- await dataStyleStore.setModelComponentsColor(
121
- modelId.value,
122
- selection.value,
123
- color,
124
- typeof activeColoring === "string" ? activeColoring : undefined,
125
- );
126
122
  hybridViewerStore.remoteRender();
127
123
  },
128
124
  });
@@ -133,15 +129,17 @@ const modelComponentsActiveColoring = computed<string | undefined>({
133
129
  if (typeof coloringType !== "string") {
134
130
  return;
135
131
  }
136
- await dataStyleStore.mutateStyle(modelId.value, {
137
- coloring: { active: coloringType },
132
+ await applyBatchStyle(modelId.value, async (targetId: string) => {
133
+ await dataStyleStore.mutateStyle(targetId, {
134
+ coloring: { active: coloringType },
135
+ });
136
+ await dataStyleStore.setModelComponentsColor(
137
+ targetId,
138
+ visibleComponents(targetId),
139
+ dataStyleStore.getModelColor(targetId),
140
+ coloringType,
141
+ );
138
142
  });
139
- await dataStyleStore.setModelComponentsColor(
140
- modelId.value,
141
- selection.value,
142
- dataStyleStore.getModelColor(modelId.value),
143
- coloringType,
144
- );
145
143
  hybridViewerStore.remoteRender();
146
144
  },
147
145
  });
@@ -1,6 +1,7 @@
1
1
  <script setup lang="ts">
2
2
  import GlobalObjects from "@ogw_front/components/Viewer/ObjectTree/Views/GlobalObjects.vue";
3
3
  import ModelTree from "@ogw_front/components/Viewer/ObjectTree/Views/ModelTree.vue";
4
+ import type { TreeMenuPayload } from "@ogw_front/utils/treeview";
4
5
  import ViewerObjectTreeBox from "@ogw_front/components/Viewer/ObjectTree/Box.vue";
5
6
  import { geode_objects } from "@ogw_front/assets/geode_objects";
6
7
  import { useAdaptiveStyles } from "@ogw_front/composables/use_adaptive_styles";
@@ -24,7 +25,7 @@ const { containerWidth } = defineProps<Props>();
24
25
  const treeviewStore = useTreeviewStore();
25
26
 
26
27
  interface Emits {
27
- "show-menu": [payload: Record<string, unknown>];
28
+ "show-menu": [payload: TreeMenuPayload];
28
29
  }
29
30
 
30
31
  const emit = defineEmits<Emits>();
@@ -1,9 +1,13 @@
1
1
  <script setup lang="ts">
2
+ import {
3
+ type DataMenuPayload,
4
+ type GeodeObjectTypeMenuPayload,
5
+ compareSelections,
6
+ } from "@ogw_front/utils/treeview";
2
7
  import CommonTreeView from "@ogw_front/components/Viewer/ObjectTree/Base/CommonTreeView.vue";
3
8
  import type { DisplayItem } from "@ogw_front/composables/virtual_tree";
4
9
  import ObjectTreeControls from "@ogw_front/components/Viewer/ObjectTree/Base/Controls.vue";
5
10
  import ObjectTreeItemLabel from "@ogw_front/components/Viewer/ObjectTree/Base/ItemLabel.vue";
6
- import { compareSelections } from "@ogw_front/utils/treeview";
7
11
  import { consola } from "consola";
8
12
  import { useDataStore } from "@ogw_front/stores/data";
9
13
  import { useDataStyleStore } from "@ogw_front/stores/data_style";
@@ -19,7 +23,7 @@ const hybridViewerStore = useHybridViewerStore();
19
23
  const { onHoverEnter, onHoverLeave } = useHoverhighlight();
20
24
 
21
25
  interface Emits {
22
- "show-menu": [payload: { event: MouseEvent; itemId: string }];
26
+ "show-menu": [payload: DataMenuPayload | GeodeObjectTypeMenuPayload];
23
27
  }
24
28
 
25
29
  const emit = defineEmits<Emits>();
@@ -51,7 +55,7 @@ const {
51
55
  } = useTreeFilter(() => treeviewStore.items, { recursiveSort: true });
52
56
 
53
57
  function onUpdateSelection(val: string[]): void {
54
- treeviewStore.selection = applySearchFilter(val, treeviewStore.selection) as string[];
58
+ treeviewStore.selection = applySearchFilter(val, treeviewStore.selection);
55
59
  }
56
60
 
57
61
  const visibleSelection = computed<string[]>(() => applySearchFilter(treeviewStore.selection, []));
@@ -83,6 +87,21 @@ watch(
83
87
  },
84
88
  );
85
89
 
90
+ function showMenu(event: MouseEvent, item: TreeGroupItem): void {
91
+ const actualItem = item.raw || item;
92
+ if (!actualItem.children) {
93
+ emit("show-menu", { event, itemId: actualItem.id });
94
+ return;
95
+ }
96
+ const childIds = actualItem.children.map((child) => child.id);
97
+ emit("show-menu", {
98
+ event,
99
+ itemId: actualItem.id,
100
+ context_type: "geode_object_type",
101
+ targetIds: applySearchFilter(childIds),
102
+ });
103
+ }
104
+
86
105
  function isModel(item: TreeGroupItem): boolean {
87
106
  const actualItem = item.raw || item;
88
107
  return (
@@ -191,18 +210,13 @@ function expandAll(): void {
191
210
  @update:scroll-top="treeviewStore.setScrollTop(mainView?.id ?? '', $event)"
192
211
  @hover:enter="({ item }) => handleHoverEnter({ item: item as unknown as TreeGroupItem })"
193
212
  @hover:leave="({ item }) => handleHoverLeave({ item: item as unknown as TreeGroupItem })"
194
- @contextmenu="
195
- emit('show-menu', {
196
- event: $event.event,
197
- itemId: $event.item.id as string,
198
- })
199
- "
213
+ @contextmenu="showMenu($event.event, $event.item as unknown as TreeGroupItem)"
200
214
  >
201
215
  <template #title="{ item, isLeaf }">
202
216
  <ObjectTreeItemLabel
203
217
  :item="item as unknown as DisplayItem"
204
218
  :is-leaf="isLeaf"
205
- @contextmenu="emit('show-menu', { event: $event, itemId: item.id as string })"
219
+ @contextmenu="showMenu($event, item as unknown as TreeGroupItem)"
206
220
  />
207
221
  </template>
208
222
 
@@ -4,6 +4,7 @@ import CommonTreeView from "@ogw_front/components/Viewer/ObjectTree/Base/CommonT
4
4
  import type { DisplayItem } from "@ogw_front/composables/virtual_tree";
5
5
  import FetchingData from "@ogw_front/components/FetchingData.vue";
6
6
  import { MESH_COMPONENT_TYPES } from "@ogw_front/utils/default_styles";
7
+ import type { ModelComponentMenuPayload } from "@ogw_front/utils/treeview";
7
8
  import ObjectTreeControls from "@ogw_front/components/Viewer/ObjectTree/Base/Controls.vue";
8
9
  import ObjectTreeItemLabel from "@ogw_front/components/Viewer/ObjectTree/Base/ItemLabel.vue";
9
10
  import { useHoverhighlight } from "@ogw_front/composables/hover_highlight";
@@ -33,16 +34,7 @@ interface CollectionTreeItem {
33
34
  const { onHoverEnter, onHoverLeave } = useHoverhighlight();
34
35
  const hybridViewerStore = useHybridViewerStore();
35
36
  interface Emits {
36
- "show-menu": [
37
- payload: {
38
- event: unknown;
39
- itemId: string;
40
- context_type: "model_component" | "model_component_type";
41
- modelId: string;
42
- modelComponentType?: string;
43
- targetComponentIds?: string[];
44
- },
45
- ];
37
+ "show-menu": [payload: ModelComponentMenuPayload];
46
38
  }
47
39
 
48
40
  const emit = defineEmits<Emits>();
@@ -87,12 +79,10 @@ const {
87
79
 
88
80
  function onUpdateSelection(newSelection: string[]): void {
89
81
  const finalSelection = applySearchFilter(newSelection, visibleComponents.value);
90
- updateVisibility(finalSelection as string[]);
82
+ updateVisibility(finalSelection);
91
83
  }
92
84
 
93
- const visibleSelection = computed<string[]>(
94
- () => applySearchFilter(visibleComponents.value, []) as string[],
95
- );
85
+ const visibleSelection = computed<string[]>(() => applySearchFilter(visibleComponents.value, []));
96
86
 
97
87
  const itemsForTreeView = computed<CollectionTreeItem[]>(() => {
98
88
  if (search.value && cache.value) {
@@ -137,7 +127,7 @@ function extractComponentIds(node: CollectionTreeItem): string[] {
137
127
  return [node.id];
138
128
  }
139
129
 
140
- function showContextMenu(event: unknown, item: CollectionTreeItem): void {
130
+ function showContextMenu(event: MouseEvent, item: CollectionTreeItem): void {
141
131
  const actualItem = item.raw || item;
142
132
  if (isCollections.value && !MESH_COMPONENT_TYPES.includes(actualItem.category ?? "")) {
143
133
  emit("show-menu", {
@@ -8,6 +8,12 @@ interface Emits {
8
8
 
9
9
  const emit = defineEmits<Emits>();
10
10
 
11
+ interface Props {
12
+ hideRange?: boolean;
13
+ }
14
+
15
+ const { hideRange = false } = defineProps<Props>();
16
+
11
17
  const minimum = defineModel<number>("minimum");
12
18
  const maximum = defineModel<number>("maximum");
13
19
  const colorMap = defineModel<string>("colorMap");
@@ -21,6 +27,7 @@ const colorMap = defineModel<string>("colorMap");
21
27
  :max="maximum ?? 0"
22
28
  />
23
29
  <AttributeRangeSelector
30
+ v-if="!hideRange"
24
31
  v-model:minimum="minimum"
25
32
  v-model:maximum="maximum"
26
33
  class="mt-2"