@eodash/eodash 5.3.3 → 5.5.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 (115) hide show
  1. package/core/client/asWebComponent.js +1 -1
  2. package/core/client/composables/DefineEodash.js +3 -1
  3. package/core/client/composables/DefineWidgets.js +12 -2
  4. package/core/client/eodashSTAC/EodashCollection.js +20 -37
  5. package/core/client/eodashSTAC/createLayers.js +306 -136
  6. package/core/client/eodashSTAC/helpers.js +60 -40
  7. package/core/client/eodashSTAC/parquet.js +2 -0
  8. package/core/client/eodashSTAC/triggers.js +5 -5
  9. package/core/client/store/actions.js +17 -17
  10. package/core/client/store/states.js +26 -4
  11. package/core/client/types.ts +12 -1
  12. package/core/client/utils/index.js +18 -1
  13. package/dist/client/{DashboardLayout-Cp8Rv3Ef.js → DashboardLayout-CkSgvaFF.js} +2 -2
  14. package/dist/client/{DynamicWebComponent-CBsxC82P.js → DynamicWebComponent-Ncsg6fb9.js} +1 -1
  15. package/dist/client/EodashChart-5v7adDpG.js +144 -0
  16. package/dist/client/{EodashDatePicker-Dewym-cx.js → EodashDatePicker-RoQJe6ss.js} +4 -4
  17. package/dist/client/{EodashItemFilter-CAsZpOoQ.js → EodashItemFilter-CCoVC5BE.js} +2 -2
  18. package/dist/client/{EodashLayerControl-fn-rt8Ac.js → EodashLayerControl-weVj7aQA.js} +2 -2
  19. package/dist/client/{EodashLayoutSwitcher-B9XqQXCS.js → EodashLayoutSwitcher-CL-Z9d5_.js} +3 -3
  20. package/dist/client/EodashMapBtns-CXU8IuPO.js +433 -0
  21. package/dist/client/{EodashStacInfo-lxBKoav9.js → EodashStacInfo-BbMnjf-n.js} +11 -15
  22. package/dist/client/{EodashTimeSlider-DI97QkNT.js → EodashTimeSlider-BZXnqfax.js} +2 -2
  23. package/dist/client/{EodashTools-D5ShUT1g.js → EodashTools-DUJlkkgx.js} +4 -4
  24. package/dist/client/{ExportState-ruNyRS2E.js → ExportState-CT3FQOHW.js} +46 -21
  25. package/dist/client/{Footer-IQNyfd78.js → Footer-D_iqP-1K.js} +1 -1
  26. package/dist/client/{Header-BBdi_-Lp.js → Header-Dzhnvsy-.js} +127 -17
  27. package/dist/client/MobileLayout-6Rg_PSO8.js +118 -0
  28. package/dist/client/{PopUp-DRgOmD7-.js → PopUp-DPPv_GSA.js} +8 -59
  29. package/dist/client/{ProcessList-DxyCFQdz.js → ProcessList-BIN_Mb27.js} +9 -13
  30. package/dist/client/{VImg-hwmwzSwG.js → VImg-DhbuvNrA.js} +2 -2
  31. package/dist/client/{VMain-vk4-rkw-.js → VMain-CVabY_NY.js} +1 -1
  32. package/dist/client/{VTooltip-BYUZeia1.js → VTooltip-Cc6au3Sn.js} +3 -4
  33. package/dist/client/{WidgetsContainer-DXD_8rqh.js → WidgetsContainer-ChqTJS4h.js} +1 -1
  34. package/dist/client/asWebComponent-DaIxULaA.js +9207 -0
  35. package/dist/client/{async-D1MvO_Z_.js → async-D6Lvv-fT.js} +15 -5
  36. package/dist/client/eo-dash.js +1 -1
  37. package/dist/client/{forwardRefs-DM-E2MfG.js → forwardRefs--IccUBdR.js} +196 -37
  38. package/dist/client/{handling-CbgeKrqT.js → handling-DSA67d6E.js} +160 -37
  39. package/dist/client/{helpers-CtUlAW0N.js → helpers-BBSdbOmv.js} +239 -126
  40. package/dist/client/{index-DBo0F4Fv.js → index-6LlXNkke.js} +5 -3
  41. package/dist/client/{index-BJvLt3Xf.js → index-BS-8Y5FE.js} +34 -77
  42. package/dist/client/{index-BkW06-Lg.js → index-CQihL_c6.js} +55 -15
  43. package/dist/client/{index-BxDh5v-H.js → index-qsZhYR_6.js} +15 -16
  44. package/dist/client/templates.js +52 -2
  45. package/dist/client/{transition-BdzATvPB.js → transition-DFr4cXu8.js} +1 -1
  46. package/dist/node/cli.js +1 -1
  47. package/dist/types/core/client/App.vue.d.ts +16 -6
  48. package/dist/types/core/client/asWebComponent.d.ts +2 -2
  49. package/dist/types/core/client/components/DashboardLayout.vue.d.ts +2 -1
  50. package/dist/types/core/client/components/DynamicWebComponent.vue.d.ts +36 -16
  51. package/dist/types/core/client/components/EodashOverlay.vue.d.ts +2 -1
  52. package/dist/types/core/client/components/ErrorAlert.vue.d.ts +9 -1
  53. package/dist/types/core/client/components/Footer.vue.d.ts +2 -1
  54. package/dist/types/core/client/components/Header.vue.d.ts +2 -1
  55. package/dist/types/core/client/components/IframeWrapper.vue.d.ts +12 -6
  56. package/dist/types/core/client/components/Loading.vue.d.ts +2 -1
  57. package/dist/types/core/client/components/MobileLayout.vue.d.ts +2 -1
  58. package/dist/types/core/client/composables/DefineEodash.d.ts +1 -1
  59. package/dist/types/core/client/eodashSTAC/EodashCollection.d.ts +27 -11
  60. package/dist/types/core/client/eodashSTAC/createLayers.d.ts +30 -23
  61. package/dist/types/core/client/eodashSTAC/helpers.d.ts +11 -4
  62. package/dist/types/core/client/store/actions.d.ts +1 -2
  63. package/dist/types/core/client/store/states.d.ts +22 -4
  64. package/dist/types/core/client/types.d.ts +7 -2
  65. package/dist/types/core/client/utils/index.d.ts +1 -0
  66. package/dist/types/core/client/views/Dashboard.vue.d.ts +20 -8
  67. package/dist/types/templates/compare.d.ts +20 -0
  68. package/dist/types/templates/expert.d.ts +30 -1
  69. package/dist/types/widgets/EodashChart.vue.d.ts +28 -0
  70. package/dist/types/widgets/EodashDatePicker.vue.d.ts +38 -9
  71. package/dist/types/widgets/EodashItemCatalog/index.vue.d.ts +88 -13
  72. package/dist/types/widgets/EodashItemCatalog/methods/map.d.ts +1 -1
  73. package/dist/types/widgets/EodashItemFilter.vue.d.ts +169 -26
  74. package/dist/types/widgets/EodashLayerControl.vue.d.ts +38 -10
  75. package/dist/types/widgets/EodashLayoutSwitcher.vue.d.ts +22 -7
  76. package/dist/types/widgets/EodashMap/EodashMapBtns.vue.d.ts +94 -19
  77. package/dist/types/widgets/EodashMap/index.vue.d.ts +647 -92
  78. package/dist/types/widgets/EodashMap/methods/btns.d.ts +14 -0
  79. package/dist/types/widgets/EodashProcess/ProcessList.vue.d.ts +24 -7
  80. package/dist/types/widgets/EodashProcess/index.vue.d.ts +26 -7
  81. package/dist/types/widgets/EodashProcess/methods/composables.d.ts +1 -2
  82. package/dist/types/widgets/EodashProcess/methods/handling.d.ts +18 -11
  83. package/dist/types/widgets/EodashProcess/methods/outputs.d.ts +2 -2
  84. package/dist/types/widgets/EodashProcess/methods/utils.d.ts +1 -0
  85. package/dist/types/widgets/EodashStacInfo.vue.d.ts +67 -18
  86. package/dist/types/widgets/EodashTimeSlider.vue.d.ts +14 -6
  87. package/dist/types/widgets/EodashTools.vue.d.ts +437 -47
  88. package/dist/types/widgets/ExportState.vue.d.ts +26 -8
  89. package/dist/types/widgets/PopUp.vue.d.ts +61 -11
  90. package/dist/types/widgets/WidgetsContainer.vue.d.ts +22 -6
  91. package/package.json +33 -34
  92. package/templates/baseConfig.js +2 -1
  93. package/templates/compare.js +28 -1
  94. package/templates/expert.js +23 -1
  95. package/widgets/EodashChart.vue +139 -0
  96. package/widgets/EodashItemCatalog/index.vue +2 -2
  97. package/widgets/EodashItemCatalog/methods/map.js +9 -10
  98. package/widgets/EodashMap/EodashMapBtns.vue +73 -93
  99. package/widgets/EodashMap/index.vue +14 -2
  100. package/widgets/EodashMap/methods/btns.js +155 -0
  101. package/widgets/EodashMap/methods/create-layers-config.js +26 -3
  102. package/widgets/EodashMap/methods/index.js +2 -1
  103. package/widgets/EodashProcess/ProcessList.vue +2 -3
  104. package/widgets/EodashProcess/index.vue +19 -70
  105. package/widgets/EodashProcess/methods/async.js +1 -1
  106. package/widgets/EodashProcess/methods/composables.js +13 -6
  107. package/widgets/EodashProcess/methods/custom-endpoints/chart/veda-endpoint.js +20 -7
  108. package/widgets/EodashProcess/methods/handling.js +100 -22
  109. package/widgets/EodashProcess/methods/outputs.js +44 -4
  110. package/widgets/EodashProcess/methods/utils.js +11 -1
  111. package/widgets/EodashStacInfo.vue +10 -23
  112. package/widgets/ExportState.vue +9 -15
  113. package/dist/client/EodashMapBtns-nFY6MIAX.js +0 -301
  114. package/dist/client/MobileLayout-BfBeF-JF.js +0 -118
  115. package/dist/client/asWebComponent-DdguWGDI.js +0 -8967
@@ -1,24 +1,19 @@
1
1
  <template>
2
- <div ref="container" class="pb-4">
2
+ <div ref="container" class="py-1">
3
3
  <ProcessList :map-element="mapElement" :enable-compare="enableCompare" />
4
-
5
4
  <eox-jsonform
6
5
  v-if="jsonformSchema"
7
6
  :key="jsonformKey"
8
7
  ref="jsonformEl"
9
8
  .schema="jsonformSchema"
10
9
  ></eox-jsonform>
11
- <eox-chart
12
- ref="chartElRef"
13
- class="chart"
14
- v-if="isProcessed && chartSpec"
15
- .spec="toRaw(chartSpec)"
16
- .dataValues="toRaw(chartData)"
17
- @click:item="onChartClick"
18
- :style="chartStyles"
19
- .opt="vegaEmbedOptions"
20
- />
21
- <div class="mt-4 text-right">
10
+ <EodashChart
11
+ v-if="!areChartsSeparateLayout"
12
+ :vega-embed-options="vegaEmbedOptions"
13
+ :enable-compare="enableCompare"
14
+ >
15
+ </EodashChart>
16
+ <div class="mt-2 text-right">
22
17
  <v-btn
23
18
  v-if="showExecBtn"
24
19
  :loading="loading"
@@ -46,9 +41,10 @@ import "@eox/drawtools";
46
41
  import "@eox/jsonform";
47
42
  import { useSTAcStore } from "@/store/stac";
48
43
  import { storeToRefs } from "pinia";
49
- import { computed, ref, toRaw, useTemplateRef, watch } from "vue";
44
+ import { computed, ref, useTemplateRef } from "vue";
50
45
  import ProcessList from "./ProcessList.vue";
51
- import { handleProcesses, onChartClick } from "./methods/handling";
46
+ import EodashChart from "../EodashChart.vue";
47
+ import { handleProcesses } from "./methods/handling";
52
48
  import { useInitProcess, useAutoExec } from "./methods/composables";
53
49
  import { updateJobsStatus } from "./methods/async";
54
50
  import {
@@ -56,10 +52,11 @@ import {
56
52
  indicator,
57
53
  mapCompareEl,
58
54
  mapEl,
59
- chartEl,
60
- compareChartEl,
55
+ chartSpec,
56
+ compareChartSpec,
57
+ areChartsSeparateLayout,
61
58
  } from "@/store/states";
62
- import { download } from "./methods/utils";
59
+ import { download, getDrawToolsProperty } from "./methods/utils";
63
60
  import { compareJobs, jobs } from "./states";
64
61
  import { mdiCogPlayOutline, mdiDownloadCircleOutline } from "@mdi/js";
65
62
 
@@ -75,11 +72,7 @@ const { enableCompare, vegaEmbedOptions } = defineProps({
75
72
  },
76
73
  },
77
74
  });
78
- /** @type {import("vue").Ref<import("vega").Spec|null>} */
79
- const chartSpec = ref(null);
80
75
 
81
- /** @type {import("vue").Ref<Record<string,any>|null>} */
82
- const chartData = ref(null);
83
76
  const isProcessed = ref(false);
84
77
 
85
78
  /** @type {import("vue").Ref<Record<string,any>|null>} */
@@ -89,16 +82,12 @@ const jsonformEl =
89
82
  /** @type {Readonly<import("vue").ShallowRef<import("@eox/jsonform").EOxJSONForm | null>>} */ (
90
83
  useTemplateRef("jsonformEl")
91
84
  );
92
- const chartElRef =
93
- /** @type {Readonly<import("vue").ShallowRef<import("@eox/chart").EOxChart | null>>} */ (
94
- useTemplateRef("chartElRef")
95
- );
85
+
96
86
  const isAsync = computed(
97
87
  () =>
98
88
  selectedStac.value?.links.filter((l) => l.endpoint === "eoxhub_workspaces")
99
89
  .length,
100
90
  );
101
- const containerEl = useTemplateRef("container");
102
91
 
103
92
  const loading = ref(false);
104
93
 
@@ -109,10 +98,7 @@ const isPolling = ref(false);
109
98
  const processResults = ref([]);
110
99
 
111
100
  const showExecBtn = computed(
112
- () =>
113
- !autoExec.value &&
114
- (!!jsonformSchema.value || !!chartSpec.value) &&
115
- !!jsonformEl.value,
101
+ () => !autoExec.value && !!jsonformSchema.value && !!jsonformEl.value,
116
102
  );
117
103
  const { selectedStac, selectedCompareStac } = storeToRefs(useSTAcStore());
118
104
  const currentSelectedStac = enableCompare ? selectedCompareStac : selectedStac;
@@ -129,7 +115,6 @@ useInitProcess({
129
115
  mapElement: mapElement.value,
130
116
  jsonformEl,
131
117
  jsonformSchema,
132
- chartSpec,
133
118
  isProcessed,
134
119
  processResults,
135
120
  loading,
@@ -155,14 +140,6 @@ const downloadResults = () => {
155
140
  };
156
141
 
157
142
  const startProcess = async () => {
158
- /** @param {*} jsonformSchema */
159
- const getDrawToolsProperty = (jsonformSchema) => {
160
- for (const property in jsonformSchema.properties) {
161
- if (jsonformSchema.properties[property]?.options?.drawtools) {
162
- return property;
163
- }
164
- }
165
- };
166
143
  const drawToolsProperty = getDrawToolsProperty(jsonformSchema.value);
167
144
  const propertyIsEmpty =
168
145
  drawToolsProperty &&
@@ -173,7 +150,8 @@ const startProcess = async () => {
173
150
 
174
151
  if (propertyIsEmpty) {
175
152
  isProcessed.value = false;
176
- chartSpec.value = null;
153
+ const usedChartSpec = enableCompare ? compareChartSpec : chartSpec;
154
+ usedChartSpec.value = null;
177
155
  return;
178
156
  }
179
157
  const errors = jsonformEl.value?.editor.validate();
@@ -189,8 +167,6 @@ const startProcess = async () => {
189
167
  selectedStac: currentSelectedStac,
190
168
  jsonformEl,
191
169
  jsonformSchema,
192
- chartSpec,
193
- chartData,
194
170
  loading,
195
171
  isPolling,
196
172
  processResults,
@@ -201,35 +177,8 @@ const startProcess = async () => {
201
177
  if (isAsync.value) updateJobsStatus(currentJobs, currentIndicator.value);
202
178
  };
203
179
  useAutoExec(autoExec, jsonformEl, jsonformSchema, startProcess);
204
-
205
- const chartStyles = computed(() => {
206
- /** @type {Record<string,string>} */
207
- const styles = {};
208
- if (!chartSpec.value?.["height"]) {
209
- styles["height"] =
210
- Math.max(
211
- (containerEl.value?.offsetHeight ?? 0) -
212
- (jsonformEl.value?.offsetHeight ?? 0),
213
- 200,
214
- ) + "px";
215
- }
216
- return styles;
217
- });
218
-
219
- // Assign chart element to global state based on compare mode
220
- watch(chartElRef, (newVal) => {
221
- if (enableCompare) {
222
- compareChartEl.value = newVal;
223
- } else {
224
- chartEl.value = newVal;
225
- }
226
- });
227
180
  </script>
228
181
  <style>
229
- eox-chart {
230
- --background-color: transparent;
231
- padding-top: 1em;
232
- }
233
182
  eox-jsonform {
234
183
  padding: 0.7em;
235
184
  min-height: 0px;
@@ -115,7 +115,7 @@ export async function updateJobsStatus(jobs, indicator) {
115
115
  new Date(a.job_start_datetime).getTime()
116
116
  );
117
117
  });
118
- jobs.value = jobResults;
118
+ jobs.value.splice(0, jobs.value.length, ...jobResults);
119
119
  }
120
120
 
121
121
  /**
@@ -1,4 +1,4 @@
1
- import { initProcess } from "./handling";
1
+ import { initProcess, updateJsonformIdentifier } from "./handling";
2
2
  import { useEventBus } from "@vueuse/core";
3
3
  import { nextTick, onMounted, watch } from "vue";
4
4
  import { eoxLayersKey } from "@/utils/keys";
@@ -13,7 +13,6 @@ import { useOnLayersUpdate } from "@/composables";
13
13
  * @param {import("vue").Ref<import("stac-ts").StacCollection | null>} params.selectedStac
14
14
  * @param {import("vue").Ref<import("@eox/jsonform").EOxJSONForm | null>} params.jsonformEl
15
15
  * @param {import("vue").Ref<Record<string,any> | null>} params.jsonformSchema
16
- * @param {import("vue").Ref<import("@eox/chart").EOxChart["spec"] | null>} params.chartSpec
17
16
  * @param {import("vue").Ref<any[]>} params.processResults
18
17
  * @param {import("vue").Ref<boolean>} params.isProcessed
19
18
  * @param {import("vue").Ref<boolean>} params.loading
@@ -24,7 +23,6 @@ export const useInitProcess = ({
24
23
  selectedStac,
25
24
  jsonformEl,
26
25
  jsonformSchema,
27
- chartSpec,
28
26
  isProcessed,
29
27
  processResults,
30
28
  loading,
@@ -41,7 +39,6 @@ export const useInitProcess = ({
41
39
  selectedStac,
42
40
  jsonformEl,
43
41
  jsonformSchema,
44
- chartSpec,
45
42
  isProcessed,
46
43
  processResults,
47
44
  loading,
@@ -54,7 +51,6 @@ export const useInitProcess = ({
54
51
  selectedStac,
55
52
  jsonformEl,
56
53
  jsonformSchema,
57
- chartSpec,
58
54
  isProcessed,
59
55
  loading,
60
56
  processResults,
@@ -67,6 +63,18 @@ export const useInitProcess = ({
67
63
  const evtKey =
68
64
  mapElement?.id === "compare" ? "compareLayers:updated" : "layers:updated";
69
65
  useOnLayersUpdate(async (evt, _payload) => {
66
+ if (
67
+ evt == "layertime:updated" ||
68
+ evt == "compareLayertime:updated" ||
69
+ evt == "time:updated" ||
70
+ evt == "compareTime:updated"
71
+ ) {
72
+ await updateJsonformIdentifier({
73
+ jsonformSchema,
74
+ // @ts-expect-error TODO payload coming from time update events is not an object with layers property
75
+ newLayers: _payload,
76
+ });
77
+ }
70
78
  if (evt !== evtKey) {
71
79
  return;
72
80
  }
@@ -75,7 +83,6 @@ export const useInitProcess = ({
75
83
  selectedStac,
76
84
  jsonformEl,
77
85
  jsonformSchema,
78
- chartSpec,
79
86
  isProcessed,
80
87
  processResults,
81
88
  loading,
@@ -19,7 +19,9 @@ export async function handleVedaEndpoint({
19
19
  enableCompare = false,
20
20
  }) {
21
21
  const vedaLink = links.find(
22
- (link) => link.rel === "service" && link.endpoint === "veda",
22
+ (link) =>
23
+ link.rel === "service" &&
24
+ (link.endpoint === "veda" || link.endpoint === "veda_stac"),
23
25
  );
24
26
  if (!vedaLink) {
25
27
  return;
@@ -32,12 +34,17 @@ export async function handleVedaEndpoint({
32
34
  const configs = await fetchVedaCOGsConfig(
33
35
  selectedStac,
34
36
  enableCompare ? currentCompareUrl.value : currentUrl.value,
37
+ vedaLink,
35
38
  );
36
39
  // TODO: convert jsonform bbox type to geojson in the schema to avoid the conversion here
37
40
  return await Promise.all(
38
41
  configs.map(({ endpoint, datetime }) => {
42
+ const url = new URL(vedaEndpoint);
43
+ const key = vedaLink.endpoint === "veda_stac" ? "ids" : "url";
44
+ url.searchParams.set(key, endpoint);
45
+
39
46
  return axios
40
- .post(vedaEndpoint + `?url=${endpoint}`, {
47
+ .post(url.toString(), {
41
48
  ...{
42
49
  type: "Feature",
43
50
  properties: {},
@@ -63,8 +70,9 @@ export async function handleVedaEndpoint({
63
70
  * Fetches the COGs endpoints from the STAC collections
64
71
  * @param {import("stac-ts").StacCollection} selectedStac
65
72
  * @param {string} absoluteUrl
73
+ * @param {import("stac-ts").StacLink} vedaLink
66
74
  */
67
- async function fetchVedaCOGsConfig(selectedStac, absoluteUrl) {
75
+ async function fetchVedaCOGsConfig(selectedStac, absoluteUrl, vedaLink) {
68
76
  // retrieve the collections from the indicator
69
77
  const collectionLinks = selectedStac.links.filter(
70
78
  (link) => link.rel == "child",
@@ -110,10 +118,15 @@ async function fetchVedaCOGsConfig(selectedStac, absoluteUrl) {
110
118
  );
111
119
  const itemLinks = collection.links.filter((link) => link.rel == "item");
112
120
  configs.push(
113
- ...itemLinks.map((link) => ({
114
- endpoint: /** @type {string} */ (link["cog_href"]),
115
- datetime: /** @type string **/ (link[datetimeProperty]),
116
- })),
121
+ ...itemLinks.map((link) => {
122
+ const endpoint = /** @type {string} */ (
123
+ vedaLink.endpoint === "veda_stac" ? link.id : link["cog_href"]
124
+ );
125
+ return {
126
+ endpoint,
127
+ datetime: /** @type string **/ (link[datetimeProperty]),
128
+ };
129
+ }),
117
130
  );
118
131
  }
119
132
 
@@ -3,6 +3,7 @@ import {
3
3
  applyProcessLayersToMap,
4
4
  extractGeometries,
5
5
  getBboxProperty,
6
+ getDrawToolsProperty,
6
7
  updateJsonformSchemaTarget,
7
8
  } from "./utils";
8
9
  import {
@@ -11,6 +12,10 @@ import {
11
12
  datetime,
12
13
  indicator,
13
14
  poi,
15
+ chartData,
16
+ chartSpec,
17
+ compareChartData,
18
+ compareChartSpec,
14
19
  } from "@/store/states";
15
20
  import axios from "@/plugins/axios";
16
21
  import { processCharts, processLayers, processSTAC } from "./outputs";
@@ -18,6 +23,7 @@ import { handleLayersCustomEndpoints } from "./custom-endpoints/layers";
18
23
  import { handleChartCustomEndpoints } from "./custom-endpoints/chart";
19
24
  import { useSTAcStore } from "@/store/stac";
20
25
  import { useGetSubCodeId } from "@/composables";
26
+ import { getLayers } from "@/store/actions";
21
27
 
22
28
  /**
23
29
  * Fetch and set the jsonform schema to initialize the process
@@ -28,7 +34,6 @@ import { useGetSubCodeId } from "@/composables";
28
34
  * @param {import("vue").Ref<import("stac-ts").StacCollection | null>} params.selectedStac
29
35
  * @param {import("vue").Ref<import("@eox/jsonform").EOxJSONForm | null>} params.jsonformEl
30
36
  * @param {import("vue").Ref<Record<string,any> | null>} params.jsonformSchema
31
- * @param {import("vue").Ref<import("@eox/chart").EOxChart["spec"] | null>} params.chartSpec
32
37
  * @param {import("vue").Ref<any[]>} params.processResults
33
38
  * @param {import("vue").Ref<boolean>} params.isProcessed
34
39
  * @param {import("vue").Ref<boolean>} params.loading
@@ -39,7 +44,6 @@ export async function initProcess({
39
44
  selectedStac,
40
45
  jsonformEl,
41
46
  jsonformSchema,
42
- chartSpec,
43
47
  isProcessed,
44
48
  processResults,
45
49
  loading,
@@ -62,14 +66,21 @@ export async function initProcess({
62
66
  resetProcess({
63
67
  loading,
64
68
  isProcessed,
65
- chartSpec,
66
69
  jsonformSchema,
67
70
  isPolling,
68
71
  processResults,
72
+ enableCompare,
69
73
  });
70
74
 
71
75
  await jsonformEl.value?.editor.destroy();
72
76
  if (updatedJsonform) {
77
+ // make sure correct target layer id is used in jsonform
78
+ if (updatedJsonform.properties?.feature?.options?.drawtools?.layerId) {
79
+ await updateJsonformIdentifier({
80
+ jsonformSchema,
81
+ newLayers: await getLayers(),
82
+ });
83
+ }
73
84
  if (enableCompare) {
74
85
  updatedJsonform = updateJsonformSchemaTarget(updatedJsonform);
75
86
  }
@@ -77,6 +88,74 @@ export async function initProcess({
77
88
  }
78
89
  }
79
90
 
91
+ /**
92
+ * Update the jsonform schema to have the correct layer id from the map
93
+ *
94
+ * @export
95
+ * @async
96
+ * @param {Object} params
97
+ * @param {import("vue").Ref<Record<string,any> | null>} params.jsonformSchema params.jsonformSchema
98
+ * @param {Record<string, any>[] | undefined} params.newLayers params.newLayers
99
+ */
100
+ export async function updateJsonformIdentifier({ jsonformSchema, newLayers }) {
101
+ const form = jsonformSchema.value;
102
+ if (!form) {
103
+ return;
104
+ }
105
+ const drawToolsProperty = getDrawToolsProperty(form);
106
+ if (
107
+ drawToolsProperty &&
108
+ newLayers &&
109
+ form?.properties[drawToolsProperty]?.options?.drawtools?.layerId
110
+ ) {
111
+ // get partial or full id and try to match with correct eoxmap layer
112
+ // check if newLayers is an array or an object with layers property
113
+ let layers = newLayers;
114
+ // @ts-expect-error TODO payload coming from time update sometimes is not an object with layers property
115
+ if (newLayers.layers && Array.isArray(newLayers.layers)) {
116
+ // @ts-expect-error TODO payload coming from time update sometimes is not an object with layers property
117
+ layers = newLayers.layers;
118
+ }
119
+
120
+ const layerId =
121
+ form.properties[drawToolsProperty].options.drawtools.layerId.split(
122
+ ";:;",
123
+ )[0];
124
+ let matchedLayerId = null;
125
+ // layers are not flat can be grouped, we need to recursively search
126
+ const traverseLayers = (
127
+ /** @type {Record<string, any>[] | undefined} */ layersArray,
128
+ ) => {
129
+ if (!layersArray) {
130
+ return;
131
+ }
132
+ for (const layer of layersArray) {
133
+ if (layer.layers) {
134
+ // @ts-expect-error TODO payload coming from time update events is not an object with layers property
135
+ traverseLayers(layer);
136
+ } else {
137
+ if (layer.properties?.id?.startsWith(layerId)) {
138
+ matchedLayerId = layer.properties.id;
139
+ break;
140
+ }
141
+ }
142
+ }
143
+ };
144
+ traverseLayers(layers);
145
+ if (matchedLayerId) {
146
+ form.properties.feature.options.drawtools.layerId = matchedLayerId;
147
+ // trigger jsonform update in next tick
148
+ jsonformSchema.value = null;
149
+ await new Promise((resolve) => setTimeout(resolve, 0));
150
+ jsonformSchema.value = form;
151
+ } else {
152
+ throw new Error(
153
+ `Could not find matching layer for processing form with id: ${layerId}`,
154
+ );
155
+ }
156
+ }
157
+ }
158
+
80
159
  /**
81
160
  *
82
161
  * @param {object} params
@@ -84,8 +163,6 @@ export async function initProcess({
84
163
  * @param {import("vue").Ref<import("stac-ts").StacCollection | null>} params.selectedStac
85
164
  * @param {import("vue").Ref<import("@eox/jsonform").EOxJSONForm | null>} params.jsonformEl
86
165
  * @param {import("vue").Ref<Record<string,any>|null>} params.jsonformSchema
87
- * @param {import("vue").Ref<import("@eox/chart").EOxChart["spec"] | null>} params.chartSpec
88
- * @param {import("vue").Ref<Record<string, any> | null>} params.chartData
89
166
  * @param {import("vue").Ref<boolean>} params.isPolling
90
167
  * @param {import("vue").Ref<any[]>} params.processResults
91
168
  * @param {import("@eox/map").EOxMap | null} params.mapElement
@@ -96,8 +173,6 @@ export async function handleProcesses({
96
173
  selectedStac,
97
174
  jsonformEl,
98
175
  jsonformSchema,
99
- chartSpec,
100
- chartData,
101
176
  isPolling,
102
177
  processResults,
103
178
  mapElement,
@@ -106,6 +181,7 @@ export async function handleProcesses({
106
181
  if (!jsonformEl.value || !jsonformSchema.value || !selectedStac.value) {
107
182
  return;
108
183
  }
184
+ const enableCompare = mapElement?.id === "compare";
109
185
 
110
186
  log.debug("Processing...");
111
187
  loading.value = true;
@@ -127,12 +203,14 @@ export async function handleProcesses({
127
203
  selectedStac.value?.["eodash:vegadefinition"]
128
204
  );
129
205
  const layerId = selectedStac.value?.id ?? "";
130
-
131
- [chartSpec.value, chartData.value] = await processCharts({
206
+ const usedChartSpec = enableCompare ? compareChartSpec : chartSpec;
207
+ const usedChartData = enableCompare ? compareChartData : chartData;
208
+ let tempChartSpec = null;
209
+ [tempChartSpec, usedChartData.value] = await processCharts({
132
210
  links: serviceLinks,
133
211
  jsonformValue: { ...(jsonformValue ?? {}) },
134
212
  jsonformSchema: jsonformSchema.value,
135
- enableCompare: mapElement?.id === "compare",
213
+ enableCompare,
136
214
  selectedStac: selectedStac.value,
137
215
  specUrl,
138
216
  isPolling,
@@ -140,19 +218,19 @@ export async function handleProcesses({
140
218
  customEndpointsHandler: handleChartCustomEndpoints,
141
219
  });
142
220
 
143
- if (Object.keys(chartData.value ?? {}).length) {
144
- processResults.value.push(chartData.value);
221
+ if (Object.keys(usedChartData.value ?? {}).length) {
222
+ processResults.value.push(usedChartData.value);
145
223
  }
146
224
 
147
225
  //@ts-expect-error we assume that the spec data is of type InlineData
148
- if (chartSpec.value?.data?.values?.length) {
226
+ if (tempChartSpec.data?.values?.length) {
149
227
  //@ts-expect-error we assume that the spec data is of type InlineData
150
- processResults.value.push(chartSpec.value?.data.values);
228
+ processResults.value.push(tempChartSpec?.data.values);
151
229
  }
152
-
153
- if (chartSpec.value && !("background" in chartSpec.value)) {
154
- chartSpec.value["background"] = "transparent";
230
+ if (tempChartSpec && !("background" in tempChartSpec)) {
231
+ tempChartSpec["background"] = "transparent";
155
232
  }
233
+ usedChartSpec.value = tempChartSpec;
156
234
 
157
235
  await processSTAC(
158
236
  serviceLinks,
@@ -203,23 +281,24 @@ export async function handleProcesses({
203
281
  * @param {Object} params
204
282
  * @param {import("vue").Ref<boolean>} params.loading
205
283
  * @param {import("vue").Ref<boolean>} params.isProcessed
206
- * @param {import("vue").Ref<import("@eox/chart").EOxChart["spec"] | null>} params.chartSpec
207
284
  * @param {import("vue").Ref<boolean>} params.isPolling
208
285
  * @param {import("vue").Ref<any[]>} params.processResults
209
286
  * @param {import("vue").Ref<Record<string,any>|null>} params.jsonformSchema
287
+ * @param {boolean} params.enableCompare
210
288
  */
211
289
  export function resetProcess({
212
290
  loading,
213
291
  isProcessed,
214
- chartSpec,
215
292
  jsonformSchema,
216
293
  processResults,
217
294
  isPolling,
295
+ enableCompare,
218
296
  }) {
219
297
  loading.value = false;
220
298
  isProcessed.value = false;
221
299
  isPolling.value = false;
222
- chartSpec.value = null;
300
+ const usedChartSpec = enableCompare ? compareChartSpec : chartSpec;
301
+ usedChartSpec.value = null;
223
302
  processResults.value = [];
224
303
  jsonformSchema.value = null;
225
304
  }
@@ -238,8 +317,7 @@ export const onChartClick = (evt) => {
238
317
  const chartSpec = evt.target?.spec;
239
318
  if (
240
319
  !chartSpec ||
241
- !evt.detail?.item?.datum ||
242
- !evt.detail?.item?.datum.datum
320
+ (!evt.detail?.item?.datum && !evt.detail?.item?.datum.datum)
243
321
  ) {
244
322
  return;
245
323
  }
@@ -17,7 +17,7 @@ import { isFirstLoad } from "@/utils/states";
17
17
  * @param {Record<string,any>} options.jsonformSchema
18
18
  * @param {import("vue").Ref<import("../types").AsyncJob[]>} options.jobs
19
19
  * @param {boolean} [options.enableCompare=false] - Whether to enable compare mode
20
- * @returns {Promise<[import("@eox/chart").EOxChart["spec"] | null,Record<string,any>|null]>}
20
+ * @returns {Promise<[import("vega-embed").VisualizationSpec | null,Record<string,any>|null]>}
21
21
  **/
22
22
  export async function processCharts({
23
23
  links,
@@ -61,10 +61,50 @@ export async function processCharts({
61
61
  if (data && data.length) {
62
62
  //@ts-expect-error we assume data to exist in spec
63
63
  spec.data.values = data;
64
- return [spec, dataValues];
64
+ return [structuredClone(spec), structuredClone(dataValues)];
65
65
  }
66
-
67
66
  const dataLinks = standardLinks.filter((link) => link.rel === "service");
67
+
68
+ // We count if there are at least two application/json links, if yes,
69
+ // we download the data and assign them to specific data ids in the spec
70
+ const jsonLinks = dataLinks.filter(
71
+ (link) => link.type === "application/json",
72
+ );
73
+ if (jsonLinks.length >= 2) {
74
+ for (const link of jsonLinks ?? []) {
75
+ let linkType = link.type;
76
+ switch (linkType) {
77
+ case undefined:
78
+ continue;
79
+ case "application/json":
80
+ dataValues[/** @type {string} */ (link.id)] = await axios
81
+ .get(
82
+ mustache.render(link.href, {
83
+ ...(jsonformValue ?? {}),
84
+ }),
85
+ )
86
+ .then((resp) => resp.data);
87
+ // assign to spec datasets, assuming spec.data is InlineData
88
+ // Always assign values as an object with string keys
89
+ if (spec.data) {
90
+ /** @type {import("vega-lite/build/src/data").InlineData} */
91
+ (spec.data).values = {
92
+ ...(spec.data &&
93
+ "values" in spec.data &&
94
+ typeof spec.data.values === "object"
95
+ ? spec.data.values
96
+ : {}),
97
+ [/** @type {string} */ (link.id)]:
98
+ dataValues[/** @type {string} */ (link.id)],
99
+ };
100
+ }
101
+ break;
102
+ default:
103
+ break;
104
+ }
105
+ }
106
+ return [spec, dataValues];
107
+ }
68
108
  try {
69
109
  checkForData: for (const link of dataLinks ?? []) {
70
110
  switch (link.type) {
@@ -104,7 +144,7 @@ export async function processCharts({
104
144
  } catch (e) {
105
145
  console.error("[eodash] Error while injecting Vega data", e);
106
146
  }
107
- return [spec, dataValues];
147
+ return [structuredClone(spec), structuredClone(dataValues)];
108
148
  }
109
149
 
110
150
  /**
@@ -508,6 +508,16 @@ export function extractAsyncResults(resultItem) {
508
508
  }
509
509
  return extracted;
510
510
  }
511
+
512
+ /** @param {*} jsonformSchema */
513
+ export const getDrawToolsProperty = (jsonformSchema) => {
514
+ for (const property in jsonformSchema.properties) {
515
+ if (jsonformSchema.properties[property]?.options?.drawtools) {
516
+ return property;
517
+ }
518
+ }
519
+ };
520
+
511
521
  /**
512
522
  * @param {import("@eox/map").EOxMap | null} mapElement
513
523
  * @param {import("@eox/map").EoxLayer[]} processLayers
@@ -533,7 +543,7 @@ export const applyProcessLayersToMap = (mapElement, processLayers) => {
533
543
  (l) => l.properties?.id === layer.properties?.id,
534
544
  );
535
545
  if (!exists) {
536
- analysisGroup.layers.unshift(layer);
546
+ analysisGroup.layers.push(layer);
537
547
  } else {
538
548
  analysisGroup.layers = replaceLayer(
539
549
  analysisGroup.layers,