@eodash/eodash 5.0.0 → 5.2.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 (162) 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 +43 -26
  5. package/core/client/components/EodashOverlay.vue +5 -6
  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 +47 -27
  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 +84 -62
  15. package/core/client/eodashSTAC/createLayers.js +30 -0
  16. package/core/client/eodashSTAC/helpers.js +159 -28
  17. package/core/client/eodashSTAC/parquet.js +145 -0
  18. package/core/client/eodashSTAC/triggers.js +6 -3
  19. package/core/client/plugins/index.js +4 -3
  20. package/core/client/plugins/vuetify.js +3 -0
  21. package/core/client/store/actions.js +21 -4
  22. package/core/client/store/stac.js +93 -56
  23. package/core/client/store/states.js +15 -5
  24. package/core/client/types.ts +59 -43
  25. package/core/client/utils/index.js +79 -0
  26. package/core/client/utils/keys.js +2 -2
  27. package/core/client/utils/states.js +30 -5
  28. package/core/client/views/Dashboard.vue +36 -32
  29. package/core/client/vite-env.d.ts +7 -0
  30. package/dist/client/{DashboardLayout-CkWvOMOW.js → DashboardLayout-Dq9Kfe6O.js} +24 -13
  31. package/dist/client/{DynamicWebComponent-DYBbpvUK.js → DynamicWebComponent-DCBMXskE.js} +1 -1
  32. package/dist/client/{EodashDatePicker-CALmW3SI.js → EodashDatePicker-DtngxU6s.js} +59 -32
  33. package/dist/client/{EodashItemFilter-DlQiE713.js → EodashItemFilter-ClQebJQt.js} +20 -10
  34. package/dist/client/{EodashLayerControl-DEzEbft7.js → EodashLayerControl-BLBds28C.js} +29 -16
  35. package/dist/client/EodashLayoutSwitcher-DQ8SfVDd.js +61 -0
  36. package/dist/client/EodashMapBtns-B89_YBDw.js +326 -0
  37. package/dist/client/{EodashStacInfo-DPPxDkF6.js → EodashStacInfo-Dt1nF06x.js} +3 -18
  38. package/dist/client/{EodashTools-CUaL9s4H.js → EodashTools-DV5ykmWc.js} +13 -13
  39. package/dist/client/{ExportState-DjyIZVhl.js → ExportState-B6zZQUmE.js} +57 -52
  40. package/dist/client/{Footer-DyL0JoWt.js → Footer-DNhXs8k6.js} +15 -13
  41. package/dist/client/{Header-B5Dgty9l.js → Header-BjhN5JY4.js} +32 -28
  42. package/dist/client/MobileLayout-JelB6w1G.js +118 -0
  43. package/dist/client/{PopUp-BfB8s_ki.js → PopUp-CgpvNr3o.js} +18 -10
  44. package/dist/client/ProcessList-vecpxThi.js +198 -0
  45. package/dist/client/{VImg-FD1WVphJ.js → VImg-CETuikH2.js} +221 -26
  46. package/dist/client/{VMain-DJKG4SvM.js → VMain-Ci9DyaGU.js} +7 -7
  47. package/dist/client/{VTooltip-CfeefrXI.js → VTooltip-J4ac48X7.js} +12 -10
  48. package/dist/client/{WidgetsContainer-C2TaTdb6.js → WidgetsContainer-CCML4TyV.js} +1 -1
  49. package/dist/client/asWebComponent-ZyEzWOOf.js +19092 -0
  50. package/dist/client/async-B7jIrM53.js +804 -0
  51. package/dist/client/eo-dash.js +1 -1
  52. package/dist/client/{VOverlay-BzOdRu9h.js → forwardRefs-BQclvjMq.js} +332 -28
  53. package/dist/client/handling-BS24aG1q.js +1227 -0
  54. package/dist/client/helpers-wXK7Ywio.js +4556 -0
  55. package/dist/client/index-4UCzZi8B.js +376 -0
  56. package/dist/client/{index-4CT7Tz83.js → index-9KR-G20t.js} +2 -2
  57. package/dist/client/{index-CIHH_3dW.js → index-B2XpdgR6.js} +227 -86
  58. package/dist/client/material-symbols-outlined.woff2 +0 -0
  59. package/dist/client/material-symbols-rounded.woff2 +0 -0
  60. package/dist/client/material-symbols-sharp.woff2 +0 -0
  61. package/dist/client/material-symbols-subset.woff2 +0 -0
  62. package/dist/client/{ssrBoot-BP7SYRyC.js → ssrBoot-Zgc_Ttvi.js} +2 -2
  63. package/dist/client/templates.js +840 -0
  64. package/dist/client/transition-yBii4fu6.js +40 -0
  65. package/dist/node/cli.js +16 -6
  66. package/dist/node/types.d.ts +1 -1
  67. package/dist/types/core/client/App.vue.d.ts +2 -2
  68. package/dist/types/core/client/asWebComponent.d.ts +1 -1
  69. package/dist/types/core/client/components/DynamicWebComponent.vue.d.ts +1 -3
  70. package/dist/types/core/client/components/Footer.vue.d.ts +1 -105
  71. package/dist/types/core/client/components/IframeWrapper.vue.d.ts +1 -1
  72. package/dist/types/core/client/components/MobileLayout.vue.d.ts +1 -324
  73. package/dist/types/core/client/composables/DefineEodash.d.ts +2 -2
  74. package/dist/types/core/client/composables/DefineTemplate.d.ts +1 -1
  75. package/dist/types/core/client/composables/DefineWidgets.d.ts +4 -4
  76. package/dist/types/core/client/composables/index.d.ts +24 -2
  77. package/dist/types/core/client/eodashSTAC/EodashCollection.d.ts +9 -6
  78. package/dist/types/core/client/eodashSTAC/helpers.d.ts +25 -5
  79. package/dist/types/core/client/eodashSTAC/parquet.d.ts +2 -0
  80. package/dist/types/core/client/plugins/vuetify.d.ts +7 -4
  81. package/dist/types/core/client/store/actions.d.ts +3 -2
  82. package/dist/types/core/client/store/stac.d.ts +16 -13
  83. package/dist/types/core/client/store/states.d.ts +14 -4
  84. package/dist/types/core/client/types.d.ts +46 -31
  85. package/dist/types/core/client/utils/index.d.ts +2 -0
  86. package/dist/types/core/client/utils/keys.d.ts +4 -4
  87. package/dist/types/core/client/utils/states.d.ts +59 -47
  88. package/dist/types/core/client/views/Dashboard.vue.d.ts +2 -2
  89. package/dist/types/templates/baseConfig.d.ts +4 -0
  90. package/dist/types/templates/compare.d.ts +185 -0
  91. package/dist/types/templates/expert.d.ts +147 -0
  92. package/dist/types/templates/index.d.ts +6 -0
  93. package/dist/types/templates/light.d.ts +154 -0
  94. package/dist/types/widgets/EodashDatePicker.vue.d.ts +1 -458
  95. package/dist/types/widgets/EodashItemFilter.vue.d.ts +3 -3
  96. package/dist/types/widgets/EodashLayerControl.vue.d.ts +14 -7
  97. package/dist/types/widgets/EodashLayoutSwitcher.vue.d.ts +1 -3
  98. package/dist/types/widgets/{EodashMapBtns.vue.d.ts → EodashMap/EodashMapBtns.vue.d.ts} +12 -8
  99. package/dist/types/widgets/EodashMap/index.vue.d.ts +9 -4
  100. package/dist/types/widgets/EodashProcess/ProcessList.vue.d.ts +8 -1
  101. package/dist/types/widgets/EodashProcess/index.vue.d.ts +8 -4
  102. package/dist/types/widgets/EodashProcess/methods/async.d.ts +19 -18
  103. package/dist/types/widgets/EodashProcess/methods/composables.d.ts +3 -2
  104. package/dist/types/widgets/EodashProcess/methods/custom-endpoints/chart/index.d.ts +1 -0
  105. package/dist/types/widgets/EodashProcess/methods/custom-endpoints/chart/sentinelhub-endpoint.d.ts +6 -0
  106. package/dist/types/widgets/EodashProcess/methods/custom-endpoints/chart/veda-endpoint.d.ts +4 -0
  107. package/dist/types/widgets/EodashProcess/methods/custom-endpoints/layers/eoxhub-workspaces-endpoint.d.ts +5 -0
  108. package/dist/types/widgets/EodashProcess/methods/custom-endpoints/layers/index.d.ts +1 -0
  109. package/dist/types/widgets/EodashProcess/methods/handling.d.ts +12 -5
  110. package/dist/types/widgets/EodashProcess/methods/outputs.d.ts +72 -41
  111. package/dist/types/widgets/EodashProcess/methods/utils.d.ts +41 -21
  112. package/dist/types/widgets/EodashProcess/states.d.ts +11 -0
  113. package/dist/types/widgets/EodashProcess/types.d.ts +41 -0
  114. package/dist/types/widgets/EodashStacInfo.vue.d.ts +14 -14
  115. package/dist/types/widgets/EodashTools.vue.d.ts +3 -3
  116. package/dist/types/widgets/ExportState.vue.d.ts +1 -1
  117. package/dist/types/widgets/PopUp.vue.d.ts +11 -16
  118. package/dist/types/widgets/WidgetsContainer.vue.d.ts +3 -6
  119. package/package.json +55 -45
  120. package/templates/baseConfig.js +68 -0
  121. package/templates/compare.js +142 -0
  122. package/templates/expert.js +124 -0
  123. package/templates/index.js +8 -0
  124. package/templates/light.js +139 -0
  125. package/widgets/EodashDatePicker.vue +80 -31
  126. package/widgets/EodashItemFilter.vue +26 -11
  127. package/widgets/EodashLayerControl.vue +20 -11
  128. package/widgets/EodashLayoutSwitcher.vue +6 -3
  129. package/widgets/EodashMap/EodashMapBtns.vue +269 -0
  130. package/widgets/EodashMap/index.vue +255 -45
  131. package/widgets/EodashMap/methods/create-layers-config.js +4 -3
  132. package/widgets/EodashMap/methods/index.js +33 -23
  133. package/widgets/EodashProcess/ProcessList.vue +47 -11
  134. package/widgets/EodashProcess/index.vue +55 -20
  135. package/widgets/EodashProcess/methods/async.js +99 -60
  136. package/widgets/EodashProcess/methods/composables.js +21 -14
  137. package/widgets/EodashProcess/methods/custom-endpoints/chart/index.js +35 -0
  138. package/widgets/EodashProcess/methods/custom-endpoints/chart/sentinelhub-endpoint.js +275 -0
  139. package/widgets/EodashProcess/methods/custom-endpoints/chart/veda-endpoint.js +132 -0
  140. package/widgets/EodashProcess/methods/custom-endpoints/layers/eoxhub-workspaces-endpoint.js +94 -0
  141. package/widgets/EodashProcess/methods/custom-endpoints/layers/index.js +33 -0
  142. package/widgets/EodashProcess/methods/handling.js +127 -80
  143. package/widgets/EodashProcess/methods/outputs.js +376 -125
  144. package/widgets/EodashProcess/methods/utils.js +442 -10
  145. package/widgets/EodashProcess/states.js +13 -0
  146. package/widgets/EodashProcess/types.ts +46 -0
  147. package/widgets/EodashStacInfo.vue +2 -17
  148. package/widgets/EodashTools.vue +13 -13
  149. package/widgets/WidgetsContainer.vue +1 -1
  150. package/core/client/eodash.js +0 -454
  151. package/dist/client/EodashLayoutSwitcher-CDeCV8F-.js +0 -52
  152. package/dist/client/EodashMapBtns-CktQCfa-.js +0 -131
  153. package/dist/client/MobileLayout-CRsg_5Q4.js +0 -1217
  154. package/dist/client/ProcessList-DTefwQZx.js +0 -484
  155. package/dist/client/asWebComponent-CLhcT715.js +0 -12479
  156. package/dist/client/eo-dash.css +0 -5
  157. package/dist/client/forwardRefs-Bon_Kku1.js +0 -245
  158. package/dist/client/index-Bm9cbtx5.js +0 -201
  159. package/dist/client/index-DiGDvTQU.js +0 -780
  160. package/dist/client/transition-C5I57hn6.js +0 -37
  161. package/dist/types/core/client/eodash.d.ts +0 -8
  162. package/widgets/EodashMapBtns.vue +0 -113
@@ -1,5 +1,12 @@
1
- import { extractLayerConfig } from "@/eodashSTAC/helpers";
1
+ import { useEmitLayersUpdate } from "@/composables";
2
+ import {
3
+ extractLayerConfig,
4
+ mergeGeojsons,
5
+ replaceLayer,
6
+ extractLayerLegend,
7
+ } from "@/eodashSTAC/helpers";
2
8
  import axios from "@/plugins/axios";
9
+ import { getCompareLayers, getLayers } from "@/store/actions";
3
10
  import { isMulti } from "@eox/jsonform/src/custom-inputs/spatial/utils";
4
11
 
5
12
  /**
@@ -53,14 +60,13 @@ export function extractGeometries(jsonformValue, jsonformSchema) {
53
60
 
54
61
  /**
55
62
  *
56
- * @param {*} link
57
- * @param {*} layerId
63
+ * @param {import("stac-ts").StacLink} link
64
+ * @param {string} layerId
58
65
  * @param {string[]} urls
59
- * @param {*} projection
60
- * @param {*} processId
61
- * @returns
66
+ * @param {import("openlayers").ProjectionLike} projection
67
+ * @param {string} processId
62
68
  */
63
- export async function createLayerDefinition(
69
+ export async function createTiffLayerDefinition(
64
70
  link,
65
71
  layerId,
66
72
  urls,
@@ -74,9 +80,7 @@ export async function createLayerDefinition(
74
80
  .then((resp) => resp.data);
75
81
  }
76
82
 
77
- /** @type {Record<string,any>|undefined} */
78
83
  let layerConfig;
79
- /** @type {Record<string,any>|undefined} */
80
84
  let style;
81
85
  if (flatStyleJSON) {
82
86
  const extracted = extractLayerConfig(layerId ?? "", flatStyleJSON);
@@ -85,6 +89,7 @@ export async function createLayerDefinition(
85
89
  }
86
90
  // We want to make sure the urls are alphabetically sorted
87
91
  urls = urls.sort();
92
+ /** @type {import("@eox/map/src/layers").EOxLayerType<"WebGLTile","GeoTIFF"> | undefined} */
88
93
  const layerdef =
89
94
  urls.length > 0
90
95
  ? {
@@ -95,7 +100,7 @@ export async function createLayerDefinition(
95
100
  sources: urls.map((url) => ({ url })),
96
101
  },
97
102
  properties: {
98
- id: layerId + "_geotiff_process" + processId,
103
+ id: link.id + "_process" + processId,
99
104
  title: "Results " + layerId,
100
105
  ...(layerConfig && { layerConfig: layerConfig }),
101
106
  layerControlToolsExpand: true,
@@ -136,3 +141,430 @@ export const download = (fileName, content) => {
136
141
  URL.revokeObjectURL(url);
137
142
  link.remove();
138
143
  };
144
+
145
+ /**
146
+ * Generate time pairs from a temporal extent
147
+ * @param {import("stac-ts").TemporalExtent} stacExtent - [start, end]
148
+ * @param {import("stac-ts").TemporalExtent} [userExtent] -[start, end]
149
+ * @param {string} [distribution] - daily, weekly, monthly, or yearly
150
+ */
151
+ export function generateTimePairs(stacExtent, userExtent, distribution) {
152
+ // check whether the userExtent is provided
153
+ // if it is check that it doesn't exceed the stacExtent
154
+ // and clamp it otherwise
155
+
156
+ /** @type {string|Date} */
157
+ let from = "";
158
+
159
+ /** @type {string|Date} */
160
+ let to = "";
161
+ [from, to] = /** @type {[string, string]} */ (userExtent ?? ["", ""]);
162
+
163
+ const [stacFrom, stacTo] = /** @type {[string, string]} */ (
164
+ stacExtent ?? ["", ""]
165
+ );
166
+
167
+ try {
168
+ if (from && to) {
169
+ from = new Date(from);
170
+ to = new Date(to);
171
+ } else {
172
+ from = new Date(stacFrom);
173
+ to = new Date(stacTo);
174
+ }
175
+
176
+ if (from < new Date(stacFrom) || from > new Date(stacTo)) {
177
+ console.warn(
178
+ "[eodash] warn: start date is outside of the collection temporal extent and will be clamped",
179
+ `\nprovided start date:${from.toISOString()}`,
180
+ `\ncollection start date:${stacFrom}`,
181
+ );
182
+ from = new Date(stacFrom);
183
+ }
184
+
185
+ if (to > new Date(stacTo) || to < new Date(stacFrom)) {
186
+ console.warn(
187
+ "[eodash] warn: end date is outside of the collection temporal extent and will be clamped",
188
+ `\nprovided end date:${to.toISOString()}`,
189
+ `\ncollection end date:${stacTo}`,
190
+ );
191
+ to = new Date(stacTo);
192
+ }
193
+
194
+ if (from > to) {
195
+ console.error(
196
+ "[eodash] Error: start date is greater than end date",
197
+ from,
198
+ to,
199
+ );
200
+ return [];
201
+ }
202
+ } catch (e) {
203
+ //@ts-expect-error e should be an error
204
+ console.error("[eodash] Invalid date:", e.message);
205
+ return [];
206
+ }
207
+
208
+ const startDate = /** @type {Date} */ (from).toISOString();
209
+ const endDate = /** @type {Date} */ (to).toISOString();
210
+
211
+ if (!startDate || !endDate) {
212
+ return [];
213
+ }
214
+ const times = [];
215
+ let latest = new Date(endDate);
216
+ const start = new Date(startDate);
217
+ const oneDay = 24 * 60 * 60 * 1000;
218
+ // Use fixed step of 1 day (in milliseconds)
219
+ const step =
220
+ distribution === "daily"
221
+ ? oneDay
222
+ : distribution === "weekly"
223
+ ? oneDay * 7
224
+ : distribution === "monthly"
225
+ ? oneDay * 30
226
+ : distribution === "yearly"
227
+ ? oneDay * 365
228
+ : oneDay;
229
+
230
+ // Add dates, limiting to 31 dates (30 pairs maximum)
231
+ while (latest >= start && times.length < 31) {
232
+ times.push(new Date(latest));
233
+ latest.setTime(latest.getTime() - step);
234
+ }
235
+
236
+ const timePairs = [];
237
+ for (let i = 0; i < times.length - 1; i++) {
238
+ timePairs.push([times[i].toISOString(), times[i + 1].toISOString()]);
239
+ }
240
+
241
+ return timePairs;
242
+ }
243
+
244
+ /**
245
+ * Filter links to separate those with and without endpoint property
246
+ * @param {import("stac-ts").StacLink[] | undefined} links
247
+ * @param {string} [relType] - Optional relationship type
248
+ * @param {string} [contentType] - Optional content type
249
+ * @returns {[import("stac-ts").StacLink[], import("stac-ts").StacLink[]]}
250
+ */
251
+ export function separateEndpointLinks(links, relType, contentType) {
252
+ if (!links) return [[], []];
253
+ const standardLinks = [];
254
+ const endpointLinks = [];
255
+
256
+ for (const link of links) {
257
+ // Check if the link matches the specified relType and contentType (if provided)
258
+ const relTypeMatch = relType ? link.rel === relType : true;
259
+ const contentTypeMatch = contentType ? link.type === contentType : true;
260
+
261
+ if (relTypeMatch && contentTypeMatch) {
262
+ if (link.endpoint) {
263
+ endpointLinks.push(link);
264
+ } else {
265
+ standardLinks.push(link);
266
+ }
267
+ }
268
+ }
269
+
270
+ return [standardLinks, endpointLinks];
271
+ }
272
+
273
+ /**
274
+ * Generates layer definitions for asynchronous process results.
275
+ * using AsyncProcessResults data structure.
276
+ * @param {import("^/EodashProcess/types").AsyncProcessResults} processResults
277
+ * @param {import("stac-ts").StacLink} endpointLink
278
+ * @param {import("stac-ts").StacCollection|null} selectedStac
279
+ * @param {string} [postfixId=""] - Optional layers id postfix
280
+ * @returns
281
+ */
282
+ export async function creatAsyncProcessLayerDefinitions(
283
+ processResults,
284
+ endpointLink,
285
+ selectedStac,
286
+ postfixId = "",
287
+ ) {
288
+ /** @type {import("@eox/map").EoxLayer[]} */
289
+ const layers = [];
290
+ const flatStyles = await fetchProcessStyles(endpointLink);
291
+
292
+ for (const resultItem of processResults) {
293
+ const flatStyleJSON = extractStyleFromResult(resultItem, flatStyles);
294
+ /** @type {import("@/types").EodashStyleJson | undefined} */
295
+ let style;
296
+ /** @type {Record<string, unknown> | undefined} */
297
+ let layerConfig;
298
+ if (flatStyleJSON) {
299
+ const extracted = extractLayerConfig(
300
+ selectedStac?.id ?? "",
301
+ flatStyleJSON,
302
+ );
303
+ layerConfig = extracted.layerConfig;
304
+ style = extracted.style;
305
+ }
306
+
307
+ // Check if collection has eox:colorlegend definition, if yes overwrite legend description
308
+ let extraProperties = extractLayerLegend(selectedStac);
309
+
310
+ switch (resultItem.type) {
311
+ case "image/tiff": {
312
+ layers.push({
313
+ type: "WebGLTile",
314
+ properties: {
315
+ id: endpointLink.id + "_process" + resultItem.id + postfixId,
316
+ title:
317
+ "Results " +
318
+ (selectedStac?.id ?? "") +
319
+ " " +
320
+ (resultItem.id ?? ""),
321
+ layerControlToolsExpand: true,
322
+ ...(layerConfig && { layerConfig }),
323
+ ...extraProperties,
324
+ },
325
+ source: {
326
+ type: "GeoTIFF",
327
+ normalize: !style,
328
+ sources: resultItem.urls.map((url) => ({ url })),
329
+ //@ts-expect-error TODO
330
+ ...(selectedStac["eodash:mapProjection"]?.["name"] && {
331
+ //@ts-expect-error TODO
332
+ projection: selectedStac["eodash:mapProjection"]["name"],
333
+ }),
334
+ },
335
+ ...(style && { style }),
336
+ });
337
+ break;
338
+ }
339
+ case "application/geo+json": {
340
+ const mergedUrl = await mergeGeojsons(resultItem.urls);
341
+ layers.push({
342
+ type: "Vector",
343
+ source: {
344
+ type: "Vector",
345
+ format: "GeoJSON",
346
+ ...(mergedUrl && { url: mergedUrl }),
347
+ },
348
+ properties: {
349
+ id: endpointLink.id + "_process_" + resultItem.id + postfixId,
350
+ title:
351
+ "Results " +
352
+ (selectedStac?.id ?? "") +
353
+ " " +
354
+ (resultItem.id ?? ""),
355
+ ...(layerConfig && {
356
+ layerConfig: {
357
+ ...layerConfig,
358
+ style,
359
+ },
360
+ }),
361
+ ...extraProperties,
362
+ },
363
+ ...(!style?.variables && { style }),
364
+ interactions: [],
365
+ });
366
+ break;
367
+ }
368
+ case "application/vnd.flatgeobuf": {
369
+ // TODO after more flatgeobuf urls are possible in EOxMap https://github.com/EOX-A/EOxElements/issues/1789
370
+ // we should change this handler to only create one layer instead of many
371
+ resultItem.urls.forEach((url, i) => {
372
+ layers.push({
373
+ type: "Vector",
374
+ source: {
375
+ type: "FlatGeoBuf",
376
+ url,
377
+ },
378
+ properties: {
379
+ id:
380
+ endpointLink.id +
381
+ "_process_" +
382
+ resultItem.id +
383
+ postfixId +
384
+ `_${i}`,
385
+ title:
386
+ "Results " +
387
+ (selectedStac?.id ?? "") +
388
+ " " +
389
+ (resultItem.id ?? ""),
390
+ layerControlToolsExpand: true,
391
+ ...(layerConfig && {
392
+ layerConfig: {
393
+ ...layerConfig,
394
+ style,
395
+ },
396
+ }),
397
+ ...extraProperties,
398
+ },
399
+ });
400
+ });
401
+ break;
402
+ }
403
+ default:
404
+ console.warn(
405
+ `[eodash] Unsupported result type "${resultItem.type}" for ${resultItem.id} layer creation.`,
406
+ );
407
+ break;
408
+ }
409
+ }
410
+ return layers;
411
+ }
412
+
413
+ /**
414
+ * @param {import("stac-ts").StacLink} endpointLink
415
+ * @returns
416
+ */
417
+ async function fetchProcessStyles(endpointLink) {
418
+ /** @type {import("@/types").EodashStyleJson | (Record<string,import("@/types").EodashStyleJson> & {multipleStyles:true}) | null} */
419
+ let flatStyles = null;
420
+ if (endpointLink["eox:flatstyle"]) {
421
+ if (typeof endpointLink["eox:flatstyle"] === "string") {
422
+ flatStyles = await axios
423
+ .get(/** @type {string} */ (endpointLink["eox:flatstyle"]))
424
+ .then((resp) => /** @type {} */ resp.data);
425
+ } else if (
426
+ Array.isArray(endpointLink["eox:flatstyle"]) &&
427
+ endpointLink["eox:flatstyle"].length
428
+ ) {
429
+ // multipleStyles as a flag to indicate it
430
+ flatStyles = { multipleStyles: true };
431
+
432
+ await Promise.all(
433
+ /** @type {{id:string;url:string}[]} */
434
+ (endpointLink["eox:flatstyle"]).map(async (styleDict) => {
435
+ //@ts-expect-error TODO
436
+ flatStyles[styleDict.id] = await axios
437
+ .get(styleDict.url)
438
+ .then(
439
+ (resp) =>
440
+ /** @type {import("@/types").EodashStyleJson} */ (resp.data),
441
+ );
442
+ }),
443
+ );
444
+ } else {
445
+ // multipleStyles as a flag to indicate it
446
+ flatStyles = { multipleStyles: true };
447
+ await Promise.all(
448
+ Object.keys(endpointLink["eox:flatstyle"] ?? {}).map((key) => {
449
+ //@ts-expect-error TODO
450
+ flatStyles[key] = axios
451
+ //@ts-expect-error TODO
452
+ .get(endpointLink["eox:flatstyle"][key])
453
+ .then((resp) => resp.data);
454
+ }),
455
+ );
456
+ }
457
+ }
458
+ return flatStyles;
459
+ }
460
+
461
+ /**
462
+ *
463
+ * @param {import("^/EodashProcess/types").AsyncProcessResults[number]} processResult
464
+ * @param {null| import("@/types").EodashStyleJson | (Record<string,import("@/types").EodashStyleJson> & {multipleStyles:true})} flatStyles
465
+ */
466
+ function extractStyleFromResult(processResult, flatStyles) {
467
+ if (!flatStyles) {
468
+ return undefined;
469
+ }
470
+ if (!("multipleStyles" in flatStyles)) {
471
+ return flatStyles;
472
+ }
473
+
474
+ const outputKey = processResult.id;
475
+ if (!outputKey || !(outputKey in flatStyles)) {
476
+ return undefined;
477
+ }
478
+ return flatStyles[outputKey];
479
+ }
480
+
481
+ /**
482
+ *
483
+ * @param {import("^/EodashProcess/types").EOxHubProcessResults} resultItem
484
+ * @returns {import("^/EodashProcess/types").AsyncProcessResults}
485
+ */
486
+ export function extractAsyncResults(resultItem) {
487
+ if (!resultItem) {
488
+ return [];
489
+ }
490
+ // if no type specified we assume the results are geotiff sources
491
+ if ("urls" in resultItem && Array.isArray(resultItem.urls)) {
492
+ return [{ id: "", urls: resultItem.urls, type: "image/tiff" }];
493
+ }
494
+
495
+ const extracted = [];
496
+ for (const key in resultItem) {
497
+ if (key === "id") {
498
+ continue;
499
+ }
500
+ extracted.push({
501
+ // used as a key to identify the corresponding style
502
+ id: key,
503
+ //@ts-expect-error TODO
504
+ urls: /** @type {string[]} */ (resultItem[key].urls),
505
+ //@ts-expect-error TODO
506
+ type: /** @type {string} */ (resultItem[key].mimetype),
507
+ });
508
+ }
509
+ return extracted;
510
+ }
511
+ /**
512
+ * @param {import("@eox/map").EOxMap | null} mapElement
513
+ * @param {import("@eox/map").EoxLayer[]} processLayers
514
+ */
515
+ export const applyProcessLayersToMap = (mapElement, processLayers) => {
516
+ if (!processLayers.length || !mapElement) {
517
+ return;
518
+ }
519
+ const getMapLayers =
520
+ mapElement.id === "compare" ? getCompareLayers : getLayers;
521
+ const currentLayers = [...getMapLayers()];
522
+
523
+ let analysisGroup =
524
+ /*** @type {import("@eox/map/src/layers").EOxLayerTypeGroup | undefined} */ (
525
+ currentLayers.find((l) => l.properties?.id.includes("AnalysisGroup"))
526
+ );
527
+ if (!analysisGroup) {
528
+ return;
529
+ }
530
+
531
+ for (const layer of processLayers) {
532
+ const exists = analysisGroup.layers.find(
533
+ (l) => l.properties?.id === layer.properties?.id,
534
+ );
535
+ if (!exists) {
536
+ analysisGroup.layers.unshift(layer);
537
+ } else {
538
+ analysisGroup.layers = replaceLayer(
539
+ analysisGroup.layers,
540
+ layer.properties?.id ?? "",
541
+ [layer],
542
+ );
543
+ }
544
+ }
545
+ if (mapElement) {
546
+ const layers = [...currentLayers];
547
+ const evtKey =
548
+ mapElement.id === "compare"
549
+ ? "compareProcess:updated"
550
+ : "process:updated";
551
+ useEmitLayersUpdate(evtKey, mapElement, layers);
552
+ mapElement.layers = layers;
553
+ }
554
+ };
555
+ /**
556
+ * Updates the jsonform schema to target the compare map
557
+ * @param {import("json-schema").JSONSchema7 | null | undefined} jsonformSchema
558
+ */
559
+ export function updateJsonformSchemaTarget(jsonformSchema) {
560
+ if (!jsonformSchema) {
561
+ return jsonformSchema;
562
+ }
563
+ const stringified = JSON.stringify(jsonformSchema).replaceAll(
564
+ "eox-map#main",
565
+ "eox-map#compare",
566
+ );
567
+ return /** @type {import("json-schema").JSONSchema7} */ (
568
+ JSON.parse(stringified)
569
+ );
570
+ }
@@ -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({