@eodash/eodash 5.0.0-rc.1.5 → 5.0.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/README.md +1 -1
  2. package/core/client/composables/EodashMap.js +47 -28
  3. package/core/client/composables/EodashProcess.js +51 -5
  4. package/core/client/composables/index.js +8 -1
  5. package/core/client/eodash.js +21 -7
  6. package/core/client/eodashSTAC/EodashCollection.js +24 -4
  7. package/core/client/eodashSTAC/createLayers.js +62 -6
  8. package/core/client/eodashSTAC/helpers.js +48 -5
  9. package/core/client/eodashSTAC/triggers.js +52 -1
  10. package/core/client/store/stac.js +7 -2
  11. package/core/client/types.ts +10 -1
  12. package/core/client/utils/index.js +12 -0
  13. package/core/client/utils/states.js +18 -1
  14. package/core/client/views/Dashboard.vue +3 -1
  15. package/dist/client/{DashboardLayout-B-4X57-t.js → DashboardLayout-VrJIbhe8.js} +2 -2
  16. package/dist/client/{DynamicWebComponent-Dj3QYwag.js → DynamicWebComponent-BCwpocDX.js} +1 -1
  17. package/dist/client/EodashDatePicker-Bp5ec3BC.js +430 -0
  18. package/dist/client/{EodashItemFilter-DBQwJQPh.js → EodashItemFilter-Cx0t-qeW.js} +1 -1
  19. package/dist/client/{EodashLayerControl-C5fOCvoI.js → EodashLayerControl-DERx00In.js} +10 -2
  20. package/dist/client/{EodashLayoutSwitcher-BMO9k_20.js → EodashLayoutSwitcher-DTS7otlk.js} +2 -2
  21. package/dist/client/{EodashMap-D2bnMLAC.js → EodashMap-C-I6puhb.js} +101 -73
  22. package/dist/client/{EodashMapBtns-l9B977id.js → EodashMapBtns-CWgtJiG4.js} +4 -4
  23. package/dist/client/{EodashProcess-BtIlJvF1.js → EodashProcess-DWrTIyHT.js} +188 -33
  24. package/dist/client/{EodashStacInfo-CPVvp_Hm.js → EodashStacInfo-Dvsk97Mz.js} +1 -1
  25. package/dist/client/{EodashTools-DY2dlNXW.js → EodashTools-CdnjgTTl.js} +4 -4
  26. package/dist/client/{ExportState-BvD5A0XG.js → ExportState-S4lcehm3.js} +4 -4
  27. package/dist/client/{Footer-w95gBnSH.js → Footer-DlIEbXp-.js} +1 -1
  28. package/dist/client/{Header-BpiorKy9.js → Header-CTiEXLi0.js} +3 -3
  29. package/dist/client/{MobileLayout-CmVlZe7S.js → MobileLayout-DRgyQYFz.js} +17 -7
  30. package/dist/client/{PopUp-CREaSybs.js → PopUp-CzqV8BFZ.js} +3 -3
  31. package/dist/client/{VImg-DF9esgdd.js → VImg-Bn8bCvVM.js} +2 -2
  32. package/dist/client/{VMain-BWLMf-rn.js → VMain-2GOqWb6m.js} +1 -1
  33. package/dist/client/{VOverlay-DmNfblmy.js → VOverlay-BetC0LGI.js} +3 -3
  34. package/dist/client/{VTooltip-C3PeE7iO.js → VTooltip-BWg0dxx5.js} +3 -3
  35. package/dist/client/{WidgetsContainer-6FHEEXns.js → WidgetsContainer-Cv466WUW.js} +1 -1
  36. package/dist/client/{asWebComponent-BnFMd0T6.js → asWebComponent-CLUhauLl.js} +422 -164
  37. package/dist/client/eo-dash.css +1 -1
  38. package/dist/client/eo-dash.js +1 -1
  39. package/dist/client/{forwardRefs-BF3Me2RX.js → forwardRefs-CxSsJulB.js} +1 -1
  40. package/dist/client/{index-CRd5-RSy.js → index-BMj56LY3.js} +1 -1
  41. package/dist/client/{transition-Cpn_g5jE.js → transition-DidoPMgC.js} +1 -1
  42. package/dist/node/cli.js +2 -2
  43. package/dist/types/core/client/composables/EodashMap.d.ts +2 -1
  44. package/dist/types/core/client/composables/EodashProcess.d.ts +17 -11
  45. package/dist/types/core/client/composables/index.d.ts +1 -1
  46. package/dist/types/core/client/eodashSTAC/EodashCollection.d.ts +11 -4
  47. package/dist/types/core/client/eodashSTAC/createLayers.d.ts +6 -6
  48. package/dist/types/core/client/eodashSTAC/helpers.d.ts +77 -20
  49. package/dist/types/core/client/eodashSTAC/triggers.d.ts +6 -0
  50. package/dist/types/core/client/types.d.ts +13 -1
  51. package/dist/types/core/client/utils/index.d.ts +1 -0
  52. package/dist/types/core/client/utils/states.d.ts +9 -0
  53. package/dist/types/widgets/EodashDatePicker.vue.d.ts +459 -2
  54. package/dist/types/widgets/EodashMap.vue.d.ts +2 -0
  55. package/dist/types/widgets/EodashProcess.vue.d.ts +1 -0
  56. package/dist/types/widgets/PopUp.vue.d.ts +1 -2
  57. package/package.json +24 -24
  58. package/widgets/EodashDatePicker.vue +139 -22
  59. package/widgets/EodashLayerControl.vue +13 -1
  60. package/widgets/EodashMap.vue +63 -5
  61. package/widgets/EodashProcess.vue +82 -22
  62. package/dist/client/EodashDatePicker-DGRJrJ0s.js +0 -306
@@ -1,6 +1,7 @@
1
1
  <template>
2
2
  <div ref="rootRef" class="datePicker">
3
3
  <VCDatePicker
4
+ ref="datePicker"
4
5
  v-model.number="currentDate"
5
6
  :attributes="attributes"
6
7
  :masks="masks"
@@ -8,34 +9,99 @@
8
9
  class="bg-surface overflow-auto"
9
10
  style="background-color: transparent; max-width: 100%"
10
11
  >
11
- <template #footer>
12
- <div class="d-flex flex-row align-center justify-center pb-1">
12
+ <template v-if="toggleCalendar" #default="{ inputValue, inputEvents }">
13
+ <div
14
+ class="bg-surface d-flex flex-row align-center justify-center pb-1"
15
+ style="overflow: hidden; width: 100%"
16
+ >
13
17
  <v-btn
14
18
  v-if="!hideArrows"
15
19
  density="compact"
20
+ :size="lgAndDown ? 'x-small' : 'large'"
16
21
  v-tooltip:bottom="'Set date to oldest available dataset'"
17
22
  variant="text"
18
23
  @click="jumpDate(true)"
24
+ class="py-2"
25
+ style="flex-shrink: 1"
19
26
  >
20
27
  <v-icon :icon="[mdiRayEndArrow]" />
21
28
  </v-btn>
22
29
  <div
23
30
  class="flex rounded-lg border border-gray-300 dark:border-gray-600"
24
- style="margin: 2px"
31
+ style="margin: 2px; min-width: 0"
25
32
  >
26
33
  <input
27
34
  v-if="!hideInputField"
28
- :value="new Date(currentDate).toLocaleDateString()"
29
- style="margin: 1px"
35
+ :value="inputValue"
36
+ v-on="inputEvents"
30
37
  class="flex-grow px-1 py-1 dark:bg-gray-700"
38
+ style="
39
+ margin: 1px;
40
+ width: 100%;
41
+ white-space: nowrap;
42
+ overflow: hidden;
43
+ text-overflow: ellipsis;
44
+ "
31
45
  />
32
46
  </div>
33
47
  <v-btn
34
48
  v-if="!hideArrows"
35
49
  density="compact"
50
+ :size="lgAndDown ? 'x-small' : 'large'"
36
51
  variant="text"
37
52
  v-tooltip:bottom="'Set date to latest available dataset'"
38
53
  @click="jumpDate(false)"
54
+ class="py-2"
55
+ style="flex-shrink: 1"
56
+ >
57
+ <v-icon :icon="[mdiRayStartArrow]" />
58
+ </v-btn>
59
+ </div>
60
+ </template>
61
+ <template v-else #footer>
62
+ <div
63
+ class="d-flex flex-row align-center justify-center pb-1"
64
+ style="overflow: hidden; width: 100%"
65
+ >
66
+ <v-btn
67
+ v-if="!hideArrows"
68
+ density="compact"
69
+ :size="lgAndDown ? 'x-small' : 'large'"
70
+ v-tooltip:bottom="'Set date to oldest available dataset'"
71
+ variant="text"
72
+ @click="jumpDate(true)"
73
+ class="py-2"
74
+ style="flex-shrink: 1"
75
+ >
76
+ <v-icon :icon="[mdiRayEndArrow]" />
77
+ </v-btn>
78
+ <div
79
+ class="flex rounded-lg border border-gray-300 dark:border-gray-600"
80
+ style="margin: 2px; min-width: 0"
81
+ >
82
+ <input
83
+ v-if="!hideInputField"
84
+ :value="maskedCurrentDate"
85
+ @change="onInputChange"
86
+ class="flex-grow px-1 py-1 dark:bg-gray-700"
87
+ style="
88
+ margin: 1px;
89
+ width: 100%;
90
+ white-space: nowrap;
91
+ overflow: hidden;
92
+ text-overflow: ellipsis;
93
+ "
94
+ />
95
+ </div>
96
+ <v-btn
97
+ v-if="!hideArrows"
98
+ density="compact"
99
+ :size="lgAndDown ? 'x-small' : 'large'"
100
+ variant="text"
101
+ v-tooltip:bottom="'Set date to latest available dataset'"
102
+ @click="jumpDate(false)"
103
+ class="py-2"
104
+ style="flex-shrink: 1"
39
105
  >
40
106
  <v-icon :icon="[mdiRayStartArrow]" />
41
107
  </v-btn>
@@ -46,15 +112,31 @@
46
112
  </template>
47
113
  <script setup>
48
114
  import { DatePicker as VCDatePicker } from "v-calendar";
115
+ import { useDisplay } from "vuetify";
49
116
  import "v-calendar/style.css";
50
- import { watch, reactive, ref, customRef, toRef } from "vue";
117
+ import {
118
+ watch,
119
+ reactive,
120
+ ref,
121
+ customRef,
122
+ toRef,
123
+ onMounted,
124
+ computed,
125
+ useTemplateRef,
126
+ } from "vue";
51
127
  import { useSTAcStore } from "@/store/stac";
52
128
  import { datetime } from "@/store/states";
53
129
  import { mdiRayStartArrow, mdiRayEndArrow } from "@mdi/js";
54
- import { eodashCollections } from "@/utils/states";
130
+ import { eodashCollections, collectionsPalette } from "@/utils/states";
55
131
  import log from "loglevel";
56
132
  import { makePanelTransparent } from "@/composables";
57
133
 
134
+ const { lgAndDown } = useDisplay();
135
+
136
+ const rootEl = useTemplateRef("rootRef");
137
+
138
+ const datePickerEl = useTemplateRef("datePicker");
139
+
58
140
  // holds the number value of the datetime
59
141
  const currentDate = customRef((track, trigger) => ({
60
142
  get() {
@@ -65,7 +147,13 @@ const currentDate = customRef((track, trigger) => ({
65
147
  set(num) {
66
148
  trigger();
67
149
  log.debug("Datepicker setting currentDate", datetime.value);
68
- datetime.value = new Date(num).toISOString();
150
+ const date = new Date(num);
151
+ datetime.value = date.toISOString();
152
+ //@ts-expect-error supports move method https://vcalendar.io/datepicker/basics.html#basics
153
+ datePickerEl.value?.move({
154
+ month: date.getMonth() + 1,
155
+ year: date.getFullYear(),
156
+ });
69
157
  },
70
158
  }));
71
159
 
@@ -73,6 +161,28 @@ const masks = ref({
73
161
  input: "YYYY-MM-DD",
74
162
  });
75
163
 
164
+ /** @param {Date} date */
165
+ const formatDate = (date) => {
166
+ const years = date.getFullYear();
167
+ const month = date.getMonth() + 1;
168
+ const day = date.getDate();
169
+ return `${years}-${month < 10 ? "0" + month : month}-${
170
+ day < 10 ? "0" + day : day
171
+ }`;
172
+ };
173
+ /**
174
+ *
175
+ * @param e {Event}
176
+ */
177
+ const onInputChange = (e) => {
178
+ currentDate.value = new Date(
179
+ /** @type {HTMLInputElement} */ (e.target)?.value,
180
+ ).getTime();
181
+ };
182
+ const maskedCurrentDate = computed(() =>
183
+ formatDate(new Date(currentDate.value)),
184
+ );
185
+
76
186
  defineProps({
77
187
  hintText: {
78
188
  type: String,
@@ -86,6 +196,10 @@ defineProps({
86
196
  type: Boolean,
87
197
  default: false,
88
198
  },
199
+ toggleCalendar: {
200
+ type: Boolean,
201
+ default: false,
202
+ },
89
203
  });
90
204
 
91
205
  /**
@@ -100,9 +214,6 @@ defineProps({
100
214
  */
101
215
  const attributes = reactive([]);
102
216
 
103
- /** @type {import("vue").Ref<HTMLDivElement|null>} */
104
- const rootRef = ref(null);
105
-
106
217
  const selectedStac = toRef(useSTAcStore(), "selectedStac");
107
218
 
108
219
  watch(
@@ -110,20 +221,13 @@ watch(
110
221
  async (updatedStac, previousStac) => {
111
222
  if (updatedStac && previousStac?.id !== updatedStac.id) {
112
223
  log.debug("Datepicker selected STAC change triggered");
113
- const wongPalette = [
114
- "#009E73",
115
- "#0072B2",
116
- "#E69F00",
117
- "#CC79A7",
118
- "#56B4E9",
119
- "#D55E00",
120
- ];
121
224
  // remove old values
122
225
  attributes.splice(0, attributes.length);
123
226
 
124
227
  for (let idx = 0; idx < eodashCollections.length; idx++) {
125
228
  log.debug("Retrieving dates", eodashCollections[idx]);
126
229
  await eodashCollections[idx].fetchCollection();
230
+
127
231
  const dates = [
128
232
  ...new Set(
129
233
  eodashCollections[idx].getItems()?.reduce((valid, it) => {
@@ -137,9 +241,10 @@ watch(
137
241
  ];
138
242
  attributes.push({
139
243
  key: "id-" + idx.toString() + Math.random().toString(16).slice(2),
140
- bar: {
244
+ dot: {
141
245
  style: {
142
- backgroundColor: wongPalette[idx % wongPalette.length],
246
+ backgroundColor:
247
+ collectionsPalette[idx % collectionsPalette.length],
143
248
  },
144
249
  },
145
250
  dates,
@@ -182,7 +287,15 @@ function jumpDate(reverse) {
182
287
  }
183
288
  }
184
289
 
185
- makePanelTransparent(rootRef);
290
+ // fixes calendar dispalcement on lib mode
291
+ const transform = ref("");
292
+ onMounted(() => {
293
+ transform.value = document.querySelector("eo-dash")
294
+ ? "translate3d(50px,-80px,0)"
295
+ : "translate3d(0px,-80px,0)";
296
+ });
297
+
298
+ makePanelTransparent(rootEl);
186
299
  </script>
187
300
  <style>
188
301
  @media (min-width: 960px) {
@@ -200,4 +313,8 @@ makePanelTransparent(rootRef);
200
313
  .vc-highlight-content-solid {
201
314
  color: white !important;
202
315
  }
316
+
317
+ .vc-popover-content-wrapper {
318
+ transform: v-bind("transform") !important;
319
+ }
203
320
  </style>
@@ -9,6 +9,7 @@
9
9
  toolsAsList="true"
10
10
  style="--eox-background-color: transparent"
11
11
  ref="eoxLayercontrol"
12
+ @layerConfig:change="onLayerConfigChange"
12
13
  />
13
14
  </span>
14
15
  </template>
@@ -22,7 +23,11 @@ import "color-legend-element";
22
23
  import { computed, ref } from "vue";
23
24
  import { mapEl, mapCompareEl } from "@/store/states";
24
25
  import { getColFromLayer } from "@/eodashSTAC/helpers";
25
- import { eodashCollections, eodashCompareCollections } from "@/utils/states";
26
+ import {
27
+ eodashCollections,
28
+ eodashCompareCollections,
29
+ layerControlFormValue,
30
+ } from "@/utils/states";
26
31
  import { storeToRefs } from "pinia";
27
32
  import { useSTAcStore } from "@/store/stac";
28
33
 
@@ -108,4 +113,11 @@ const debouncedHandleDateTime = (evt) => {
108
113
  }, 500);
109
114
  };
110
115
  // ------
116
+ /**
117
+ *
118
+ * @param {Event & {detail:{layer:import("ol/layer").Layer;jsonformValue:Record<string,any>}}} evt
119
+ */
120
+ const onLayerConfigChange = (evt) => {
121
+ layerControlFormValue.value = evt.detail.jsonformValue;
122
+ };
111
123
  </script>
@@ -12,7 +12,12 @@
12
12
  .center="initialCenter"
13
13
  .zoom="initialZoom"
14
14
  .layers="eoxMapLayers"
15
- />
15
+ >
16
+ <eox-map-tooltip
17
+ :style="tooltipStyles"
18
+ .propertyTransform="tooltipPropertyTransform"
19
+ />
20
+ </eox-map>
16
21
  <eox-map
17
22
  class="fill-height fill-width overflow-none"
18
23
  id="compare"
@@ -29,9 +34,19 @@ import { computed, onMounted, ref, toRaw } from "vue";
29
34
  import { datetime, mapEl, mapPosition, mapCompareEl } from "@/store/states";
30
35
  import { storeToRefs } from "pinia";
31
36
  import { useSTAcStore } from "@/store/stac";
32
- import { eodashCollections, eodashCompareCollections } from "@/utils/states";
33
- import { useHandleMapMoveEnd, useInitMap } from "@/composables/EodashMap";
37
+ import {
38
+ eodashCollections,
39
+ eodashCompareCollections,
40
+ layerControlFormValue,
41
+ } from "@/utils/states";
42
+ import {
43
+ useHandleMapMoveEnd,
44
+ useInitMap,
45
+ useUpdateTooltipProperties,
46
+ } from "@/composables/EodashMap";
34
47
  import { inAndOut } from "ol/easing.js";
48
+ import mustache from "mustache";
49
+
35
50
  const props = defineProps({
36
51
  enableCompare: {
37
52
  type: Boolean,
@@ -47,8 +62,15 @@ const props = defineProps({
47
62
  type: Number,
48
63
  default: 4,
49
64
  },
65
+ zoomToExtent: {
66
+ type: Boolean,
67
+ default: true,
68
+ },
50
69
  });
51
70
 
71
+ /** @type {import("vue").Ref<Exclude<import("@/types").EodashStyleJson["tooltip"], undefined>>} */
72
+ const tooltipProperties = ref([]);
73
+
52
74
  const initialCenter = toRaw([
53
75
  mapPosition.value?.[0] ?? props.center?.[0],
54
76
  mapPosition.value?.[1] ?? props.center?.[1],
@@ -83,9 +105,9 @@ const animationOptions = {
83
105
  easing: inAndOut,
84
106
  };
85
107
 
86
- /** @type {import("vue").Ref<(HTMLElement & Record<string,any> & { map:import("ol").Map }) | null>} */
108
+ /** @type {import("vue").Ref<import("@eox/map").EOxMap | null>} */
87
109
  const eoxMap = ref(null);
88
- /** @type {import("vue").Ref<(HTMLElement & Record<string,any> & { map:import("ol").Map }) | null>} */
110
+ /** @type {import("vue").Ref<import("@eox/map").EOxMap | null>} */
89
111
  const compareMap = ref(null);
90
112
  const { selectedCompareStac } = storeToRefs(useSTAcStore());
91
113
  const showCompare = computed(() =>
@@ -112,6 +134,7 @@ onMounted(() => {
112
134
  datetime,
113
135
  eoxMapCompareLayers,
114
136
  eoxMap,
137
+ false,
115
138
  );
116
139
  }
117
140
 
@@ -123,6 +146,41 @@ onMounted(() => {
123
146
  datetime,
124
147
  eoxMapLayers,
125
148
  compareMap,
149
+ props.zoomToExtent,
126
150
  );
127
151
  });
152
+
153
+ useUpdateTooltipProperties(eodashCollections, tooltipProperties);
154
+
155
+ const tooltipStyles = computed(() => ({
156
+ visibility: tooltipProperties.value.length ? "visible" : "hidden",
157
+ }));
158
+ /**
159
+ * @param {{key:string; value:string}} param
160
+ * @returns {{key:string; value?:string} | undefined}
161
+ */
162
+ const tooltipPropertyTransform = (param) => {
163
+ /** @type {typeof tooltipProperties.value} */
164
+ const updatedProperties = JSON.parse(
165
+ mustache.render(JSON.stringify(tooltipProperties.value), {
166
+ ...(layerControlFormValue.value ?? {}),
167
+ }),
168
+ );
169
+
170
+ const tooltipProp = updatedProperties?.find((prop) => prop.id === param.key);
171
+ if (!tooltipProp) {
172
+ return undefined;
173
+ }
174
+ if (typeof param.value === "object") {
175
+ param.value = JSON.stringify(param.value);
176
+ }
177
+ if (!isNaN(Number(param.value))) {
178
+ param.value = Number(param.value).toFixed(4).toString();
179
+ }
180
+
181
+ return {
182
+ key: tooltipProp.title || tooltipProp.id,
183
+ value: param.value + " " + (tooltipProp.appendix || ""),
184
+ };
185
+ };
128
186
  </script>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div class="process-container">
2
+ <div ref="container" class="process-container">
3
3
  <eox-jsonform
4
4
  v-if="jsonformSchema"
5
5
  ref="jsonformEl"
@@ -10,18 +10,28 @@
10
10
  v-if="isProcessed && chartSpec"
11
11
  .spec="toRaw(chartSpec)"
12
12
  .dataValues="toRaw(chartData)"
13
+ :style="chartStyles"
13
14
  />
14
- <span>
15
- <v-btn
16
- v-if="!autoExec"
17
- :loading="loading"
18
- style="float: right; margin-right: 20px"
19
- @click="startProcess"
20
- color="primary"
21
- >
22
- Execute
23
- </v-btn>
24
- </span>
15
+ <v-container>
16
+ <span>
17
+ <v-btn
18
+ v-if="!autoExec"
19
+ :loading="loading"
20
+ style="float: right; margin-right: 20px"
21
+ @click="startProcess"
22
+ color="primary"
23
+ >
24
+ Execute
25
+ </v-btn>
26
+ <v-btn
27
+ v-if="processResults.length && isProcessed"
28
+ color="primary"
29
+ @click="downloadResults"
30
+ >
31
+ Download
32
+ </v-btn>
33
+ </span>
34
+ </v-container>
25
35
  </div>
26
36
  </template>
27
37
  <script setup>
@@ -29,7 +39,7 @@ import "@eox/chart";
29
39
  import "@eox/drawtools";
30
40
  import "@eox/jsonform";
31
41
 
32
- import { onMounted, ref, toRaw } from "vue";
42
+ import { computed, onMounted, ref, toRaw, useTemplateRef } from "vue";
33
43
  import { useSTAcStore } from "@/store/stac";
34
44
  import { storeToRefs } from "pinia";
35
45
  import { mapEl } from "@/store/states";
@@ -57,12 +67,47 @@ const jsonformSchema = ref(null);
57
67
 
58
68
  /** @type {import("vue").Ref<import("@eox/jsonform").EOxJSONForm | null>} */
59
69
  const jsonformEl = ref(null);
70
+
71
+ const containerEl = useTemplateRef("container");
72
+
60
73
  const loading = ref(false);
61
74
 
62
75
  const autoExec = ref(false);
63
76
 
64
77
  const isPolling = ref(false);
78
+ /** @type {import("vue").Ref<any[]>} */
79
+ const processResults = ref([]);
65
80
 
81
+ const downloadResults = () => {
82
+ processResults.value.forEach((result) => {
83
+ if (!result) {
84
+ return;
85
+ }
86
+ let url = "";
87
+ let downloadFile = "";
88
+ if (typeof result === "string") {
89
+ url = result;
90
+ //@ts-expect-error TODO
91
+ downloadFile = url.includes("/") ? url.split("/").pop() : url;
92
+ downloadFile = downloadFile.includes("?")
93
+ ? downloadFile.split("?")[0]
94
+ : downloadFile;
95
+ } else {
96
+ result = JSON.stringify(result);
97
+ const blob = new Blob([result], { type: "text" });
98
+ url = URL.createObjectURL(blob);
99
+ downloadFile = selectedStac.value?.id + "_process_results.json";
100
+ }
101
+ const link = document.createElement("a");
102
+ if (confirm(`Would you like to download ${downloadFile}?`)) {
103
+ link.href = url;
104
+ link.download = downloadFile;
105
+ link.click();
106
+ }
107
+ URL.revokeObjectURL(url);
108
+ link.remove();
109
+ });
110
+ };
66
111
  onMounted(async () => {
67
112
  // wait for the layers to be rendered
68
113
  if (mapEl.value?.layers.length <= 1) {
@@ -75,6 +120,7 @@ onMounted(async () => {
75
120
  chartSpec,
76
121
  isProcessed,
77
122
  loading,
123
+ processResults,
78
124
  isPolling,
79
125
  });
80
126
  });
@@ -86,14 +132,15 @@ onMounted(async () => {
86
132
  jsonformSchema,
87
133
  chartSpec,
88
134
  isProcessed,
135
+ processResults,
89
136
  loading,
90
137
  isPolling,
91
138
  });
92
139
  }
93
140
  });
94
141
 
95
- useOnLayersUpdate(
96
- async () =>
142
+ useOnLayersUpdate(async (evt, _payload) => {
143
+ if (evt === "layers:updated") {
97
144
  await initProcess({
98
145
  //@ts-expect-error TODO
99
146
  selectedStac,
@@ -101,10 +148,12 @@ useOnLayersUpdate(
101
148
  jsonformSchema,
102
149
  chartSpec,
103
150
  isProcessed,
151
+ processResults,
104
152
  loading,
105
153
  isPolling,
106
- }),
107
- );
154
+ });
155
+ }
156
+ });
108
157
 
109
158
  const startProcess = async () => {
110
159
  const errors = jsonformEl.value?.editor.validate();
@@ -112,6 +161,7 @@ const startProcess = async () => {
112
161
  console.warn("[eodash] Form validation failed", errors);
113
162
  return;
114
163
  }
164
+ processResults.value = [];
115
165
  await handleProcesses({
116
166
  jsonformEl,
117
167
  jsonformSchema,
@@ -122,17 +172,27 @@ const startProcess = async () => {
122
172
  selectedStac,
123
173
  isProcessed,
124
174
  isPolling,
175
+ processResults,
125
176
  });
126
177
  isProcessed.value = true;
127
178
  };
128
179
  useAutoExec(autoExec, jsonformEl, jsonformSchema, startProcess);
180
+
181
+ const chartStyles = computed(() => {
182
+ /** @type {Record<string,string> }*/
183
+ const styles = {};
184
+ if (!chartSpec.value?.["height"]) {
185
+ styles["height"] =
186
+ Math.max(
187
+ (containerEl.value?.offsetHeight ?? 0) -
188
+ (jsonformEl.value?.offsetHeight ?? 0),
189
+ 200,
190
+ ) + "px";
191
+ }
192
+ return styles;
193
+ });
129
194
  </script>
130
195
  <style>
131
- .chart {
132
- height: 400px;
133
- width: 100%;
134
- }
135
-
136
196
  .process-container {
137
197
  height: 100%;
138
198
  overflow-y: auto;