@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.
- package/README.md +1 -1
- package/core/client/composables/EodashMap.js +47 -28
- package/core/client/composables/EodashProcess.js +51 -5
- package/core/client/composables/index.js +8 -1
- package/core/client/eodash.js +21 -7
- package/core/client/eodashSTAC/EodashCollection.js +24 -4
- package/core/client/eodashSTAC/createLayers.js +62 -6
- package/core/client/eodashSTAC/helpers.js +48 -5
- package/core/client/eodashSTAC/triggers.js +52 -1
- package/core/client/store/stac.js +7 -2
- package/core/client/types.ts +10 -1
- package/core/client/utils/index.js +12 -0
- package/core/client/utils/states.js +18 -1
- package/core/client/views/Dashboard.vue +3 -1
- package/dist/client/{DashboardLayout-B-4X57-t.js → DashboardLayout-VrJIbhe8.js} +2 -2
- package/dist/client/{DynamicWebComponent-Dj3QYwag.js → DynamicWebComponent-BCwpocDX.js} +1 -1
- package/dist/client/EodashDatePicker-Bp5ec3BC.js +430 -0
- package/dist/client/{EodashItemFilter-DBQwJQPh.js → EodashItemFilter-Cx0t-qeW.js} +1 -1
- package/dist/client/{EodashLayerControl-C5fOCvoI.js → EodashLayerControl-DERx00In.js} +10 -2
- package/dist/client/{EodashLayoutSwitcher-BMO9k_20.js → EodashLayoutSwitcher-DTS7otlk.js} +2 -2
- package/dist/client/{EodashMap-D2bnMLAC.js → EodashMap-C-I6puhb.js} +101 -73
- package/dist/client/{EodashMapBtns-l9B977id.js → EodashMapBtns-CWgtJiG4.js} +4 -4
- package/dist/client/{EodashProcess-BtIlJvF1.js → EodashProcess-DWrTIyHT.js} +188 -33
- package/dist/client/{EodashStacInfo-CPVvp_Hm.js → EodashStacInfo-Dvsk97Mz.js} +1 -1
- package/dist/client/{EodashTools-DY2dlNXW.js → EodashTools-CdnjgTTl.js} +4 -4
- package/dist/client/{ExportState-BvD5A0XG.js → ExportState-S4lcehm3.js} +4 -4
- package/dist/client/{Footer-w95gBnSH.js → Footer-DlIEbXp-.js} +1 -1
- package/dist/client/{Header-BpiorKy9.js → Header-CTiEXLi0.js} +3 -3
- package/dist/client/{MobileLayout-CmVlZe7S.js → MobileLayout-DRgyQYFz.js} +17 -7
- package/dist/client/{PopUp-CREaSybs.js → PopUp-CzqV8BFZ.js} +3 -3
- package/dist/client/{VImg-DF9esgdd.js → VImg-Bn8bCvVM.js} +2 -2
- package/dist/client/{VMain-BWLMf-rn.js → VMain-2GOqWb6m.js} +1 -1
- package/dist/client/{VOverlay-DmNfblmy.js → VOverlay-BetC0LGI.js} +3 -3
- package/dist/client/{VTooltip-C3PeE7iO.js → VTooltip-BWg0dxx5.js} +3 -3
- package/dist/client/{WidgetsContainer-6FHEEXns.js → WidgetsContainer-Cv466WUW.js} +1 -1
- package/dist/client/{asWebComponent-BnFMd0T6.js → asWebComponent-CLUhauLl.js} +422 -164
- package/dist/client/eo-dash.css +1 -1
- package/dist/client/eo-dash.js +1 -1
- package/dist/client/{forwardRefs-BF3Me2RX.js → forwardRefs-CxSsJulB.js} +1 -1
- package/dist/client/{index-CRd5-RSy.js → index-BMj56LY3.js} +1 -1
- package/dist/client/{transition-Cpn_g5jE.js → transition-DidoPMgC.js} +1 -1
- package/dist/node/cli.js +2 -2
- package/dist/types/core/client/composables/EodashMap.d.ts +2 -1
- package/dist/types/core/client/composables/EodashProcess.d.ts +17 -11
- package/dist/types/core/client/composables/index.d.ts +1 -1
- package/dist/types/core/client/eodashSTAC/EodashCollection.d.ts +11 -4
- package/dist/types/core/client/eodashSTAC/createLayers.d.ts +6 -6
- package/dist/types/core/client/eodashSTAC/helpers.d.ts +77 -20
- package/dist/types/core/client/eodashSTAC/triggers.d.ts +6 -0
- package/dist/types/core/client/types.d.ts +13 -1
- package/dist/types/core/client/utils/index.d.ts +1 -0
- package/dist/types/core/client/utils/states.d.ts +9 -0
- package/dist/types/widgets/EodashDatePicker.vue.d.ts +459 -2
- package/dist/types/widgets/EodashMap.vue.d.ts +2 -0
- package/dist/types/widgets/EodashProcess.vue.d.ts +1 -0
- package/dist/types/widgets/PopUp.vue.d.ts +1 -2
- package/package.json +24 -24
- package/widgets/EodashDatePicker.vue +139 -22
- package/widgets/EodashLayerControl.vue +13 -1
- package/widgets/EodashMap.vue +63 -5
- package/widgets/EodashProcess.vue +82 -22
- 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 #
|
|
12
|
-
<div
|
|
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="
|
|
29
|
-
|
|
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 {
|
|
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
|
-
|
|
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
|
-
|
|
244
|
+
dot: {
|
|
141
245
|
style: {
|
|
142
|
-
backgroundColor:
|
|
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
|
-
|
|
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 {
|
|
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>
|
package/widgets/EodashMap.vue
CHANGED
|
@@ -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 {
|
|
33
|
-
|
|
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<
|
|
108
|
+
/** @type {import("vue").Ref<import("@eox/map").EOxMap | null>} */
|
|
87
109
|
const eoxMap = ref(null);
|
|
88
|
-
/** @type {import("vue").Ref<
|
|
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
|
-
<
|
|
15
|
-
<
|
|
16
|
-
v-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
|
|
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;
|