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

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 (51) hide show
  1. package/README.md +1 -1
  2. package/core/client/composables/EodashMap.js +19 -5
  3. package/core/client/composables/EodashProcess.js +51 -5
  4. package/core/client/eodash.js +8 -7
  5. package/core/client/eodashSTAC/EodashCollection.js +16 -0
  6. package/core/client/eodashSTAC/createLayers.js +62 -6
  7. package/core/client/eodashSTAC/helpers.js +39 -4
  8. package/core/client/types.ts +7 -0
  9. package/core/client/utils/states.js +3 -0
  10. package/dist/client/{DashboardLayout-B-4X57-t.js → DashboardLayout-SZfMDUoR.js} +2 -2
  11. package/dist/client/{DynamicWebComponent-Dj3QYwag.js → DynamicWebComponent-I9gzMY0L.js} +1 -1
  12. package/dist/client/EodashDatePicker-B9_u6TTm.js +405 -0
  13. package/dist/client/{EodashItemFilter-DBQwJQPh.js → EodashItemFilter-G7YsYO3B.js} +1 -1
  14. package/dist/client/{EodashLayerControl-C5fOCvoI.js → EodashLayerControl-CJ94ul63.js} +10 -2
  15. package/dist/client/{EodashLayoutSwitcher-BMO9k_20.js → EodashLayoutSwitcher-DRKm8A8U.js} +2 -2
  16. package/dist/client/{EodashMap-D2bnMLAC.js → EodashMap-Dp44Ajbi.js} +60 -10
  17. package/dist/client/{EodashMapBtns-l9B977id.js → EodashMapBtns-BlPFwhPc.js} +4 -4
  18. package/dist/client/{EodashProcess-BtIlJvF1.js → EodashProcess-BLmIgUGT.js} +158 -25
  19. package/dist/client/{EodashStacInfo-CPVvp_Hm.js → EodashStacInfo-BIRcfcMo.js} +1 -1
  20. package/dist/client/{EodashTools-DY2dlNXW.js → EodashTools-PNfJ-Cw3.js} +4 -4
  21. package/dist/client/{ExportState-BvD5A0XG.js → ExportState-5JyTshJH.js} +4 -4
  22. package/dist/client/{Footer-w95gBnSH.js → Footer-CM9hgdQP.js} +1 -1
  23. package/dist/client/{Header-BpiorKy9.js → Header-BTq4DW1x.js} +3 -3
  24. package/dist/client/{MobileLayout-CmVlZe7S.js → MobileLayout-Atfoxf8d.js} +5 -5
  25. package/dist/client/{PopUp-CREaSybs.js → PopUp-Bmfn3N_4.js} +3 -3
  26. package/dist/client/{VImg-DF9esgdd.js → VImg-CUF4S39i.js} +2 -2
  27. package/dist/client/{VMain-BWLMf-rn.js → VMain-CQpXnzDR.js} +1 -1
  28. package/dist/client/{VOverlay-DmNfblmy.js → VOverlay-DUnITwM1.js} +3 -3
  29. package/dist/client/{VTooltip-C3PeE7iO.js → VTooltip-BYTlbKer.js} +3 -3
  30. package/dist/client/{WidgetsContainer-6FHEEXns.js → WidgetsContainer-BPbgxdb0.js} +1 -1
  31. package/dist/client/{asWebComponent-BnFMd0T6.js → asWebComponent-DW1XzZkL.js} +139 -29
  32. package/dist/client/eo-dash.css +1 -1
  33. package/dist/client/eo-dash.js +1 -1
  34. package/dist/client/{forwardRefs-BF3Me2RX.js → forwardRefs-gx1Fzngc.js} +1 -1
  35. package/dist/client/{index-CRd5-RSy.js → index-DvFppNyk.js} +1 -1
  36. package/dist/client/{transition-Cpn_g5jE.js → transition-j2eWJYMg.js} +1 -1
  37. package/dist/types/core/client/composables/EodashMap.d.ts +2 -1
  38. package/dist/types/core/client/composables/EodashProcess.d.ts +17 -11
  39. package/dist/types/core/client/eodashSTAC/EodashCollection.d.ts +9 -4
  40. package/dist/types/core/client/eodashSTAC/createLayers.d.ts +6 -6
  41. package/dist/types/core/client/eodashSTAC/helpers.d.ts +75 -20
  42. package/dist/types/core/client/types.d.ts +10 -0
  43. package/dist/types/core/client/utils/states.d.ts +2 -0
  44. package/dist/types/widgets/EodashDatePicker.vue.d.ts +4 -2
  45. package/dist/types/widgets/PopUp.vue.d.ts +1 -2
  46. package/package.json +8 -8
  47. package/widgets/EodashDatePicker.vue +89 -6
  48. package/widgets/EodashLayerControl.vue +13 -1
  49. package/widgets/EodashMap.vue +51 -5
  50. package/widgets/EodashProcess.vue +57 -11
  51. package/dist/client/EodashDatePicker-DGRJrJ0s.js +0 -306
@@ -12,7 +12,12 @@
12
12
  .center="initialCenter"
13
13
  .zoom="initialZoom"
14
14
  .layers="eoxMapLayers"
15
- />
15
+ >
16
+ <eox-map-tooltip
17
+ v-show="tooltipProperties?.length"
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,
@@ -48,6 +63,8 @@ const props = defineProps({
48
63
  default: 4,
49
64
  },
50
65
  });
66
+ /** @type {import("vue").Ref<import("@/types").EodashStyleJson["tooltip"]>} */
67
+ const tooltipProperties = ref([]);
51
68
 
52
69
  const initialCenter = toRaw([
53
70
  mapPosition.value?.[0] ?? props.center?.[0],
@@ -83,9 +100,9 @@ const animationOptions = {
83
100
  easing: inAndOut,
84
101
  };
85
102
 
86
- /** @type {import("vue").Ref<(HTMLElement & Record<string,any> & { map:import("ol").Map }) | null>} */
103
+ /** @type {import("vue").Ref<import("@eox/map").EOxMap | null>} */
87
104
  const eoxMap = ref(null);
88
- /** @type {import("vue").Ref<(HTMLElement & Record<string,any> & { map:import("ol").Map }) | null>} */
105
+ /** @type {import("vue").Ref<import("@eox/map").EOxMap | null>} */
89
106
  const compareMap = ref(null);
90
107
  const { selectedCompareStac } = storeToRefs(useSTAcStore());
91
108
  const showCompare = computed(() =>
@@ -125,4 +142,33 @@ onMounted(() => {
125
142
  compareMap,
126
143
  );
127
144
  });
145
+ useUpdateTooltipProperties(eodashCollections, tooltipProperties);
146
+ /**
147
+ * @param {{key:string; value:string}} param
148
+ * @returns {{key:string; value?:string} | undefined}
149
+ */
150
+ const tooltipPropertyTransform = (param) => {
151
+ /** @type {typeof tooltipProperties.value} */
152
+ const updatedProperties = JSON.parse(
153
+ mustache.render(JSON.stringify(tooltipProperties.value), {
154
+ ...(layerControlFormValue.value ?? {}),
155
+ }),
156
+ );
157
+
158
+ const tooltipProp = updatedProperties?.find((prop) => prop.id === param.key);
159
+ if (!tooltipProp) {
160
+ return undefined;
161
+ }
162
+ if (typeof param.value === "object") {
163
+ param.value = JSON.stringify(param.value);
164
+ }
165
+ if (!isNaN(Number(param.value))) {
166
+ param.value = Number(param.value).toFixed(4).toString();
167
+ }
168
+
169
+ return {
170
+ key: tooltipProp.title || tooltipProp.id,
171
+ value: param.value + " " + (tooltipProp.appendix || ""),
172
+ };
173
+ };
128
174
  </script>
@@ -11,17 +11,26 @@
11
11
  .spec="toRaw(chartSpec)"
12
12
  .dataValues="toRaw(chartData)"
13
13
  />
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>
14
+ <v-container>
15
+ <span>
16
+ <v-btn
17
+ v-if="!autoExec"
18
+ :loading="loading"
19
+ style="float: right; margin-right: 20px"
20
+ @click="startProcess"
21
+ color="primary"
22
+ >
23
+ Execute
24
+ </v-btn>
25
+ <v-btn
26
+ v-if="processResults.length && isProcessed"
27
+ color="primary"
28
+ @click="downloadResults"
29
+ >
30
+ Download
31
+ </v-btn>
32
+ </span>
33
+ </v-container>
25
34
  </div>
26
35
  </template>
27
36
  <script setup>
@@ -62,7 +71,39 @@ const loading = ref(false);
62
71
  const autoExec = ref(false);
63
72
 
64
73
  const isPolling = ref(false);
74
+ /** @type {import("vue").Ref<any[]>} */
75
+ const processResults = ref([]);
65
76
 
77
+ const downloadResults = () => {
78
+ processResults.value.forEach((result) => {
79
+ if (!result) {
80
+ return;
81
+ }
82
+ let url = "";
83
+ let downloadFile = "";
84
+ if (typeof result === "string") {
85
+ url = result;
86
+ //@ts-expect-error TODO
87
+ downloadFile = url.includes("/") ? url.split("/").pop() : url;
88
+ downloadFile = downloadFile.includes("?")
89
+ ? downloadFile.split("?")[0]
90
+ : downloadFile;
91
+ } else {
92
+ result = JSON.stringify(result);
93
+ const blob = new Blob([result], { type: "text" });
94
+ url = URL.createObjectURL(blob);
95
+ downloadFile = selectedStac.value?.id + "_process_results.json";
96
+ }
97
+ const link = document.createElement("a");
98
+ if (confirm(`Would you like to download ${downloadFile}?`)) {
99
+ link.href = url;
100
+ link.download = downloadFile;
101
+ link.click();
102
+ }
103
+ URL.revokeObjectURL(url);
104
+ link.remove();
105
+ });
106
+ };
66
107
  onMounted(async () => {
67
108
  // wait for the layers to be rendered
68
109
  if (mapEl.value?.layers.length <= 1) {
@@ -75,6 +116,7 @@ onMounted(async () => {
75
116
  chartSpec,
76
117
  isProcessed,
77
118
  loading,
119
+ processResults,
78
120
  isPolling,
79
121
  });
80
122
  });
@@ -86,6 +128,7 @@ onMounted(async () => {
86
128
  jsonformSchema,
87
129
  chartSpec,
88
130
  isProcessed,
131
+ processResults,
89
132
  loading,
90
133
  isPolling,
91
134
  });
@@ -101,6 +144,7 @@ useOnLayersUpdate(
101
144
  jsonformSchema,
102
145
  chartSpec,
103
146
  isProcessed,
147
+ processResults,
104
148
  loading,
105
149
  isPolling,
106
150
  }),
@@ -112,6 +156,7 @@ const startProcess = async () => {
112
156
  console.warn("[eodash] Form validation failed", errors);
113
157
  return;
114
158
  }
159
+ processResults.value = [];
115
160
  await handleProcesses({
116
161
  jsonformEl,
117
162
  jsonformSchema,
@@ -122,6 +167,7 @@ const startProcess = async () => {
122
167
  selectedStac,
123
168
  isProcessed,
124
169
  isPolling,
170
+ processResults,
125
171
  });
126
172
  isProcessed.value = true;
127
173
  };
@@ -1,306 +0,0 @@
1
- import { resolveComponent, render, h, mergeProps, customRef, ref, reactive, toRef, watch, openBlock, createElementBlock, createVNode, unref, withCtx, createElementVNode, withDirectives, createBlock, createCommentVNode } from 'vue';
2
- import { DatePicker } from 'v-calendar';
3
- import { E as isObject, Y as consoleError, Z as datetime, $ as useSTAcStore, a0 as eodashCollections, a1 as makePanelTransparent, V as VBtn, y as VIcon } from './asWebComponent-BnFMd0T6.js';
4
- import { mdiRayEndArrow, mdiRayStartArrow } from '@mdi/js';
5
- import log from 'loglevel';
6
- import { V as VTooltip } from './VTooltip-C3PeE7iO.js';
7
-
8
- // Utilities
9
- function useDirectiveComponent(component, props) {
10
- const concreteComponent = typeof component === 'string' ? resolveComponent(component) : component;
11
- const hook = mountComponent(concreteComponent, props);
12
- return {
13
- mounted: hook,
14
- updated: hook,
15
- unmounted(el) {
16
- render(null, el);
17
- }
18
- };
19
- }
20
- function mountComponent(component, props) {
21
- return function (el, binding, vnode) {
22
- const _props = typeof props === 'function' ? props(binding) : props;
23
- const text = binding.value?.text ?? binding.value ?? _props?.text;
24
- const value = isObject(binding.value) ? binding.value : {};
25
-
26
- // Get the children from the props or directive value, or the element's children
27
- const children = () => text ?? el.textContent;
28
-
29
- // If vnode.ctx is the same as the instance, then we're bound to a plain element
30
- // and need to find the nearest parent component instance to inherit provides from
31
- const provides = (vnode.ctx === binding.instance.$ ? findComponentParent(vnode, binding.instance.$)?.provides : vnode.ctx?.provides) ?? binding.instance.$.provides;
32
- const node = h(component, mergeProps(_props, value), children);
33
- node.appContext = Object.assign(Object.create(null), binding.instance.$.appContext, {
34
- provides
35
- });
36
- render(node, el);
37
- };
38
- }
39
- function findComponentParent(vnode, root) {
40
- // Walk the tree from root until we find the child vnode
41
- const stack = new Set();
42
- const walk = children => {
43
- for (const child of children) {
44
- if (!child) continue;
45
- if (child === vnode || child.el && vnode.el && child.el === vnode.el) {
46
- return true;
47
- }
48
- stack.add(child);
49
- let result;
50
- if (child.suspense) {
51
- result = walk([child.ssContent]);
52
- } else if (Array.isArray(child.children)) {
53
- result = walk(child.children);
54
- } else if (child.component?.vnode) {
55
- result = walk([child.component?.subTree]);
56
- }
57
- if (result) {
58
- return result;
59
- }
60
- stack.delete(child);
61
- }
62
- return false;
63
- };
64
- if (!walk([root.subTree])) {
65
- consoleError('Could not find original vnode, component will not inherit provides');
66
- return root;
67
- }
68
-
69
- // Return the first component parent
70
- const result = Array.from(stack).reverse();
71
- for (const child of result) {
72
- if (child.component) {
73
- return child.component;
74
- }
75
- }
76
- return root;
77
- }
78
-
79
- // Components
80
- const Tooltip = useDirectiveComponent(VTooltip, binding => {
81
- return {
82
- activator: 'parent',
83
- location: binding.arg?.replace('-', ' '),
84
- text: typeof binding.value === 'boolean' ? undefined : binding.value
85
- };
86
- });
87
-
88
- const _hoisted_1 = { class: "d-flex flex-row align-center justify-center pb-1" };
89
- const _hoisted_2 = {
90
- class: "flex rounded-lg border border-gray-300 dark:border-gray-600",
91
- style: {"margin":"2px"}
92
- };
93
- const _hoisted_3 = ["value"];
94
-
95
- // holds the number value of the datetime
96
-
97
- const _sfc_main = {
98
- __name: 'EodashDatePicker',
99
- props: {
100
- hintText: {
101
- type: String,
102
- default: null,
103
- },
104
- hideArrows: {
105
- type: Boolean,
106
- default: false,
107
- },
108
- hideInputField: {
109
- type: Boolean,
110
- default: false,
111
- },
112
- },
113
- setup(__props) {
114
-
115
- const currentDate = customRef((track, trigger) => ({
116
- get() {
117
- track();
118
- return new Date(datetime.value).getTime();
119
- },
120
- /** @param {number} num */
121
- set(num) {
122
- trigger();
123
- log.debug("Datepicker setting currentDate", datetime.value);
124
- datetime.value = new Date(num).toISOString();
125
- },
126
- }));
127
-
128
- const masks = ref({
129
- input: "YYYY-MM-DD",
130
- });
131
-
132
-
133
-
134
- /**
135
- * Attributes displayed on datepicker
136
- *
137
- * @type {import("vue").Reactive<
138
- * (
139
- * | Partial<import("v-calendar/dist/types/src/utils/attribute").AttributeConfig>
140
- * | undefined
141
- * )[]
142
- * >}
143
- */
144
- const attributes = reactive([]);
145
-
146
- /** @type {import("vue").Ref<HTMLDivElement|null>} */
147
- const rootRef = ref(null);
148
-
149
- const selectedStac = toRef(useSTAcStore(), "selectedStac");
150
-
151
- watch(
152
- selectedStac,
153
- async (updatedStac, previousStac) => {
154
- if (updatedStac && previousStac?.id !== updatedStac.id) {
155
- log.debug("Datepicker selected STAC change triggered");
156
- const wongPalette = [
157
- "#009E73",
158
- "#0072B2",
159
- "#E69F00",
160
- "#CC79A7",
161
- "#56B4E9",
162
- "#D55E00",
163
- ];
164
- // remove old values
165
- attributes.splice(0, attributes.length);
166
-
167
- for (let idx = 0; idx < eodashCollections.length; idx++) {
168
- log.debug("Retrieving dates", eodashCollections[idx]);
169
- await eodashCollections[idx].fetchCollection();
170
- const dates = [
171
- ...new Set(
172
- eodashCollections[idx].getItems()?.reduce((valid, it) => {
173
- const parsed = Date.parse(/** @type {string} */ (it.datetime));
174
- if (parsed) {
175
- valid.push(new Date(parsed));
176
- }
177
- return valid;
178
- }, /** @type {Date[]} */ ([])),
179
- ),
180
- ];
181
- attributes.push({
182
- key: "id-" + idx.toString() + Math.random().toString(16).slice(2),
183
- bar: {
184
- style: {
185
- backgroundColor: wongPalette[idx % wongPalette.length],
186
- },
187
- },
188
- dates,
189
- content: {
190
- style: {
191
- color: "#000000",
192
- "font-weight": "bold",
193
- },
194
- },
195
- });
196
- }
197
- }
198
- },
199
- { immediate: true },
200
- );
201
-
202
- /**
203
- * @param {boolean} reverse
204
- */
205
- function jumpDate(reverse) {
206
- if (attributes.length) {
207
- let latestDateMS = reverse ? Infinity : -Infinity;
208
- attributes.forEach((coll) => {
209
- if (coll?.dates) {
210
- coll.dates.forEach((d) => {
211
- // TODO: we need to handle time ranges and other options here
212
- if (d instanceof Date) {
213
- const mathFun = reverse ? "min" : "max";
214
- latestDateMS = Math[mathFun](latestDateMS, d.getTime());
215
- }
216
- });
217
- }
218
- });
219
- currentDate.value =
220
- latestDateMS === -Infinity
221
- ? Date.now()
222
- : latestDateMS === Infinity
223
- ? 0
224
- : latestDateMS;
225
- }
226
- }
227
-
228
- makePanelTransparent(rootRef);
229
-
230
- return (_ctx, _cache) => {
231
-
232
-
233
-
234
-
235
- return (openBlock(), createElementBlock("div", {
236
- ref_key: "rootRef",
237
- ref: rootRef,
238
- class: "datePicker"
239
- }, [
240
- createVNode(unref(DatePicker), {
241
- modelValue: currentDate.value,
242
- "onUpdate:modelValue": _cache[2] || (_cache[2] = $event => ((currentDate).value = $event)),
243
- modelModifiers: { number: true },
244
- attributes: attributes,
245
- masks: masks.value,
246
- expanded: "",
247
- class: "bg-surface overflow-auto",
248
- style: {"background-color":"transparent","max-width":"100%"}
249
- }, {
250
- footer: withCtx(() => [
251
- createElementVNode("div", _hoisted_1, [
252
- (!__props.hideArrows)
253
- ? withDirectives((openBlock(), createBlock(VBtn, {
254
- key: 0,
255
- density: "compact",
256
- variant: "text",
257
- onClick: _cache[0] || (_cache[0] = $event => (jumpDate(true)))
258
- }, {
259
- default: withCtx(() => [
260
- createVNode(VIcon, {
261
- icon: [unref(mdiRayEndArrow)]
262
- }, null, 8 /* PROPS */, ["icon"])
263
- ]),
264
- _: 1 /* STABLE */
265
- })), [
266
- [Tooltip, 'Set date to oldest available dataset', "bottom"]
267
- ])
268
- : createCommentVNode("v-if", true),
269
- createElementVNode("div", _hoisted_2, [
270
- (!__props.hideInputField)
271
- ? (openBlock(), createElementBlock("input", {
272
- key: 0,
273
- value: new Date(currentDate.value).toLocaleDateString(),
274
- style: {"margin":"1px"},
275
- class: "flex-grow px-1 py-1 dark:bg-gray-700"
276
- }, null, 8 /* PROPS */, _hoisted_3))
277
- : createCommentVNode("v-if", true)
278
- ]),
279
- (!__props.hideArrows)
280
- ? withDirectives((openBlock(), createBlock(VBtn, {
281
- key: 1,
282
- density: "compact",
283
- variant: "text",
284
- onClick: _cache[1] || (_cache[1] = $event => (jumpDate(false)))
285
- }, {
286
- default: withCtx(() => [
287
- createVNode(VIcon, {
288
- icon: [unref(mdiRayStartArrow)]
289
- }, null, 8 /* PROPS */, ["icon"])
290
- ]),
291
- _: 1 /* STABLE */
292
- })), [
293
- [Tooltip, 'Set date to latest available dataset', "bottom"]
294
- ])
295
- : createCommentVNode("v-if", true)
296
- ])
297
- ]),
298
- _: 1 /* STABLE */
299
- }, 8 /* PROPS */, ["modelValue", "attributes", "masks"])
300
- ], 512 /* NEED_PATCH */))
301
- }
302
- }
303
-
304
- };
305
-
306
- export { _sfc_main as default };