@eodash/eodash 5.6.1 → 5.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/client/components/DashboardLayout.vue +1 -1
- package/core/client/composables/index.js +6 -2
- package/core/client/eodashSTAC/EodashCollection.js +5 -25
- package/core/client/eodashSTAC/createLayers.js +23 -9
- package/core/client/eodashSTAC/helpers.js +33 -0
- package/core/client/types.ts +8 -1
- package/core/client/utils/index.js +4 -0
- package/dist/client/{DashboardLayout-CqMb7OXc.js → DashboardLayout-kRsmsNW5.js} +5 -5
- package/dist/client/{DynamicWebComponent-DqKqTf7l.js → DynamicWebComponent-CnKhYo0K.js} +1 -1
- package/dist/client/{EodashChart-PkUQfH0k.js → EodashChart-CLDqE93C.js} +4 -4
- package/dist/client/{EodashDatePicker-DLJGdTtX.js → EodashDatePicker-CMPDT-ce.js} +3 -3
- package/dist/client/{EodashItemFilter-Dk8KjFcX.js → EodashItemFilter-BpdA8QQa.js} +1 -1
- package/dist/client/{EodashLayerControl-CC1Cogrn.js → EodashLayerControl-BHpDA4_0.js} +25 -7
- package/dist/client/{EodashLayoutSwitcher-5WZYd6rr.js → EodashLayoutSwitcher-B1fRUt7G.js} +3 -3
- package/dist/client/EodashMapBtns-Cpned0tc.js +478 -0
- package/dist/client/{EodashStacInfo-B90wobPc.js → EodashStacInfo-BQspAHKH.js} +1 -1
- package/dist/client/{EodashTools-CGZtTh45.js → EodashTools-1zHz26gv.js} +4 -4
- package/dist/client/{ExportState-Ce0ZnrX_.js → ExportState-DbOm8hBI.js} +4 -4
- package/dist/client/{Footer-CnZqEiop.js → Footer-BKg-VVkj.js} +1 -1
- package/dist/client/{Header-Dr5PBIm8.js → Header-DCrwCvmY.js} +2 -2
- package/dist/client/MobileLayout-vWSHpluo.js +118 -0
- package/dist/client/{PopUp-DjvE_71e.js → PopUp-9uimfK49.js} +2 -2
- package/dist/client/{ProcessList-kf3olI7W.js → ProcessList-CTTIZa06.js} +4 -4
- package/dist/client/{VImg-Bj6uWt6j.js → VImg-CrmB76ZY.js} +2 -2
- package/dist/client/{VMain-Cm0UmKGi.js → VMain-OKZNpcEG.js} +1 -1
- package/dist/client/{VTooltip-DbBu-ky3.js → VTooltip-CJw2FyWk.js} +2 -2
- package/dist/client/{WidgetsContainer-CfLnd44U.js → WidgetsContainer-BaWOnE5R.js} +1 -1
- package/dist/client/{asWebComponent-DfULAbpq.js → asWebComponent-BHWpMuE3.js} +47 -39
- package/dist/client/{async-CIbKXEEe.js → async-DSKj6g1f.js} +21 -10
- package/dist/client/create-layers-config-CBoYedqB.js +182 -0
- package/dist/client/eo-dash.js +1 -1
- package/dist/client/{forwardRefs-yj3VWOK5.js → forwardRefs-DH51zPUr.js} +2 -2
- package/dist/client/{handling-s8xt2JwF.js → handling-BrcDDlgS.js} +123 -85
- package/dist/client/{helpers-DAVGYl_f.js → helpers-DjZVl_WF.js} +2273 -1500
- package/dist/client/{index-4TrjfJ32.js → index-1JKE68n3.js} +49 -194
- package/dist/client/{index-CugS__t5.js → index-5Jhsa8Xe.js} +3 -3
- package/dist/client/index-CSG_JoOA.js +436 -0
- package/dist/client/{index-CYz6dT7K.js → index-CUjl-ZsI.js} +2 -2
- package/dist/client/{index-Bu8BMA9q.js → index-Cu3-13Xg.js} +69 -83
- package/dist/client/material-symbols-outlined.woff2 +0 -0
- package/dist/client/material-symbols-rounded.woff2 +0 -0
- package/dist/client/material-symbols-sharp.woff2 +0 -0
- package/dist/client/material-symbols-subset.woff2 +0 -0
- package/dist/client/templates.js +1 -1
- package/dist/client/{transition-DaOsiD4u.js → transition-OHcz5Qq1.js} +1 -1
- package/dist/node/cli.js +1 -1
- package/dist/types/core/client/composables/index.d.ts +1 -3
- package/dist/types/core/client/eodashSTAC/EodashCollection.d.ts +6 -7
- package/dist/types/core/client/eodashSTAC/createLayers.d.ts +3 -3
- package/dist/types/core/client/eodashSTAC/helpers.d.ts +1 -0
- package/dist/types/core/client/types.d.ts +8 -1
- package/dist/types/templates/baseConfig.d.ts +12 -0
- package/dist/types/widgets/EodashLayerControl.vue.d.ts +1 -1
- package/dist/types/widgets/EodashMap/EodashMapBtns.vue.d.ts +9 -0
- package/dist/types/widgets/EodashMap/index.vue.d.ts +7 -0
- package/dist/types/widgets/EodashMap/methods/create-layers-config.d.ts +1 -8
- package/dist/types/widgets/EodashProcess/methods/composables.d.ts +1 -1
- package/dist/types/widgets/EodashProcess/methods/handling.d.ts +13 -8
- package/dist/types/widgets/EodashTimeSlider/index.vue.d.ts +34 -0
- package/dist/types/widgets/EodashTimeSlider/methods/index.d.ts +39 -0
- package/dist/types/widgets/EodashTimeSlider/types.d.ts +62 -0
- package/package.json +32 -32
- package/widgets/EodashLayerControl.vue +22 -3
- package/widgets/EodashMap/EodashMapBtns.vue +46 -1
- package/widgets/EodashMap/index.vue +17 -5
- package/widgets/EodashMap/methods/create-layers-config.js +2 -0
- package/widgets/EodashMap/methods/index.js +23 -5
- package/widgets/EodashProcess/index.vue +1 -1
- package/widgets/EodashProcess/methods/async.js +19 -8
- package/widgets/EodashProcess/methods/composables.js +63 -77
- package/widgets/EodashProcess/methods/custom-endpoints/chart/sentinelhub-endpoint.js +9 -5
- package/widgets/EodashProcess/methods/custom-endpoints/chart/veda-endpoint.js +7 -4
- package/widgets/EodashProcess/methods/handling.js +105 -72
- package/widgets/EodashTimeSlider/index.vue +152 -0
- package/widgets/EodashTimeSlider/methods/index.js +279 -0
- package/widgets/EodashTimeSlider/types.ts +64 -0
- package/dist/client/EodashMapBtns-BHrSDNoC.js +0 -435
- package/dist/client/EodashTimeSlider-5vm7F3ju.js +0 -53
- package/dist/client/MobileLayout-DyMjaeif.js +0 -118
- package/dist/types/widgets/EodashTimeSlider.vue.d.ts +0 -15
- package/widgets/EodashTimeSlider.vue +0 -40
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
<script setup>
|
|
25
25
|
import "color-legend-element";
|
|
26
26
|
import "@eox/timecontrol";
|
|
27
|
-
import { computed, ref } from "vue";
|
|
27
|
+
import { computed, ref, watch } from "vue";
|
|
28
28
|
import { mapEl, mapCompareEl } from "@/store/states";
|
|
29
29
|
import { getColFromLayer } from "@/eodashSTAC/helpers";
|
|
30
30
|
import {
|
|
@@ -36,6 +36,7 @@ import {
|
|
|
36
36
|
import { storeToRefs } from "pinia";
|
|
37
37
|
import { useSTAcStore } from "@/store/stac";
|
|
38
38
|
import { bandsEditorInterface } from "@/utils/bands-editor";
|
|
39
|
+
import { useEmitLayersUpdate } from "@/composables";
|
|
39
40
|
|
|
40
41
|
if (!customElements.get("eox-layercontrol")) {
|
|
41
42
|
await import("@eox/layercontrol");
|
|
@@ -70,6 +71,7 @@ const config = {
|
|
|
70
71
|
};
|
|
71
72
|
|
|
72
73
|
const { selectedCompareStac, selectedStac } = storeToRefs(useSTAcStore());
|
|
74
|
+
|
|
73
75
|
const showControls = computed(() => {
|
|
74
76
|
if (props.map === "second") {
|
|
75
77
|
return mapCompareEl.value !== null && selectedCompareStac.value !== null;
|
|
@@ -84,9 +86,20 @@ const mapElement = props.map === "second" ? mapCompareEl : mapEl;
|
|
|
84
86
|
/** @type { import("vue").Ref<HTMLElement & Record<string,any> | null>} */
|
|
85
87
|
const eoxLayercontrol = ref(null);
|
|
86
88
|
|
|
89
|
+
// eox-timecontrol re-fires datetime:updated after layer reassignment;
|
|
90
|
+
// dedupe by (collectionId, datetime)
|
|
91
|
+
const processedDatetimes = new Map();
|
|
92
|
+
watch([selectedStac, selectedCompareStac], () => processedDatetimes.clear());
|
|
93
|
+
|
|
87
94
|
/** @param {CustomEvent<{layer:import('ol/layer').Layer; datetime:string;}>} evt */
|
|
88
95
|
const handleDatetimeUpdate = async (evt) => {
|
|
89
96
|
const { layer, datetime } = evt.detail;
|
|
97
|
+
const collectionId = layer.get("id")?.split(";:;")[0] ?? layer.get("id");
|
|
98
|
+
if (processedDatetimes.get(collectionId) === datetime) return;
|
|
99
|
+
// First event per collection is eox-timecontrol's mount echo.
|
|
100
|
+
const isFirstEvent = !processedDatetimes.has(collectionId);
|
|
101
|
+
processedDatetimes.set(collectionId, datetime);
|
|
102
|
+
if (isFirstEvent) return;
|
|
90
103
|
|
|
91
104
|
const ec = await getColFromLayer(eodashCols, layer);
|
|
92
105
|
|
|
@@ -97,9 +110,10 @@ const handleDatetimeUpdate = async (evt) => {
|
|
|
97
110
|
updatedLayers = await ec.updateLayerJson(
|
|
98
111
|
datetime,
|
|
99
112
|
layer.get("id"),
|
|
100
|
-
|
|
113
|
+
mapElement.value?.layers ?? [],
|
|
101
114
|
);
|
|
102
115
|
}
|
|
116
|
+
if (!updatedLayers?.length) return;
|
|
103
117
|
/** @type {Record<String,any>[] | undefined} */
|
|
104
118
|
const dataLayers = updatedLayers?.find(
|
|
105
119
|
(l) => l?.properties?.id === "AnalysisGroup",
|
|
@@ -111,9 +125,14 @@ const handleDatetimeUpdate = async (evt) => {
|
|
|
111
125
|
dl.properties.layerControlExpand = true;
|
|
112
126
|
dl.properties.layerControlToolsExpand = true;
|
|
113
127
|
});
|
|
114
|
-
// assign layers to the map
|
|
115
128
|
/** @type {HTMLElement & Record<string,any>} */
|
|
116
129
|
(mapElement.value).layers = updatedLayers;
|
|
130
|
+
// Emit after layer assignment so listeners resolve against the new layer.
|
|
131
|
+
await useEmitLayersUpdate(
|
|
132
|
+
props.map === "second" ? "compareLayertime:updated" : "layertime:updated",
|
|
133
|
+
mapElement.value,
|
|
134
|
+
updatedLayers,
|
|
135
|
+
);
|
|
117
136
|
}
|
|
118
137
|
};
|
|
119
138
|
|
|
@@ -80,6 +80,28 @@
|
|
|
80
80
|
{{ isGlobe ? "switch to 2D" : "switch to 3D" }}
|
|
81
81
|
</div>
|
|
82
82
|
</button>
|
|
83
|
+
<button
|
|
84
|
+
v-if="enableFeedback && eodash?.brand?.feedback"
|
|
85
|
+
class="primary small circle small-elevate"
|
|
86
|
+
@click="showFeedback = !showFeedback"
|
|
87
|
+
>
|
|
88
|
+
<i class="small"
|
|
89
|
+
><svg viewBox="0 0 24 24">
|
|
90
|
+
<path :d="mdiMessageQuestion" />
|
|
91
|
+
</svg>
|
|
92
|
+
</i>
|
|
93
|
+
<div class="tooltip left">Provide Feedback</div>
|
|
94
|
+
</button>
|
|
95
|
+
<div
|
|
96
|
+
v-if="showFeedback && enableFeedback && eodash?.brand?.feedback"
|
|
97
|
+
class="feedback-container small-elevate"
|
|
98
|
+
>
|
|
99
|
+
<eox-feedback
|
|
100
|
+
:endpoint="eodash?.brand?.feedback?.endpoint"
|
|
101
|
+
.schema="eodash?.brand?.feedback?.schema"
|
|
102
|
+
@close="showFeedback = false"
|
|
103
|
+
></eox-feedback>
|
|
104
|
+
</div>
|
|
83
105
|
<eox-geosearch
|
|
84
106
|
v-if="mapEl && !isGlobe && enableSearch"
|
|
85
107
|
:for="mapEl"
|
|
@@ -110,7 +132,7 @@
|
|
|
110
132
|
</div>
|
|
111
133
|
</template>
|
|
112
134
|
<script setup>
|
|
113
|
-
import { useTransparentPanel } from "@/composables";
|
|
135
|
+
import { useTransparentPanel, useEodash } from "@/composables";
|
|
114
136
|
import { changeMapProjection } from "@/store/actions";
|
|
115
137
|
import {
|
|
116
138
|
activeTemplate,
|
|
@@ -129,6 +151,7 @@ import {
|
|
|
129
151
|
mdiPlus,
|
|
130
152
|
mdiStarFourPointsCircleOutline,
|
|
131
153
|
mdiEarth,
|
|
154
|
+
mdiMessageQuestion,
|
|
132
155
|
} from "@mdi/js";
|
|
133
156
|
import ExportState from "^/ExportState.vue";
|
|
134
157
|
import { computed, ref } from "vue";
|
|
@@ -146,6 +169,12 @@ import {
|
|
|
146
169
|
} from "./methods/btns";
|
|
147
170
|
import "@eox/geosearch";
|
|
148
171
|
|
|
172
|
+
if (!customElements.get("eox-feedback")) {
|
|
173
|
+
//@ts-expect-error will be fixed in https://github.com/EOX-A/EOxElements/pull/2238
|
|
174
|
+
await import("@eox/feedback");
|
|
175
|
+
}
|
|
176
|
+
const eodash = useEodash();
|
|
177
|
+
|
|
149
178
|
const {
|
|
150
179
|
compareIndicators,
|
|
151
180
|
changeProjection,
|
|
@@ -155,6 +184,7 @@ const {
|
|
|
155
184
|
enableZoom,
|
|
156
185
|
searchParams,
|
|
157
186
|
enableGlobe,
|
|
187
|
+
enableFeedback,
|
|
158
188
|
} = defineProps({
|
|
159
189
|
exportMap: {
|
|
160
190
|
type: Boolean,
|
|
@@ -193,6 +223,10 @@ const {
|
|
|
193
223
|
type: Boolean,
|
|
194
224
|
default: true,
|
|
195
225
|
},
|
|
226
|
+
enableFeedback: {
|
|
227
|
+
type: Boolean,
|
|
228
|
+
default: true,
|
|
229
|
+
},
|
|
196
230
|
});
|
|
197
231
|
|
|
198
232
|
const { smAndDown } = useDisplay();
|
|
@@ -200,6 +234,7 @@ const popupWidth = computed(() => (smAndDown.value ? "80%" : "70%"));
|
|
|
200
234
|
const popupHeight = computed(() => (smAndDown.value ? "90%" : "70%"));
|
|
201
235
|
|
|
202
236
|
const showMapState = ref(false);
|
|
237
|
+
const showFeedback = ref(false);
|
|
203
238
|
const isInCompareMode = computed(
|
|
204
239
|
() =>
|
|
205
240
|
activeTemplate.value ===
|
|
@@ -246,6 +281,16 @@ const opencageUrl = `https://api.opencagedata.com/geocode/v1/json?key=${opencage
|
|
|
246
281
|
margin-bottom: 5px;
|
|
247
282
|
background-color: var(--primary);
|
|
248
283
|
}
|
|
284
|
+
|
|
285
|
+
.feedback-container {
|
|
286
|
+
position: absolute;
|
|
287
|
+
right: 70px;
|
|
288
|
+
pointer-events: auto;
|
|
289
|
+
z-index: 20;
|
|
290
|
+
border-radius: 8px;
|
|
291
|
+
min-width: 300px;
|
|
292
|
+
}
|
|
293
|
+
|
|
249
294
|
/* Make sure buttons have pointer event */
|
|
250
295
|
.geosearch-detached {
|
|
251
296
|
pointer-events: auto !important;
|
|
@@ -61,6 +61,7 @@
|
|
|
61
61
|
:enableZoom="(indicator || compareIndicator || poi) ? btnsProps.enableZoom : false
|
|
62
62
|
"
|
|
63
63
|
:enableGlobe="(indicator || compareIndicator || poi) ? btnsProps.enableGlobe : false"
|
|
64
|
+
:enableFeedback="(indicator || compareIndicator || poi) ? btnsProps.enableFeedback : false"
|
|
64
65
|
:searchParams="btnsProps.searchParams"
|
|
65
66
|
/>
|
|
66
67
|
</div>
|
|
@@ -69,7 +70,7 @@
|
|
|
69
70
|
<script setup>
|
|
70
71
|
import "@eox/map";
|
|
71
72
|
import "@eox/map/src/plugins/advancedLayersAndSources";
|
|
72
|
-
import { computed, onMounted, ref, toRaw, useTemplateRef } from "vue";
|
|
73
|
+
import { nextTick, computed, onMounted, ref, toRaw, useTemplateRef } from "vue";
|
|
73
74
|
import {
|
|
74
75
|
datetime,
|
|
75
76
|
mapEl,
|
|
@@ -142,6 +143,7 @@ const props = defineProps({
|
|
|
142
143
|
* searchParams?: object;
|
|
143
144
|
* enableZoom?: boolean;
|
|
144
145
|
* enableGlobe?: boolean;
|
|
146
|
+
* enableFeedback?: boolean;
|
|
145
147
|
* enableCompareIndicators?: boolean | {
|
|
146
148
|
* compareTemplate?:string;
|
|
147
149
|
* fallbackTemplate?:string;
|
|
@@ -157,6 +159,7 @@ const props = defineProps({
|
|
|
157
159
|
enableSearch: true,
|
|
158
160
|
enableZoom: true,
|
|
159
161
|
enableGlobe: true,
|
|
162
|
+
enableFeedback: true,
|
|
160
163
|
searchParams: {},
|
|
161
164
|
}),
|
|
162
165
|
},
|
|
@@ -200,6 +203,7 @@ const btnsProps = computed(() => ({
|
|
|
200
203
|
enableSearch: props.btns.enableSearch ?? true,
|
|
201
204
|
enableZoom: props.btns.enableZoom ?? true,
|
|
202
205
|
enableGlobe: props.btns.enableGlobe ?? true,
|
|
206
|
+
enableFeedback: props.btns.enableFeedback ?? true,
|
|
203
207
|
searchParams: props.btns.searchParams,
|
|
204
208
|
}));
|
|
205
209
|
|
|
@@ -241,7 +245,11 @@ const controls = computed(() => {
|
|
|
241
245
|
controlsObj.MousePosition = {
|
|
242
246
|
projection: "EPSG:4326",
|
|
243
247
|
coordinateFormat: (/** @type {[number, number]} */ c) => {
|
|
244
|
-
|
|
248
|
+
const lat = c[1];
|
|
249
|
+
const lng = c[0];
|
|
250
|
+
const latStr = `${Math.abs(lat).toFixed(3)}°${lat >= 0 ? "N" : "S"}`;
|
|
251
|
+
const lngStr = `${Math.abs(lng).toFixed(3)}°${lng >= 0 ? "E" : "W"}`;
|
|
252
|
+
return `${latStr}, ${lngStr}`;
|
|
245
253
|
},
|
|
246
254
|
target: cursorCoordsRef.value,
|
|
247
255
|
};
|
|
@@ -276,10 +284,10 @@ const eoxMapCompareLayers = ref([
|
|
|
276
284
|
},
|
|
277
285
|
]);
|
|
278
286
|
|
|
279
|
-
const animationOptions = {
|
|
280
|
-
duration:
|
|
287
|
+
const animationOptions = ref({
|
|
288
|
+
duration: 0, // Initially set to 0 for an instant "jump"
|
|
281
289
|
easing: inAndOut,
|
|
282
|
-
};
|
|
290
|
+
});
|
|
283
291
|
|
|
284
292
|
/** @type {import("vue").Ref<import("@eox/map").EOxMap | null>} */
|
|
285
293
|
const eoxMap = ref(null);
|
|
@@ -330,6 +338,10 @@ onMounted(() => {
|
|
|
330
338
|
props.zoomToExtent,
|
|
331
339
|
selectedItem,
|
|
332
340
|
);
|
|
341
|
+
// After the initial mount and "jump", set the animation duration for subsequent flyTo calls
|
|
342
|
+
nextTick(() => {
|
|
343
|
+
animationOptions.value.duration = 1200;
|
|
344
|
+
});
|
|
333
345
|
});
|
|
334
346
|
|
|
335
347
|
useUpdateTooltipProperties(eodashCollections, tooltipProperties);
|
|
@@ -10,6 +10,7 @@ import log from "loglevel";
|
|
|
10
10
|
* } selectedIndicator
|
|
11
11
|
* @param {EodashCollection[]} eodashCols
|
|
12
12
|
* @param {string | import("stac-ts").StacItem | null} [timeOrItem] - time as a string, or a stac item
|
|
13
|
+
* @returns {Promise<Record<string, any>[]>}
|
|
13
14
|
*/
|
|
14
15
|
|
|
15
16
|
export const createLayersConfig = async (
|
|
@@ -68,6 +69,7 @@ export const createLayersConfig = async (
|
|
|
68
69
|
if (targetLayer) {
|
|
69
70
|
if (Array.isArray(vl.roles) && vl.roles.includes("disable")) {
|
|
70
71
|
targetLayer.properties.visible = false;
|
|
72
|
+
targetLayer.properties.layerControlExpand = false;
|
|
71
73
|
} else if (Array.isArray(vl.roles) && vl.roles.includes("hidden")) {
|
|
72
74
|
targetLayer.properties.layerControlHide = true;
|
|
73
75
|
}
|
|
@@ -83,6 +83,10 @@ export const useInitMap = (
|
|
|
83
83
|
const watching = selectedItem
|
|
84
84
|
? [selectedIndicator, datetime, selectedItem]
|
|
85
85
|
: [selectedIndicator, datetime];
|
|
86
|
+
// Tags datetime values we set ourselves so the watcher skips its own echo.
|
|
87
|
+
/** @type {string | null} */
|
|
88
|
+
let internalDatetime = null;
|
|
89
|
+
|
|
86
90
|
const stopIndicatorWatcher = watch(
|
|
87
91
|
watching,
|
|
88
92
|
async (updated, previous) => {
|
|
@@ -96,6 +100,16 @@ export const useInitMap = (
|
|
|
96
100
|
);
|
|
97
101
|
|
|
98
102
|
if (updatedStac) {
|
|
103
|
+
if (
|
|
104
|
+
internalDatetime !== null &&
|
|
105
|
+
updatedTime === internalDatetime &&
|
|
106
|
+
updatedStac?.id === previousStac?.id &&
|
|
107
|
+
updatedItem?.id === previousItem?.id
|
|
108
|
+
) {
|
|
109
|
+
internalDatetime = null;
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
99
113
|
log.debug(
|
|
100
114
|
"Selected Indicator watch triggered",
|
|
101
115
|
updatedStac,
|
|
@@ -145,7 +159,6 @@ export const useInitMap = (
|
|
|
145
159
|
JSON.parse(JSON.stringify(layersCollection)),
|
|
146
160
|
);
|
|
147
161
|
mapLayers.value = layersCollection;
|
|
148
|
-
|
|
149
162
|
useEmitLayersUpdate(
|
|
150
163
|
mapElement.value?.id === "compare"
|
|
151
164
|
? "compareTime:updated"
|
|
@@ -167,22 +180,27 @@ export const useInitMap = (
|
|
|
167
180
|
endInterval,
|
|
168
181
|
);
|
|
169
182
|
}
|
|
183
|
+
let resolvedTime = updatedItem ?? updatedTime;
|
|
170
184
|
if (
|
|
171
185
|
!updatedItem &&
|
|
172
186
|
endInterval !== null &&
|
|
173
187
|
endInterval.toISOString() !== datetime.value &&
|
|
174
188
|
!isFirstLoad.value
|
|
175
189
|
) {
|
|
176
|
-
|
|
190
|
+
resolvedTime = endInterval.toISOString();
|
|
191
|
+
internalDatetime = resolvedTime;
|
|
192
|
+
datetime.value = resolvedTime;
|
|
177
193
|
} else if (isFirstLoad.value && !datetime.value && endInterval) {
|
|
178
|
-
|
|
194
|
+
resolvedTime = endInterval.toISOString();
|
|
195
|
+
internalDatetime = resolvedTime;
|
|
196
|
+
datetime.value = resolvedTime;
|
|
179
197
|
}
|
|
180
198
|
|
|
181
199
|
/** @type {Record<string,any>[]} */
|
|
182
200
|
layersCollection = await createLayersConfig(
|
|
183
201
|
updatedStac,
|
|
184
202
|
eodashCols,
|
|
185
|
-
|
|
203
|
+
resolvedTime,
|
|
186
204
|
);
|
|
187
205
|
|
|
188
206
|
if (zoomToExtent) {
|
|
@@ -251,7 +269,7 @@ export const useUpdateTooltipProperties = (
|
|
|
251
269
|
* @param {string} evt */
|
|
252
270
|
const listenTo = (evt) =>
|
|
253
271
|
enableCompare ? evt.includes("compare") : !evt.includes("compare");
|
|
254
|
-
useOnLayersUpdate(async (evt
|
|
272
|
+
useOnLayersUpdate(async (evt) => {
|
|
255
273
|
if (!listenTo(evt)) {
|
|
256
274
|
return;
|
|
257
275
|
}
|
|
@@ -106,16 +106,27 @@ export async function updateJobsStatus(jobs, indicator) {
|
|
|
106
106
|
jobsUrls.map((url) =>
|
|
107
107
|
axios
|
|
108
108
|
.get(url, { params: { t: Date.now() } })
|
|
109
|
-
.then((response) => response.data)
|
|
109
|
+
.then((response) => response.data)
|
|
110
|
+
.catch((error) => {
|
|
111
|
+
if (axios.isAxiosError(error)) {
|
|
112
|
+
console.warn(
|
|
113
|
+
`Job URL not accessible: ${url}. Maybe was deleted from the processing endpoint or endpoint is unavailable. Skipping...`,
|
|
114
|
+
);
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
throw error;
|
|
118
|
+
}),
|
|
110
119
|
),
|
|
111
120
|
);
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
121
|
+
const validResults = jobResults
|
|
122
|
+
.filter((job) => job !== null)
|
|
123
|
+
.sort((a, b) => {
|
|
124
|
+
return (
|
|
125
|
+
new Date(b.job_start_datetime).getTime() -
|
|
126
|
+
new Date(a.job_start_datetime).getTime()
|
|
127
|
+
);
|
|
128
|
+
});
|
|
129
|
+
jobs.value.splice(0, jobs.value.length, ...validResults);
|
|
119
130
|
}
|
|
120
131
|
|
|
121
132
|
/**
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { initProcess, updateJsonformIdentifier } from "./handling";
|
|
2
|
-
import {
|
|
3
|
-
import { nextTick, onMounted, watch } from "vue";
|
|
4
|
-
import { eoxLayersKey } from "@/utils/keys";
|
|
2
|
+
import { nextTick, onMounted, onUnmounted, watch } from "vue";
|
|
5
3
|
import { useOnLayersUpdate } from "@/composables";
|
|
4
|
+
import { getCompareLayers, getLayers } from "@/store/actions";
|
|
6
5
|
/**
|
|
7
6
|
* Composable resposible of timing the Initialization of the process
|
|
8
7
|
*
|
|
@@ -15,7 +14,7 @@ import { useOnLayersUpdate } from "@/composables";
|
|
|
15
14
|
* @param {import("vue").Ref<boolean>} params.isProcessed
|
|
16
15
|
* @param {import("vue").Ref<boolean>} params.loading
|
|
17
16
|
* @param {import("vue").Ref<boolean>} params.isPolling
|
|
18
|
-
* @param {import("@eox/map").EOxMap | null} params.mapElement
|
|
17
|
+
* @param {import("vue").Ref<import("@eox/map").EOxMap | null>} params.mapElement
|
|
19
18
|
*/
|
|
20
19
|
export const useInitProcess = ({
|
|
21
20
|
selectedStac,
|
|
@@ -26,60 +25,45 @@ export const useInitProcess = ({
|
|
|
26
25
|
isPolling,
|
|
27
26
|
mapElement,
|
|
28
27
|
}) => {
|
|
29
|
-
const layersEvents = useEventBus(eoxLayersKey);
|
|
30
|
-
|
|
31
28
|
onMounted(async () => {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
});
|
|
43
|
-
} else {
|
|
44
|
-
layersEvents.once(async () => {
|
|
45
|
-
await initProcess({
|
|
46
|
-
enableCompare: mapElement?.id === "compare",
|
|
47
|
-
selectedStac,
|
|
48
|
-
jsonformSchema,
|
|
49
|
-
isProcessed,
|
|
50
|
-
loading,
|
|
51
|
-
processResults,
|
|
52
|
-
isPolling,
|
|
53
|
-
});
|
|
54
|
-
});
|
|
55
|
-
}
|
|
29
|
+
await initProcess({
|
|
30
|
+
enableCompare: mapElement.value?.id === "compare",
|
|
31
|
+
selectedStac,
|
|
32
|
+
jsonformSchema,
|
|
33
|
+
isProcessed,
|
|
34
|
+
processResults,
|
|
35
|
+
loading,
|
|
36
|
+
isPolling,
|
|
37
|
+
mapElement: mapElement.value,
|
|
38
|
+
});
|
|
56
39
|
});
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
40
|
+
|
|
41
|
+
useOnLayersUpdate(async (evt) => {
|
|
42
|
+
const enableCompare = mapElement.value?.id === "compare";
|
|
43
|
+
const layerUpdatedKey = enableCompare
|
|
44
|
+
? "compareLayers:updated"
|
|
45
|
+
: "layers:updated";
|
|
46
|
+
const timeUpdatedKeys = enableCompare
|
|
47
|
+
? ["compareLayertime:updated", "compareTime:updated"]
|
|
48
|
+
: ["layertime:updated", "time:updated"];
|
|
49
|
+
|
|
50
|
+
if (timeUpdatedKeys.includes(evt)) {
|
|
51
|
+
// we need to update jsonform on time change in cases
|
|
52
|
+
// when the feature selection layer was time-based,
|
|
53
|
+
// so that it attaches to a correct new layer
|
|
54
|
+
const newJsonForm = await updateJsonformIdentifier({
|
|
55
|
+
jsonformSchema: jsonformSchema.value,
|
|
56
|
+
newLayers: enableCompare ? getCompareLayers() : getLayers(),
|
|
57
|
+
enableCompare,
|
|
58
|
+
mapElement: mapElement.value,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
if (newJsonForm) {
|
|
79
62
|
jsonformSchema.value = newJsonForm;
|
|
80
63
|
}
|
|
81
64
|
}
|
|
82
|
-
|
|
65
|
+
|
|
66
|
+
if (evt !== layerUpdatedKey) {
|
|
83
67
|
return;
|
|
84
68
|
}
|
|
85
69
|
await initProcess({
|
|
@@ -90,6 +74,7 @@ export const useInitProcess = ({
|
|
|
90
74
|
processResults,
|
|
91
75
|
loading,
|
|
92
76
|
isPolling,
|
|
77
|
+
mapElement: mapElement.value,
|
|
93
78
|
});
|
|
94
79
|
});
|
|
95
80
|
};
|
|
@@ -109,38 +94,39 @@ export function useAutoExec(
|
|
|
109
94
|
startProcess,
|
|
110
95
|
) {
|
|
111
96
|
/**
|
|
112
|
-
* @param {
|
|
97
|
+
* @param {any} _e
|
|
113
98
|
**/
|
|
114
99
|
const onJsonFormChange = async (_e) => {
|
|
115
100
|
await startProcess();
|
|
116
101
|
};
|
|
117
102
|
|
|
118
|
-
const addEventListener = async () => {
|
|
119
|
-
await nextTick(() => {
|
|
120
|
-
//@ts-expect-error TODO
|
|
121
|
-
jsonformEl.value?.addEventListener("change", onJsonFormChange);
|
|
122
|
-
});
|
|
123
|
-
};
|
|
124
|
-
const removeEventListener = () => {
|
|
125
|
-
//@ts-expect-error TODO
|
|
126
|
-
jsonformEl.value?.removeEventListener("change", onJsonFormChange);
|
|
127
|
-
};
|
|
128
|
-
|
|
129
103
|
watch(jsonformSchema, (updatedSchema) => {
|
|
130
104
|
autoExec.value = updatedSchema?.options?.["execute"] || false;
|
|
131
105
|
});
|
|
132
106
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
107
|
+
// Re-attach listener whenever the element or autoExec changes
|
|
108
|
+
const stop = watch(
|
|
109
|
+
[autoExec, jsonformEl],
|
|
110
|
+
async ([exec, el], [_prevExec, prevEl]) => {
|
|
111
|
+
// Cleanup if previous element existed
|
|
112
|
+
if (prevEl) {
|
|
113
|
+
prevEl.removeEventListener("change", onJsonFormChange);
|
|
114
|
+
}
|
|
115
|
+
// Add if enabled and we have an element
|
|
116
|
+
if (exec && el) {
|
|
117
|
+
// remove listener before adding to avoid duplicates in case of element change
|
|
118
|
+
el.removeEventListener("change", onJsonFormChange);
|
|
119
|
+
await nextTick();
|
|
120
|
+
el.addEventListener("change", onJsonFormChange);
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
{ immediate: true },
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
onUnmounted(() => {
|
|
127
|
+
if (jsonformEl.value) {
|
|
128
|
+
jsonformEl.value.removeEventListener("change", onJsonFormChange);
|
|
129
|
+
}
|
|
130
|
+
stop();
|
|
145
131
|
});
|
|
146
132
|
}
|
|
@@ -58,7 +58,7 @@ export async function handleSentinelHubProcess({
|
|
|
58
58
|
);
|
|
59
59
|
|
|
60
60
|
// fetch data from sentinel hub
|
|
61
|
-
|
|
61
|
+
const results = await Promise.all(
|
|
62
62
|
timePairs.map(([to, from]) => {
|
|
63
63
|
return fetchSentinelHubData({
|
|
64
64
|
url: endpoint,
|
|
@@ -67,14 +67,18 @@ export async function handleSentinelHubProcess({
|
|
|
67
67
|
from,
|
|
68
68
|
to,
|
|
69
69
|
exampleLink: evalScriptLink,
|
|
70
|
-
}).catch((err) =>
|
|
70
|
+
}).catch((err) => {
|
|
71
71
|
console.error(
|
|
72
72
|
"[eodash] Error while fetching data from sentinel hub endpoint:",
|
|
73
73
|
err,
|
|
74
|
-
)
|
|
75
|
-
|
|
74
|
+
);
|
|
75
|
+
return [];
|
|
76
|
+
});
|
|
76
77
|
}),
|
|
77
|
-
)
|
|
78
|
+
)
|
|
79
|
+
.then((data) => data.filter((result) => result.length > 0))
|
|
80
|
+
.then((data) => data.flat().map((data) => data.outputs.data));
|
|
81
|
+
return results;
|
|
78
82
|
}
|
|
79
83
|
|
|
80
84
|
/**
|
|
@@ -37,7 +37,7 @@ export async function handleVedaEndpoint({
|
|
|
37
37
|
vedaLink,
|
|
38
38
|
);
|
|
39
39
|
// TODO: convert jsonform bbox type to geojson in the schema to avoid the conversion here
|
|
40
|
-
|
|
40
|
+
const results = await Promise.all(
|
|
41
41
|
configs.map(({ endpoint, datetime }) => {
|
|
42
42
|
const url = new URL(vedaEndpoint);
|
|
43
43
|
const key = vedaLink.endpoint === "veda_stac" ? "ids" : "url";
|
|
@@ -56,14 +56,17 @@ export async function handleVedaEndpoint({
|
|
|
56
56
|
fetchedSats.date = datetime;
|
|
57
57
|
return fetchedSats;
|
|
58
58
|
})
|
|
59
|
-
.catch((resp) =>
|
|
59
|
+
.catch((resp) => {
|
|
60
60
|
console.error(
|
|
61
61
|
"[eodash] Error while fetching data from veda endpoint:",
|
|
62
62
|
resp,
|
|
63
|
-
)
|
|
64
|
-
|
|
63
|
+
);
|
|
64
|
+
return null;
|
|
65
|
+
});
|
|
65
66
|
}),
|
|
66
67
|
);
|
|
68
|
+
// Filter out the nulls (failed requests) before returning
|
|
69
|
+
return results.filter((result) => result !== null);
|
|
67
70
|
}
|
|
68
71
|
|
|
69
72
|
/**
|