@geode/opengeodeweb-front 9.11.2 → 9.11.3-rc.2

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 (77) hide show
  1. package/.github/workflows/test.yml +23 -0
  2. package/.github/workflows/test_pr.yml +1 -0
  3. package/components/FeedBack/ErrorBanner.vue +1 -1
  4. package/components/FeedBack/Snackers.vue +1 -1
  5. package/components/HybridRenderingView.vue +38 -12
  6. package/components/Launcher.vue +1 -1
  7. package/components/PackagesVersions.vue +1 -1
  8. package/components/Recaptcha.vue +1 -1
  9. package/components/RemoteRenderingView.vue +1 -1
  10. package/components/Viewer/BreadCrumb.vue +1 -1
  11. package/components/Viewer/Options/PolygonAttributeSelector.vue +1 -8
  12. package/components/Viewer/Options/PolyhedronAttributeSelector.vue +1 -7
  13. package/components/Viewer/Options/TextureItem.vue +1 -8
  14. package/components/Viewer/Options/VertexAttributeSelector.vue +1 -5
  15. package/components/Viewer/Tree/ObjectTree.vue +7 -23
  16. package/components/Viewer/TreeObject.vue +1 -1
  17. package/components/Wrapper.vue +1 -1
  18. package/composables/api_fetch.js +2 -2
  19. package/composables/run_function_when_microservices_connected.js +1 -1
  20. package/composables/upload_file.js +2 -2
  21. package/composables/viewer_call.js +38 -38
  22. package/geode-opengeodeweb-back-5.10.0-rc.12.tgz +0 -0
  23. package/geode-opengeodeweb-viewer-1.11.0-rc.5.tgz +0 -0
  24. package/internal_stores/mesh/edges.js +49 -52
  25. package/internal_stores/mesh/index.js +20 -14
  26. package/internal_stores/mesh/points.js +9 -7
  27. package/internal_stores/mesh/polygons.js +9 -7
  28. package/internal_stores/mesh/polyhedra.js +8 -6
  29. package/internal_stores/model/blocks.js +1 -1
  30. package/internal_stores/model/corners.js +1 -1
  31. package/internal_stores/model/edges.js +1 -8
  32. package/internal_stores/model/index.js +1 -1
  33. package/internal_stores/model/lines.js +2 -2
  34. package/internal_stores/model/points.js +2 -2
  35. package/internal_stores/model/surfaces.js +1 -1
  36. package/package.json +13 -6
  37. package/stores/data_base.js +9 -1
  38. package/stores/data_style.js +7 -6
  39. package/stores/feedback.js +1 -1
  40. package/stores/geode.js +5 -5
  41. package/stores/hybrid_viewer.js +1 -1
  42. package/stores/infra.js +10 -10
  43. package/stores/treeview.js +1 -1
  44. package/stores/viewer.js +5 -6
  45. package/tests/integration/data/fake_id/edged_curve.vtp +20 -0
  46. package/tests/integration/microservices/back/requirements.in +1 -0
  47. package/tests/integration/microservices/back/requirements.txt +75 -0
  48. package/tests/integration/microservices/viewer/requirements.in +1 -0
  49. package/tests/integration/microservices/viewer/requirements.txt +87 -0
  50. package/tests/integration/stores/DataStyle/mesh/Edges.nuxt.test.js +138 -0
  51. package/{test → tests/unit}/components/CrsSelector.nuxt.test.js +6 -3
  52. package/{test → tests/unit}/components/ExtensionSelector.nuxt.test.js +6 -3
  53. package/{test → tests/unit}/components/FeedBack/ErrorsBanner.nuxt.test.js +10 -3
  54. package/{test → tests/unit}/components/FeedBack/Snackers.nuxt.test.js +24 -21
  55. package/{test → tests/unit}/components/FileSelector.nuxt.test.js +5 -2
  56. package/{test → tests/unit}/components/FileUploader.nuxt.test.js +6 -3
  57. package/{test → tests/unit}/components/Inspector/InspectionButton.nuxt.test.js +6 -3
  58. package/{test → tests/unit}/components/Launcher.nuxt.test.js +9 -2
  59. package/{test → tests/unit}/components/MissingFilesSelector.nuxt.test.js +6 -3
  60. package/{test → tests/unit}/components/ObjectSelector.nuxt.test.js +6 -3
  61. package/{test → tests/unit}/components/PackagesVersions.nuxt.test.js +5 -3
  62. package/{test → tests/unit}/components/Stepper.nuxt.test.js +1 -0
  63. package/{test → tests/unit}/components/Wrapper.nuxt.test.js +1 -1
  64. package/{test → tests/unit}/composables/api_fetch.nuxt.test.js +3 -2
  65. package/{test/composables/run_function_when_microservices_connected.test.js → tests/unit/composables/run_function_when_microservices_connected.nuxt.test.js} +18 -5
  66. package/{test → tests/unit}/composables/upload_file.nuxt.test.js +7 -8
  67. package/{test → tests/unit}/stores/Feedback.nuxt.test.js +12 -8
  68. package/{test → tests/unit}/stores/Geode.nuxt.test.js +33 -10
  69. package/{test → tests/unit}/stores/Infra.nuxt.test.js +58 -25
  70. package/{test → tests/unit}/stores/Viewer.nuxt.test.js +101 -20
  71. package/{test → tests/unit}/utils/validate_schema.nuxt.test.js +3 -0
  72. package/tests/vitest.config.js +33 -0
  73. package/utils/default_styles.js +246 -0
  74. package/utils/local.js +180 -0
  75. package/vitest.config.js +0 -13
  76. /package/{test → tests/unit}/components/Inspector/ResultPanel.nuxt.test.js +0 -0
  77. /package/{test → tests/unit}/components/Step.nuxt.test.js +0 -0
@@ -7,6 +7,29 @@ on:
7
7
  - next
8
8
 
9
9
  jobs:
10
+ test-integration:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+ - name: Node setup
15
+ uses: actions/setup-node@v4
16
+ with:
17
+ node-version: 22
18
+ - name: Python setup
19
+ uses: actions/setup-python@v5
20
+ with:
21
+ python-version: 3.12
22
+ - name: Install python dependencies
23
+ run: |
24
+ cd ./tests/integration/microservices/viewer
25
+ python3 -m venv venv
26
+ source venv/bin/activate
27
+ pip install --extra-index-url https://wheels.vtk.org -r requirements.txt
28
+ - name: Install and run tests
29
+ run: |
30
+ npm i
31
+
32
+ npm run test:integration
10
33
  test:
11
34
  uses: Geode-solutions/actions/.github/workflows/js-test.yml@master
12
35
  with:
@@ -9,4 +9,5 @@ jobs:
9
9
  uses: Geode-solutions/actions/.github/workflows/js-test-pr.yml@master
10
10
  with:
11
11
  repos: ${{ vars.REPOS }}
12
+ integration: false
12
13
  secrets: inherit
@@ -43,7 +43,7 @@
43
43
  </template>
44
44
 
45
45
  <script setup>
46
- const feedback_store = use_feedback_store()
46
+ const feedback_store = useFeedbackStore()
47
47
 
48
48
  function reload() {
49
49
  window.location.reload()
@@ -61,7 +61,7 @@
61
61
  </template>
62
62
 
63
63
  <script setup>
64
- const feedback_store = use_feedback_store()
64
+ const feedback_store = useFeedbackStore()
65
65
  const show = true
66
66
 
67
67
  function calc_margin(index) {
@@ -1,34 +1,43 @@
1
1
  <template>
2
2
  <ClientOnly>
3
- <div style="position: relative; width: 100%; height: calc(100vh - 75px)">
3
+ <div class="fill-height" style="position: relative">
4
4
  <VeaseViewToolbar />
5
5
  <slot name="ui"></slot>
6
6
  <v-col
7
7
  ref="viewer"
8
- style="
9
- overflow: hidden;
10
- position: relative;
11
- z-index: 0;
12
- height: 100%;
13
- width: 100%;
14
- "
15
- class="pa-0"
8
+ style="overflow: hidden; position: relative; z-index: 0"
9
+ :style="{ height: viewerHeight }"
16
10
  @click="get_x_y"
17
- @keydown.esc="viewer_store.toggle_picking_mode(false)"
11
+ @keydown.esc="viewerStore.toggle_picking_mode(false)"
18
12
  />
19
13
  </div>
20
14
  </ClientOnly>
21
15
  </template>
22
16
 
23
17
  <script setup>
18
+ const props = defineProps({
19
+ height: {
20
+ type: String,
21
+ default: "100%",
22
+ },
23
+ })
24
+
25
+ const emit = defineEmits(["click"])
26
+
24
27
  const container = useTemplateRef("viewer")
25
28
  const hybridViewerStore = useHybridViewerStore()
26
-
29
+ const viewerStore = useViewerStore()
27
30
  const { windowWidth, windowHeight } = useWindowSize()
28
31
  const { width, height } = useElementSize(container)
29
32
 
30
- watch([windowWidth, windowHeight, height, width], () => {
33
+ const viewerHeight = computed(() => props.height)
34
+
35
+ const debouncedResize = debounce(() => {
31
36
  hybridViewerStore.resize(width.value, height.value)
37
+ }, 100)
38
+
39
+ watch([windowWidth, windowHeight, width, height], () => {
40
+ debouncedResize()
32
41
  })
33
42
 
34
43
  onMounted(async () => {
@@ -36,6 +45,23 @@
36
45
  await hybridViewerStore.initHybridViewer()
37
46
  await nextTick()
38
47
  hybridViewerStore.setContainer(container)
48
+ debouncedResize()
39
49
  }
40
50
  })
51
+
52
+ function debounce(func, wait) {
53
+ let timeout
54
+ return function executedFunction(...args) {
55
+ const later = () => {
56
+ clearTimeout(timeout)
57
+ func(...args)
58
+ }
59
+ clearTimeout(timeout)
60
+ timeout = setTimeout(later, wait)
61
+ }
62
+ }
63
+
64
+ function get_x_y(event) {
65
+ emit("click", event)
66
+ }
41
67
  </script>
@@ -21,7 +21,7 @@
21
21
  <script setup>
22
22
  import Status from "@ogw_f/utils/status.js"
23
23
 
24
- const infra_store = use_infra_store()
24
+ const infra_store = useInfraStore()
25
25
  const site_key = useRuntimeConfig().public.RECAPTCHA_SITE_KEY
26
26
 
27
27
  watch(
@@ -25,7 +25,7 @@
25
25
  schema: { type: Object, required: true },
26
26
  })
27
27
 
28
- const geode_store = use_geode_store()
28
+ const geode_store = useGeodeStore()
29
29
  const packages_versions = ref([])
30
30
 
31
31
  async function get_packages_versions() {
@@ -13,7 +13,7 @@
13
13
 
14
14
  <script setup>
15
15
  import { VueRecaptcha } from "vue-recaptcha"
16
- const infra_store = use_infra_store()
16
+ const infra_store = useInfraStore()
17
17
 
18
18
  const props = defineProps({
19
19
  site_key: { type: String, required: true },
@@ -30,7 +30,7 @@
30
30
  viewId: { type: String, default: "-1" },
31
31
  })
32
32
 
33
- const viewer_store = use_viewer_store()
33
+ const viewer_store = useViewerStore()
34
34
  const viewer = useTemplateRef("viewer")
35
35
  const { width, height } = useElementSize(viewer)
36
36
 
@@ -37,7 +37,7 @@
37
37
  </template>
38
38
 
39
39
  <script setup>
40
- const treeviewStore = use_treeview_store()
40
+ const treeviewStore = useTreeviewStore()
41
41
 
42
42
  const selectedTree = computed(() => treeviewStore.selectedTree)
43
43
 
@@ -10,8 +10,6 @@
10
10
  <script setup>
11
11
  import back_schemas from "@geode/opengeodeweb-back/opengeodeweb_back_schemas.json"
12
12
 
13
- const dataBaseStore = useDataBaseStore()
14
-
15
13
  const props = defineProps({
16
14
  id: { type: String, required: true },
17
15
  })
@@ -21,10 +19,6 @@
21
19
  const polygon_attribute_names = ref([])
22
20
  const polygon_attribute = reactive({ name: polygon_attribute_name.value })
23
21
 
24
- const meta_data = computed(() => {
25
- return dataBaseStore.itemMetaDatas(props.id)
26
- })
27
-
28
22
  onMounted(() => {
29
23
  if (model.value != null) {
30
24
  polygon_attribute_name.value = model.value.name
@@ -45,8 +39,7 @@
45
39
  {
46
40
  schema: back_schemas.opengeodeweb_back.polygon_attribute_names,
47
41
  params: {
48
- input_geode_object: meta_data.value.geode_object,
49
- filename: meta_data.value.native_filename,
42
+ id: props.id,
50
43
  },
51
44
  },
52
45
  {
@@ -32,12 +32,7 @@
32
32
  id: { type: String, required: true },
33
33
  })
34
34
 
35
- const dataBaseStore = useDataBaseStore()
36
-
37
35
  const polyhedron_attribute_names = ref([])
38
- const meta_data = computed(() => {
39
- return dataBaseStore.itemMetaDatas(props.id)
40
- })
41
36
 
42
37
  onMounted(() => {
43
38
  getVertexAttributes()
@@ -48,8 +43,7 @@
48
43
  {
49
44
  schema: back_schemas.opengeodeweb_back.polyhedron_attribute_names,
50
45
  params: {
51
- input_geode_object: meta_data.value.geode_object,
52
- filename: meta_data.value.native_filename,
46
+ id: props.id,
53
47
  },
54
48
  },
55
49
  {
@@ -38,8 +38,6 @@
38
38
  <script setup>
39
39
  import back_schemas from "@geode/opengeodeweb-back/opengeodeweb_back_schemas.json"
40
40
 
41
- const dataBaseStore = useDataBaseStore()
42
-
43
41
  const emit = defineEmits(["update_value"])
44
42
 
45
43
  const props = defineProps({
@@ -56,10 +54,6 @@
56
54
 
57
55
  const texture_coordinates = ref([])
58
56
 
59
- const meta_data = computed(() => {
60
- return dataBaseStore.itemMetaDatas(props.id)
61
- })
62
-
63
57
  onMounted(() => {
64
58
  getTextureCoordinates()
65
59
  })
@@ -69,8 +63,7 @@
69
63
  {
70
64
  schema: back_schemas.opengeodeweb_back.texture_coordinates,
71
65
  params: {
72
- input_geode_object: meta_data.value.geode_object,
73
- filename: meta_data.value.native_filename,
66
+ id: props.id,
74
67
  },
75
68
  },
76
69
  {
@@ -33,9 +33,6 @@
33
33
  const dataBaseStore = useDataBaseStore()
34
34
 
35
35
  const vertex_attribute_names = ref([])
36
- const meta_data = computed(() => {
37
- return dataBaseStore.itemMetaDatas(props.id)
38
- })
39
36
 
40
37
  onMounted(() => {
41
38
  getVertexAttributes()
@@ -46,8 +43,7 @@
46
43
  {
47
44
  schema: back_schemas.opengeodeweb_back.vertex_attribute_names,
48
45
  params: {
49
- input_geode_object: meta_data.value.geode_object,
50
- filename: meta_data.value.native_filename,
46
+ id: props.id,
51
47
  },
52
48
  },
53
49
  {
@@ -42,30 +42,30 @@
42
42
  </template>
43
43
 
44
44
  <script setup>
45
- const treeviewStore = use_treeview_store()
45
+ const treeviewStore = useTreeviewStore()
46
46
  const menuStore = useMenuStore()
47
47
  const cardContainer = useTemplateRef("cardContainer")
48
48
  const containerWidth = ref(window.innerWidth)
49
49
  const containerHeight = ref(window.innerHeight)
50
-
51
50
  const menuX = ref(0)
52
51
  const menuY = ref(0)
53
52
  const id = ref(null)
54
53
 
55
- const emit = defineEmits(["show-menu", "position-menu"])
54
+ const handleResize = () => {
55
+ containerWidth.value = window.innerWidth
56
+ containerHeight.value = window.innerHeight
57
+ }
56
58
 
57
59
  function handleTreeMenu({ event, itemId }) {
58
60
  menuX.value = event.clientX
59
61
  menuY.value = event.clientY
60
62
  id.value = itemId
61
-
62
63
  menuStore.openMenu(itemId, event.clientX, event.clientY)
63
64
  }
64
65
 
65
66
  function onResizeStart(event) {
66
67
  const startWidth = treeviewStore.panelWidth
67
68
  const startX = event.clientX
68
-
69
69
  const resize = (e) => {
70
70
  const deltaX = e.clientX - startX
71
71
  const newWidth = Math.max(
@@ -75,13 +75,11 @@
75
75
  treeviewStore.setPanelWidth(newWidth)
76
76
  document.body.style.userSelect = "none"
77
77
  }
78
-
79
78
  const stopResize = () => {
80
79
  document.removeEventListener("mousemove", resize)
81
80
  document.removeEventListener("mouseup", stopResize)
82
81
  document.body.style.userSelect = ""
83
82
  }
84
-
85
83
  document.addEventListener("mousemove", resize)
86
84
  document.addEventListener("mouseup", stopResize)
87
85
  }
@@ -89,15 +87,11 @@
89
87
  onMounted(() => {
90
88
  containerWidth.value = window.innerWidth
91
89
  containerHeight.value = window.innerHeight
92
-
93
- window.addEventListener("resize", () => {
94
- containerWidth.value = window.innerWidth
95
- containerHeight.value = window.innerHeight
96
- })
90
+ window.addEventListener("resize", handleResize)
97
91
  })
98
92
 
99
93
  onUnmounted(() => {
100
- window.removeEventListener("resize")
94
+ window.removeEventListener("resize", handleResize)
101
95
  })
102
96
  </script>
103
97
 
@@ -113,20 +107,17 @@
113
107
  display: flex;
114
108
  box-sizing: border-box;
115
109
  }
116
-
117
110
  .resizable-panel {
118
111
  display: flex;
119
112
  height: 100%;
120
113
  position: relative;
121
114
  box-sizing: border-box;
122
115
  }
123
-
124
116
  .scrollable-wrapper {
125
117
  overflow-y: auto;
126
118
  padding-right: 6px;
127
119
  flex: 1;
128
120
  }
129
-
130
121
  .resizer {
131
122
  position: absolute;
132
123
  top: 0;
@@ -137,32 +128,25 @@
137
128
  background-color: transparent;
138
129
  z-index: 15;
139
130
  }
140
-
141
131
  .resizer:hover {
142
132
  background-color: #999;
143
133
  }
144
-
145
134
  .resizer:active {
146
135
  background-color: #666;
147
136
  }
148
-
149
137
  .transparent-treeview {
150
138
  background-color: transparent;
151
139
  margin: 4px 0;
152
140
  }
153
-
154
141
  .scrollbar-hover {
155
142
  overflow-x: hidden;
156
143
  }
157
-
158
144
  .scrollbar-hover::-webkit-scrollbar {
159
145
  width: 5px;
160
146
  }
161
-
162
147
  .scrollbar-hover::-webkit-scrollbar-thumb {
163
148
  background-color: transparent;
164
149
  }
165
-
166
150
  .scrollbar-hover:hover::-webkit-scrollbar-thumb {
167
151
  background-color: rgba(0, 0, 0, 0.3);
168
152
  border-radius: 10px;
@@ -36,7 +36,7 @@
36
36
  </template>
37
37
 
38
38
  <script setup>
39
- const treeviewStore = use_treeview_store()
39
+ const treeviewStore = useTreeviewStore()
40
40
  const dataStyleStore = useDataStyleStore()
41
41
  const dataBaseStore = useDataBaseStore()
42
42
  const emit = defineEmits(["show-menu"])
@@ -17,7 +17,7 @@
17
17
  </template>
18
18
 
19
19
  <script setup>
20
- const infra_store = use_infra_store()
20
+ const infra_store = useInfraStore()
21
21
 
22
22
  const props = defineProps({
23
23
  versions_schema: { type: Object, required: true },
@@ -4,8 +4,8 @@ export function api_fetch(
4
4
  { schema, params },
5
5
  { request_error_function, response_function, response_error_function } = {},
6
6
  ) {
7
- const feedback_store = use_feedback_store()
8
- const geode_store = use_geode_store()
7
+ const feedback_store = useFeedbackStore()
8
+ const geode_store = useGeodeStore()
9
9
 
10
10
  const body = params || {}
11
11
 
@@ -1,5 +1,5 @@
1
1
  export function run_function_when_microservices_connected(function_to_run) {
2
- const infra_store = use_infra_store()
2
+ const infra_store = useInfraStore()
3
3
  const { microservices_connected } = storeToRefs(infra_store)
4
4
  if (microservices_connected.value) {
5
5
  function_to_run()
@@ -2,8 +2,8 @@ export async function upload_file(
2
2
  { route, file },
3
3
  { request_error_function, response_function, response_error_function } = {},
4
4
  ) {
5
- const feedback_store = use_feedback_store()
6
- const geode_store = use_geode_store()
5
+ const feedback_store = useFeedbackStore()
6
+ const geode_store = useGeodeStore()
7
7
  if (!(file instanceof File)) {
8
8
  throw new Error("file must be a instance of File")
9
9
  }
@@ -2,8 +2,8 @@ export function viewer_call(
2
2
  { schema, params = {} },
3
3
  { request_error_function, response_function, response_error_function } = {},
4
4
  ) {
5
- const feedback_store = use_feedback_store()
6
- const viewer_store = use_viewer_store()
5
+ const feedback_store = useFeedbackStore()
6
+ const viewer_store = useViewerStore()
7
7
 
8
8
  const { valid, error } = validate_schema(schema, params)
9
9
 
@@ -19,45 +19,45 @@ export function viewer_call(
19
19
 
20
20
  const client = viewer_store.client
21
21
 
22
- let promise = new Promise((resolve, reject) => {
23
- if (client) {
24
- viewer_store.start_request()
25
- client
26
- .getConnection()
27
- .getSession()
28
- .call(schema.$id, [params])
29
- .then(
30
- (value) => {
31
- if (response_function) {
32
- response_function(value)
33
- }
34
- resolve()
35
- },
36
- (reason) => {
37
- if (request_error_function) {
38
- request_error_function(reason)
39
- }
40
- reject()
41
- },
42
- )
43
- .catch((error) => {
44
- feedback_store.add_error(
45
- error.code,
46
- schema.route,
47
- error.message,
48
- error.message,
49
- )
50
- if (response_error_function) {
51
- response_error_function(error)
22
+ return new Promise((resolve, reject) => {
23
+ if (!client) {
24
+ reject()
25
+ }
26
+ viewer_store.start_request()
27
+ client
28
+ .getConnection()
29
+ .getSession()
30
+ .call(schema.$id, [params])
31
+ .then(
32
+ (value) => {
33
+ if (response_function) {
34
+ response_function(value)
35
+ }
36
+ resolve()
37
+ },
38
+ (reason) => {
39
+ if (request_error_function) {
40
+ request_error_function(reason)
52
41
  }
53
42
  reject()
54
- })
55
- .finally(() => {
56
- viewer_store.stop_request()
57
- })
58
- }
43
+ },
44
+ )
45
+ .catch((error) => {
46
+ feedback_store.add_error(
47
+ error.code,
48
+ schema.route,
49
+ error.message,
50
+ error.message,
51
+ )
52
+ if (response_error_function) {
53
+ response_error_function(error)
54
+ }
55
+ reject()
56
+ })
57
+ .finally(() => {
58
+ viewer_store.stop_request()
59
+ })
59
60
  })
60
- return promise
61
61
  }
62
62
 
63
63
  export default viewer_call