@eodash/eodash 5.0.0-rc.2.4 → 5.0.0-rc.3

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 (80) hide show
  1. package/core/client/composables/DefineWidgets.js +8 -1
  2. package/core/client/eodash.js +9 -9
  3. package/core/client/eodashSTAC/createLayers.js +4 -17
  4. package/core/client/eodashSTAC/helpers.js +23 -0
  5. package/core/client/store/stac.js +3 -1
  6. package/core/client/types.ts +127 -21
  7. package/core/client/utils/states.js +9 -0
  8. package/core/client/vite-env.d.ts +0 -13
  9. package/dist/client/{DashboardLayout-D1UcB3RV.js → DashboardLayout-t_PavJPO.js} +2 -2
  10. package/dist/client/{DynamicWebComponent-DtZ_mHL9.js → DynamicWebComponent-y07rVJch.js} +1 -1
  11. package/dist/client/{EodashDatePicker-CYU0MZX5.js → EodashDatePicker-CcOfyzGD.js} +3 -83
  12. package/dist/client/{EodashItemFilter-SE9oW3oZ.js → EodashItemFilter-B9HCvIMi.js} +1 -1
  13. package/dist/client/{EodashLayerControl-BuGe29Nt.js → EodashLayerControl-KStn7Nb_.js} +8 -2
  14. package/dist/client/{EodashLayoutSwitcher-6wLl-Gtd.js → EodashLayoutSwitcher-DqeFO3RN.js} +2 -2
  15. package/dist/client/{EodashMapBtns-BWWu6eHG.js → EodashMapBtns-5BF27qJB.js} +36 -12
  16. package/dist/client/{EodashStacInfo-DjRSGLHM.js → EodashStacInfo-C_hDy6Pd.js} +7 -1
  17. package/dist/client/{EodashTools-CJ4hBH_X.js → EodashTools-BXflvRf8.js} +5 -4
  18. package/dist/client/{ExportState-BqnlEpzR.js → ExportState-C0QRemK1.js} +27 -12
  19. package/dist/client/{Footer-C_3WrfI4.js → Footer-7VGyGUAs.js} +1 -1
  20. package/dist/client/{Header-D_hcGpNG.js → Header-BQJnXHYq.js} +3 -3
  21. package/dist/client/{MobileLayout-CDbupC9v.js → MobileLayout-b8nQ-Vyl.js} +5 -5
  22. package/dist/client/{PopUp-Ba6mY2jQ.js → PopUp-DgNrh9Df.js} +3 -3
  23. package/dist/client/ProcessList-C62SOVO6.js +484 -0
  24. package/dist/client/{VImg-Yc9F9pYq.js → VImg-D4eT3IQ1.js} +2 -2
  25. package/dist/client/{VMain-BiS7HPEk.js → VMain-C3hN2-H3.js} +1 -1
  26. package/dist/client/{VOverlay-B9mxXaCv.js → VOverlay-tAeNygaA.js} +15 -6
  27. package/dist/client/{VTooltip-XJLaLrZQ.js → VTooltip-B0Q3iHMZ.js} +3 -3
  28. package/dist/client/{WidgetsContainer-DRVb_73N.js → WidgetsContainer-CtDHfCYf.js} +1 -1
  29. package/dist/client/{asWebComponent-DZpMGxEY.js → asWebComponent-BJ2NWunV.js} +100 -95
  30. package/dist/client/eo-dash.css +2 -2
  31. package/dist/client/eo-dash.js +1 -1
  32. package/dist/client/{forwardRefs-BtkfywIE.js → forwardRefs-CIFAqXaZ.js} +9 -9
  33. package/dist/client/{EodashMap-DhVCoYMi.js → index-BQ16n4Sk.js} +103 -78
  34. package/dist/client/index-Cv7HBz49.js +85 -0
  35. package/dist/client/{EodashProcess-GSj_LMsK.js → index-Da5xXX6Q.js} +349 -443
  36. package/dist/client/{index-f55xuyof.js → index-DvcUndod.js} +1 -1
  37. package/dist/client/{transition-CtL4BoVi.js → transition-Cdb4K27U.js} +1 -1
  38. package/dist/types/core/client/components/MobileLayout.vue.d.ts +9 -9
  39. package/dist/types/core/client/eodashSTAC/EodashCollection.d.ts +11 -6
  40. package/dist/types/core/client/eodashSTAC/createLayers.d.ts +6 -5
  41. package/dist/types/core/client/eodashSTAC/helpers.d.ts +383 -2
  42. package/dist/types/core/client/types.d.ts +85 -19
  43. package/dist/types/core/client/utils/states.d.ts +7 -0
  44. package/dist/types/widgets/EodashDatePicker.vue.d.ts +4 -4
  45. package/dist/types/widgets/EodashItemFilter.vue.d.ts +18 -18
  46. package/dist/types/widgets/EodashLayerControl.vue.d.ts +2 -2
  47. package/dist/types/widgets/EodashLayoutSwitcher.vue.d.ts +2 -2
  48. package/dist/types/widgets/EodashMap/methods/create-layers-config.d.ts +9 -0
  49. package/dist/types/widgets/EodashMap/methods/index.d.ts +5 -0
  50. package/dist/types/widgets/EodashMapBtns.vue.d.ts +8 -2
  51. package/dist/types/widgets/EodashProcess/ProcessList.vue.d.ts +2 -0
  52. package/dist/types/widgets/EodashProcess/methods/async.d.ts +45 -0
  53. package/dist/types/widgets/EodashProcess/methods/composables.d.ts +19 -0
  54. package/dist/types/widgets/EodashProcess/methods/handling.d.ts +78 -0
  55. package/dist/types/widgets/EodashProcess/methods/outputs.d.ts +54 -0
  56. package/dist/types/widgets/EodashProcess/methods/utils.d.ts +42 -0
  57. package/dist/types/widgets/EodashStacInfo.vue.d.ts +12 -12
  58. package/dist/types/widgets/EodashTools.vue.d.ts +44 -6
  59. package/dist/types/widgets/PopUp.vue.d.ts +4 -4
  60. package/package.json +30 -29
  61. package/widgets/EodashLayerControl.vue +8 -1
  62. package/widgets/{EodashMap.vue → EodashMap/index.vue} +53 -29
  63. package/widgets/EodashMap/methods/create-layers-config.js +151 -0
  64. package/{core/client/composables/EodashMap.js → widgets/EodashMap/methods/index.js} +4 -153
  65. package/widgets/EodashMapBtns.vue +33 -7
  66. package/widgets/EodashProcess/ProcessList.vue +82 -0
  67. package/widgets/EodashProcess/index.vue +186 -0
  68. package/widgets/EodashProcess/methods/async.js +209 -0
  69. package/widgets/EodashProcess/methods/composables.js +129 -0
  70. package/widgets/EodashProcess/methods/handling.js +254 -0
  71. package/widgets/EodashProcess/methods/outputs.js +216 -0
  72. package/widgets/EodashProcess/methods/utils.js +138 -0
  73. package/widgets/EodashStacInfo.vue +6 -0
  74. package/widgets/EodashTools.vue +1 -0
  75. package/core/client/composables/EodashProcess.js +0 -624
  76. package/dist/types/core/client/composables/EodashMap.d.ts +0 -6
  77. package/dist/types/core/client/composables/EodashProcess.d.ts +0 -162
  78. package/widgets/EodashProcess.vue +0 -208
  79. /package/dist/types/widgets/{EodashMap.vue.d.ts → EodashMap/index.vue.d.ts} +0 -0
  80. /package/dist/types/widgets/{EodashProcess.vue.d.ts → EodashProcess/index.vue.d.ts} +0 -0
@@ -0,0 +1,484 @@
1
+ import { ref, createVNode, toRefs, onMounted, createElementBlock, openBlock, createBlock, createCommentVNode, unref, withCtx, createElementVNode, Fragment, renderList, toDisplayString, withDirectives } from 'vue';
2
+ import { mdiUploadBox, mdiDownloadBox, mdiTrashCanOutline } from '@mdi/js';
3
+ import { ai as axios, ak as extractLayerConfig, am as axios$1, aj as indicator, al as getLayers, a3 as mapEl, g as genericComponent, p as propsFactory, b as provideTheme, A as useDensity, a as useRender, f as makeThemeProps, h as makeTagProps, D as makeDensityProps, i as makeComponentProps, q as convertToUnit, Z as useSTAcStore, V as VBtn } from './asWebComponent-BJ2NWunV.js';
4
+ import { isMulti } from '@eox/jsonform/src/custom-inputs/spatial/utils';
5
+ import log from 'loglevel';
6
+ import { T as Tooltip } from './index-Cv7HBz49.js';
7
+
8
+ /**
9
+ * @param {Record<string,any> |null} [jsonformSchema]
10
+ **/
11
+ function getBboxProperty(jsonformSchema) {
12
+ return /** @type {string} */ (
13
+ Object.keys(jsonformSchema?.properties ?? {}).find(
14
+ (key) => jsonformSchema?.properties[key].format === "bounding-box",
15
+ )
16
+ );
17
+ }
18
+
19
+ /**
20
+ * Extracts the keys of type "geojson" from the jsonform schema
21
+ * @param {Record<string,any> |null} [jsonformSchema]
22
+ **/
23
+ function getGeoJsonProperties(jsonformSchema) {
24
+ return /** @type {string[]} */ (
25
+ Object.keys(jsonformSchema?.properties ?? {}).filter(
26
+ (key) => jsonformSchema?.properties[key].type === "geojson",
27
+ )
28
+ );
29
+ }
30
+
31
+ /**
32
+ * Converts jsonform geojson values to stringified geometries
33
+ * @param {Record<string,any> |null} [jsonformSchema]
34
+ * @param {Record<string,any>} jsonformValue
35
+ **/
36
+ function extractGeometries(jsonformValue, jsonformSchema) {
37
+ const geojsonKeys = getGeoJsonProperties(jsonformSchema);
38
+
39
+ for (const key of geojsonKeys) {
40
+ if (!jsonformValue[key]) {
41
+ continue;
42
+ }
43
+
44
+ if (isMulti(jsonformSchema?.properties[key])) {
45
+ // jsonformValue[key] is a feature collection
46
+ jsonformValue[key] =
47
+ /** @type {import("ol/format/GeoJSON").GeoJSONFeatureCollection} */ (
48
+ jsonformValue[key]
49
+ ).features.map((feature) => JSON.stringify(feature.geometry));
50
+ } else {
51
+ // jsonformValue[key] is a single feature
52
+ jsonformValue[key] = JSON.stringify(jsonformValue[key].geometry);
53
+ }
54
+ }
55
+ }
56
+
57
+ /**
58
+ *
59
+ * @param {*} link
60
+ * @param {*} layerId
61
+ * @param {string[]} urls
62
+ * @param {*} projection
63
+ * @param {*} processId
64
+ * @returns
65
+ */
66
+ async function createLayerDefinition(
67
+ link,
68
+ layerId,
69
+ urls,
70
+ projection,
71
+ processId,
72
+ ) {
73
+ let flatStyleJSON = null;
74
+ if ("eox:flatstyle" in (link ?? {})) {
75
+ flatStyleJSON = await axios
76
+ .get(/** @type {string} */ (link["eox:flatstyle"]))
77
+ .then((resp) => resp.data);
78
+ }
79
+
80
+ /** @type {Record<string,any>|undefined} */
81
+ let layerConfig;
82
+ /** @type {Record<string,any>|undefined} */
83
+ let style;
84
+ if (flatStyleJSON) {
85
+ const extracted = extractLayerConfig(layerId ?? "", flatStyleJSON);
86
+ layerConfig = extracted.layerConfig;
87
+ style = extracted.style;
88
+ }
89
+ // We want to make sure the urls are alphabetically sorted
90
+ urls = urls.sort();
91
+ const layerdef =
92
+ urls.length > 0
93
+ ? {
94
+ type: "WebGLTile",
95
+ source: {
96
+ type: "GeoTIFF",
97
+ normalize: !style,
98
+ sources: urls.map((url) => ({ url })),
99
+ },
100
+ properties: {
101
+ id: layerId + "_geotiff_process" + processId,
102
+ title: "Results " + layerId,
103
+ ...(layerConfig && { layerConfig: layerConfig }),
104
+ layerControlToolsExpand: true,
105
+ },
106
+ ...(style && { style: style }),
107
+ }
108
+ : undefined;
109
+
110
+ // We want to see if the currently selected indicator uses a
111
+ // specific map projection if it does we want to apply it
112
+ if (projection && layerdef) {
113
+ //@ts-expect-error TODO
114
+ layerdef.source.projection = projection;
115
+ }
116
+ return layerdef;
117
+ }
118
+ /**
119
+ * @param {string} fileName
120
+ * @param {string|Record<string,any>} content
121
+ * @returns
122
+ */
123
+ const download = (fileName, content) => {
124
+ if (!content) {
125
+ return;
126
+ }
127
+ let url = /** @type string */ (content);
128
+ if (typeof content === "object") {
129
+ content = JSON.stringify(content);
130
+ const blob = new Blob([content], { type: "text" });
131
+ url = URL.createObjectURL(blob);
132
+ }
133
+ const link = document.createElement("a");
134
+ if (confirm(`Would you like to download ${fileName}?`)) {
135
+ link.href = url;
136
+ link.download = fileName;
137
+ link.click();
138
+ }
139
+ URL.revokeObjectURL(url);
140
+ link.remove();
141
+ };
142
+
143
+ /**
144
+ * The list of job result from the server
145
+ * {job_start_datetime: string, job_end_datetime: string,status: string}
146
+ * @type {import("vue").Ref<any[]>}
147
+ **/
148
+ const jobs = ref([]);
149
+
150
+ /**
151
+ * Polls the process status and fetches a result item when the process is successful.
152
+ *
153
+ * @param {Object} params - Parameters for polling the process status.
154
+ * @param {string} params.processUrl - The URL of the process JSON report.
155
+ * @param {import("vue").Ref<boolean>} params.isPolling - checks wether the polling should continue
156
+ * @param {number} [params.pollInterval=5000] - The interval (in milliseconds) between polling attempts.
157
+ * @param {number} [params.maxRetries=60] - The maximum number of polling attempts.
158
+ * @returns {Promise<JSON>} The fetched results JSON.
159
+ * @throws {Error} If the process does not complete successfully within the maximum retries.
160
+ */
161
+ async function pollProcessStatus({
162
+ processUrl,
163
+ isPolling,
164
+ pollInterval = 10000,
165
+ maxRetries = 560,
166
+ }) {
167
+ let retries = 0;
168
+ isPolling.value = true;
169
+ setTimeout(() => {
170
+ updateJobsStatus(jobs, indicator);
171
+ }, 500);
172
+ while (retries < maxRetries && isPolling.value) {
173
+ try {
174
+ // Fetch the process JSON report
175
+ const cacheBuster = new Date().getTime(); // Add a timestamp for cache busting
176
+ const response = await axios$1.get(`${processUrl}?t=${cacheBuster}`);
177
+ const processReport = response.data;
178
+
179
+ // Check if the status is "successful"
180
+ if (processReport.status === "successful") {
181
+ console.log("Process completed successfully. Fetching result item...");
182
+
183
+ // Extract the result item URL
184
+ const resultsUrl = processReport.links[1].href;
185
+ if (!resultsUrl) {
186
+ throw new Error(`Result links not found in the process report.`);
187
+ }
188
+
189
+ // Fetch the result item
190
+ const resultResponse = await axios$1.get(resultsUrl);
191
+ console.log("Result file fetched successfully:", resultResponse.data);
192
+ return resultResponse.data; // Return the json result list
193
+ }
194
+ if (processReport.status === "failed") {
195
+ isPolling.value = false;
196
+ throw new Error("Process failed.", processReport);
197
+ }
198
+
199
+ // Log the current status if not successful
200
+ console.log(
201
+ `Status: ${processReport.status}. Retrying in ${pollInterval / 1000} seconds...`,
202
+ );
203
+ } catch (error) {
204
+ if (error instanceof Error) {
205
+ console.error("Error while polling process status:", error.message);
206
+ } else {
207
+ console.error("Unknown error occurred:", error);
208
+ }
209
+ }
210
+
211
+ // Wait for the next poll
212
+ await new Promise((resolve) => setTimeout(resolve, pollInterval));
213
+ retries++;
214
+ }
215
+ if (!isPolling.value) {
216
+ console.warn("Polling was stopped before the process was completed.");
217
+ return JSON.parse("{}");
218
+ }
219
+
220
+ throw new Error(
221
+ "Max retries reached. Process did not complete successfully.",
222
+ );
223
+ }
224
+
225
+ /**
226
+ *
227
+ * @param {*} jobs
228
+ * @param {*} indicator
229
+ */
230
+ async function updateJobsStatus(jobs, indicator) {
231
+ /** @type {string[]} */
232
+ const jobsUrls = JSON.parse(localStorage.getItem(indicator.value) || "[]");
233
+ const jobResults = await Promise.all(
234
+ jobsUrls.map((url) => fetch(url).then((response) => response.json())),
235
+ );
236
+ jobResults.sort((a, b) => {
237
+ return (
238
+ new Date(b.job_start_datetime).getTime() -
239
+ new Date(a.job_start_datetime).getTime()
240
+ );
241
+ });
242
+ jobs.value = jobResults;
243
+ }
244
+
245
+ /**
246
+ * Removes a job from the local storage and updates the job status
247
+ * @param {*} jobObject
248
+ */
249
+ const deleteJob = async (jobObject) => {
250
+ /** @type {string[]} */
251
+ const jobsUrls = JSON.parse(localStorage.getItem(indicator.value) || "[]");
252
+ const newJobs = jobsUrls.filter((url) => !url.includes(jobObject.jobID));
253
+ localStorage.setItem(indicator.value, JSON.stringify(newJobs));
254
+ updateJobsStatus(jobs, indicator);
255
+ };
256
+
257
+ /**
258
+ * Downloads an existing process results
259
+ * @param {*} jobObject
260
+ * @param {*} selectedStac
261
+ */
262
+ const downloadPreviousResults = async (jobObject, selectedStac) => {
263
+ /** @type {any[]} */
264
+ const results = [];
265
+ await fetch(jobObject.links[1].href)
266
+ .then((response) => response.json())
267
+ .then((data) => {
268
+ results.push(...data.urls);
269
+ });
270
+ results.forEach((result) => {
271
+ if (!result) {
272
+ return;
273
+ }
274
+ let fileName = "";
275
+ if (typeof result === "string") {
276
+ fileName = result.includes("/")
277
+ ? (result.split("/").pop() ?? "")
278
+ : result;
279
+ fileName = fileName.includes("?") ? fileName.split("?")[0] : fileName;
280
+ } else {
281
+ fileName = selectedStac?.id + "_process_results.json";
282
+ }
283
+ download(fileName, result);
284
+ });
285
+ };
286
+
287
+ /**
288
+ * Load the process results and update the map layers.
289
+ *
290
+ * @async
291
+ * @param {*} jobObject
292
+ * @param {*} selectedStac
293
+ */
294
+ const loadProcess = async (jobObject, selectedStac) => {
295
+ /** @type {any[]} */
296
+ const results = [];
297
+ await axios$1
298
+ .get(jobObject.links[1].href)
299
+ .then((response) => results.push(response.data));
300
+
301
+ await loadPreviousProcess({
302
+ selectedStac,
303
+ results,
304
+ jobId: jobObject.jobID,
305
+ });
306
+ };
307
+
308
+ /**
309
+ * load a geotiff to the map from an existing process
310
+ *
311
+ * @param {Object} params
312
+ * @param {import("stac-ts").StacCollection | null} params.selectedStac
313
+ * @param {any[]} params.results
314
+ * @param {string} params.jobId
315
+ */
316
+ async function loadPreviousProcess({ selectedStac, results, jobId }) {
317
+ const geotiffLinks = selectedStac?.links.filter(
318
+ (link) => link.rel === "service" && link.type === "image/tiff",
319
+ );
320
+ // const stacProjection = selectedStac
321
+ const geotiffLayer = await createLayerDefinition(
322
+ geotiffLinks?.[0],
323
+ selectedStac?.id ?? "",
324
+ results?.[0].urls,
325
+ //@ts-expect-error TODO
326
+ selectedStac?.["eodash:mapProjection"]?.["name"] ?? null,
327
+ jobId,
328
+ );
329
+
330
+ log.debug("rendered layers after loading previous process:", geotiffLayer);
331
+
332
+ if (geotiffLayer) {
333
+ const layers = [...(geotiffLayer ? [geotiffLayer] : [])];
334
+ let currentLayers = [...getLayers()];
335
+ let analysisGroup = currentLayers.find((l) =>
336
+ l.properties.id.includes("AnalysisGroup"),
337
+ );
338
+ analysisGroup?.layers.push(...layers);
339
+
340
+ if (mapEl.value) {
341
+ mapEl.value.layers = [...currentLayers];
342
+ }
343
+ }
344
+ }
345
+
346
+ const makeVTableProps = propsFactory({
347
+ fixedHeader: Boolean,
348
+ fixedFooter: Boolean,
349
+ height: [Number, String],
350
+ hover: Boolean,
351
+ ...makeComponentProps(),
352
+ ...makeDensityProps(),
353
+ ...makeTagProps(),
354
+ ...makeThemeProps()
355
+ }, 'VTable');
356
+ const VTable = genericComponent()({
357
+ name: 'VTable',
358
+ props: makeVTableProps(),
359
+ setup(props, _ref) {
360
+ let {
361
+ slots,
362
+ emit
363
+ } = _ref;
364
+ const {
365
+ themeClasses
366
+ } = provideTheme(props);
367
+ const {
368
+ densityClasses
369
+ } = useDensity(props);
370
+ useRender(() => createVNode(props.tag, {
371
+ "class": ['v-table', {
372
+ 'v-table--fixed-height': !!props.height,
373
+ 'v-table--fixed-header': props.fixedHeader,
374
+ 'v-table--fixed-footer': props.fixedFooter,
375
+ 'v-table--has-top': !!slots.top,
376
+ 'v-table--has-bottom': !!slots.bottom,
377
+ 'v-table--hover': props.hover
378
+ }, themeClasses.value, densityClasses.value, props.class],
379
+ "style": props.style
380
+ }, {
381
+ default: () => [slots.top?.(), slots.default ? createVNode("div", {
382
+ "class": "v-table__wrapper",
383
+ "style": {
384
+ height: convertToUnit(props.height)
385
+ }
386
+ }, [createVNode("table", null, [slots.default()])]) : slots.wrapper?.(), slots.bottom?.()]
387
+ }));
388
+ return {};
389
+ }
390
+ });
391
+
392
+ const _hoisted_1 = { style: {"padding":"0px"} };
393
+ const _hoisted_2 = { style: {"padding":"0px"} };
394
+ const _hoisted_3 = { style: {"padding":"0px"} };
395
+
396
+
397
+ const _sfc_main = {
398
+ __name: 'ProcessList',
399
+ setup(__props) {
400
+
401
+ const { selectedStac } = toRefs(useSTAcStore());
402
+
403
+ onMounted(() => updateJobsStatus(jobs, indicator));
404
+
405
+ return (_ctx, _cache) => {
406
+
407
+
408
+
409
+
410
+ return (openBlock(), createElementBlock("div", null, [
411
+ (unref(jobs).length)
412
+ ? (openBlock(), createBlock(VTable, {
413
+ key: 0,
414
+ density: "compact",
415
+ style: {"background-color":"transparent"}
416
+ }, {
417
+ default: withCtx(() => [
418
+ _cache[0] || (_cache[0] = createElementVNode("thead", null, [
419
+ createElementVNode("tr", null, [
420
+ createElementVNode("th", { class: "text-left" }, "Executed on"),
421
+ createElementVNode("th", { class: "text-left" }, "Status"),
422
+ createElementVNode("th", { class: "text-left" }),
423
+ createElementVNode("th", { class: "text-left" }),
424
+ createElementVNode("th", { class: "text-left" })
425
+ ])
426
+ ], -1 /* HOISTED */)),
427
+ createElementVNode("tbody", null, [
428
+ (openBlock(true), createElementBlock(Fragment, null, renderList(unref(jobs), (item) => {
429
+ return (openBlock(), createElementBlock("tr", {
430
+ key: item.date
431
+ }, [
432
+ createElementVNode("td", null, toDisplayString(new Date(item.job_start_datetime).toISOString().slice(0, 16)), 1 /* TEXT */),
433
+ createElementVNode("td", null, toDisplayString(item.status), 1 /* TEXT */),
434
+ createElementVNode("td", _hoisted_1, [
435
+ withDirectives(createVNode(VBtn, {
436
+ disabled: item.status !== 'successful',
437
+ color: "primary",
438
+ onClick: $event => (unref(loadProcess)(item, unref(selectedStac))),
439
+ icon: [unref(mdiUploadBox)],
440
+ variant: "text"
441
+ }, null, 8 /* PROPS */, ["disabled", "onClick", "icon"]), [
442
+ [Tooltip, 'Load results to map']
443
+ ])
444
+ ]),
445
+ createElementVNode("td", _hoisted_2, [
446
+ withDirectives(createVNode(VBtn, {
447
+ disabled: item.status !== 'successful',
448
+ color: "primary",
449
+ onClick: $event => (unref(downloadPreviousResults)(item, unref(selectedStac))),
450
+ icon: [unref(mdiDownloadBox)],
451
+ variant: "text"
452
+ }, null, 8 /* PROPS */, ["disabled", "onClick", "icon"]), [
453
+ [Tooltip, 'Download results']
454
+ ])
455
+ ]),
456
+ createElementVNode("td", _hoisted_3, [
457
+ withDirectives(createVNode(VBtn, {
458
+ color: "#ff5252",
459
+ onClick: $event => (unref(deleteJob)(item)),
460
+ icon: [unref(mdiTrashCanOutline)],
461
+ variant: "text"
462
+ }, null, 8 /* PROPS */, ["onClick", "icon"]), [
463
+ [Tooltip, 'Remove job']
464
+ ])
465
+ ])
466
+ ]))
467
+ }), 128 /* KEYED_FRAGMENT */))
468
+ ])
469
+ ]),
470
+ _: 1 /* STABLE */
471
+ }))
472
+ : createCommentVNode("v-if", true)
473
+ ]))
474
+ }
475
+ }
476
+
477
+ };
478
+
479
+ const ProcessList = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
480
+ __proto__: null,
481
+ default: _sfc_main
482
+ }, Symbol.toStringTag, { value: 'Module' }));
483
+
484
+ export { ProcessList as P, _sfc_main as _, createLayerDefinition as c, download as d, extractGeometries as e, getBboxProperty as g, jobs as j, pollProcessStatus as p, updateJobsStatus as u };
@@ -1,6 +1,6 @@
1
1
  import { createVNode, computed, toRef, shallowRef, ref, watch, onBeforeMount, nextTick, onBeforeUnmount, withDirectives, mergeProps, Fragment, resolveDirective, vShow } from 'vue';
2
- import { aH as SUPPORTS_INTERSECTION, g as genericComponent, p as propsFactory, H as useDimension, a as useRender, J as makeDimensionProps, i as makeComponentProps, B as useBackgroundColor, M as useRounded, aI as getCurrentInstance, q as convertToUnit, O as makeRoundedProps } from './asWebComponent-DZpMGxEY.js';
3
- import { m as makeTransitionProps, M as MaybeTransition } from './transition-CtL4BoVi.js';
2
+ import { aL as SUPPORTS_INTERSECTION, g as genericComponent, p as propsFactory, H as useDimension, a as useRender, J as makeDimensionProps, i as makeComponentProps, B as useBackgroundColor, M as useRounded, aM as getCurrentInstance, q as convertToUnit, O as makeRoundedProps } from './asWebComponent-BJ2NWunV.js';
3
+ import { m as makeTransitionProps, M as MaybeTransition } from './transition-Cdb4K27U.js';
4
4
 
5
5
  // Utilities
6
6
  function mounted(el, binding) {
@@ -1,5 +1,5 @@
1
1
  import { createVNode } from 'vue';
2
- import { g as genericComponent, p as propsFactory, H as useDimension, G as useLayout, a as useRender, h as makeTagProps, J as makeDimensionProps, i as makeComponentProps } from './asWebComponent-DZpMGxEY.js';
2
+ import { g as genericComponent, p as propsFactory, H as useDimension, G as useLayout, a as useRender, h as makeTagProps, J as makeDimensionProps, i as makeComponentProps } from './asWebComponent-BJ2NWunV.js';
3
3
  import { u as useSsrBoot } from './ssrBoot-BP7SYRyC.js';
4
4
 
5
5
  const makeVMainProps = propsFactory({
@@ -1,7 +1,7 @@
1
1
  import { computed, watch, onScopeDispose, nextTick, ref, watchEffect, effectScope, inject, mergeProps, shallowRef, onMounted, reactive, provide, toRaw, readonly, warn, toRef, onBeforeUnmount, createVNode, Fragment, Teleport, withDirectives, vShow, resolveDirective, Transition } from 'vue';
2
- import { aK as isOn, aL as eventName, p as propsFactory, aM as destructComputed, aN as parseAnchor, aO as flipSide, aP as flipAlign, aQ as flipCorner, Y as consoleError, aR as getAxis, q as convertToUnit, R as clamp, I as IN_BROWSER, T as useToggleScope, aS as defer, aI as getCurrentInstance, aT as templateRef, aU as matchesSelector, r as useDisplay, f as makeThemeProps, J as makeDimensionProps, i as makeComponentProps, g as genericComponent, j as useProxiedModel, b as provideTheme, c as useRtl, B as useBackgroundColor, H as useDimension, aV as useRouter, aW as useBackButton, a as useRender } from './asWebComponent-DZpMGxEY.js';
3
- import { g as getTargetBox, B as Box, e as getOverflow, n as nullifyTransforms, m as makeLazyProps, u as useLazy, b as useScopeId, a as animate, s as standardEasing } from './forwardRefs-BtkfywIE.js';
4
- import { m as makeTransitionProps, M as MaybeTransition } from './transition-CtL4BoVi.js';
2
+ import { aO as isOn, aP as eventName, p as propsFactory, aQ as destructComputed, aR as parseAnchor, aS as flipSide, aT as flipAlign, aU as flipCorner, an as consoleError, aV as getAxis, q as convertToUnit, R as clamp, I as IN_BROWSER, T as useToggleScope, aW as defer, aM as getCurrentInstance, aX as templateRef, aY as matchesSelector, r as useDisplay, f as makeThemeProps, J as makeDimensionProps, i as makeComponentProps, g as genericComponent, j as useProxiedModel, b as provideTheme, c as useRtl, B as useBackgroundColor, H as useDimension, aZ as useRouter, a_ as useBackButton, a as useRender } from './asWebComponent-BJ2NWunV.js';
3
+ import { g as getTargetBox, B as Box, e as getOverflow, n as nullifyTransforms, m as makeLazyProps, u as useLazy, b as useScopeId, a as animate, s as standardEasing } from './forwardRefs-CIFAqXaZ.js';
4
+ import { m as makeTransitionProps, M as MaybeTransition } from './transition-Cdb4K27U.js';
5
5
 
6
6
  // Utilities
7
7
  const handlers = new WeakMap();
@@ -1112,10 +1112,10 @@ function useStack(isActive, zIndex, disableGlobalStack) {
1112
1112
  activeChildren: new Set()
1113
1113
  });
1114
1114
  provide(StackSymbol, stack);
1115
- const _zIndex = shallowRef(+zIndex.value);
1115
+ const _zIndex = shallowRef(Number(zIndex.value));
1116
1116
  useToggleScope(isActive, () => {
1117
1117
  const lastZIndex = globalStack.at(-1)?.[1];
1118
- _zIndex.value = lastZIndex ? lastZIndex + 10 : +zIndex.value;
1118
+ _zIndex.value = lastZIndex ? lastZIndex + 10 : Number(zIndex.value);
1119
1119
  if (createStackEntry) {
1120
1120
  globalStack.push([vm.uid, _zIndex.value]);
1121
1121
  }
@@ -1229,6 +1229,7 @@ const VOverlay = genericComponent()({
1229
1229
  emits: {
1230
1230
  'click:outside': e => true,
1231
1231
  'update:modelValue': value => true,
1232
+ keydown: e => true,
1232
1233
  afterEnter: () => true,
1233
1234
  afterLeave: () => true
1234
1235
  },
@@ -1341,6 +1342,9 @@ const VOverlay = genericComponent()({
1341
1342
  });
1342
1343
  function onKeydown(e) {
1343
1344
  if (e.key === 'Escape' && globalTop.value) {
1345
+ if (!contentEl.value?.contains(document.activeElement)) {
1346
+ emit('keydown', e);
1347
+ }
1344
1348
  if (!props.persistent) {
1345
1349
  isActive.value = false;
1346
1350
  if (contentEl.value?.contains(document.activeElement)) {
@@ -1349,6 +1353,10 @@ const VOverlay = genericComponent()({
1349
1353
  } else animateClick();
1350
1354
  }
1351
1355
  }
1356
+ function onKeydownSelf(e) {
1357
+ if (e.key === 'Escape' && !globalTop.value) return;
1358
+ emit('keydown', e);
1359
+ }
1352
1360
  const router = useRouter();
1353
1361
  useToggleScope(() => props.closeOnBack, () => {
1354
1362
  useBackButton(router, next => {
@@ -1411,7 +1419,8 @@ const VOverlay = genericComponent()({
1411
1419
  '--v-overlay-opacity': props.opacity,
1412
1420
  top: convertToUnit(top.value)
1413
1421
  }, props.style],
1414
- "ref": root
1422
+ "ref": root,
1423
+ "onKeydown": onKeydownSelf
1415
1424
  }, scopeId, attrs), [createVNode(Scrim, mergeProps({
1416
1425
  "color": scrimColor,
1417
1426
  "modelValue": isActive.value && !!props.scrim,
@@ -1,7 +1,7 @@
1
1
  import { computed, ref, mergeProps, createVNode } from 'vue';
2
- import { m as makeVOverlayProps, V as VOverlay } from './VOverlay-B9mxXaCv.js';
3
- import { b as useScopeId, f as forwardRefs } from './forwardRefs-BtkfywIE.js';
4
- import { g as genericComponent, p as propsFactory, j as useProxiedModel, am as getUid, a as useRender, o as omit } from './asWebComponent-DZpMGxEY.js';
2
+ import { m as makeVOverlayProps, V as VOverlay } from './VOverlay-tAeNygaA.js';
3
+ import { b as useScopeId, f as forwardRefs } from './forwardRefs-CIFAqXaZ.js';
4
+ import { g as genericComponent, p as propsFactory, j as useProxiedModel, aq as getUid, a as useRender, o as omit } from './asWebComponent-BJ2NWunV.js';
5
5
 
6
6
  const makeVTooltipProps = propsFactory({
7
7
  id: String,
@@ -1,5 +1,5 @@
1
1
  import { ref, onMounted, nextTick, createElementBlock, openBlock, Fragment, renderList, unref, createElementVNode, toDisplayString, normalizeStyle, createBlock, resolveDynamicComponent, mergeProps } from 'vue';
2
- import { aJ as useDefineWidgets, G as useLayout } from './asWebComponent-DZpMGxEY.js';
2
+ import { aN as useDefineWidgets, G as useLayout } from './asWebComponent-BJ2NWunV.js';
3
3
  import 'animated-details';
4
4
 
5
5
  const _sfc_main = {