@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.
Files changed (282) hide show
  1. package/{server → .build/server}/utils/app_config.js +10 -9
  2. package/{server → .build/server}/utils/cleanup.js +31 -17
  3. package/{server → .build/server}/utils/cloud.js +1 -4
  4. package/{server → .build/server}/utils/microservices.js +21 -9
  5. package/{server → .build/server}/utils/path.js +4 -4
  6. package/{server → .build/server}/utils/scripts.js +9 -9
  7. package/.build/server/utils/server_config.js +51 -0
  8. package/.build/server/utils/stream.js +6 -0
  9. package/{server → .build/server}/utils/ws_client.js +18 -3
  10. package/{shared → .build/shared}/scripts.js +10 -10
  11. package/.build/shared/utils/call_raw.js +31 -0
  12. package/{shared → .build/shared}/utils/call_schema.js +2 -2
  13. package/.build/shared/utils/fetch_raw.js +52 -0
  14. package/{shared → .build/shared}/utils/fetch_schema.js +2 -2
  15. package/{shared → .build/shared}/utils/file.js +3 -1
  16. package/{shared → .build/shared}/utils/response_handlers/load.js +10 -7
  17. package/{shared → .build/shared}/utils/validate_schema.js +1 -1
  18. package/app/components/ActionButton.vue +6 -6
  19. package/app/components/CameraManager/List.vue +5 -5
  20. package/app/components/CameraManager/Saver.vue +3 -5
  21. package/app/components/CameraManager.vue +6 -4
  22. package/app/components/CameraOrientation.vue +12 -12
  23. package/app/components/ClippingPlaneCard.vue +4 -2
  24. package/app/components/ClippingPlanes.vue +8 -8
  25. package/app/components/CrsSelector.vue +9 -10
  26. package/app/components/DeleteDialog.vue +4 -2
  27. package/app/components/DragAndDrop.vue +10 -12
  28. package/app/components/DragAndDropInternal/DragAndDropInline.vue +4 -2
  29. package/app/components/ExtensionSelector.vue +4 -4
  30. package/app/components/FeedBack/ErrorBanner.vue +3 -1
  31. package/app/components/FeedBack/Snackers.vue +4 -3
  32. package/app/components/FileSelector.vue +10 -8
  33. package/app/components/FileUploader.vue +11 -11
  34. package/app/components/GlassCard.vue +1 -1
  35. package/app/components/HybridRenderingView.vue +7 -5
  36. package/app/components/HybridViewerTooltip.vue +7 -7
  37. package/app/components/Launcher.vue +1 -1
  38. package/app/components/Loading/EcoMessages.vue +9 -3
  39. package/app/components/Loading.vue +2 -2
  40. package/app/components/MissingFilesSelector.vue +12 -10
  41. package/app/components/ObjectSelector.vue +10 -9
  42. package/app/components/PackagesVersions.vue +6 -5
  43. package/app/components/Recaptcha.vue +3 -3
  44. package/app/components/RemoteRenderingView.vue +6 -7
  45. package/app/components/Ruler.vue +3 -3
  46. package/app/components/Screenshot.vue +6 -6
  47. package/app/components/SearchBar.vue +4 -2
  48. package/app/components/ShrinkFilter.vue +7 -7
  49. package/app/components/Step.vue +6 -5
  50. package/app/components/Stepper.vue +4 -3
  51. package/app/components/ToolPanel.vue +6 -3
  52. package/app/components/ViewToolbar.vue +25 -28
  53. package/app/components/Viewer/ContextMenu/CenterButton.vue +7 -5
  54. package/app/components/Viewer/ContextMenu/CircularItems.vue +3 -3
  55. package/app/components/Viewer/ContextMenu/ContextMenu.vue +22 -19
  56. package/app/components/Viewer/ContextMenu/ContextMenuItem.vue +10 -8
  57. package/app/components/Viewer/ContextMenu/InfoCard.vue +11 -12
  58. package/app/components/Viewer/EdgedCurve/SpecificEdgesOptions.vue +13 -17
  59. package/app/components/Viewer/Generic/Mesh/CellsOptions.vue +11 -15
  60. package/app/components/Viewer/Generic/Mesh/EdgesOptions.vue +12 -16
  61. package/app/components/Viewer/Generic/Mesh/PointsOptions.vue +8 -12
  62. package/app/components/Viewer/Generic/Mesh/PolygonsOptions.vue +11 -15
  63. package/app/components/Viewer/Generic/Mesh/PolyhedraOptions.vue +11 -15
  64. package/app/components/Viewer/Generic/Model/BlocksOptions.vue +67 -38
  65. package/app/components/Viewer/Generic/Model/CornersOptions.vue +53 -23
  66. package/app/components/Viewer/Generic/Model/EdgesOptions.vue +1 -3
  67. package/app/components/Viewer/Generic/Model/LinesOptions.vue +67 -38
  68. package/app/components/Viewer/Generic/Model/ModelStyleCard.vue +31 -15
  69. package/app/components/Viewer/Generic/Model/ModelStyleOptions.vue +2 -3
  70. package/app/components/Viewer/Generic/Model/PointsOptions.vue +6 -6
  71. package/app/components/Viewer/Generic/Model/SurfacesOptions.vue +69 -38
  72. package/app/components/Viewer/ObjectTree/Base/CommonTreeView.vue +64 -46
  73. package/app/components/Viewer/ObjectTree/Base/Controls.vue +5 -5
  74. package/app/components/Viewer/ObjectTree/Base/ItemLabel.vue +13 -9
  75. package/app/components/Viewer/ObjectTree/Base/StickyHeader.vue +5 -5
  76. package/app/components/Viewer/ObjectTree/Base/TreeRow.vue +10 -10
  77. package/app/components/Viewer/ObjectTree/Box.vue +6 -4
  78. package/app/components/Viewer/ObjectTree/Layout.vue +23 -21
  79. package/app/components/Viewer/ObjectTree/Views/GlobalObjects.vue +14 -14
  80. package/app/components/Viewer/ObjectTree/Views/{ModelCollections.vue → ModelTree.vue} +59 -24
  81. package/app/components/Viewer/Options/AttributeColorBar.vue +4 -2
  82. package/app/components/Viewer/Options/AttributeRangeSelector.vue +4 -2
  83. package/app/components/Viewer/Options/AttributeSelector.vue +7 -9
  84. package/app/components/Viewer/Options/ColorMapList.vue +15 -13
  85. package/app/components/Viewer/Options/ColorMapPicker.vue +4 -4
  86. package/app/components/Viewer/Options/ColorPicker.vue +223 -41
  87. package/app/components/Viewer/Options/ColoringTypeSelector.vue +16 -16
  88. package/app/components/Viewer/Options/ColormapQuickPicker.vue +7 -5
  89. package/app/components/Viewer/Options/OptionsSection.vue +1 -1
  90. package/app/components/Viewer/Options/TextureItem.vue +8 -6
  91. package/app/components/Viewer/Options/TexturesSelector.vue +1 -1
  92. package/app/components/Viewer/OverlappingObjectsPicker.vue +8 -9
  93. package/app/components/Viewer/PointSet/SpecificPointsOptions.vue +2 -6
  94. package/app/components/Viewer/Solid/SpecificPolyhedraOptions.vue +12 -16
  95. package/app/components/Viewer/Surface/PolygonsOptions.vue +12 -16
  96. package/app/components/Viewer/Ui.vue +2 -2
  97. package/app/components/Wrapper.vue +1 -4
  98. package/app/components/ZScaling.vue +5 -3
  99. package/app/components/csv-preview/CsvPreviewer.vue +38 -37
  100. package/app/components/csv-preview/CsvSettings.vue +6 -4
  101. package/app/components/csv-preview/CsvTable.vue +1 -1
  102. package/app/composables/batch_style.ts +5 -6
  103. package/app/composables/clipping_planes_widget.ts +73 -181
  104. package/app/composables/clipping_planes_widget_entries.ts +189 -0
  105. package/app/composables/copy_to_clipboard.ts +7 -0
  106. package/app/composables/global_attribute_style.ts +163 -83
  107. package/app/composables/hover_highlight.ts +46 -14
  108. package/app/composables/model_collections.ts +26 -13
  109. package/app/composables/model_components.ts +26 -13
  110. package/app/composables/project_manager.ts +76 -19
  111. package/app/composables/responsive_middle_truncate.ts +13 -13
  112. package/app/composables/stepper_tree.ts +34 -11
  113. package/app/composables/tree_filter.ts +66 -44
  114. package/app/composables/tree_keyboard_nav.ts +25 -11
  115. package/app/composables/tree_scroll.ts +44 -14
  116. package/app/composables/use_adaptive_styles.ts +66 -23
  117. package/app/composables/use_overlapping_picker.ts +66 -16
  118. package/app/composables/use_quick_colormap.ts +16 -5
  119. package/app/composables/virtual_tree.ts +75 -43
  120. package/app/composables/vtk_implicit_plane_widget.d.ts +2 -0
  121. package/app/plugins/auto_store_register.ts +2 -7
  122. package/app/plugins/click_outside_ignore_snackbars.client.ts +39 -0
  123. package/app/stores/app.ts +57 -192
  124. package/app/stores/app_helpers/extension.ts +179 -0
  125. package/app/stores/back.ts +37 -21
  126. package/app/stores/camera_manager.ts +22 -20
  127. package/app/stores/cloud.ts +17 -13
  128. package/app/stores/data.ts +88 -47
  129. package/app/stores/data_helpers/collections.ts +36 -38
  130. package/app/stores/data_helpers/mesh.ts +45 -36
  131. package/app/stores/data_style.ts +50 -28
  132. package/app/stores/feedback.ts +6 -6
  133. package/app/stores/hybrid_viewer.ts +41 -52
  134. package/app/stores/infra.ts +39 -37
  135. package/app/stores/menu.ts +23 -14
  136. package/app/stores/treeview.ts +72 -42
  137. package/app/stores/viewer.ts +39 -27
  138. package/app/utils/attributes.ts +3 -3
  139. package/app/utils/clipping_planes.ts +111 -14
  140. package/app/utils/color_picker.ts +57 -0
  141. package/app/utils/colormap.ts +58 -35
  142. package/app/utils/default_styles/index.ts +2 -2
  143. package/app/utils/default_styles/meshes.ts +107 -13
  144. package/app/utils/default_styles/models.ts +83 -14
  145. package/app/utils/extension.ts +47 -20
  146. package/app/utils/import_workflow.ts +21 -13
  147. package/app/utils/name_cleaner.ts +1 -1
  148. package/app/utils/string.ts +1 -1
  149. package/app/utils/treeview.ts +2 -2
  150. package/internal/database/base_database.ts +7 -3
  151. package/internal/database/database.ts +36 -26
  152. package/internal/database/extended_database.ts +1 -1
  153. package/internal/stores/data_style/mesh/cells/cell.ts +70 -34
  154. package/internal/stores/data_style/mesh/cells/color.ts +12 -6
  155. package/internal/stores/data_style/mesh/cells/common.ts +18 -8
  156. package/internal/stores/data_style/mesh/cells/index.ts +122 -42
  157. package/internal/stores/data_style/mesh/cells/textures.ts +12 -6
  158. package/internal/stores/data_style/mesh/cells/vertex.ts +75 -34
  159. package/internal/stores/data_style/mesh/cells/visibility.ts +15 -4
  160. package/internal/stores/data_style/mesh/edges/color.ts +12 -6
  161. package/internal/stores/data_style/mesh/edges/common.ts +14 -6
  162. package/internal/stores/data_style/mesh/edges/edge.ts +71 -39
  163. package/internal/stores/data_style/mesh/edges/index.ts +117 -42
  164. package/internal/stores/data_style/mesh/edges/vertex.ts +76 -39
  165. package/internal/stores/data_style/mesh/edges/visibility.ts +15 -4
  166. package/internal/stores/data_style/mesh/edges/width.ts +12 -4
  167. package/internal/stores/data_style/mesh/index.ts +30 -11
  168. package/internal/stores/data_style/mesh/points/color.ts +12 -6
  169. package/internal/stores/data_style/mesh/points/common.ts +21 -8
  170. package/internal/stores/data_style/mesh/points/index.ts +101 -50
  171. package/internal/stores/data_style/mesh/points/size.ts +12 -4
  172. package/internal/stores/data_style/mesh/points/vertex.ts +75 -34
  173. package/internal/stores/data_style/mesh/points/visibility.ts +17 -7
  174. package/internal/stores/data_style/mesh/polygons/color.ts +12 -6
  175. package/internal/stores/data_style/mesh/polygons/common.ts +23 -6
  176. package/internal/stores/data_style/mesh/polygons/index.ts +130 -70
  177. package/internal/stores/data_style/mesh/polygons/polygon.ts +77 -43
  178. package/internal/stores/data_style/mesh/polygons/textures.ts +12 -6
  179. package/internal/stores/data_style/mesh/polygons/vertex.ts +79 -39
  180. package/internal/stores/data_style/mesh/polygons/visibility.ts +16 -6
  181. package/internal/stores/data_style/mesh/polyhedra/color.ts +12 -6
  182. package/internal/stores/data_style/mesh/polyhedra/common.ts +14 -6
  183. package/internal/stores/data_style/mesh/polyhedra/index.ts +115 -56
  184. package/internal/stores/data_style/mesh/polyhedra/polyhedron.ts +80 -39
  185. package/internal/stores/data_style/mesh/polyhedra/vertex.ts +79 -39
  186. package/internal/stores/data_style/mesh/polyhedra/visibility.ts +16 -6
  187. package/internal/stores/data_style/model/blocks/color.ts +43 -13
  188. package/internal/stores/data_style/model/blocks/common.ts +21 -6
  189. package/internal/stores/data_style/model/blocks/index.ts +89 -59
  190. package/internal/stores/data_style/model/blocks/polyhedron.ts +101 -44
  191. package/internal/stores/data_style/model/blocks/vertex.ts +107 -42
  192. package/internal/stores/data_style/model/blocks/visibility.ts +17 -4
  193. package/internal/stores/data_style/model/color.ts +171 -83
  194. package/internal/stores/data_style/model/common.ts +70 -21
  195. package/internal/stores/data_style/model/corners/color.ts +43 -11
  196. package/internal/stores/data_style/model/corners/common.ts +25 -6
  197. package/internal/stores/data_style/model/corners/index.ts +66 -41
  198. package/internal/stores/data_style/model/corners/vertex.ts +105 -74
  199. package/internal/stores/data_style/model/corners/visibility.ts +19 -4
  200. package/internal/stores/data_style/model/edges/common.ts +12 -4
  201. package/internal/stores/data_style/model/edges/index.ts +2 -1
  202. package/internal/stores/data_style/model/edges/visibility.ts +24 -7
  203. package/internal/stores/data_style/model/index.ts +24 -11
  204. package/internal/stores/data_style/model/lines/color.ts +41 -11
  205. package/internal/stores/data_style/model/lines/common.ts +17 -6
  206. package/internal/stores/data_style/model/lines/edge.ts +105 -42
  207. package/internal/stores/data_style/model/lines/index.ts +86 -59
  208. package/internal/stores/data_style/model/lines/vertex.ts +105 -42
  209. package/internal/stores/data_style/model/lines/visibility.ts +17 -4
  210. package/internal/stores/data_style/model/points/common.ts +8 -4
  211. package/internal/stores/data_style/model/points/index.ts +10 -3
  212. package/internal/stores/data_style/model/points/size.ts +12 -4
  213. package/internal/stores/data_style/model/points/visibility.ts +16 -6
  214. package/internal/stores/data_style/model/selection.ts +80 -58
  215. package/internal/stores/data_style/model/surfaces/color.ts +41 -11
  216. package/internal/stores/data_style/model/surfaces/common.ts +23 -6
  217. package/internal/stores/data_style/model/surfaces/index.ts +89 -59
  218. package/internal/stores/data_style/model/surfaces/polygon.ts +107 -67
  219. package/internal/stores/data_style/model/surfaces/vertex.ts +111 -67
  220. package/internal/stores/data_style/model/surfaces/visibility.ts +18 -5
  221. package/internal/stores/data_style/model/visibility.ts +82 -20
  222. package/internal/stores/data_style/state.ts +77 -65
  223. package/internal/stores/hybrid_viewer/brightness.ts +49 -31
  224. package/internal/stores/hybrid_viewer/camera.ts +191 -177
  225. package/internal/stores/hybrid_viewer/camera_animation.ts +11 -10
  226. package/internal/stores/hybrid_viewer/core.ts +64 -0
  227. package/internal/stores/hybrid_viewer/filters.ts +10 -16
  228. package/internal/stores/hybrid_viewer/highlight.ts +91 -130
  229. package/internal/stores/hybrid_viewer/ruler.ts +24 -15
  230. package/internal/stores/hybrid_viewer/scene.ts +96 -117
  231. package/internal/stores/hybrid_viewer/viewport.ts +74 -65
  232. package/internal/stores/hybrid_viewer/vtk_types.ts +13 -29
  233. package/internal/utils/api_fetch.ts +54 -23
  234. package/internal/utils/upload_file.ts +74 -53
  235. package/internal/utils/viewer_call.ts +22 -13
  236. package/internal/utils/ws_client.ts +24 -13
  237. package/nuxt.config.ts +58 -1
  238. package/package.json +20 -8
  239. package/server/api/cloud/extensions/run.post.ts +6 -10
  240. package/server/api/local/app/project_folder_path.post.ts +4 -4
  241. package/server/api/local/app/run_back.post.ts +5 -7
  242. package/server/api/local/app/run_viewer.post.ts +5 -7
  243. package/server/api/local/extensions/kill.post.ts +4 -3
  244. package/server/api/local/extensions/run.post.ts +7 -10
  245. package/server/api/local/extensions/upload.put.ts +44 -54
  246. package/server/api/microservice/app/get_is_app_ready.get.ts +4 -5
  247. package/server/api/microservice/app/set_app_base_url.post.ts +5 -6
  248. package/server/api/microservice/app/set_back_base_url.post.ts +5 -6
  249. package/server/api/microservice/app/set_is_app_ready.post.ts +5 -6
  250. package/server/api/microservice/app/set_viewer_base_url.post.ts +5 -6
  251. package/server/api/microservice/extensions/download.post.ts +5 -4
  252. package/server/api/serverless/run_cloud.post.ts +53 -11
  253. package/server/utils/app_config.ts +29 -22
  254. package/server/utils/cleanup.ts +60 -30
  255. package/server/utils/cloud.ts +9 -8
  256. package/server/utils/extension.ts +23 -9
  257. package/server/utils/microservices.ts +33 -24
  258. package/server/utils/path.ts +4 -4
  259. package/server/utils/scripts.ts +26 -23
  260. package/server/utils/server.ts +2 -2
  261. package/server/utils/server_config.ts +41 -27
  262. package/server/utils/stream.ts +6 -0
  263. package/server/utils/ws_client.ts +42 -8
  264. package/shared/scripts.ts +15 -10
  265. package/shared/utils/call_raw.ts +23 -16
  266. package/shared/utils/call_schema.ts +5 -8
  267. package/shared/utils/fetch_raw.ts +87 -47
  268. package/shared/utils/fetch_schema.ts +6 -9
  269. package/shared/utils/file.ts +8 -2
  270. package/shared/utils/response_handlers/load.ts +26 -11
  271. package/shared/utils/types.ts +9 -9
  272. package/shared/utils/validate_schema.ts +1 -1
  273. package/app/components/Viewer/ObjectTree/Views/ModelComponents.vue +0 -276
  274. package/server/types/vendor.d.ts +0 -64
  275. package/server/utils/server_config.js +0 -43
  276. package/shared/utils/call_raw.js +0 -30
  277. package/shared/utils/fetch_raw.js +0 -40
  278. /package/{opengeodeweb_front_schemas.js → .build/opengeodeweb_front_schemas.js} +0 -0
  279. /package/{server → .build/server}/utils/server.js +0 -0
  280. /package/{shared → .build/shared}/app_mode.js +0 -0
  281. /package/{shared → .build/shared}/utils/parse_boolean.js +0 -0
  282. /package/{shared → .build/shared}/utils/types.js +0 -0
@@ -1,3 +1,4 @@
1
+ import type { MaybeComputedElementRef } from "@vueuse/core";
1
2
  import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
2
3
  import { useTreeviewStore } from "@ogw_front/stores/treeview";
3
4
 
@@ -29,45 +30,72 @@ interface CoordinatesLike {
29
30
  height?: unknown;
30
31
  }
31
32
 
33
+ interface RefLike {
34
+ value?: unknown;
35
+ x?: unknown;
36
+ }
37
+
38
+ function isRefLike(value: unknown): value is RefLike {
39
+ return typeof value === "object" && value !== null;
40
+ }
41
+
42
+ function isCoordinatesGetter(value: unknown): value is () => CoordinatesLike | undefined {
43
+ return typeof value === "function";
44
+ }
45
+
46
+ function isCoordinatesLike(value: unknown): value is CoordinatesLike {
47
+ return typeof value === "object" && value !== null;
48
+ }
49
+
32
50
  function getValue(val: unknown): number {
33
51
  if (typeof val === "object" && val !== null && "value" in val) {
34
52
  const wrapped = (val as { value?: unknown }).value;
35
- if (wrapped !== undefined) {
36
- return wrapped as number;
53
+ if (typeof wrapped === "number") {
54
+ return wrapped;
37
55
  }
38
56
  }
39
- return (val as number | undefined) ?? 0;
57
+ return typeof val === "number" ? val : 0;
40
58
  }
41
59
 
42
60
  // oxlint-disable max-lines-per-function
43
61
  export function useAdaptiveStyles(
44
62
  target: AdaptiveStylesTarget,
45
63
  options: AdaptiveStylesOptions = {},
46
- ) {
64
+ ): {
65
+ adaptiveStyles: ComputedRef<{
66
+ "--adaptive-blur": string;
67
+ "--adaptive-opacity": number;
68
+ "--adaptive-brightness": number;
69
+ }>;
70
+ brightness: Ref<number>;
71
+ } {
47
72
  const hybridViewerStore = useHybridViewerStore();
48
73
  const treeviewStore = useTreeviewStore();
49
74
 
50
- const targetAsRefLike = target as { value?: unknown; x?: unknown } | undefined;
51
- const isCoordinates = Boolean(
52
- target &&
75
+ const targetAsRefLike = isRefLike(target) ? target : undefined;
76
+ const isCoordinates =
77
+ target !== undefined &&
78
+ target !== null &&
53
79
  (typeof target === "function" ||
54
80
  (targetAsRefLike?.value !== undefined &&
55
81
  targetAsRefLike.value !== null &&
56
82
  (targetAsRefLike.value as { x?: unknown }).x !== undefined) ||
57
- (targetAsRefLike?.x !== undefined && targetAsRefLike.value === undefined)),
58
- );
83
+ (targetAsRefLike?.x !== undefined && targetAsRefLike.value === undefined));
59
84
 
60
- const bounding = useElementBounding(isCoordinates ? undefined : (target as never));
85
+ const bounding = useElementBounding(
86
+ // oxlint-disable-next-line no-unsafe-type-assertion -- duck-typed target; see comment above.
87
+ isCoordinates ? undefined : (target as MaybeComputedElementRef),
88
+ );
61
89
 
62
90
  const unwrapped = computed(() => {
63
91
  if (isCoordinates) {
64
92
  let val: CoordinatesLike | undefined = undefined;
65
- if (typeof target === "function") {
66
- val = (target as () => CoordinatesLike | undefined)();
93
+ if (isCoordinatesGetter(target)) {
94
+ val = target();
67
95
  } else if (targetAsRefLike?.value === undefined) {
68
96
  val = targetAsRefLike;
69
- } else {
70
- val = targetAsRefLike.value as CoordinatesLike | undefined;
97
+ } else if (isCoordinatesLike(targetAsRefLike.value)) {
98
+ val = targetAsRefLike.value;
71
99
  }
72
100
  return {
73
101
  x: getValue(val?.x),
@@ -91,7 +119,7 @@ export function useAdaptiveStyles(
91
119
 
92
120
  const brightness = ref(LUMINANCE_THRESHOLD);
93
121
 
94
- function calculateBrightness() {
122
+ function calculateBrightness(): void {
95
123
  brightness.value = hybridViewerStore.getAverageBrightness({
96
124
  x: x.value,
97
125
  y: y.value,
@@ -100,21 +128,36 @@ export function useAdaptiveStyles(
100
128
  });
101
129
  }
102
130
 
103
- const updateBrightness = useThrottleFn(calculateBrightness, ADAPTIVE_REFRESH_RATE);
104
-
105
- watch([x, y, width, height, () => hybridViewerStore.latestImage], updateBrightness, {
106
- immediate: true,
107
- });
131
+ // Trailing call so the last image of a burst is always sampled; otherwise the final opacity depends on image timing
132
+ const updateBrightness = useThrottleFn(calculateBrightness, ADAPTIVE_REFRESH_RATE, true);
133
+
134
+ watch(
135
+ [
136
+ x,
137
+ y,
138
+ width,
139
+ height,
140
+ (): typeof hybridViewerStore.latestImage => hybridViewerStore.latestImage,
141
+ ],
142
+ updateBrightness,
143
+ {
144
+ immediate: true,
145
+ },
146
+ );
108
147
 
109
- async function forceRefresh() {
148
+ async function forceRefresh(): Promise<void> {
110
149
  await nextTick();
111
150
  bounding.update?.();
112
151
  calculateBrightness();
113
152
  }
114
153
 
115
154
  if (getCurrentInstance()) {
116
- onMounted(() => {
117
- forceRefresh();
155
+ onMounted(async () => {
156
+ try {
157
+ await forceRefresh();
158
+ } catch (error) {
159
+ console.error("forceRefresh failed:", error);
160
+ }
118
161
  });
119
162
  }
120
163
 
@@ -1,17 +1,18 @@
1
1
  import { ref } from "vue";
2
- import { useDataStore } from "@ogw_front/stores/data";
2
+ import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json";
3
+
4
+ import { type DataItem, useDataStore } from "@ogw_front/stores/data";
3
5
  import { useDataStyleStore } from "@ogw_front/stores/data_style";
4
6
  import { useViewerStore } from "@ogw_front/stores/viewer";
5
- import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json";
6
7
 
7
8
  interface PickedItem {
8
9
  id: string;
9
- viewer_id: number;
10
+ viewer_id: number | undefined;
10
11
  }
11
12
 
12
13
  interface ProposedItem {
13
14
  id: string;
14
- viewer_id: number;
15
+ viewer_id: number | undefined;
15
16
  name: string;
16
17
  viewer_type: string | undefined;
17
18
  geode_object_type: string | undefined;
@@ -19,7 +20,7 @@ interface ProposedItem {
19
20
 
20
21
  interface PickedResponse {
21
22
  array_ids: string[];
22
- viewer_id: number;
23
+ viewer_id: number | null;
23
24
  picked_data?: PickedItem[];
24
25
  }
25
26
 
@@ -36,7 +37,55 @@ interface GetViewerIdParams {
36
37
  containerRect: { left: number; top: number };
37
38
  }
38
39
 
39
- export function useOverlappingPicker() {
40
+ interface UseOverlappingPickerReturn {
41
+ displayIntermediate: Ref<boolean>;
42
+ intermediateItems: Ref<ProposedItem[]>;
43
+ intermediateMenuX: Ref<number>;
44
+ intermediateMenuY: Ref<number>;
45
+ getIntermediateMenuStyle: () => { position: string; left: string; top: string };
46
+ selectIntermediateItem: (item: ProposedItem | undefined) => void;
47
+ handleIntermediateMenuUpdate: (val: boolean) => void;
48
+ get_viewer_id: (params: GetViewerIdParams) => Promise<ViewerIdResult>;
49
+ }
50
+
51
+ function isPickedItem(entry: unknown): entry is PickedItem {
52
+ return (
53
+ typeof entry === "object" &&
54
+ entry !== null &&
55
+ "id" in entry &&
56
+ typeof entry.id === "string" &&
57
+ (!("viewer_id" in entry) ||
58
+ entry.viewer_id === undefined ||
59
+ typeof entry.viewer_id === "number")
60
+ );
61
+ }
62
+
63
+ function isPickedItemArray(value: unknown): value is PickedItem[] {
64
+ return Array.isArray(value) && value.every((entry) => isPickedItem(entry));
65
+ }
66
+
67
+ function isPickedResponse(value: unknown): value is PickedResponse {
68
+ if (typeof value !== "object" || value === null) {
69
+ return false;
70
+ }
71
+ if (!("array_ids" in value) || !("viewer_id" in value)) {
72
+ return false;
73
+ }
74
+ const { array_ids, viewer_id } = value;
75
+ if (
76
+ !Array.isArray(array_ids) ||
77
+ !array_ids.every((entry) => typeof entry === "string") ||
78
+ (typeof viewer_id !== "number" && viewer_id !== null)
79
+ ) {
80
+ return false;
81
+ }
82
+ if ("picked_data" in value) {
83
+ return value.picked_data === undefined || isPickedItemArray(value.picked_data);
84
+ }
85
+ return true;
86
+ }
87
+
88
+ export function useOverlappingPicker(): UseOverlappingPickerReturn {
40
89
  const dataStore = useDataStore();
41
90
  const dataStyleStore = useDataStyleStore();
42
91
  const viewerStore = useViewerStore();
@@ -48,9 +97,9 @@ export function useOverlappingPicker() {
48
97
  const intermediateMenuY = ref(0);
49
98
  let resolveIntermediate: ((item: ProposedItem | undefined) => void) | undefined = undefined;
50
99
 
51
- function fetchProposedItems(pickedList: PickedItem[]): Promise<ProposedItem[]> {
52
- return Promise.all(
53
- pickedList.map(async (pick) => {
100
+ async function fetchProposedItems(pickedList: readonly PickedItem[]): Promise<ProposedItem[]> {
101
+ const proposedItems = await Promise.all(
102
+ pickedList.map(async (pick: PickedItem) => {
54
103
  try {
55
104
  const item = await dataStore.item(pick.id);
56
105
  return {
@@ -71,9 +120,10 @@ export function useOverlappingPicker() {
71
120
  }
72
121
  }),
73
122
  );
123
+ return proposedItems;
74
124
  }
75
125
 
76
- function getIntermediateMenuStyle() {
126
+ function getIntermediateMenuStyle(): { position: string; left: string; top: string } {
77
127
  return {
78
128
  position: "fixed",
79
129
  left: `${intermediateMenuX.value}px`,
@@ -102,9 +152,9 @@ export function useOverlappingPicker() {
102
152
  containerHeight,
103
153
  containerRect,
104
154
  }: GetViewerIdParams): Promise<ViewerIdResult> {
105
- const activeIds = new Set(dataItems.value.map((i) => i.id));
155
+ const activeIds = new Set(dataItems.value.map((i: DataItem) => i.id));
106
156
  const visibleStyleIds = Object.keys(dataStyleStore.styles).filter(
107
- (styleId) => activeIds.has(styleId) && dataStyleStore.objectVisibility(styleId),
157
+ (styleId) => activeIds.has(styleId) && dataStyleStore.objectVisibility(styleId) === true,
108
158
  );
109
159
 
110
160
  const viewableChecks = await Promise.all(
@@ -134,13 +184,13 @@ export function useOverlappingPicker() {
134
184
  },
135
185
  {
136
186
  response_function: (response: unknown) => {
137
- responseHolder.pickedResponse = response as PickedResponse;
187
+ responseHolder.pickedResponse = isPickedResponse(response) ? response : undefined;
138
188
  },
139
189
  },
140
190
  );
141
191
  const { pickedResponse } = responseHolder;
142
192
 
143
- if (!pickedResponse || !pickedResponse.array_ids || pickedResponse.array_ids.length === 0) {
193
+ if (!pickedResponse || pickedResponse.array_ids.length === 0) {
144
194
  return result;
145
195
  }
146
196
 
@@ -151,7 +201,7 @@ export function useOverlappingPicker() {
151
201
  pickedList.push(...picked_data);
152
202
  } else {
153
203
  for (const pickId of array_ids) {
154
- pickedList.push({ id: pickId, viewer_id });
204
+ pickedList.push({ id: pickId, viewer_id: viewer_id ?? undefined });
155
205
  }
156
206
  }
157
207
 
@@ -189,7 +239,7 @@ export function useOverlappingPicker() {
189
239
 
190
240
  /* eslint-disable-next-line promise/avoid-new */
191
241
  return new Promise<ViewerIdResult>((resolve) => {
192
- resolveIntermediate = (chosenResult) => {
242
+ resolveIntermediate = (chosenResult: ProposedItem | undefined): void => {
193
243
  displayIntermediate.value = false;
194
244
  resolve(
195
245
  chosenResult
@@ -1,7 +1,20 @@
1
1
  import { useViewerStore } from "@ogw_front/stores/viewer";
2
2
  import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json";
3
3
 
4
- export function useQuickColormap() {
4
+ // Runtime guard for the unknown response of viewerStore.request(), used instead of an
5
+ // `as` cast so the shape is actually verified (data_id, when present, must be a string).
6
+ function isPickColormapResult(value: unknown): value is { data_id?: string } {
7
+ return (
8
+ typeof value === "object" &&
9
+ value !== null &&
10
+ (!("data_id" in value) || typeof value.data_id === "string")
11
+ );
12
+ }
13
+
14
+ export function useQuickColormap(): {
15
+ pickColormap: typeof pickColormap;
16
+ quickColormap: typeof quickColormap;
17
+ } {
5
18
  const viewerStore = useViewerStore();
6
19
  const quickColormap = reactive<{
7
20
  data_id: string | undefined;
@@ -24,10 +37,8 @@ export function useQuickColormap() {
24
37
  try {
25
38
  const schema = viewer_schemas.opengeodeweb_viewer.viewer.pick_colormap;
26
39
  const params = { x: offsetX, y: offsetY };
27
- const result = (await viewerStore.request({ schema, params })) as
28
- | { data_id?: string }
29
- | undefined;
30
- if (result && result.data_id) {
40
+ const result = await viewerStore.request({ schema, params });
41
+ if (isPickColormapResult(result) && result.data_id !== undefined && result.data_id !== "") {
31
42
  quickColormap.data_id = result.data_id;
32
43
  quickColormap.x = clientX;
33
44
  quickColormap.y = clientY;
@@ -1,4 +1,7 @@
1
- import type { MaybeRefOrGetter } from "vue";
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);
2
5
 
3
6
  type TreeItem = Record<string, unknown>;
4
7
 
@@ -17,14 +20,14 @@ interface SelectionConfig {
17
20
  }
18
21
 
19
22
  interface VirtualTreeProps {
20
- items?: TreeItem[];
21
- opened?: unknown[];
22
- selected?: unknown[];
23
- active?: unknown[];
24
- itemProps?: Partial<ItemPropsConfig>;
25
- selection?: Partial<SelectionConfig>;
26
- search?: string;
27
- customFilter?: (id: unknown, search: string, context: { raw: TreeItem }) => boolean;
23
+ readonly items?: readonly TreeItem[];
24
+ readonly opened?: readonly unknown[];
25
+ readonly selected?: readonly unknown[];
26
+ readonly active?: readonly unknown[];
27
+ readonly itemProps?: Partial<ItemPropsConfig>;
28
+ readonly selection?: Partial<SelectionConfig>;
29
+ readonly search?: string;
30
+ readonly customFilter?: (id: unknown, search: string, context: { raw: TreeItem }) => boolean;
28
31
  }
29
32
 
30
33
  interface DisplayItem {
@@ -36,9 +39,39 @@ interface DisplayItem {
36
39
  isLeaf: boolean;
37
40
  }
38
41
 
39
- type EmitFn = (event: string, ...args: unknown[]) => void;
42
+ type EmitFn = (event: string, ...args: readonly unknown[]) => void;
43
+
44
+ interface UseVirtualTreeReturn {
45
+ actualItemProps: ComputedRef<ItemPropsConfig>;
46
+ actualSelection: ComputedRef<SelectionConfig>;
47
+ displayItems: ComputedRef<DisplayItem[]>;
48
+ toggleOpen: (item: TreeItem) => void;
49
+ toggleSelect: (item: TreeItem) => void;
50
+ isSelected: (item: TreeItem) => boolean;
51
+ getIndeterminate: (item: TreeItem) => boolean;
52
+ }
53
+
54
+ // Real runtime check (rather than an `as TreeItem[]` cast) for the duck-typed "children" field:
55
+ // Item shapes vary across callers (treeview groups, model component/collection groups, ...), so
56
+ // This only verifies it is actually an array, same as the assumption the old cast silently made.
57
+ function isTreeItemArray(value: unknown): value is TreeItem[] {
58
+ return Array.isArray(value);
59
+ }
60
+
61
+ // Extracted so we never call String() directly on a value typed as `unknown` (ids and titles can
62
+ // Be anything at runtime): only stringify primitives that have a sane toString, and fall back to
63
+ // "" for anything else instead of risking "[object Object]".
64
+ function toDisplayString(value: unknown): string {
65
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
66
+ return String(value);
67
+ }
68
+ return "";
69
+ }
40
70
 
41
- function useVirtualTree(propsIn: MaybeRefOrGetter<VirtualTreeProps>, emit: EmitFn) {
71
+ function useVirtualTree(
72
+ propsIn: ReadonlyMaybeRefOrGetter<VirtualTreeProps>,
73
+ emit: EmitFn,
74
+ ): UseVirtualTreeReturn {
42
75
  const props = toRef(propsIn);
43
76
 
44
77
  const actualItemProps = computed<ItemPropsConfig>(() => ({
@@ -57,7 +90,7 @@ function useVirtualTree(propsIn: MaybeRefOrGetter<VirtualTreeProps>, emit: EmitF
57
90
 
58
91
  const openedSet = computed(() => new Set(props.value.opened));
59
92
  const selectedSet = computed(() => new Set(props.value.selected));
60
- const activeSet = computed(() => new Set(props.value.active || []));
93
+ const activeSet = computed(() => new Set(props.value.active));
61
94
 
62
95
  function toggleOpen(item: TreeItem): void {
63
96
  const id = item[actualItemProps.value.value];
@@ -71,16 +104,17 @@ function useVirtualTree(propsIn: MaybeRefOrGetter<VirtualTreeProps>, emit: EmitF
71
104
  emit("update:opened", [...newOpened]);
72
105
  }
73
106
 
74
- function getLeafChildrenIds(item: TreeItem, ids: unknown[] = []): unknown[] {
75
- const children = item[actualItemProps.value.children] as TreeItem[] | undefined;
107
+ function getChildrenOf(item: TreeItem): TreeItem[] | undefined {
108
+ const rawChildren = item[actualItemProps.value.children];
109
+ return isTreeItemArray(rawChildren) ? rawChildren : undefined;
110
+ }
111
+
112
+ function getLeafChildrenIds(item: TreeItem): unknown[] {
113
+ const children = getChildrenOf(item);
76
114
  if (children) {
77
- for (const child of children) {
78
- getLeafChildrenIds(child, ids);
79
- }
80
- } else {
81
- ids.push(item[actualItemProps.value.value]);
115
+ return children.flatMap((child) => getLeafChildrenIds(child));
82
116
  }
83
- return ids;
117
+ return [item[actualItemProps.value.value]];
84
118
  }
85
119
 
86
120
  function isSelected(item: TreeItem): boolean {
@@ -137,32 +171,28 @@ function useVirtualTree(propsIn: MaybeRefOrGetter<VirtualTreeProps>, emit: EmitF
137
171
  emit("update:selected", [...newSelected]);
138
172
  }
139
173
 
140
- function flattenTree(
141
- itemsList: TreeItem[],
142
- depth = 0,
143
- result: DisplayItem[] = [],
144
- ): DisplayItem[] {
174
+ function flattenTree(itemsList: readonly TreeItem[], depth = 0): DisplayItem[] {
145
175
  const { search, customFilter } = props.value;
146
- const lowerSearch = search ? search.toLowerCase() : "";
176
+ const result: DisplayItem[] = [];
147
177
 
148
178
  for (const item of itemsList) {
149
179
  const id = item[actualItemProps.value.value];
150
- const children = item[actualItemProps.value.children] as TreeItem[] | undefined;
180
+ const children = getChildrenOf(item);
151
181
  const hasChildren = Boolean(children && children.length > 0);
152
182
 
153
183
  const isOpen = openedSet.value.has(id);
154
184
  const isActive = activeSet.value.has(id);
155
185
 
156
- if (lowerSearch) {
186
+ if (search !== undefined && search !== "") {
187
+ const lowerSearch = search.toLowerCase();
157
188
  const matches = customFilter
158
- ? customFilter(id, search as string, { raw: item })
159
- : String(item[actualItemProps.value.title] ?? "")
189
+ ? customFilter(id, search, { raw: item })
190
+ : toDisplayString(item[actualItemProps.value.title])
160
191
  .toLowerCase()
161
- .includes(lowerSearch) || String(id).toLowerCase().includes(lowerSearch);
192
+ .includes(lowerSearch) || toDisplayString(id).toLowerCase().includes(lowerSearch);
162
193
 
163
194
  if (hasChildren) {
164
- const subtree: DisplayItem[] = [];
165
- flattenTree(children ?? [], depth + 1, subtree);
195
+ const subtree = flattenTree(children ?? [], depth + 1);
166
196
  if (subtree.length === 0 && !matches) {
167
197
  continue;
168
198
  }
@@ -195,31 +225,33 @@ function useVirtualTree(propsIn: MaybeRefOrGetter<VirtualTreeProps>, emit: EmitF
195
225
  });
196
226
 
197
227
  if (isOpen && hasChildren) {
198
- flattenTree(children ?? [], depth + 1, result);
228
+ result.push(...flattenTree(children ?? [], depth + 1));
199
229
  }
200
230
  }
201
231
  return result;
202
232
  }
203
233
 
204
- function traverse(itemsList: TreeItem[], allIds: unknown[]): void {
234
+ function collectNonLeafIds(itemsList: readonly TreeItem[]): unknown[] {
235
+ const allIds: unknown[] = [];
205
236
  for (const item of itemsList) {
206
- const children = item[actualItemProps.value.children] as TreeItem[] | undefined;
237
+ const children = getChildrenOf(item);
207
238
  if (children && children.length > 0) {
208
- allIds.push(item[actualItemProps.value.value]);
209
- traverse(children, allIds);
239
+ allIds.push(item[actualItemProps.value.value], ...collectNonLeafIds(children));
210
240
  }
211
241
  }
242
+ return allIds;
212
243
  }
213
244
 
214
- const displayItems = computed(() => flattenTree(props.value.items || []));
245
+ const displayItems = computed(() => flattenTree(props.value.items ?? []));
215
246
 
216
247
  watch(
217
248
  () => props.value.search,
218
249
  (newSearch, oldSearch) => {
219
- if (newSearch && !oldSearch) {
220
- const allIds: unknown[] = [];
221
- traverse(props.value.items || [], allIds);
222
- emit("update:opened", [...new Set([...(props.value.opened || []), ...allIds])]);
250
+ const hasNewSearch = newSearch !== undefined && newSearch !== "";
251
+ const hadOldSearch = oldSearch !== undefined && oldSearch !== "";
252
+ if (hasNewSearch && !hadOldSearch) {
253
+ const allIds = collectNonLeafIds(props.value.items ?? []);
254
+ emit("update:opened", [...new Set([...(props.value.opened ?? []), ...allIds])]);
223
255
  }
224
256
  },
225
257
  );
@@ -0,0 +1,2 @@
1
+ // Vtk.js does not ship type declarations for this widget module.
2
+ declare module "@kitware/vtk.js/Widgets/Widgets3D/ImplicitPlaneWidget";
@@ -1,7 +1,5 @@
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 { useAppStore } from "@ogw_front/stores/app";
4
1
  import type { PiniaPluginContext } from "pinia";
2
+ import { useAppStore } from "@ogw_front/stores/app";
5
3
 
6
4
  function autoStoreRegister({ store }: PiniaPluginContext): void {
7
5
  if (store.$id === "app") {
@@ -10,7 +8,6 @@ function autoStoreRegister({ store }: PiniaPluginContext): void {
10
8
 
11
9
  const appStore = useAppStore();
12
10
  appStore.registerStore(store);
13
- console.log(`[AutoRegister] Store "${store.$id}" processed`);
14
11
  }
15
12
 
16
13
  export default defineNuxtPlugin({
@@ -18,12 +15,10 @@ export default defineNuxtPlugin({
18
15
  dependsOn: ["pinia"],
19
16
  setup(nuxtApp) {
20
17
  const { $pinia } = nuxtApp;
21
- if (!$pinia) {
22
- console.warn("Pinia instance not available.");
18
+ if ($pinia === undefined) {
23
19
  return;
24
20
  }
25
21
 
26
22
  $pinia.use(autoStoreRegister);
27
- console.log("[AUTOREGISTER PLUGIN] Loaded automatically from OpenGeodeWeb-Front");
28
23
  },
29
24
  });
@@ -0,0 +1,39 @@
1
+ import { ClickOutside } from "vuetify/directives/click-outside";
2
+ import type { DirectiveBinding } from "vue";
3
+
4
+ type ClickOutsideValue =
5
+ | ((event: MouseEvent) => void)
6
+ | {
7
+ handler: (event: MouseEvent) => void;
8
+ closeConditional?: (event: Event) => boolean;
9
+ include?: () => HTMLElement[];
10
+ };
11
+
12
+ function snackbarElements(): HTMLElement[] {
13
+ return [...document.querySelectorAll<HTMLElement>(".v-snackbar")];
14
+ }
15
+
16
+ export default defineNuxtPlugin({
17
+ name: "click-outside-ignore-snackbars",
18
+ setup() {
19
+ const originalMounted = ClickOutside.mounted.bind(ClickOutside);
20
+
21
+ ClickOutside.mounted = (
22
+ element: HTMLElement,
23
+ binding: DirectiveBinding<ClickOutsideValue>,
24
+ ): void => {
25
+ const { value } = binding;
26
+ const handler = typeof value === "function" ? value : value.handler;
27
+ const closeConditional = typeof value === "function" ? undefined : value.closeConditional;
28
+ const include = typeof value === "function" ? undefined : value.include;
29
+
30
+ binding.value = {
31
+ handler,
32
+ closeConditional,
33
+ include: (): HTMLElement[] => [...(include?.() ?? []), ...snackbarElements()],
34
+ };
35
+
36
+ originalMounted(element, binding);
37
+ };
38
+ },
39
+ });