@geode/opengeodeweb-front 10.29.1 → 10.30.0-rc.10

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 (82) hide show
  1. package/app/components/ClippingPlaneCard.vue +112 -0
  2. package/app/components/ClippingPlanes.vue +238 -0
  3. package/app/components/Launcher.vue +1 -1
  4. package/app/components/ObjectSelector.vue +26 -76
  5. package/app/components/ToolPanel.vue +3 -2
  6. package/app/components/ViewToolbar.vue +12 -0
  7. package/app/components/Viewer/ObjectTree/Base/TreeRow.vue +58 -20
  8. package/app/components/Viewer/ObjectTree/Views/GlobalObjects.vue +42 -40
  9. package/app/composables/clipping_planes_widget.js +262 -0
  10. package/app/composables/hover_highlight.js +6 -0
  11. package/app/composables/project_manager.js +14 -11
  12. package/app/composables/use_overlapping_picker.js +15 -2
  13. package/app/stores/app.js +56 -11
  14. package/app/stores/back.js +10 -27
  15. package/app/stores/cloud.js +7 -1
  16. package/app/stores/data.js +32 -1
  17. package/app/stores/data_style.js +11 -0
  18. package/app/stores/hybrid_viewer.js +13 -5
  19. package/app/stores/infra.js +2 -7
  20. package/app/stores/viewer.js +9 -27
  21. package/app/utils/clipping_planes.js +110 -0
  22. package/app/utils/extension.js +30 -3
  23. package/app/utils/import_workflow.js +9 -12
  24. package/app/utils/log.js +18 -0
  25. package/app/utils/stores.js +32 -0
  26. package/internal/stores/hybrid_viewer.js +8 -63
  27. package/internal/stores/hybrid_viewer_brightness.js +62 -0
  28. package/internal/utils/api_fetch.js +27 -53
  29. package/internal/utils/upload_file.js +36 -29
  30. package/internal/utils/viewer_call.js +7 -2
  31. package/nuxt.config.js +2 -1
  32. package/package.json +4 -3
  33. package/server/api/local/{project_folder_path.post.js → app/project_folder_path.post.js} +1 -1
  34. package/server/api/local/{run_back.post.js → app/run_back.post.js} +1 -1
  35. package/server/api/local/{run_viewer.post.js → app/run_viewer.post.js} +1 -1
  36. package/server/api/{microservice → local}/extensions/upload.put.js +16 -37
  37. package/server/api/microservice/app/set_app_base_url.post.js +25 -0
  38. package/server/api/microservice/app/set_back_base_url.post.js +22 -0
  39. package/server/api/microservice/app/set_viewer_base_url.post.js +22 -0
  40. package/server/api/microservice/extensions/download.post.js +32 -0
  41. package/server/api/microservice/extensions/kill.post.js +3 -3
  42. package/server/api/microservice/extensions/run.post.js +5 -4
  43. package/server/api/serverless/{run_cloud.js → run_cloud.post.js} +1 -1
  44. package/{app/utils/config.js → server/utils/app_config.js} +28 -3
  45. package/{app/utils/local → server/utils}/path.js +1 -1
  46. package/{app/utils/local → server/utils}/scripts.js +5 -2
  47. package/server/utils/server_config.js +32 -0
  48. package/shared/scripts.js +56 -0
  49. package/shared/utils/fetch_raw.js +61 -0
  50. package/shared/utils/fetch_schema.js +46 -0
  51. package/shared/utils/file.js +16 -0
  52. package/shared/utils/response_handlers/load.js +74 -0
  53. package/tests/integration/setup.js +3 -3
  54. package/tests/integration/stores/data_style/mesh/cells.nuxt.test.js +1 -1
  55. package/tests/integration/stores/data_style/mesh/edges.nuxt.test.js +1 -1
  56. package/tests/integration/stores/data_style/mesh/index.nuxt.test.js +1 -1
  57. package/tests/integration/stores/data_style/mesh/points.nuxt.test.js +1 -1
  58. package/tests/integration/stores/data_style/mesh/polygons.nuxt.test.js +1 -1
  59. package/tests/integration/stores/data_style/mesh/polyhedra.nuxt.test.js +1 -1
  60. package/tests/integration/stores/data_style/model/blocks.nuxt.test.js +1 -1
  61. package/tests/integration/stores/data_style/model/corners.nuxt.test.js +1 -1
  62. package/tests/integration/stores/data_style/model/edges.nuxt.test.js +1 -1
  63. package/tests/integration/stores/data_style/model/index.nuxt.test.js +1 -1
  64. package/tests/integration/stores/data_style/model/lines.nuxt.test.js +1 -1
  65. package/tests/integration/stores/data_style/model/points.nuxt.test.js +1 -1
  66. package/tests/integration/stores/data_style/model/surfaces.nuxt.test.js +1 -1
  67. package/tests/integration/stores/viewer.nuxt.test.js +1 -1
  68. package/tests/unit/composables/project_manager.nuxt.test.js +14 -2
  69. package/tests/unit/composables/upload_file.nuxt.test.js +2 -2
  70. package/tests/unit/stores/back.nuxt.test.js +1 -1
  71. package/tests/unit/stores/cloud.nuxt.test.js +22 -20
  72. package/tests/unit/stores/data.nuxt.test.js +35 -0
  73. package/tests/unit/stores/infra.nuxt.test.js +13 -6
  74. package/tests/unit/stores/viewer.nuxt.test.js +1 -1
  75. package/tests/unit/utils/validate_schema.nuxt.test.js +1 -1
  76. package/tests/vitest.config.js +7 -5
  77. /package/server/api/local/{kill.post.js → app/kill.post.js} +0 -0
  78. /package/{app/utils/local → server/utils}/cleanup.js +0 -0
  79. /package/{app/utils/local → server/utils}/microservices.js +0 -0
  80. /package/{app → server}/utils/server.js +0 -0
  81. /package/{app/utils/local → shared}/app_mode.js +0 -0
  82. /package/{app → shared}/utils/validate_schema.js +0 -0
@@ -0,0 +1,56 @@
1
+ // Node imports
2
+
3
+ // Third party imports
4
+
5
+ // Local imports
6
+ import { fetchSchema } from "./utils/fetch_schema.js";
7
+
8
+ function setAppBaseUrl(appBaseUrl) {
9
+ console.log("[API] setAppBaseUrl", appBaseUrl);
10
+ const schema = {
11
+ $id: "/api/microservice/app/set_app_base_url",
12
+ methods: ["POST"],
13
+ type: "object",
14
+ properties: {
15
+ baseUrl: { type: "string" },
16
+ },
17
+ required: ["baseUrl"],
18
+ additionalProperties: false,
19
+ };
20
+ const params = { baseUrl: appBaseUrl };
21
+ return fetchSchema({ schema, params, baseURL: appBaseUrl });
22
+ }
23
+
24
+ function setBackBaseUrl(appBaseUrl, backBaseUrl) {
25
+ console.log("[API] setBackBaseUrl", appBaseUrl, backBaseUrl);
26
+ const schema = {
27
+ $id: "/api/microservice/app/set_back_base_url",
28
+ methods: ["POST"],
29
+ type: "object",
30
+ properties: {
31
+ baseUrl: { type: "string" },
32
+ },
33
+ required: ["baseUrl"],
34
+ additionalProperties: false,
35
+ };
36
+ const params = { baseUrl: backBaseUrl };
37
+ return fetchSchema({ schema, params, baseURL: appBaseUrl });
38
+ }
39
+
40
+ function setViewerBaseUrl(appBaseUrl, viewerBaseUrl) {
41
+ console.log("[API] setViewerBaseUrl", appBaseUrl, viewerBaseUrl);
42
+ const schema = {
43
+ $id: "/api/microservice/app/set_viewer_base_url",
44
+ methods: ["POST"],
45
+ type: "object",
46
+ properties: {
47
+ baseUrl: { type: "string" },
48
+ },
49
+ required: ["baseUrl"],
50
+ additionalProperties: false,
51
+ };
52
+ const params = { baseUrl: viewerBaseUrl };
53
+ return fetchSchema({ schema, params, baseURL: appBaseUrl });
54
+ }
55
+
56
+ export { setAppBaseUrl, setBackBaseUrl, setViewerBaseUrl };
@@ -0,0 +1,61 @@
1
+ // Third party imports
2
+ import { $fetch } from "ofetch";
3
+ import _ from "lodash";
4
+ import pTimeout from "p-timeout";
5
+
6
+ // Local imports
7
+ import { hasBody } from "./file.js";
8
+
9
+ function fetchRaw(
10
+ { route, method, params = {}, baseURL, headers = {}, max_retry, timeout, expectEvent = false },
11
+ { request_error_function, response_function, response_error_function } = {},
12
+ ) {
13
+ if (expectEvent) {
14
+ const value = "text/event-stream";
15
+ if (_.isEmpty(headers)) {
16
+ headers["Accept"] = value;
17
+ } else {
18
+ headers["Accept"] = `${headers["Accept"]}, ${value}`;
19
+ }
20
+ }
21
+
22
+ const request_options = { method, headers };
23
+ if (hasBody(params)) {
24
+ request_options.body = params;
25
+ }
26
+ if (max_retry) {
27
+ request_options.max_retry = max_retry;
28
+ }
29
+
30
+ function doFetch() {
31
+ return $fetch(route, {
32
+ baseURL,
33
+ ...request_options,
34
+ onRequestError({ error }) {
35
+ if (request_error_function) {
36
+ request_error_function(error);
37
+ }
38
+ },
39
+ onResponse({ response }) {
40
+ if (response.ok && response_function) {
41
+ response_function(response._data);
42
+ }
43
+ },
44
+ onResponseError({ response }) {
45
+ if (response_error_function) {
46
+ response_error_function(response);
47
+ }
48
+ },
49
+ });
50
+ }
51
+
52
+ if (timeout > 0) {
53
+ return pTimeout(doFetch(), {
54
+ milliseconds: timeout,
55
+ message: `${route}: Timed out after ${timeout}ms`,
56
+ });
57
+ }
58
+ return doFetch();
59
+ }
60
+
61
+ export { fetchRaw };
@@ -0,0 +1,46 @@
1
+ // Third party imports
2
+
3
+ // Local imports
4
+ import { fetchRaw } from "./fetch_raw.js";
5
+ import { validate_schema } from "./validate_schema.js";
6
+
7
+ const ERROR_400 = 400;
8
+
9
+ function fetchSchema(
10
+ { schema, params = {}, baseURL, headers, timeout, expectEvent = false },
11
+ {
12
+ request_error_function,
13
+ response_function,
14
+ response_error_function,
15
+ validation_error_function,
16
+ } = {},
17
+ ) {
18
+ console.log("fetchSchema", { schema, baseURL, params, headers, timeout });
19
+ const { valid, error: schema_error } = validate_schema(schema, params);
20
+
21
+ if (!valid) {
22
+ if (process.env.NODE_ENV !== "production") {
23
+ console.log("Bad request", schema_error, schema, params);
24
+ }
25
+ if (validation_error_function) {
26
+ validation_error_function({ code: ERROR_400, name: "Bad request", error: schema_error });
27
+ }
28
+ throw new Error(`${schema.$id}: ${schema_error}`);
29
+ }
30
+
31
+ return fetchRaw(
32
+ {
33
+ route: schema.$id,
34
+ method: schema.methods.find((method) => method !== "OPTIONS"),
35
+ params,
36
+ baseURL,
37
+ headers,
38
+ max_retry: schema.max_retry,
39
+ timeout,
40
+ expectEvent,
41
+ },
42
+ { request_error_function, response_function, response_error_function },
43
+ );
44
+ }
45
+
46
+ export { fetchSchema };
@@ -0,0 +1,16 @@
1
+ import _ from "lodash";
2
+
3
+ function assertFile(file) {
4
+ console.log("[ASSERT_FILE] Asserting file", { file });
5
+ if (!(file instanceof File)) {
6
+ throw new Error("file must be an instance of File");
7
+ }
8
+ }
9
+
10
+ function hasBody(params) {
11
+ if (params instanceof FormData || params instanceof Blob) {
12
+ return true;
13
+ }
14
+ return !_.isEmpty(params);
15
+ }
16
+ export { assertFile, hasBody };
@@ -0,0 +1,74 @@
1
+ function getFileExtension(filename) {
2
+ return filename.slice(filename.lastIndexOf(".") + 1);
3
+ }
4
+
5
+ function selectGeodeObject(objectMap) {
6
+ const objectKeys = Object.keys(objectMap);
7
+ if (objectKeys.length === 0) {
8
+ return undefined;
9
+ }
10
+ if (objectKeys.length === 1 && objectMap[objectKeys[0]].is_loadable > 0) {
11
+ return objectKeys[0];
12
+ }
13
+
14
+ const highestLoadScore = Math.max(...objectKeys.map((key) => objectMap[key].is_loadable));
15
+ if (highestLoadScore <= 0) {
16
+ return undefined;
17
+ }
18
+
19
+ const bestScoreObjects = objectKeys.filter(
20
+ (key) => objectMap[key].is_loadable === highestLoadScore,
21
+ );
22
+ if (bestScoreObjects.length === 1) {
23
+ return bestScoreObjects[0];
24
+ }
25
+
26
+ const highestPriority = Math.max(
27
+ ...bestScoreObjects.map((key) => objectMap[key].object_priority ?? -Infinity),
28
+ );
29
+ const bestPriorityObjects = bestScoreObjects.filter(
30
+ (key) => objectMap[key].object_priority === highestPriority,
31
+ );
32
+ if (highestPriority !== -Infinity && bestPriorityObjects.length === 1) {
33
+ return bestPriorityObjects[0];
34
+ }
35
+
36
+ return undefined;
37
+ }
38
+
39
+ function intersectAllowedObjects(allowedObjectsList) {
40
+ const allKeys = [...new Set(allowedObjectsList.flatMap((object) => Object.keys(object)))];
41
+ const commonKeys = allKeys.filter((key) => allowedObjectsList.every((object) => key in object));
42
+
43
+ const mergedAllowedObjects = {};
44
+ for (const key of commonKeys) {
45
+ const loadScores = allowedObjectsList.map((object) => object[key].is_loadable);
46
+ const priorities = allowedObjectsList
47
+ .map((object) => object[key].object_priority)
48
+ .filter((priority) => priority !== undefined);
49
+
50
+ mergedAllowedObjects[key] = { is_loadable: Math.min(...loadScores) };
51
+ if (priorities.length > 0) {
52
+ mergedAllowedObjects[key].object_priority = Math.max(...priorities);
53
+ }
54
+ }
55
+
56
+ return { commonKeys, allKeys, mergedAllowedObjects };
57
+ }
58
+
59
+ function resolveAllowedObjects(filenames, allowedObjectsList) {
60
+ const { commonKeys, allKeys, mergedAllowedObjects } = intersectAllowedObjects(allowedObjectsList);
61
+
62
+ const multipleFilesNoCommon =
63
+ filenames.length > 1 && allKeys.length > 0 && commonKeys.length === 0;
64
+
65
+ const selectedGeodeObject = selectGeodeObject(mergedAllowedObjects);
66
+
67
+ return {
68
+ mergedAllowedObjects,
69
+ multipleFilesNoCommon,
70
+ selectedGeodeObject,
71
+ };
72
+ }
73
+
74
+ export { resolveAllowedObjects, getFileExtension };
@@ -8,10 +8,10 @@ import path from "node:path";
8
8
  import { afterAll, beforeAll, expect, vi } from "vitest";
9
9
 
10
10
  // Local imports
11
- import { addMicroserviceMetadatas, runBack, runViewer } from "@ogw_front/utils/local/microservices";
12
- import { createPath, generateProjectFolderPath } from "@ogw_front/utils/local/path";
11
+ import { addMicroserviceMetadatas, runBack, runViewer } from "@ogw_server/utils/microservices";
12
+ import { createPath, generateProjectFolderPath } from "@ogw_server/utils/path";
13
13
  import { Status } from "@ogw_front/utils/status";
14
- import { appMode } from "@ogw_front/utils/local/app_mode";
14
+ import { appMode } from "@ogw_shared/app_mode";
15
15
  import { importFile } from "@ogw_front/utils/import_workflow";
16
16
  import { setupActivePinia } from "@ogw_tests/utils";
17
17
  import { useBackStore } from "@ogw_front/stores/back";
@@ -6,7 +6,7 @@ import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schem
6
6
  // Local imports
7
7
  import { beforeAllTimeout, setupIntegrationTests } from "@ogw_tests/integration/setup";
8
8
  import { Status } from "@ogw_front/utils/status";
9
- import { cleanupBackend } from "@ogw_front/utils/local/cleanup";
9
+ import { cleanupBackend } from "@ogw_server/utils/cleanup";
10
10
  import { getRGBPointsFromPreset } from "@ogw_front/utils/colormap";
11
11
  import { isMeshCellsVertexAttributeValid } from "@ogw_internal/stores/data_style/mesh/cells/vertex";
12
12
  import { useDataStyleStore } from "@ogw_front/stores/data_style";
@@ -5,7 +5,7 @@ import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schem
5
5
  // Local imports
6
6
  import { beforeAllTimeout, setupIntegrationTests } from "@ogw_tests/integration/setup";
7
7
  import { Status } from "@ogw_front/utils/status";
8
- import { cleanupBackend } from "@ogw_front/utils/local/cleanup";
8
+ import { cleanupBackend } from "@ogw_server/utils/cleanup";
9
9
  import { getRGBPointsFromPreset } from "@ogw_front/utils/colormap";
10
10
  import { useDataStyleStore } from "@ogw_front/stores/data_style";
11
11
  import { useViewerStore } from "@ogw_front/stores/viewer";
@@ -5,7 +5,7 @@ import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schem
5
5
  // Local imports
6
6
  import { beforeAllTimeout, setupIntegrationTests } from "@ogw_tests/integration/setup";
7
7
  import { Status } from "@ogw_front/utils/status";
8
- import { cleanupBackend } from "@ogw_front/utils/local/cleanup";
8
+ import { cleanupBackend } from "@ogw_server/utils/cleanup";
9
9
  import { useDataStyleStore } from "@ogw_front/stores/data_style";
10
10
  import { useViewerStore } from "@ogw_front/stores/viewer";
11
11
 
@@ -5,7 +5,7 @@ import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schem
5
5
  // Local imports
6
6
  import { beforeAllTimeout, setupIntegrationTests } from "@ogw_tests/integration/setup";
7
7
  import { Status } from "@ogw_front/utils/status";
8
- import { cleanupBackend } from "@ogw_front/utils/local/cleanup";
8
+ import { cleanupBackend } from "@ogw_server/utils/cleanup";
9
9
  import { getRGBPointsFromPreset } from "@ogw_front/utils/colormap";
10
10
  import { useDataStyleStore } from "@ogw_front/stores/data_style";
11
11
  import { useViewerStore } from "@ogw_front/stores/viewer";
@@ -5,7 +5,7 @@ import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schem
5
5
  // Local imports
6
6
  import { beforeAllTimeout, setupIntegrationTests } from "@ogw_tests/integration/setup";
7
7
  import { Status } from "@ogw_front/utils/status";
8
- import { cleanupBackend } from "@ogw_front/utils/local/cleanup";
8
+ import { cleanupBackend } from "@ogw_server/utils/cleanup";
9
9
  import { getRGBPointsFromPreset } from "@ogw_front/utils/colormap";
10
10
  import { useDataStyleStore } from "@ogw_front/stores/data_style";
11
11
  import { useViewerStore } from "@ogw_front/stores/viewer";
@@ -5,7 +5,7 @@ import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schem
5
5
  // Local imports
6
6
  import { beforeAllTimeout, setupIntegrationTests } from "@ogw_tests/integration/setup";
7
7
  import { Status } from "@ogw_front/utils/status";
8
- import { cleanupBackend } from "@ogw_front/utils/local/cleanup";
8
+ import { cleanupBackend } from "@ogw_server/utils/cleanup";
9
9
  import { getRGBPointsFromPreset } from "@ogw_front/utils/colormap";
10
10
  import { useDataStyleStore } from "@ogw_front/stores/data_style";
11
11
  import { useViewerStore } from "@ogw_front/stores/viewer";
@@ -6,7 +6,7 @@ import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schem
6
6
  // Local imports
7
7
  import { beforeAllTimeout, setupIntegrationTests } from "@ogw_tests/integration/setup";
8
8
  import { Status } from "@ogw_front/utils/status";
9
- import { cleanupBackend } from "@ogw_front/utils/local/cleanup";
9
+ import { cleanupBackend } from "@ogw_server/utils/cleanup";
10
10
  import { useDataStore } from "@ogw_front/stores/data";
11
11
  import { useDataStyleStore } from "@ogw_front/stores/data_style";
12
12
  import { useViewerStore } from "@ogw_front/stores/viewer";
@@ -5,7 +5,7 @@ import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schem
5
5
  // Local imports
6
6
  import { beforeAllTimeout, setupIntegrationTests } from "@ogw_tests/integration/setup";
7
7
  import { Status } from "@ogw_front/utils/status";
8
- import { cleanupBackend } from "@ogw_front/utils/local/cleanup";
8
+ import { cleanupBackend } from "@ogw_server/utils/cleanup";
9
9
  import { useDataStore } from "@ogw_front/stores/data";
10
10
  import { useDataStyleStore } from "@ogw_front/stores/data_style";
11
11
  import { useViewerStore } from "@ogw_front/stores/viewer";
@@ -5,7 +5,7 @@ import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schem
5
5
  // Local imports
6
6
  import { beforeAllTimeout, setupIntegrationTests } from "@ogw_tests/integration/setup";
7
7
  import { Status } from "@ogw_front/utils/status";
8
- import { cleanupBackend } from "@ogw_front/utils/local/cleanup";
8
+ import { cleanupBackend } from "@ogw_server/utils/cleanup";
9
9
  import { useDataStyleStore } from "@ogw_front/stores/data_style";
10
10
  import { useViewerStore } from "@ogw_front/stores/viewer";
11
11
 
@@ -5,7 +5,7 @@ import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schem
5
5
  // Local imports
6
6
  import { beforeAllTimeout, setupIntegrationTests } from "@ogw_tests/integration/setup";
7
7
  import { Status } from "@ogw_front/utils/status";
8
- import { cleanupBackend } from "@ogw_front/utils/local/cleanup";
8
+ import { cleanupBackend } from "@ogw_server/utils/cleanup";
9
9
  import { useDataStore } from "@ogw_front/stores/data";
10
10
  import { useDataStyleStore } from "@ogw_front/stores/data_style";
11
11
  import { useViewerStore } from "@ogw_front/stores/viewer";
@@ -6,7 +6,7 @@ import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schem
6
6
  // Local imports
7
7
  import { beforeAllTimeout, setupIntegrationTests } from "@ogw_tests/integration/setup";
8
8
  import { Status } from "@ogw_front/utils/status";
9
- import { cleanupBackend } from "@ogw_front/utils/local/cleanup";
9
+ import { cleanupBackend } from "@ogw_server/utils/cleanup";
10
10
  import { useDataStore } from "@ogw_front/stores/data";
11
11
  import { useDataStyleStore } from "@ogw_front/stores/data_style";
12
12
  import { useViewerStore } from "@ogw_front/stores/viewer";
@@ -5,7 +5,7 @@ import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schem
5
5
  // Local imports
6
6
  import { beforeAllTimeout, setupIntegrationTests } from "@ogw_tests/integration/setup";
7
7
  import { Status } from "@ogw_front/utils/status";
8
- import { cleanupBackend } from "@ogw_front/utils/local/cleanup";
8
+ import { cleanupBackend } from "@ogw_server/utils/cleanup";
9
9
  import { useDataStyleStore } from "@ogw_front/stores/data_style";
10
10
  import { useViewerStore } from "@ogw_front/stores/viewer";
11
11
 
@@ -6,7 +6,7 @@ import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schem
6
6
  // Local imports
7
7
  import { beforeAllTimeout, setupIntegrationTests } from "@ogw_tests/integration/setup";
8
8
  import { Status } from "@ogw_front/utils/status";
9
- import { cleanupBackend } from "@ogw_front/utils/local/cleanup";
9
+ import { cleanupBackend } from "@ogw_server/utils/cleanup";
10
10
  import { getRGBPointsFromPreset } from "@ogw_front/utils/colormap";
11
11
  import { isModelSurfacesPolygonAttributeValid } from "@ogw_internal/stores/data_style/model/surfaces/polygon";
12
12
  import { isModelSurfacesVertexAttributeValid } from "@ogw_internal/stores/data_style/model/surfaces/vertex";
@@ -7,7 +7,7 @@ import opengeodeweb_viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb
7
7
  // Local imports
8
8
  import { beforeAllTimeout, runMicroservices } from "@ogw_tests/integration/setup";
9
9
  import { Status } from "@ogw_front/utils/status";
10
- import { cleanupBackend } from "@ogw_front/utils/local/cleanup";
10
+ import { cleanupBackend } from "@ogw_server/utils/cleanup";
11
11
  import { setupActivePinia } from "@ogw_tests/utils";
12
12
  import { useViewerStore } from "@ogw_front/stores/viewer";
13
13
 
@@ -5,9 +5,15 @@
5
5
  import { beforeEach, describe, expect, test, vi } from "vitest";
6
6
 
7
7
  import { exportProject, importProject } from "@ogw_front/composables/project_manager";
8
- import { appMode } from "@ogw_front/utils/local/app_mode";
8
+ import { appMode } from "@ogw_shared/app_mode";
9
9
  import { setupActivePinia } from "@ogw_tests/utils";
10
10
 
11
+ import { $fetch } from "ofetch";
12
+
13
+ vi.mock(import("ofetch"), () => ({
14
+ $fetch: vi.fn(),
15
+ }));
16
+
11
17
  // Constants
12
18
  const PANEL_WIDTH = 300;
13
19
  const Z_SCALE = 1.5;
@@ -105,6 +111,7 @@ const dataStoreMock = {
105
111
  registerObject: vi.fn().mockResolvedValue(),
106
112
  addItem: vi.fn().mockResolvedValue(),
107
113
  importStores: vi.fn().mockResolvedValue(),
114
+ isItemViewable: vi.fn().mockReturnValue(true),
108
115
  };
109
116
  const dataStyleStoreMock = {
110
117
  importStores: vi.fn().mockResolvedValue(),
@@ -140,7 +147,12 @@ const hybridViewerStoreMock = {
140
147
  };
141
148
 
142
149
  // MOCKS
143
- vi.stubGlobal("$fetch", vi.fn().mockResolvedValue({ snapshot: snapshotMock }));
150
+ $fetch.mockImplementation((route, options) => {
151
+ const data = { snapshot: snapshotMock };
152
+ // oxlint-disable-next-line eslint/id-length
153
+ options.onResponse?.({ response: { ok: true, _data: data } });
154
+ return Promise.resolve(data);
155
+ });
144
156
  vi.mock(import("@ogw_internal/utils/viewer_call"), () => ({
145
157
  viewer_call: viewer_call_mock_fn,
146
158
  }));
@@ -22,7 +22,7 @@ describe("upload_file", () => {
22
22
  const backStore = useBackStore();
23
23
  const file = "toto";
24
24
 
25
- await expect(backStore.upload(file)).rejects.toThrow("file must be a instance of File");
25
+ await expect(backStore.upload(file)).rejects.toThrow("file must be an instance of File");
26
26
  });
27
27
 
28
28
  test("onResponse", async () => {
@@ -36,7 +36,7 @@ describe("upload_file", () => {
36
36
  let response_value = "";
37
37
  await backStore.upload(file, {
38
38
  response_function: (response) => {
39
- response_value = response._data.test;
39
+ response_value = response.test;
40
40
  },
41
41
  });
42
42
  expect(feedbackStore.feedbacks).toHaveLength(ZERO);
@@ -5,7 +5,7 @@ import { registerEndpoint } from "@nuxt/test-utils/runtime";
5
5
 
6
6
  // Local imports
7
7
  import { Status } from "@ogw_front/utils/status";
8
- import { appMode } from "@ogw_front/utils/local/app_mode";
8
+ import { appMode } from "@ogw_shared/app_mode";
9
9
  import { setupActivePinia } from "@ogw_tests/utils";
10
10
  import { useBackStore } from "@ogw_front/stores/back";
11
11
  import { useInfraStore } from "@ogw_front/stores/infra";
@@ -1,6 +1,6 @@
1
1
  // Third party imports
2
2
  import { beforeEach, describe, expect, expectTypeOf, test, vi } from "vitest";
3
- import { registerEndpoint } from "@nuxt/test-utils/runtime";
3
+ import { $fetch } from "ofetch";
4
4
 
5
5
  // Local imports
6
6
  import { Status } from "@ogw_front/utils/status";
@@ -8,9 +8,12 @@ import { setupActivePinia } from "@ogw_tests/utils";
8
8
  import { useCloudStore } from "@ogw_front/stores/cloud";
9
9
  import { useFeedbackStore } from "@ogw_front/stores/feedback";
10
10
 
11
+ vi.mock(import("ofetch"), () => ({
12
+ $fetch: vi.fn(),
13
+ }));
14
+
11
15
  // CONSTANTS
12
16
  const PROJECT = "project";
13
- const STATUS_500 = 500;
14
17
 
15
18
  function setupConfig() {
16
19
  const config = useRuntimeConfig();
@@ -31,23 +34,23 @@ describe("cloud store", () => {
31
34
 
32
35
  describe("actions", () => {
33
36
  describe("launch", () => {
34
- const postFakeCall = vi.fn();
37
+ beforeEach(() => {
38
+ $fetch.mockReset();
39
+ });
35
40
 
36
41
  test("successful launch", async () => {
37
42
  setupConfig();
38
43
  const cloudStore = useCloudStore();
39
44
  const feedbackStore = useFeedbackStore();
40
45
 
41
- registerEndpoint("/api/serverless/run_cloud", {
42
- method: "POST",
43
- handler: postFakeCall,
46
+ $fetch.mockImplementation((route, options) => {
47
+ const data = { url: "test.com" };
48
+ // oxlint-disable-next-line eslint/id-length
49
+ options.onResponse?.({ response: { ok: true, _data: data } });
50
+ return Promise.resolve(data);
44
51
  });
45
52
 
46
- postFakeCall.mockReturnValue({
47
- url: "http://test.com",
48
- });
49
-
50
- await cloudStore.launch("", "", false);
53
+ await cloudStore.launch("noreply@example.com");
51
54
 
52
55
  expect(cloudStore.status).toBe(Status.CONNECTED);
53
56
  expect(feedbackStore.server_error).toBe(false);
@@ -58,19 +61,18 @@ describe("cloud store", () => {
58
61
  const cloudStore = useCloudStore();
59
62
  const feedbackStore = useFeedbackStore();
60
63
 
61
- registerEndpoint("/api/serverless/run_cloud", {
62
- method: "POST",
63
- handler: postFakeCall,
64
- });
64
+ const error = createError({ statusCode: 500, statusMessage: "500 Internal Server Error" });
65
65
 
66
- postFakeCall.mockImplementation(() => {
67
- throw createError({
68
- status: STATUS_500,
69
- statusMessage: "Internal Server Error",
66
+ $fetch.mockImplementation((route, options) => {
67
+ options.onResponseError?.({
68
+ response: { status: 500, name: "Error", description: "500 Internal Server Error" },
70
69
  });
70
+ return Promise.reject(error);
71
71
  });
72
72
 
73
- await expect(cloudStore.launch("", "", false)).rejects.toThrow("500 Internal Server Error");
73
+ await expect(cloudStore.launch("noreply@example.com")).rejects.toThrow(
74
+ "500 Internal Server Error",
75
+ );
74
76
 
75
77
  expect(cloudStore.status).toBe(Status.NOT_CONNECTED);
76
78
  expect(feedbackStore.server_error).toBe(true);
@@ -124,4 +124,39 @@ describe("useDataStore - collections", () => {
124
124
  },
125
125
  ]);
126
126
  });
127
+
128
+ describe("isItemViewable", () => {
129
+ test("correctly identifies viewable and HorizonStack3D items", () => {
130
+ const dataStore = useDataStore();
131
+
132
+ // Standard viewable item (BRep)
133
+ expect(
134
+ dataStore.isItemViewable({ id: "1", title: "BRep 1", geode_object_type: "BRep" }),
135
+ ).toBe(true);
136
+
137
+ // Group node for viewable type
138
+ expect(dataStore.isItemViewable({ id: "BRep", title: "BRep" })).toBe(true);
139
+
140
+ // HorizonStack3D leaf item
141
+ expect(
142
+ dataStore.isItemViewable({
143
+ id: "2",
144
+ title: "HS 1",
145
+ geode_object_type: "HorizonStack3D",
146
+ }),
147
+ ).toBe(false);
148
+
149
+ // HorizonStack3D group node
150
+ expect(dataStore.isItemViewable({ id: "HorizonStack3D", title: "HorizonStack3D" })).toBe(
151
+ false,
152
+ );
153
+ });
154
+
155
+ test("respects explicit is_viewable overrides", () => {
156
+ const dataStore = useDataStore();
157
+
158
+ expect(dataStore.isItemViewable({ is_viewable: false })).toBe(false);
159
+ expect(dataStore.isItemViewable({ is_viewable: true })).toBe(true);
160
+ });
161
+ });
127
162
  });
@@ -1,15 +1,19 @@
1
1
  // Third party imports
2
2
  import { beforeEach, describe, expect, expectTypeOf, test, vi } from "vitest";
3
- import { registerEndpoint } from "@nuxt/test-utils/runtime";
3
+ import { $fetch } from "ofetch";
4
4
 
5
5
  // Local imports
6
6
  import { Status } from "@ogw_front/utils/status";
7
- import { appMode } from "@ogw_front/utils/local/app_mode";
7
+ import { appMode } from "@ogw_shared/app_mode";
8
8
  import { setupActivePinia } from "@ogw_tests/utils";
9
9
  import { useBackStore } from "@ogw_front/stores/back";
10
10
  import { useInfraStore } from "@ogw_front/stores/infra";
11
11
  import { useViewerStore } from "@ogw_front/stores/viewer";
12
12
 
13
+ vi.mock(import("ofetch"), () => ({
14
+ $fetch: vi.fn(),
15
+ }));
16
+
13
17
  // Mock navigator.locks API
14
18
  const mockLockRequest = vi
15
19
  .fn()
@@ -291,11 +295,14 @@ describe("infra store", () => {
291
295
 
292
296
  infraStore.app_mode = appMode.CLOUD;
293
297
  const url = "test.com";
294
- registerEndpoint("/api/serverless/run_cloud", {
295
- method: "POST",
296
- handler: () => ({ url }),
298
+ $fetch.mockImplementation((route, options) => {
299
+ const data = { url };
300
+ // oxlint-disable-next-line eslint/id-length
301
+ options.onResponse?.({ response: { ok: true, _data: data } });
302
+ return Promise.resolve(data);
297
303
  });
298
- await infraStore.create_backend("", "", false);
304
+
305
+ await infraStore.create_backend("noreply@example.com");
299
306
  expect(infraStore.status).toBe(Status.CREATED);
300
307
  expect(infraStore.domain_name).toBe(url);
301
308