@geode/opengeodeweb-front 10.34.0-rc.9 → 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,7 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import GlobalObjects from "@ogw_front/components/Viewer/ObjectTree/Views/GlobalObjects.vue";
3
- import ModelCollections from "@ogw_front/components/Viewer/ObjectTree/Views/ModelCollections.vue";
4
- import ModelComponents from "@ogw_front/components/Viewer/ObjectTree/Views/ModelComponents.vue";
3
+ import ModelTree from "@ogw_front/components/Viewer/ObjectTree/Views/ModelTree.vue";
5
4
  import ViewerObjectTreeBox from "@ogw_front/components/Viewer/ObjectTree/Box.vue";
6
5
  import { geode_objects } from "@ogw_front/assets/geode_objects";
7
6
  import { useAdaptiveStyles } from "@ogw_front/composables/use_adaptive_styles";
@@ -23,21 +22,24 @@ interface Props {
23
22
  const { containerWidth } = defineProps<Props>();
24
23
 
25
24
  const treeviewStore = useTreeviewStore();
26
- const emit = defineEmits<{
25
+
26
+ interface Emits {
27
27
  "show-menu": [payload: Record<string, unknown>];
28
- }>();
28
+ }
29
+
30
+ const emit = defineEmits<Emits>();
29
31
 
30
32
  const activityBar = useTemplateRef("activity-bar");
31
33
  const { adaptiveStyles: activityBarAdaptiveStyles } = useAdaptiveStyles(activityBar);
32
34
 
33
- const maxWidth = computed(() => containerWidth * MAX_PANEL_WIDTH_RATIO);
35
+ const maxWidth = computed<number>(() => containerWidth * MAX_PANEL_WIDTH_RATIO);
34
36
 
35
37
  const mainView = computed(() => treeviewStore.opened_views.find((view) => view.id === "main"));
36
38
  const additionalViews = computed(() =>
37
39
  treeviewStore.opened_views.filter((view) => view.id !== "main"),
38
40
  );
39
41
 
40
- const totalWidth = computed(() => {
42
+ const totalWidth = computed<string>(() => {
41
43
  const hasAdditional = additionalViews.value.length > 0;
42
44
  const hasMain = Boolean(mainView.value);
43
45
  const gap = hasAdditional && hasMain ? GAP_WIDTH : 0;
@@ -62,7 +64,7 @@ watch(
62
64
  { immediate: true },
63
65
  );
64
66
 
65
- watch([maxWidth, () => additionalViews.value.length], ([newMax]) => {
67
+ watch([maxWidth, (): number => additionalViews.value.length], ([newMax]): void => {
66
68
  const hasAdditional = additionalViews.value.length > 0;
67
69
  const gap = hasAdditional ? GAP_WIDTH : 0;
68
70
  const total =
@@ -84,25 +86,25 @@ watch([maxWidth, () => additionalViews.value.length], ([newMax]) => {
84
86
  }
85
87
  });
86
88
 
87
- function onDragStart(index: number) {
89
+ function onDragStart(index: number): void {
88
90
  draggedIndex.value = index;
89
91
  }
90
92
 
91
- function onDragOver(event: DragEvent) {
93
+ function onDragOver(event: DragEvent): void {
92
94
  event.preventDefault();
93
95
  }
94
96
 
95
- function onDrop(targetIndex: number) {
97
+ function onDrop(targetIndex: number): void {
96
98
  if (draggedIndex.value !== undefined && draggedIndex.value !== targetIndex) {
97
99
  treeviewStore.moveView(draggedIndex.value, targetIndex);
98
100
  }
99
101
  draggedIndex.value = undefined;
100
102
  }
101
103
 
102
- function onResizeStart(event: MouseEvent) {
104
+ function onResizeStart(event: MouseEvent): void {
103
105
  const startWidth = treeviewStore.panelWidth;
104
106
  const startX = event.clientX;
105
- function resize(move_event: MouseEvent) {
107
+ function resize(move_event: MouseEvent): void {
106
108
  const deltaX = move_event.clientX - startX;
107
109
  let newWidth = startWidth + deltaX;
108
110
  const hasAdditional = additionalViews.value.length > 0;
@@ -121,7 +123,7 @@ function onResizeStart(event: MouseEvent) {
121
123
  treeviewStore.setPanelWidth(Math.max(WIDTH_MIN, newWidth));
122
124
  document.body.style.userSelect = "none";
123
125
  }
124
- function stopResize() {
126
+ function stopResize(): void {
125
127
  document.removeEventListener("mousemove", resize);
126
128
  document.removeEventListener("mouseup", stopResize);
127
129
  document.body.style.userSelect = "";
@@ -130,10 +132,10 @@ function onResizeStart(event: MouseEvent) {
130
132
  document.addEventListener("mouseup", stopResize);
131
133
  }
132
134
 
133
- function onAdditionalResizeStart(event: MouseEvent) {
135
+ function onAdditionalResizeStart(event: MouseEvent): void {
134
136
  const startWidth = treeviewStore.additionalPanelWidth;
135
137
  const startX = event.clientX;
136
- function resize(move_event: MouseEvent) {
138
+ function resize(move_event: MouseEvent): void {
137
139
  const deltaX = move_event.clientX - startX;
138
140
  const newWidth = startWidth + deltaX;
139
141
  const currentTotalWidth = treeviewStore.panelWidth + newWidth + GAP_WIDTH;
@@ -148,7 +150,7 @@ function onAdditionalResizeStart(event: MouseEvent) {
148
150
  treeviewStore.setAdditionalPanelWidth(Math.max(WIDTH_MIN, newWidth));
149
151
  document.body.style.userSelect = "none";
150
152
  }
151
- function stopResize() {
153
+ function stopResize(): void {
152
154
  document.removeEventListener("mousemove", resize);
153
155
  document.removeEventListener("mouseup", stopResize);
154
156
  document.body.style.userSelect = "";
@@ -157,13 +159,13 @@ function onAdditionalResizeStart(event: MouseEvent) {
157
159
  document.addEventListener("mouseup", stopResize);
158
160
  }
159
161
 
160
- function onVerticalResizeStart(event: MouseEvent, index: number) {
162
+ function onVerticalResizeStart(event: MouseEvent, index: number): void {
161
163
  const startY = event.clientY;
162
164
  const startHeight1 = rowHeights.value[index] ?? 0;
163
165
  const startHeight2 = rowHeights.value[index + 1] ?? 0;
164
166
  const containerHeight = (event.currentTarget as HTMLElement).parentElement?.offsetHeight ?? 0;
165
167
 
166
- function resize(move_event: MouseEvent) {
168
+ function resize(move_event: MouseEvent): void {
167
169
  const deltaY = move_event.clientY - startY;
168
170
  const deltaPercent = (deltaY / containerHeight) * PERCENT_100;
169
171
  const minHeightPercent = (HEIGHT_MIN / containerHeight) * PERCENT_100;
@@ -188,7 +190,7 @@ function onVerticalResizeStart(event: MouseEvent, index: number) {
188
190
  document.body.style.cursor = "ns-resize";
189
191
  }
190
192
 
191
- function stopResize() {
193
+ function stopResize(): void {
192
194
  document.removeEventListener("mousemove", resize);
193
195
  document.removeEventListener("mouseup", stopResize);
194
196
  document.body.style.userSelect = "";
@@ -279,11 +281,11 @@ function onVerticalResizeStart(event: MouseEvent, index: number) {
279
281
  @dragstart="onDragStart(index + 1)"
280
282
  @update:scroll-top="treeviewStore.setScrollTop(view.id, $event)"
281
283
  >
282
- <component
283
- :is="view.viewType === 'model_collections' ? ModelCollections : ModelComponents"
284
+ <ModelTree
284
285
  data-testid="modelComponentsObjectTree"
285
286
  :id="view.modelId || view.id"
286
287
  :view-id="view.id"
288
+ :view-type="view.viewType"
287
289
  @show-menu="emit('show-menu', $event)"
288
290
  />
289
291
  </ViewerObjectTreeBox>
@@ -1,10 +1,8 @@
1
1
  <script setup lang="ts">
2
- // 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.
3
- // oxlint-disable eslint/sort-imports
4
2
  import CommonTreeView from "@ogw_front/components/Viewer/ObjectTree/Base/CommonTreeView.vue";
3
+ import type { DisplayItem } from "@ogw_front/composables/virtual_tree";
5
4
  import ObjectTreeControls from "@ogw_front/components/Viewer/ObjectTree/Base/Controls.vue";
6
5
  import ObjectTreeItemLabel from "@ogw_front/components/Viewer/ObjectTree/Base/ItemLabel.vue";
7
- import type { DisplayItem } from "@ogw_front/composables/virtual_tree";
8
6
  import { compareSelections } from "@ogw_front/utils/treeview";
9
7
  import { useDataStore } from "@ogw_front/stores/data";
10
8
  import { useDataStyleStore } from "@ogw_front/stores/data_style";
@@ -19,9 +17,11 @@ const dataStyleStore = useDataStyleStore();
19
17
  const hybridViewerStore = useHybridViewerStore();
20
18
  const { onHoverEnter, onHoverLeave } = useHoverhighlight();
21
19
 
22
- const emit = defineEmits<{
20
+ interface Emits {
23
21
  "show-menu": [payload: { event: MouseEvent; itemId: string }];
24
- }>();
22
+ }
23
+
24
+ const emit = defineEmits<Emits>();
25
25
 
26
26
  interface TreeGroupItem {
27
27
  raw?: TreeGroupItem;
@@ -32,8 +32,8 @@ interface TreeGroupItem {
32
32
  children?: TreeGroupItem[];
33
33
  }
34
34
 
35
- const mainView = computed(() => treeviewStore.opened_views[0]);
36
- const opened = computed({
35
+ const mainView = computed<TreeGroupItem>(() => treeviewStore.opened_views[0]);
36
+ const opened = computed<string[]>({
37
37
  get: () => mainView.value?.opened || [],
38
38
  set: (val) => treeviewStore.setOpened(mainView.value?.id ?? "", val),
39
39
  });
@@ -49,11 +49,11 @@ const {
49
49
  applySearchFilter,
50
50
  } = useTreeFilter(() => treeviewStore.items, { recursiveSort: true });
51
51
 
52
- function onUpdateSelection(val: string[]) {
52
+ function onUpdateSelection(val: string[]): void {
53
53
  treeviewStore.selection = applySearchFilter(val, treeviewStore.selection) as string[];
54
54
  }
55
55
 
56
- const visibleSelection = computed(() => applySearchFilter(treeviewStore.selection, []));
56
+ const visibleSelection = computed<string[]>(() => applySearchFilter(treeviewStore.selection, []));
57
57
 
58
58
  watch(
59
59
  () => treeviewStore.selection,
@@ -82,7 +82,7 @@ watch(
82
82
  },
83
83
  );
84
84
 
85
- function isModel(item: TreeGroupItem) {
85
+ function isModel(item: TreeGroupItem): boolean {
86
86
  const actualItem = item.raw || item;
87
87
  return (
88
88
  actualItem.viewer_type === "model" ||
@@ -121,7 +121,7 @@ function handleHoverEnter({
121
121
  }: {
122
122
  item: TreeGroupItem;
123
123
  immediate?: boolean;
124
- }) {
124
+ }): void {
125
125
  const actualItem = item.raw || item;
126
126
 
127
127
  if (!actualItem.viewer_type) {
@@ -138,7 +138,7 @@ function handleHoverEnter({
138
138
  );
139
139
  }
140
140
 
141
- function handleHoverLeave({ item }: { item: TreeGroupItem }) {
141
+ function handleHoverLeave({ item }: { item: TreeGroupItem }): void {
142
142
  const actualItem = item.raw || item;
143
143
  if (!actualItem.viewer_type) {
144
144
  return;
@@ -146,9 +146,9 @@ function handleHoverLeave({ item }: { item: TreeGroupItem }) {
146
146
  onHoverLeave(actualItem.id);
147
147
  }
148
148
 
149
- function expandAll() {
149
+ function expandAll(): void {
150
150
  const allIds: string[] = [];
151
- function traverse(itemsList: TreeGroupItem[]) {
151
+ function traverse(itemsList: TreeGroupItem[]): void {
152
152
  for (const item of itemsList) {
153
153
  if (item.children && item.children.length > 0) {
154
154
  allIds.push(item.id);
@@ -1,23 +1,24 @@
1
1
  <script setup lang="ts">
2
- // 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.
3
- // oxlint-disable eslint/sort-imports
4
2
  import { sortAndFormatItems, useTreeFilter } from "@ogw_front/composables/tree_filter";
5
3
  import CommonTreeView from "@ogw_front/components/Viewer/ObjectTree/Base/CommonTreeView.vue";
4
+ import type { DisplayItem } from "@ogw_front/composables/virtual_tree";
6
5
  import FetchingData from "@ogw_front/components/FetchingData.vue";
6
+ import { MESH_COMPONENT_TYPES } from "@ogw_front/utils/default_styles";
7
7
  import ObjectTreeControls from "@ogw_front/components/Viewer/ObjectTree/Base/Controls.vue";
8
8
  import ObjectTreeItemLabel from "@ogw_front/components/Viewer/ObjectTree/Base/ItemLabel.vue";
9
- import type { DisplayItem } from "@ogw_front/composables/virtual_tree";
10
9
  import { useHoverhighlight } from "@ogw_front/composables/hover_highlight";
11
10
  import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
12
11
  import { useModelCollections } from "@ogw_front/composables/model_collections";
12
+ import { useModelComponents } from "@ogw_front/composables/model_components";
13
13
  import { useTreeviewStore } from "@ogw_front/stores/treeview";
14
14
 
15
15
  interface Props {
16
16
  id: string;
17
17
  viewId?: string;
18
+ viewType?: string;
18
19
  }
19
20
 
20
- const { id, viewId = undefined } = defineProps<Props>();
21
+ const { id, viewId = undefined, viewType = "model_components" } = defineProps<Props>();
21
22
  const actualViewId = viewId || id;
22
23
 
23
24
  interface CollectionTreeItem {
@@ -31,32 +32,44 @@ interface CollectionTreeItem {
31
32
 
32
33
  const { onHoverEnter, onHoverLeave } = useHoverhighlight();
33
34
  const hybridViewerStore = useHybridViewerStore();
34
- const emit = defineEmits<{
35
+ interface Emits {
35
36
  "show-menu": [
36
37
  payload: {
37
38
  event: unknown;
38
39
  itemId: string;
39
40
  context_type: "model_component" | "model_component_type";
40
41
  modelId: string;
41
- modelComponentType: string | undefined;
42
+ modelComponentType?: string;
43
+ targetComponentIds?: string[];
42
44
  },
43
45
  ];
44
- }>();
46
+ }
47
+
48
+ const emit = defineEmits<Emits>();
45
49
 
46
50
  const treeviewStore = useTreeviewStore();
51
+
52
+ const isCollections = computed(() => viewType === "model_collections");
53
+
54
+ const composable = isCollections.value ? useModelCollections(id) : useModelComponents(id);
47
55
  const {
48
56
  items: rawItems,
49
- collectionsCache: componentsCache,
50
57
  localCategories,
51
58
  selection: visibleComponents,
52
59
  updateVisibility,
53
- } = useModelCollections(id);
60
+ } = composable;
61
+
62
+ const cache = computed(
63
+ () =>
64
+ ("componentsCache" in composable ? composable.componentsCache.value : undefined) ??
65
+ ("collectionsCache" in composable ? composable.collectionsCache.value : undefined),
66
+ );
54
67
 
55
68
  const currentView = computed(() =>
56
69
  treeviewStore.opened_views.find((view) => view.id === actualViewId),
57
70
  );
58
71
 
59
- const opened = computed({
72
+ const opened = computed<string[]>({
60
73
  get: () => currentView.value?.opened || [],
61
74
  set: (val) => treeviewStore.setOpened(actualViewId, val),
62
75
  });
@@ -72,19 +85,21 @@ const {
72
85
  applySearchFilter,
73
86
  } = useTreeFilter(localCategories);
74
87
 
75
- function onUpdateSelection(newSelection: string[]) {
88
+ function onUpdateSelection(newSelection: string[]): void {
76
89
  const finalSelection = applySearchFilter(newSelection, visibleComponents.value);
77
90
  updateVisibility(finalSelection as string[]);
78
91
  }
79
92
 
80
- const visibleSelection = computed(() => applySearchFilter(visibleComponents.value, []));
93
+ const visibleSelection = computed<string[]>(
94
+ () => applySearchFilter(visibleComponents.value, []) as string[],
95
+ );
81
96
 
82
97
  const itemsForTreeView = computed<CollectionTreeItem[]>(() => {
83
- if (search.value && componentsCache.value) {
98
+ if (search.value && cache.value) {
84
99
  const query = search.value.toLowerCase();
85
100
  const result: CollectionTreeItem[] = [];
86
- for (const type of Object.keys(componentsCache.value)) {
87
- const matches = (componentsCache.value[type] ?? []).filter(
101
+ for (const type of Object.keys(cache.value)) {
102
+ const matches = (cache.value[type] ?? []).filter(
88
103
  (component: { title: string; id: string }) =>
89
104
  component.title.toLowerCase().includes(query) ||
90
105
  component.id.toLowerCase().includes(query),
@@ -107,7 +122,7 @@ const itemsForTreeView = computed<CollectionTreeItem[]>(() => {
107
122
  ...category,
108
123
  id: categoryId,
109
124
  children: sortAndFormatItems(
110
- componentsCache.value?.[categoryId],
125
+ cache.value?.[categoryId],
111
126
  sortType.value,
112
127
  ) as unknown as CollectionTreeItem[],
113
128
  });
@@ -115,14 +130,36 @@ const itemsForTreeView = computed<CollectionTreeItem[]>(() => {
115
130
  return result;
116
131
  });
117
132
 
118
- function showContextMenu(event: unknown, item: CollectionTreeItem) {
133
+ function extractComponentIds(node: CollectionTreeItem): string[] {
134
+ if (node.children) {
135
+ return node.children.flatMap((child) => extractComponentIds(child));
136
+ }
137
+ return [node.id];
138
+ }
139
+
140
+ function showContextMenu(event: unknown, item: CollectionTreeItem): void {
119
141
  const actualItem = item.raw || item;
142
+ if (isCollections.value && !MESH_COMPONENT_TYPES.includes(actualItem.category ?? "")) {
143
+ emit("show-menu", {
144
+ event,
145
+ itemId: id,
146
+ context_type: "model_component_type",
147
+ modelId: id,
148
+ modelComponentType: actualItem.category ?? actualItem.id,
149
+ targetComponentIds: extractComponentIds(actualItem),
150
+ });
151
+ return;
152
+ }
153
+ const typeId = actualItem.category || actualItem.id;
154
+ const typeItem = itemsForTreeView.value.find((type) => type.id === typeId);
155
+ const targetComponentIds = typeItem?.children?.map((child) => child.id);
120
156
  emit("show-menu", {
121
157
  event,
122
158
  itemId: actualItem.category ? actualItem.id : id,
123
159
  context_type: actualItem.category ? "model_component" : "model_component_type",
124
160
  modelId: id,
125
161
  modelComponentType: actualItem.category ? undefined : actualItem.id,
162
+ targetComponentIds,
126
163
  });
127
164
  }
128
165
 
@@ -142,7 +179,7 @@ function handleHoverEnter({
142
179
  }: {
143
180
  item: CollectionTreeItem;
144
181
  immediate?: boolean;
145
- }) {
182
+ }): void {
146
183
  const actualItem = item.raw || item;
147
184
 
148
185
  if (!actualItem.category && (!actualItem.children || actualItem.children.length === 0)) {
@@ -150,17 +187,16 @@ function handleHoverEnter({
150
187
  }
151
188
 
152
189
  const viewerIdsToHover = extractIds(actualItem);
153
-
154
190
  onHoverEnter(id, () => viewerIdsToHover, "model", immediate);
155
191
  }
156
192
 
157
- function handleHoverLeave() {
193
+ function handleHoverLeave(): void {
158
194
  onHoverLeave(id);
159
195
  }
160
196
 
161
- function expandAll() {
197
+ function expandAll(): void {
162
198
  const allIds: string[] = [];
163
- function traverse(itemsList: CollectionTreeItem[]) {
199
+ function traverse(itemsList: CollectionTreeItem[]): void {
164
200
  for (const item of itemsList) {
165
201
  if (item.children && item.children.length > 0) {
166
202
  allIds.push(item.id);
@@ -172,12 +208,11 @@ function expandAll() {
172
208
  opened.value = allIds;
173
209
  }
174
210
 
175
- function getLeafViewerIds(item: CollectionTreeItem) {
211
+ function getLeafViewerIds(item: CollectionTreeItem): number[] {
176
212
  const actualItem = item.raw || item;
177
213
  return extractIds(actualItem);
178
214
  }
179
215
 
180
- // The focusCameraOnObject composable's block_ids parameter is declared as string[], but this view (like the sibling ModelComponents view) has always focused the camera using the numeric viewer/actor ids collected by extractIds; that pre-dates this typing pass, so the ids are passed through as-is (no Number/String conversion) rather than changed here.
181
216
  function getLeafViewerIdsForFocus(item: CollectionTreeItem): string[] {
182
217
  return getLeafViewerIds(item) as unknown as string[];
183
218
  }
@@ -2,9 +2,11 @@
2
2
  import AttributeRangeSelector from "./AttributeRangeSelector.vue";
3
3
  import ColorMapPicker from "./ColorMapPicker.vue";
4
4
 
5
- const emit = defineEmits<{
5
+ interface Emits {
6
6
  reset: [];
7
- }>();
7
+ }
8
+
9
+ const emit = defineEmits<Emits>();
8
10
 
9
11
  const minimum = defineModel<number>("minimum");
10
12
  const maximum = defineModel<number>("maximum");
@@ -1,7 +1,9 @@
1
1
  <script setup lang="ts">
2
- const emit = defineEmits<{
2
+ interface Emits {
3
3
  reset: [];
4
- }>();
4
+ }
5
+
6
+ const emit = defineEmits<Emits>();
5
7
 
6
8
  const minimum = defineModel<number>("minimum");
7
9
  const maximum = defineModel<number>("maximum");
@@ -1,12 +1,10 @@
1
1
  <script setup lang="ts">
2
- // 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.
3
- // oxlint-disable eslint/sort-imports
4
2
  import { DEFAULT_NO_DATA_COLOR } from "@ogw_front/utils/default_styles/constants";
3
+ import type { JsonRpcSchema } from "@ogw_shared/utils/types.js";
5
4
  import ViewerOptionsAttributeColorBar from "@ogw_front/components/Viewer/Options/AttributeColorBar.vue";
6
5
  import ViewerOptionsColorPicker from "@ogw_front/components/Viewer/Options/ColorPicker.vue";
7
6
  import { getAttributeRange } from "@ogw_front/utils/attributes";
8
7
  import { useBackStore } from "@ogw_front/stores/back";
9
- import type { JsonRpcSchema } from "@ogw_shared/utils/types.js";
10
8
 
11
9
  const backStore = useBackStore();
12
10
 
@@ -33,10 +31,10 @@ interface AttributeInfo {
33
31
 
34
32
  const attributes = ref<AttributeInfo[]>([]);
35
33
 
36
- const currentAttribute = computed(() =>
34
+ const currentAttribute = computed<AttributeInfo | undefined>(() =>
37
35
  attributes.value.find((attr) => attr.attribute_name === attributeName.value),
38
36
  );
39
- const cssNoDataColor = computed(() => {
37
+ const cssNoDataColor = computed<string>(() => {
40
38
  const { red, green, blue, alpha } = attributeNoDataColor.value ?? DEFAULT_NO_DATA_COLOR;
41
39
  return `rgba(${red}, ${green}, ${blue}, ${alpha})`;
42
40
  });
@@ -77,7 +75,7 @@ const rangeMax = computed<number | undefined>({
77
75
  },
78
76
  });
79
77
 
80
- const componentItems = computed(() => {
78
+ const componentItems = computed<{ title: string; value: number }[]>(() => {
81
79
  if (!currentAttribute.value) {
82
80
  return [];
83
81
  }
@@ -87,7 +85,7 @@ const componentItems = computed(() => {
87
85
  }));
88
86
  });
89
87
 
90
- function resetRange() {
88
+ function resetRange(): void {
91
89
  if (currentAttribute.value) {
92
90
  const comp = attributeItem.value ?? 0;
93
91
  // GetAttributeRange's parameter type (AttributeRangeSource) isn't exported;
@@ -101,11 +99,11 @@ function resetRange() {
101
99
  }
102
100
  }
103
101
 
104
- function hasSelectedComponent(components: unknown) {
102
+ function hasSelectedComponent(components: unknown): boolean {
105
103
  return Array.isArray(components) && components.length > 0;
106
104
  }
107
105
 
108
- function getAttributes() {
106
+ function getAttributes(): void {
109
107
  const schemaProperties = schema.properties as Record<string, unknown> | undefined;
110
108
  const requiresComponent = schemaProperties?.component_ids !== undefined;
111
109
  if (requiresComponent && !hasSelectedComponent(componentIds)) {
@@ -17,29 +17,31 @@ interface Props {
17
17
 
18
18
  const { presets, selectedPresetName = "" } = defineProps<Props>();
19
19
 
20
- const emit = defineEmits<{
20
+ interface Emits {
21
21
  select: [preset: ColorMapPreset];
22
- }>();
22
+ }
23
+
24
+ const emit = defineEmits<Emits>();
23
25
 
24
26
  interface CanvasRefEntry {
25
27
  element: HTMLCanvasElement;
26
28
  presetName: string;
27
29
  }
28
30
 
29
- const filterText = ref("");
30
- const canvasRefs = ref<Record<string, CanvasRefEntry>>({});
31
- const loading = ref(true);
32
- const renderJobId = ref(0);
31
+ const filterText = ref<string>("");
32
+ const canvasRefs = ref<Map<string, CanvasRefEntry>>(new Map());
33
+ const loading = ref<boolean>(true);
34
+ const renderJobId = ref<number>(0);
33
35
  const openedGroups = ref<string[]>([]);
34
36
 
35
- function setCanvasRef(presetName: string, element: Element | null, id: string) {
37
+ function setCanvasRef(presetName: string, element: Element | null, id: string): void {
36
38
  if (element) {
37
- canvasRefs.value[id] = {
39
+ canvasRefs.value.set(id, {
38
40
  element: element as HTMLCanvasElement,
39
41
  presetName,
40
- };
42
+ });
41
43
  } else {
42
- delete canvasRefs.value[id];
44
+ canvasRefs.value.delete(id);
43
45
  }
44
46
  }
45
47
 
@@ -74,7 +76,7 @@ watch(filterText, (newFilterText) => {
74
76
  }
75
77
  });
76
78
 
77
- function processChunk(entries: [string, CanvasRefEntry][], index: number, jobId: number) {
79
+ function processChunk(entries: [string, CanvasRefEntry][], index: number, jobId: number): void {
78
80
  if (jobId !== renderJobId.value || index >= entries.length) {
79
81
  if (jobId === renderJobId.value) {
80
82
  loading.value = false;
@@ -95,13 +97,13 @@ function processChunk(entries: [string, CanvasRefEntry][], index: number, jobId:
95
97
  setTimeout(() => processChunk(entries, end, jobId), ZERO);
96
98
  }
97
99
 
98
- function drawAllCanvases() {
100
+ function drawAllCanvases(): void {
99
101
  renderJobId.value += 1;
100
102
  const jobId = renderJobId.value;
101
103
  loading.value = true;
102
104
  nextTick(() => {
103
105
  const WAIT_MS = 50;
104
- setTimeout(() => processChunk(Object.entries(canvasRefs.value), 0, jobId), WAIT_MS);
106
+ setTimeout(() => processChunk([...canvasRefs.value.entries()], 0, jobId), WAIT_MS);
105
107
  });
106
108
  }
107
109
 
@@ -14,22 +14,22 @@ const selectedPresetName = defineModel<string>("selectedPresetName", {
14
14
  default: "batlow",
15
15
  });
16
16
 
17
- const menuOpen = ref(false);
17
+ const menuOpen = ref<boolean>(false);
18
18
  const lutCanvas = ref<HTMLCanvasElement | undefined>(undefined);
19
19
 
20
20
  const presets = computed(() => getPresetsWithCurrentAtTop(selectedPresetName.value));
21
21
 
22
- function drawLutCanvas() {
22
+ function drawLutCanvas(): void {
23
23
  drawCanvasForPreset(selectedPresetName.value, lutCanvas.value);
24
24
  }
25
25
 
26
- function onSelectPreset(preset: { Name: string }) {
26
+ function onSelectPreset(preset: { Name: string }): void {
27
27
  selectedPresetName.value = preset.Name;
28
28
  menuOpen.value = false;
29
29
  }
30
30
 
31
31
  onMounted(() => nextTick(drawLutCanvas));
32
- watch([lutCanvas, selectedPresetName, () => min, () => max], drawLutCanvas);
32
+ watch([lutCanvas, selectedPresetName, (): number => min, (): number => max], drawLutCanvas);
33
33
  </script>
34
34
 
35
35
  <template>