@eodash/eodash 5.0.0 → 5.1.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 (155) hide show
  1. package/README.md +1 -0
  2. package/core/client/App.vue +8 -2
  3. package/core/client/asWebComponent.js +5 -5
  4. package/core/client/components/DashboardLayout.vue +42 -25
  5. package/core/client/components/EodashOverlay.vue +1 -1
  6. package/core/client/components/ErrorAlert.vue +2 -2
  7. package/core/client/components/Footer.vue +4 -4
  8. package/core/client/components/Header.vue +3 -3
  9. package/core/client/components/MobileLayout.vue +9 -10
  10. package/core/client/composables/DefineEodash.js +38 -43
  11. package/core/client/composables/DefineTemplate.js +4 -2
  12. package/core/client/composables/DefineWidgets.js +14 -8
  13. package/core/client/composables/index.js +273 -23
  14. package/core/client/eodashSTAC/EodashCollection.js +80 -47
  15. package/core/client/eodashSTAC/helpers.js +136 -27
  16. package/core/client/eodashSTAC/parquet.js +145 -0
  17. package/core/client/eodashSTAC/triggers.js +6 -3
  18. package/core/client/plugins/index.js +4 -3
  19. package/core/client/plugins/vuetify.js +3 -0
  20. package/core/client/store/actions.js +21 -4
  21. package/core/client/store/stac.js +93 -56
  22. package/core/client/store/states.js +15 -5
  23. package/core/client/types.ts +59 -43
  24. package/core/client/utils/index.js +79 -0
  25. package/core/client/utils/keys.js +2 -2
  26. package/core/client/utils/states.js +30 -5
  27. package/core/client/views/Dashboard.vue +36 -32
  28. package/core/client/vite-env.d.ts +7 -0
  29. package/dist/client/{DashboardLayout-CkWvOMOW.js → DashboardLayout-ByVs1DrY.js} +23 -12
  30. package/dist/client/{DynamicWebComponent-DYBbpvUK.js → DynamicWebComponent-C3W7HSQm.js} +1 -1
  31. package/dist/client/{EodashDatePicker-CALmW3SI.js → EodashDatePicker-BIAf1sMT.js} +59 -32
  32. package/dist/client/{EodashItemFilter-DlQiE713.js → EodashItemFilter-DPznh8UB.js} +20 -10
  33. package/dist/client/{EodashLayerControl-DEzEbft7.js → EodashLayerControl-Bhxjw4V2.js} +29 -16
  34. package/dist/client/EodashLayoutSwitcher-C5qTEffW.js +61 -0
  35. package/dist/client/EodashMapBtns-WoGq8MuV.js +173 -0
  36. package/dist/client/{EodashStacInfo-DPPxDkF6.js → EodashStacInfo-CSvvF2jI.js} +3 -18
  37. package/dist/client/{EodashTools-CUaL9s4H.js → EodashTools-Cv1SXQ5y.js} +13 -13
  38. package/dist/client/{ExportState-DjyIZVhl.js → ExportState-D-iuwaad.js} +58 -52
  39. package/dist/client/{Footer-DyL0JoWt.js → Footer-CyF0zRAk.js} +15 -13
  40. package/dist/client/{Header-B5Dgty9l.js → Header-CgD8jDKU.js} +33 -28
  41. package/dist/client/{MobileLayout-CRsg_5Q4.js → MobileLayout-EKQ_kpSh.js} +69 -60
  42. package/dist/client/{PopUp-BfB8s_ki.js → PopUp-BsYLvWch.js} +19 -10
  43. package/dist/client/ProcessList-C2xsLU2_.js +191 -0
  44. package/dist/client/{VImg-FD1WVphJ.js → VImg-OHe8YTs2.js} +24 -24
  45. package/dist/client/{VMain-DJKG4SvM.js → VMain-PryTLU4a.js} +7 -7
  46. package/dist/client/{VOverlay-BzOdRu9h.js → VOverlay-yUn7p-Uf.js} +64 -27
  47. package/dist/client/{VTooltip-CfeefrXI.js → VTooltip-DZ0fjpB3.js} +13 -10
  48. package/dist/client/{WidgetsContainer-C2TaTdb6.js → WidgetsContainer-B9LBadcC.js} +1 -1
  49. package/dist/client/asWebComponent-By_7_JjS.js +19193 -0
  50. package/dist/client/async-DkSu_u2K.js +740 -0
  51. package/dist/client/eo-dash.js +1 -1
  52. package/dist/client/{forwardRefs-Bon_Kku1.js → forwardRefs-BXxrv98s.js} +31 -4
  53. package/dist/client/handling-CgmFXkW6.js +1212 -0
  54. package/dist/client/helpers-Dy0Q13tP.js +4534 -0
  55. package/dist/client/{index-Bm9cbtx5.js → index-BuhOHXKv.js} +2 -4
  56. package/dist/client/{index-CIHH_3dW.js → index-Ch_HchK3.js} +39 -32
  57. package/dist/client/{index-4CT7Tz83.js → index-Dqj4tbx2.js} +2 -2
  58. package/dist/client/index-skjhlH8u.js +376 -0
  59. package/dist/client/{ssrBoot-BP7SYRyC.js → ssrBoot-Zgc_Ttvi.js} +2 -2
  60. package/dist/client/templates.js +850 -0
  61. package/dist/client/transition-C98Yn4Vo.js +40 -0
  62. package/dist/node/cli.js +16 -6
  63. package/dist/node/types.d.ts +1 -1
  64. package/dist/types/core/client/App.vue.d.ts +2 -2
  65. package/dist/types/core/client/asWebComponent.d.ts +1 -1
  66. package/dist/types/core/client/components/DynamicWebComponent.vue.d.ts +1 -3
  67. package/dist/types/core/client/components/Footer.vue.d.ts +1 -105
  68. package/dist/types/core/client/components/IframeWrapper.vue.d.ts +1 -1
  69. package/dist/types/core/client/components/MobileLayout.vue.d.ts +1 -324
  70. package/dist/types/core/client/composables/DefineEodash.d.ts +2 -2
  71. package/dist/types/core/client/composables/DefineTemplate.d.ts +1 -1
  72. package/dist/types/core/client/composables/DefineWidgets.d.ts +4 -4
  73. package/dist/types/core/client/composables/index.d.ts +24 -2
  74. package/dist/types/core/client/eodashSTAC/EodashCollection.d.ts +9 -6
  75. package/dist/types/core/client/eodashSTAC/helpers.d.ts +20 -5
  76. package/dist/types/core/client/eodashSTAC/parquet.d.ts +2 -0
  77. package/dist/types/core/client/plugins/vuetify.d.ts +7 -4
  78. package/dist/types/core/client/store/actions.d.ts +3 -2
  79. package/dist/types/core/client/store/stac.d.ts +16 -13
  80. package/dist/types/core/client/store/states.d.ts +14 -4
  81. package/dist/types/core/client/types.d.ts +45 -30
  82. package/dist/types/core/client/utils/index.d.ts +2 -0
  83. package/dist/types/core/client/utils/keys.d.ts +4 -4
  84. package/dist/types/core/client/utils/states.d.ts +59 -47
  85. package/dist/types/core/client/views/Dashboard.vue.d.ts +2 -2
  86. package/dist/types/templates/baseConfig.d.ts +4 -0
  87. package/dist/types/templates/compare.d.ts +210 -0
  88. package/dist/types/templates/expert.d.ts +151 -0
  89. package/dist/types/templates/index.d.ts +6 -0
  90. package/dist/types/templates/light.d.ts +145 -0
  91. package/dist/types/widgets/EodashDatePicker.vue.d.ts +1 -458
  92. package/dist/types/widgets/EodashItemFilter.vue.d.ts +3 -3
  93. package/dist/types/widgets/EodashLayerControl.vue.d.ts +14 -7
  94. package/dist/types/widgets/EodashLayoutSwitcher.vue.d.ts +1 -3
  95. package/dist/types/widgets/EodashMap/index.vue.d.ts +1 -4
  96. package/dist/types/widgets/EodashMapBtns.vue.d.ts +8 -8
  97. package/dist/types/widgets/EodashProcess/ProcessList.vue.d.ts +8 -1
  98. package/dist/types/widgets/EodashProcess/index.vue.d.ts +8 -4
  99. package/dist/types/widgets/EodashProcess/methods/async.d.ts +18 -18
  100. package/dist/types/widgets/EodashProcess/methods/composables.d.ts +3 -2
  101. package/dist/types/widgets/EodashProcess/methods/custom-endpoints/chart/index.d.ts +1 -0
  102. package/dist/types/widgets/EodashProcess/methods/custom-endpoints/chart/sentinelhub-endpoint.d.ts +6 -0
  103. package/dist/types/widgets/EodashProcess/methods/custom-endpoints/chart/veda-endpoint.d.ts +4 -0
  104. package/dist/types/widgets/EodashProcess/methods/custom-endpoints/layers/eoxhub-workspaces-endpoint.d.ts +5 -0
  105. package/dist/types/widgets/EodashProcess/methods/custom-endpoints/layers/index.d.ts +1 -0
  106. package/dist/types/widgets/EodashProcess/methods/handling.d.ts +12 -5
  107. package/dist/types/widgets/EodashProcess/methods/outputs.d.ts +72 -41
  108. package/dist/types/widgets/EodashProcess/methods/utils.d.ts +41 -21
  109. package/dist/types/widgets/EodashProcess/states.d.ts +11 -0
  110. package/dist/types/widgets/EodashProcess/types.d.ts +41 -0
  111. package/dist/types/widgets/EodashStacInfo.vue.d.ts +14 -14
  112. package/dist/types/widgets/EodashTools.vue.d.ts +3 -3
  113. package/dist/types/widgets/ExportState.vue.d.ts +1 -1
  114. package/dist/types/widgets/PopUp.vue.d.ts +11 -16
  115. package/dist/types/widgets/WidgetsContainer.vue.d.ts +3 -6
  116. package/package.json +53 -45
  117. package/templates/baseConfig.js +68 -0
  118. package/templates/compare.js +162 -0
  119. package/templates/expert.js +123 -0
  120. package/templates/index.js +8 -0
  121. package/templates/light.js +130 -0
  122. package/widgets/EodashDatePicker.vue +80 -31
  123. package/widgets/EodashItemFilter.vue +26 -11
  124. package/widgets/EodashLayerControl.vue +20 -11
  125. package/widgets/EodashLayoutSwitcher.vue +6 -3
  126. package/widgets/EodashMap/index.vue +3 -8
  127. package/widgets/EodashMap/methods/create-layers-config.js +4 -3
  128. package/widgets/EodashMap/methods/index.js +33 -23
  129. package/widgets/EodashMapBtns.vue +83 -41
  130. package/widgets/EodashProcess/ProcessList.vue +34 -10
  131. package/widgets/EodashProcess/index.vue +55 -20
  132. package/widgets/EodashProcess/methods/async.js +77 -59
  133. package/widgets/EodashProcess/methods/composables.js +21 -14
  134. package/widgets/EodashProcess/methods/custom-endpoints/chart/index.js +35 -0
  135. package/widgets/EodashProcess/methods/custom-endpoints/chart/sentinelhub-endpoint.js +275 -0
  136. package/widgets/EodashProcess/methods/custom-endpoints/chart/veda-endpoint.js +116 -0
  137. package/widgets/EodashProcess/methods/custom-endpoints/layers/eoxhub-workspaces-endpoint.js +94 -0
  138. package/widgets/EodashProcess/methods/custom-endpoints/layers/index.js +33 -0
  139. package/widgets/EodashProcess/methods/handling.js +127 -80
  140. package/widgets/EodashProcess/methods/outputs.js +376 -125
  141. package/widgets/EodashProcess/methods/utils.js +398 -10
  142. package/widgets/EodashProcess/states.js +13 -0
  143. package/widgets/EodashProcess/types.ts +46 -0
  144. package/widgets/EodashStacInfo.vue +2 -17
  145. package/widgets/EodashTools.vue +13 -13
  146. package/widgets/WidgetsContainer.vue +1 -1
  147. package/core/client/eodash.js +0 -454
  148. package/dist/client/EodashLayoutSwitcher-CDeCV8F-.js +0 -52
  149. package/dist/client/EodashMapBtns-CktQCfa-.js +0 -131
  150. package/dist/client/ProcessList-DTefwQZx.js +0 -484
  151. package/dist/client/asWebComponent-CLhcT715.js +0 -12479
  152. package/dist/client/eo-dash.css +0 -5
  153. package/dist/client/index-DiGDvTQU.js +0 -780
  154. package/dist/client/transition-C5I57hn6.js +0 -37
  155. package/dist/types/core/client/eodash.d.ts +0 -8
@@ -1,5 +1,11 @@
1
- import { extractLayerConfig } from "@/eodashSTAC/helpers";
1
+ import { useEmitLayersUpdate } from "@/composables";
2
+ import {
3
+ extractLayerConfig,
4
+ mergeGeojsons,
5
+ replaceLayer,
6
+ } from "@/eodashSTAC/helpers";
2
7
  import axios from "@/plugins/axios";
8
+ import { getCompareLayers, getLayers } from "@/store/actions";
3
9
  import { isMulti } from "@eox/jsonform/src/custom-inputs/spatial/utils";
4
10
 
5
11
  /**
@@ -53,14 +59,13 @@ export function extractGeometries(jsonformValue, jsonformSchema) {
53
59
 
54
60
  /**
55
61
  *
56
- * @param {*} link
57
- * @param {*} layerId
62
+ * @param {import("stac-ts").StacLink} link
63
+ * @param {string} layerId
58
64
  * @param {string[]} urls
59
- * @param {*} projection
60
- * @param {*} processId
61
- * @returns
65
+ * @param {import("openlayers").ProjectionLike} projection
66
+ * @param {string} processId
62
67
  */
63
- export async function createLayerDefinition(
68
+ export async function createTiffLayerDefinition(
64
69
  link,
65
70
  layerId,
66
71
  urls,
@@ -74,9 +79,7 @@ export async function createLayerDefinition(
74
79
  .then((resp) => resp.data);
75
80
  }
76
81
 
77
- /** @type {Record<string,any>|undefined} */
78
82
  let layerConfig;
79
- /** @type {Record<string,any>|undefined} */
80
83
  let style;
81
84
  if (flatStyleJSON) {
82
85
  const extracted = extractLayerConfig(layerId ?? "", flatStyleJSON);
@@ -85,6 +88,7 @@ export async function createLayerDefinition(
85
88
  }
86
89
  // We want to make sure the urls are alphabetically sorted
87
90
  urls = urls.sort();
91
+ /** @type {import("@eox/map/src/layers").EOxLayerType<"WebGLTile","GeoTIFF"> | undefined} */
88
92
  const layerdef =
89
93
  urls.length > 0
90
94
  ? {
@@ -95,7 +99,7 @@ export async function createLayerDefinition(
95
99
  sources: urls.map((url) => ({ url })),
96
100
  },
97
101
  properties: {
98
- id: layerId + "_geotiff_process" + processId,
102
+ id: link.id + "_process" + processId,
99
103
  title: "Results " + layerId,
100
104
  ...(layerConfig && { layerConfig: layerConfig }),
101
105
  layerControlToolsExpand: true,
@@ -136,3 +140,387 @@ export const download = (fileName, content) => {
136
140
  URL.revokeObjectURL(url);
137
141
  link.remove();
138
142
  };
143
+
144
+ /**
145
+ * Generate time pairs from a temporal extent
146
+ * @param {import("stac-ts").TemporalExtent} stacExtent - [start, end]
147
+ * @param {import("stac-ts").TemporalExtent} [userExtent] -[start, end]
148
+ * @param {string} [distribution] - daily, weekly, monthly, or yearly
149
+ */
150
+ export function generateTimePairs(stacExtent, userExtent, distribution) {
151
+ // check whether the userExtent is provided
152
+ // if it is check that it doesn't exceed the stacExtent
153
+ // and clamp it otherwise
154
+
155
+ /** @type {string|Date} */
156
+ let from = "";
157
+
158
+ /** @type {string|Date} */
159
+ let to = "";
160
+ [from, to] = /** @type {[string, string]} */ (userExtent ?? ["", ""]);
161
+
162
+ const [stacFrom, stacTo] = /** @type {[string, string]} */ (
163
+ stacExtent ?? ["", ""]
164
+ );
165
+
166
+ try {
167
+ if (from && to) {
168
+ from = new Date(from);
169
+ to = new Date(to);
170
+ } else {
171
+ from = new Date(stacFrom);
172
+ to = new Date(stacTo);
173
+ }
174
+
175
+ if (from < new Date(stacFrom) || from > new Date(stacTo)) {
176
+ console.warn(
177
+ "[eodash] warn: start date is outside of the collection temporal extent and will be clamped",
178
+ `\nprovided start date:${from.toISOString()}`,
179
+ `\ncollection start date:${stacFrom}`,
180
+ );
181
+ from = new Date(stacFrom);
182
+ }
183
+
184
+ if (to > new Date(stacTo) || to < new Date(stacFrom)) {
185
+ console.warn(
186
+ "[eodash] warn: end date is outside of the collection temporal extent and will be clamped",
187
+ `\nprovided end date:${to.toISOString()}`,
188
+ `\ncollection end date:${stacTo}`,
189
+ );
190
+ to = new Date(stacTo);
191
+ }
192
+
193
+ if (from > to) {
194
+ console.error(
195
+ "[eodash] Error: start date is greater than end date",
196
+ from,
197
+ to,
198
+ );
199
+ return [];
200
+ }
201
+ } catch (e) {
202
+ //@ts-expect-error e should be an error
203
+ console.error("[eodash] Invalid date:", e.message);
204
+ return [];
205
+ }
206
+
207
+ const startDate = /** @type {Date} */ (from).toISOString();
208
+ const endDate = /** @type {Date} */ (to).toISOString();
209
+
210
+ if (!startDate || !endDate) {
211
+ return [];
212
+ }
213
+ const times = [];
214
+ let latest = new Date(endDate);
215
+ const start = new Date(startDate);
216
+ const oneDay = 24 * 60 * 60 * 1000;
217
+ // Use fixed step of 1 day (in milliseconds)
218
+ const step =
219
+ distribution === "daily"
220
+ ? oneDay
221
+ : distribution === "weekly"
222
+ ? oneDay * 7
223
+ : distribution === "monthly"
224
+ ? oneDay * 30
225
+ : distribution === "yearly"
226
+ ? oneDay * 365
227
+ : oneDay;
228
+
229
+ // Add dates, limiting to 31 dates (30 pairs maximum)
230
+ while (latest >= start && times.length < 31) {
231
+ times.push(new Date(latest));
232
+ latest.setTime(latest.getTime() - step);
233
+ }
234
+
235
+ const timePairs = [];
236
+ for (let i = 0; i < times.length - 1; i++) {
237
+ timePairs.push([times[i].toISOString(), times[i + 1].toISOString()]);
238
+ }
239
+
240
+ return timePairs;
241
+ }
242
+
243
+ /**
244
+ * Filter links to separate those with and without endpoint property
245
+ * @param {import("stac-ts").StacLink[] | undefined} links
246
+ * @param {string} [relType] - Optional relationship type
247
+ * @param {string} [contentType] - Optional content type
248
+ * @returns {[import("stac-ts").StacLink[], import("stac-ts").StacLink[]]}
249
+ */
250
+ export function separateEndpointLinks(links, relType, contentType) {
251
+ if (!links) return [[], []];
252
+ const standardLinks = [];
253
+ const endpointLinks = [];
254
+
255
+ for (const link of links) {
256
+ // Check if the link matches the specified relType and contentType (if provided)
257
+ const relTypeMatch = relType ? link.rel === relType : true;
258
+ const contentTypeMatch = contentType ? link.type === contentType : true;
259
+
260
+ if (relTypeMatch && contentTypeMatch) {
261
+ if (link.endpoint) {
262
+ endpointLinks.push(link);
263
+ } else {
264
+ standardLinks.push(link);
265
+ }
266
+ }
267
+ }
268
+
269
+ return [standardLinks, endpointLinks];
270
+ }
271
+
272
+ /**
273
+ * Generates layer definitions for asynchronous process results.
274
+ * using AsyncProcessResults data structure.
275
+ * @param {import("^/EodashProcess/types").AsyncProcessResults} processResults
276
+ * @param {import("stac-ts").StacLink} endpointLink
277
+ * @param {import("stac-ts").StacCollection|null} selectedStac
278
+ * @param {string} [postfixId=""] - Optional layers id postfix
279
+ * @returns
280
+ */
281
+ export async function creatAsyncProcessLayerDefinitions(
282
+ processResults,
283
+ endpointLink,
284
+ selectedStac,
285
+ postfixId = "",
286
+ ) {
287
+ /** @type {import("@eox/map").EoxLayer[]} */
288
+ const layers = [];
289
+ const flatStyles = await fetchProcessStyles(endpointLink);
290
+
291
+ for (const resultItem of processResults) {
292
+ const flatStyleJSON = extractStyleFromResult(resultItem, flatStyles);
293
+ let style, layerConfig;
294
+ if (flatStyleJSON) {
295
+ const extracted = extractLayerConfig(
296
+ selectedStac?.id ?? "",
297
+ flatStyleJSON,
298
+ );
299
+ layerConfig = extracted.layerConfig;
300
+ style = extracted.style;
301
+ }
302
+
303
+ switch (resultItem.type) {
304
+ case "image/tiff": {
305
+ layers.push({
306
+ type: "WebGLTile",
307
+ properties: {
308
+ id: endpointLink.id + "_process" + resultItem.id + postfixId,
309
+ title:
310
+ "Results " +
311
+ (selectedStac?.id ?? "") +
312
+ " " +
313
+ (resultItem.id ?? ""),
314
+ layerControlToolsExpand: true,
315
+ ...(layerConfig && { layerConfig }),
316
+ },
317
+ source: {
318
+ type: "GeoTIFF",
319
+ normalize: !style,
320
+ sources: resultItem.urls.map((url) => ({ url })),
321
+ //@ts-expect-error TODO
322
+ ...(selectedStac["eodash:mapProjection"]?.["name"] && {
323
+ //@ts-expect-error TODO
324
+ projection: selectedStac["eodash:mapProjection"]["name"],
325
+ }),
326
+ },
327
+ ...(style && { style }),
328
+ });
329
+ break;
330
+ }
331
+ case "application/geo+json": {
332
+ const mergedUrl = await mergeGeojsons(resultItem.urls);
333
+ layers.push({
334
+ type: "Vector",
335
+ source: {
336
+ type: "Vector",
337
+ format: "GeoJSON",
338
+ ...(mergedUrl && { url: mergedUrl }),
339
+ },
340
+ properties: {
341
+ id: endpointLink.id + "_process_" + resultItem.id + postfixId,
342
+ title:
343
+ "Results " +
344
+ (selectedStac?.id ?? "") +
345
+ " " +
346
+ (resultItem.id ?? ""),
347
+ ...(layerConfig && {
348
+ layerConfig: {
349
+ ...layerConfig,
350
+ style,
351
+ },
352
+ }),
353
+ },
354
+ ...(!style?.variables && { style }),
355
+ interactions: [],
356
+ });
357
+ break;
358
+ }
359
+ default:
360
+ console.warn(
361
+ `[eodash] Unsupported result type "${resultItem.type}" for ${resultItem.id} layer creation.`,
362
+ );
363
+ break;
364
+ }
365
+ }
366
+ return layers;
367
+ }
368
+
369
+ /**
370
+ * @param {import("stac-ts").StacLink} endpointLink
371
+ * @returns
372
+ */
373
+ async function fetchProcessStyles(endpointLink) {
374
+ /** @type {import("@/types").EodashStyleJson | (Record<string,import("@/types").EodashStyleJson> & {multipleStyles:true}) | null} */
375
+ let flatStyles = null;
376
+ if (endpointLink["eox:flatstyle"]) {
377
+ if (typeof endpointLink["eox:flatstyle"] === "string") {
378
+ flatStyles = await axios
379
+ .get(/** @type {string} */ (endpointLink["eox:flatstyle"]))
380
+ .then((resp) => /** @type {} */ resp.data);
381
+ } else if (
382
+ Array.isArray(endpointLink["eox:flatstyle"]) &&
383
+ endpointLink["eox:flatstyle"].length
384
+ ) {
385
+ // multipleStyles as a flag to indicate it
386
+ flatStyles = { multipleStyles: true };
387
+
388
+ await Promise.all(
389
+ /** @type {{id:string;url:string}[]} */
390
+ (endpointLink["eox:flatstyle"]).map(async (styleDict) => {
391
+ //@ts-expect-error TODO
392
+ flatStyles[styleDict.id] = await axios
393
+ .get(styleDict.url)
394
+ .then(
395
+ (resp) =>
396
+ /** @type {import("@/types").EodashStyleJson} */ (resp.data),
397
+ );
398
+ }),
399
+ );
400
+ } else {
401
+ // multipleStyles as a flag to indicate it
402
+ flatStyles = { multipleStyles: true };
403
+ await Promise.all(
404
+ Object.keys(endpointLink["eox:flatstyle"] ?? {}).map((key) => {
405
+ //@ts-expect-error TODO
406
+ flatStyles[key] = axios
407
+ //@ts-expect-error TODO
408
+ .get(endpointLink["eox:flatstyle"][key])
409
+ .then((resp) => resp.data);
410
+ }),
411
+ );
412
+ }
413
+ }
414
+ return flatStyles;
415
+ }
416
+
417
+ /**
418
+ *
419
+ * @param {import("^/EodashProcess/types").AsyncProcessResults[number]} processResult
420
+ * @param {null| import("@/types").EodashStyleJson | (Record<string,import("@/types").EodashStyleJson> & {multipleStyles:true})} flatStyles
421
+ */
422
+ function extractStyleFromResult(processResult, flatStyles) {
423
+ if (!flatStyles) {
424
+ return undefined;
425
+ }
426
+ if (!("multipleStyles" in flatStyles)) {
427
+ return flatStyles;
428
+ }
429
+
430
+ const outputKey = processResult.id;
431
+ if (!outputKey || !(outputKey in flatStyles)) {
432
+ return undefined;
433
+ }
434
+ return flatStyles[outputKey];
435
+ }
436
+
437
+ /**
438
+ *
439
+ * @param {import("^/EodashProcess/types").EOxHubProcessResults} resultItem
440
+ * @returns {import("^/EodashProcess/types").AsyncProcessResults}
441
+ */
442
+ export function extractAsyncResults(resultItem) {
443
+ if (!resultItem) {
444
+ return [];
445
+ }
446
+ // if no type specified we assume the results are geotiff sources
447
+ if ("urls" in resultItem && Array.isArray(resultItem.urls)) {
448
+ return [{ id: "", urls: resultItem.urls, type: "image/tiff" }];
449
+ }
450
+
451
+ const extracted = [];
452
+ for (const key in resultItem) {
453
+ if (key === "id") {
454
+ continue;
455
+ }
456
+ extracted.push({
457
+ // used as a key to identify the corresponding style
458
+ id: key,
459
+ //@ts-expect-error TODO
460
+ urls: /** @type {string[]} */ (resultItem[key].urls),
461
+ //@ts-expect-error TODO
462
+ type: /** @type {string} */ (resultItem[key].mimetype),
463
+ });
464
+ }
465
+ return extracted;
466
+ }
467
+ /**
468
+ * @param {import("@eox/map").EOxMap | null} mapElement
469
+ * @param {import("@eox/map").EoxLayer[]} processLayers
470
+ */
471
+ export const applyProcessLayersToMap = (mapElement, processLayers) => {
472
+ if (!processLayers.length || !mapElement) {
473
+ return;
474
+ }
475
+ const getMapLayers =
476
+ mapElement.id === "compare" ? getCompareLayers : getLayers;
477
+ const currentLayers = [...getMapLayers()];
478
+
479
+ let analysisGroup =
480
+ /*** @type {import("@eox/map/src/layers").EOxLayerTypeGroup | undefined} */ (
481
+ currentLayers.find((l) => l.properties?.id.includes("AnalysisGroup"))
482
+ );
483
+ if (!analysisGroup) {
484
+ return;
485
+ }
486
+
487
+ for (const layer of processLayers) {
488
+ const exists = analysisGroup.layers.find(
489
+ (l) => l.properties?.id === layer.properties?.id,
490
+ );
491
+ if (!exists) {
492
+ analysisGroup.layers.unshift(layer);
493
+ } else {
494
+ analysisGroup.layers = replaceLayer(
495
+ analysisGroup.layers,
496
+ layer.properties?.id ?? "",
497
+ [layer],
498
+ );
499
+ }
500
+ }
501
+ if (mapElement) {
502
+ const layers = [...currentLayers];
503
+ const evtKey =
504
+ mapElement.id === "compare"
505
+ ? "compareProcess:updated"
506
+ : "process:updated";
507
+ useEmitLayersUpdate(evtKey, mapElement, layers);
508
+ mapElement.layers = layers;
509
+ }
510
+ };
511
+ /**
512
+ * Updates the jsonform schema to target the compare map
513
+ * @param {import("json-schema").JSONSchema7 | null | undefined} jsonformSchema
514
+ */
515
+ export function updateJsonformSchemaTarget(jsonformSchema) {
516
+ if (!jsonformSchema) {
517
+ return jsonformSchema;
518
+ }
519
+ const stringified = JSON.stringify(jsonformSchema).replaceAll(
520
+ "eox-map#main",
521
+ "eox-map#compare",
522
+ );
523
+ return /** @type {import("json-schema").JSONSchema7} */ (
524
+ JSON.parse(stringified)
525
+ );
526
+ }
@@ -0,0 +1,13 @@
1
+ import { ref } from "vue";
2
+
3
+ /**
4
+ * The list of job result from the server
5
+ * {job_start_datetime: string, job_end_datetime: string,status: string}
6
+ * @type {import("vue").Ref<import("./types").AsyncJob[]>}
7
+ **/
8
+ export const jobs = ref([]);
9
+ /**
10
+ * The list of jobs results from the server for the compare map
11
+ * @type {import("vue").Ref<import("./types").AsyncJob[]>}
12
+ */
13
+ export const compareJobs = ref([]);
@@ -0,0 +1,46 @@
1
+ import type { StacLink, StacCollection } from "stac-ts";
2
+ import type { Ref } from "vue";
3
+
4
+ export interface CustomEnpointInput {
5
+ links: StacLink[];
6
+ jsonformSchema: Record<string, any>;
7
+ jsonformValue: Record<string, any>;
8
+ selectedStac: StacCollection;
9
+ isPolling?: Ref<boolean>;
10
+ enableCompare?: boolean;
11
+ jobs: Ref<AsyncJob[]>;
12
+ }
13
+ export interface AsyncJob {
14
+ type: string;
15
+ processID: string;
16
+ jobID: string;
17
+ status: "successful" | "failed" | "running";
18
+ message: string;
19
+ /** percentage of completion */
20
+ progress: number | string;
21
+ /** stringified object of parameters */
22
+ parameters: string;
23
+ /** ISO datetime string */
24
+ job_start_datetime: string;
25
+ /** ISO datetime string */
26
+ job_end_datetime: string;
27
+ /** typically contains links to differen types of the results */
28
+ links: StacLink[];
29
+ }
30
+
31
+ export type EOxHubProcessResults =
32
+ | {
33
+ urls: string[];
34
+ }
35
+ | {
36
+ [K in string as K extends "urls" ? never : K]: {
37
+ urls: string[];
38
+ mimetype: string;
39
+ };
40
+ };
41
+
42
+ export type AsyncProcessResults = {
43
+ type: string;
44
+ urls: string[];
45
+ id: string;
46
+ }[];
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div class="flex-grow-1 fill-height overflow-auto">
2
+ <div class="flex-grow-1">
3
3
  <eox-stacinfo
4
4
  .for="currentUrl"
5
5
  .allowHtml="allowHtml"
@@ -37,22 +37,7 @@ const {
37
37
 
38
38
  styleOverride: {
39
39
  type: String,
40
- default: `
41
- .single-property {columns: 1!important;}
42
- h1 {margin:0px!important;font-size:16px!important;}
43
- header h1:after {
44
- content:' ';
45
- display:block;
46
- border:1px solid #d0d0d0;
47
- }
48
- h2 {font-size:15px}
49
- h3 {font-size:14px}
50
- summary {cursor: pointer;}
51
- #properties li > .value { font-weight: normal !important;}
52
- main {padding-bottom: 10px;}
53
- .footer-container {line-height:1;}
54
- .footer-container button {margin-top: -10px;}
55
- .footer-container small {font-size:10px;line-height:1;}`,
40
+ default: "",
56
41
  },
57
42
  header: {
58
43
  /** @type {import("vue").PropType<string[]>} */
@@ -1,14 +1,13 @@
1
1
  <template>
2
- <div
3
- ref="rootEl"
4
- class="d-flex flex-column fill-height overflow-auto bg-primary"
5
- >
6
- <div class="d-flex flex-row justify-space-between pa-4 align-center">
2
+ <div ref="rootEl" class="d-flex flex-column fill-height bg-primary">
3
+ <div
4
+ class="d-flex flex-row align-center fill-height justify-space-between pa-2 align-center"
5
+ >
7
6
  <v-btn
8
7
  v-if="props.showIndicatorsBtn"
9
8
  color="secondary"
10
- class="text-none py-2 px-4"
11
- :append-icon="[mdiPlus]"
9
+ class="text-none"
10
+ :append-icon="[mdiPlusCircleOutline]"
12
11
  :text="indicatorBtnText"
13
12
  @click="dialog = !dialog"
14
13
  >
@@ -40,16 +39,16 @@
40
39
  import PopUp from "^/PopUp.vue";
41
40
  import EodashItemFilter from "^/EodashItemFilter.vue";
42
41
  import EodashLayoutSwitcher from "^/EodashLayoutSwitcher.vue";
43
- import { mdiPlus, mdiViewDashboard } from "@mdi/js";
42
+ import { mdiPlusCircleOutline, mdiViewDashboard } from "@mdi/js";
44
43
  import { computed, ref } from "vue";
45
- import { makePanelTransparent } from "@/composables";
46
- import { useDisplay } from "vuetify/lib/framework.mjs";
44
+ import { useTransparentPanel } from "@/composables";
45
+ import { useDisplay } from "vuetify";
47
46
 
48
47
  const dialog = ref(false);
49
48
 
50
49
  const { smAndDown } = useDisplay();
51
- const popupWidth = computed(() => (smAndDown.value ? "80%" : "1500px"));
52
- const popupHeight = computed(() => (smAndDown.value ? "90%" : "800px"));
50
+ const popupWidth = computed(() => (smAndDown.value ? "90%" : "70%"));
51
+ const popupHeight = computed(() => (smAndDown.value ? "90%" : "70%"));
53
52
 
54
53
  const props = defineProps({
55
54
  showIndicatorsBtn: {
@@ -80,5 +79,6 @@ const props = defineProps({
80
79
  },
81
80
  });
82
81
  const rootEl = ref(null);
83
- makePanelTransparent(rootEl);
82
+ useTransparentPanel(rootEl);
84
83
  </script>
84
+ <style lang="scss" scoped></style>
@@ -17,7 +17,7 @@
17
17
  import { useDefineWidgets } from "@/composables/DefineWidgets";
18
18
  import { nextTick, onMounted } from "vue";
19
19
  import { ref } from "vue";
20
- import { useLayout } from "vuetify/lib/framework.mjs";
20
+ import { useLayout } from "vuetify";
21
21
  import "animated-details";
22
22
 
23
23
  const props = defineProps({