@eodash/eodash 5.6.0 → 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.
Files changed (91) hide show
  1. package/core/client/components/DashboardLayout.vue +1 -1
  2. package/core/client/composables/index.js +6 -2
  3. package/core/client/eodashSTAC/EodashCollection.js +5 -21
  4. package/core/client/eodashSTAC/createLayers.js +23 -9
  5. package/core/client/eodashSTAC/helpers.js +37 -4
  6. package/core/client/types.ts +8 -1
  7. package/core/client/utils/index.js +4 -0
  8. package/dist/client/{DashboardLayout-DkKDhfgH.js → DashboardLayout-kRsmsNW5.js} +5 -5
  9. package/dist/client/{DynamicWebComponent-BrpkA-e3.js → DynamicWebComponent-CnKhYo0K.js} +1 -1
  10. package/dist/client/{EodashChart-p7_1FRlF.js → EodashChart-CLDqE93C.js} +4 -4
  11. package/dist/client/{EodashDatePicker-HK0Jl7wQ.js → EodashDatePicker-CMPDT-ce.js} +3 -3
  12. package/dist/client/{EodashItemFilter-BYQDA78B.js → EodashItemFilter-BpdA8QQa.js} +1 -1
  13. package/dist/client/{EodashLayerControl-NcrNncGn.js → EodashLayerControl-BHpDA4_0.js} +25 -7
  14. package/dist/client/{EodashLayoutSwitcher-CC2Znd0I.js → EodashLayoutSwitcher-B1fRUt7G.js} +3 -3
  15. package/dist/client/EodashMapBtns-Cpned0tc.js +478 -0
  16. package/dist/client/{EodashStacInfo-BA-0UjvT.js → EodashStacInfo-BQspAHKH.js} +31 -31
  17. package/dist/client/{EodashTools-CWmoH0g_.js → EodashTools-1zHz26gv.js} +4 -4
  18. package/dist/client/{ExportState-CfAfX4RN.js → ExportState-DbOm8hBI.js} +4 -4
  19. package/dist/client/{Footer-DLGxQTZt.js → Footer-BKg-VVkj.js} +1 -1
  20. package/dist/client/{Header-eyEyyzD6.js → Header-DCrwCvmY.js} +2 -2
  21. package/dist/client/MobileLayout-vWSHpluo.js +118 -0
  22. package/dist/client/{PopUp-WNs6Io2N.js → PopUp-9uimfK49.js} +2 -2
  23. package/dist/client/{ProcessList-RzVqbd5E.js → ProcessList-CTTIZa06.js} +4 -4
  24. package/dist/client/{VImg-GKUTFoV-.js → VImg-CrmB76ZY.js} +2 -2
  25. package/dist/client/{VMain-D7_72mHr.js → VMain-OKZNpcEG.js} +1 -1
  26. package/dist/client/{VTooltip-BbmvtvYw.js → VTooltip-CJw2FyWk.js} +2 -2
  27. package/dist/client/{WidgetsContainer-Dw5d7SOW.js → WidgetsContainer-BaWOnE5R.js} +1 -1
  28. package/dist/client/{asWebComponent-DDt7V3Bl.js → asWebComponent-BHWpMuE3.js} +47 -35
  29. package/dist/client/{async-CT3KEV52.js → async-DSKj6g1f.js} +29 -28
  30. package/dist/client/create-layers-config-CBoYedqB.js +182 -0
  31. package/dist/client/eo-dash.js +1 -1
  32. package/dist/client/{forwardRefs-CVzxyoSq.js → forwardRefs-DH51zPUr.js} +2 -2
  33. package/dist/client/{handling-C285F_Mq.js → handling-BrcDDlgS.js} +452 -114
  34. package/dist/client/{helpers-CZFH0EVN.js → helpers-DjZVl_WF.js} +2277 -1504
  35. package/dist/client/{index-B-m7V3Kb.js → index-1JKE68n3.js} +49 -194
  36. package/dist/client/{index-CF3ZMzTz.js → index-5Jhsa8Xe.js} +3 -3
  37. package/dist/client/index-CSG_JoOA.js +436 -0
  38. package/dist/client/{index-DgOXD7wd.js → index-CUjl-ZsI.js} +2 -2
  39. package/dist/client/{index-B_6H-N14.js → index-Cu3-13Xg.js} +84 -90
  40. package/dist/client/material-symbols-outlined.woff2 +0 -0
  41. package/dist/client/material-symbols-rounded.woff2 +0 -0
  42. package/dist/client/material-symbols-sharp.woff2 +0 -0
  43. package/dist/client/material-symbols-subset.woff2 +0 -0
  44. package/dist/client/templates.js +1 -1
  45. package/dist/client/{transition-C2gnrWg0.js → transition-OHcz5Qq1.js} +1 -1
  46. package/dist/node/cli.js +1 -1
  47. package/dist/types/core/client/composables/index.d.ts +1 -3
  48. package/dist/types/core/client/eodashSTAC/EodashCollection.d.ts +6 -7
  49. package/dist/types/core/client/eodashSTAC/createLayers.d.ts +3 -3
  50. package/dist/types/core/client/eodashSTAC/helpers.d.ts +1 -0
  51. package/dist/types/core/client/types.d.ts +8 -1
  52. package/dist/types/templates/baseConfig.d.ts +12 -0
  53. package/dist/types/widgets/EodashLayerControl.vue.d.ts +1 -1
  54. package/dist/types/widgets/EodashMap/EodashMapBtns.vue.d.ts +9 -0
  55. package/dist/types/widgets/EodashMap/index.vue.d.ts +7 -0
  56. package/dist/types/widgets/EodashMap/methods/create-layers-config.d.ts +1 -8
  57. package/dist/types/widgets/EodashProcess/methods/composables.d.ts +2 -3
  58. package/dist/types/widgets/EodashProcess/methods/handling.d.ts +15 -10
  59. package/dist/types/widgets/EodashProcess/methods/outputs.d.ts +3 -1
  60. package/dist/types/widgets/EodashProcess/methods/template-helpers.d.ts +99 -0
  61. package/dist/types/widgets/EodashProcess/methods/utils.d.ts +1 -6
  62. package/dist/types/widgets/EodashProcess/types.d.ts +1 -0
  63. package/dist/types/widgets/EodashStacInfo.vue.d.ts +10 -10
  64. package/dist/types/widgets/EodashTimeSlider/index.vue.d.ts +34 -0
  65. package/dist/types/widgets/EodashTimeSlider/methods/index.d.ts +39 -0
  66. package/dist/types/widgets/EodashTimeSlider/types.d.ts +62 -0
  67. package/package.json +32 -32
  68. package/widgets/EodashLayerControl.vue +22 -3
  69. package/widgets/EodashMap/EodashMapBtns.vue +46 -1
  70. package/widgets/EodashMap/index.vue +17 -5
  71. package/widgets/EodashMap/methods/create-layers-config.js +2 -0
  72. package/widgets/EodashMap/methods/index.js +23 -5
  73. package/widgets/EodashProcess/index.vue +17 -13
  74. package/widgets/EodashProcess/methods/async.js +19 -8
  75. package/widgets/EodashProcess/methods/composables.js +63 -74
  76. package/widgets/EodashProcess/methods/custom-endpoints/chart/sentinelhub-endpoint.js +9 -5
  77. package/widgets/EodashProcess/methods/custom-endpoints/chart/veda-endpoint.js +7 -4
  78. package/widgets/EodashProcess/methods/handling.js +125 -76
  79. package/widgets/EodashProcess/methods/outputs.js +74 -29
  80. package/widgets/EodashProcess/methods/template-helpers.js +246 -0
  81. package/widgets/EodashProcess/methods/utils.js +7 -17
  82. package/widgets/EodashProcess/types.ts +1 -0
  83. package/widgets/EodashStacInfo.vue +30 -30
  84. package/widgets/EodashTimeSlider/index.vue +152 -0
  85. package/widgets/EodashTimeSlider/methods/index.js +279 -0
  86. package/widgets/EodashTimeSlider/types.ts +64 -0
  87. package/dist/client/EodashMapBtns-BJSh7qT-.js +0 -435
  88. package/dist/client/EodashTimeSlider-GDv1hbw7.js +0 -53
  89. package/dist/client/MobileLayout-RzLOyXwL.js +0 -118
  90. package/dist/types/widgets/EodashTimeSlider.vue.d.ts +0 -15
  91. package/widgets/EodashTimeSlider.vue +0 -40
@@ -0,0 +1,152 @@
1
+ <template>
2
+ <eox-timecontrol
3
+ v-if="hasMultipleItems"
4
+ :key="unref(mapEl)"
5
+ ref="eoxTimecontrol"
6
+ .for="mapEl"
7
+ @select="onSelect"
8
+ titleKey="title"
9
+ .externalMapRendering="true"
10
+ .animate="animate"
11
+ .initDate="initDate"
12
+ >
13
+ <div class="d-flex g-10 align-center">
14
+ <eox-timecontrol-date class="flex-grow-1"></eox-timecontrol-date>
15
+ <eox-timecontrol-picker
16
+ .range="false"
17
+ .showDots="true"
18
+ .showItems="true"
19
+ .popup="true"
20
+ ></eox-timecontrol-picker>
21
+
22
+ <eox-itemfilter
23
+ v-if="filters.length"
24
+ .inlineMode="true"
25
+ :showResults="false"
26
+ .filterProperties="filters"
27
+ ></eox-itemfilter>
28
+ <eox-timecontrol-timelapse @export="onExport"></eox-timecontrol-timelapse>
29
+ </div>
30
+
31
+ <eox-timecontrol-timeline class="mt-2"></eox-timecontrol-timeline>
32
+ </eox-timecontrol>
33
+ </template>
34
+ <script setup>
35
+ import { datetime, mapEl } from "@/store/states";
36
+ import { eodashCollections } from "@/utils/states";
37
+ import "@eox/timecontrol";
38
+ import "@eox/itemfilter";
39
+
40
+ import { computed, onMounted, ref, unref, useTemplateRef } from "vue";
41
+ import { storeToRefs } from "pinia";
42
+ import { useSTAcStore } from "@/store/stac";
43
+ import { createAnimationLayers } from "./methods";
44
+
45
+ const { animate } = defineProps({
46
+ filters: {
47
+ /** @type {import("vue").PropType<import("@eox/itemfilter").EOxItemFilter["filterProperties"]>} */
48
+ type: Array,
49
+ default: () => [],
50
+ },
51
+ animate: {
52
+ type: Boolean,
53
+ default: true,
54
+ },
55
+ });
56
+
57
+ /** @type {import("vue").ShallowRef<HTMLElement>} */
58
+ const timesliderEl = useTemplateRef("eoxTimecontrol");
59
+
60
+ const startDate = new Date(datetime.value);
61
+ const endDate = new Date(startDate.getTime() + 24 * 60 * 60 * 1000);
62
+
63
+ const selectedRange = /** @type {import("vue").Ref<[string, string]>} */ (
64
+ ref([startDate, endDate].map((d) => d.toISOString()))
65
+ );
66
+ const initDate = [startDate.toISOString().split("T")[0]];
67
+
68
+ const hasMultipleItems = computed(() => {
69
+ return eodashCollections.some((ec) => {
70
+ const itemLinks = ec.collectionStac?.links.filter((l) => l.rel === "item");
71
+ const itemsLink = ec.collectionStac?.links.some((l) => l.rel === "items");
72
+ return (itemLinks && itemLinks.length > 1) || itemsLink;
73
+ });
74
+ });
75
+
76
+ /**
77
+ * Handles the selection event from the time control component.
78
+ * It finds the closest item to the "from" selected date
79
+ * and updates the global datetime state with that item's original date.
80
+ *
81
+ * @param {CustomEvent<import("./types").TimelineSelectionEventDetail>} e
82
+ */
83
+ const onSelect = (e) => {
84
+ const { selectedItems, date } = e.detail;
85
+ // Update the selected range with the new dates
86
+ selectedRange.value = date;
87
+
88
+ const allItems = Object.keys(selectedItems ?? {}).flatMap(
89
+ (id) => selectedItems[id],
90
+ );
91
+ if (!allItems.length) {
92
+ return;
93
+ }
94
+ const [from, _to] = date;
95
+ const fromDate = new Date(from).getTime();
96
+
97
+ const closestItem = allItems.reduce((prev, curr) => {
98
+ const prevDiff = Math.abs(new Date(prev.originalDate).getTime() - fromDate);
99
+ const currDiff = Math.abs(new Date(curr.originalDate).getTime() - fromDate);
100
+ return currDiff < prevDiff ? curr : prev;
101
+ });
102
+
103
+ if (closestItem) {
104
+ datetime.value = closestItem.originalDate;
105
+ }
106
+ };
107
+
108
+ const { selectedStac, stacEndpoint } = storeToRefs(useSTAcStore());
109
+
110
+ /**
111
+ *
112
+ * @param {CustomEvent<import("./types").TimelineExportEventDetail>} evt
113
+ */
114
+ const onExport = async (evt) => {
115
+ const { generate, selectedRangeItems, filters } = evt.detail;
116
+
117
+ if (!stacEndpoint.value) {
118
+ return;
119
+ }
120
+
121
+ const mapLayers = await createAnimationLayers(
122
+ stacEndpoint.value,
123
+ selectedRange.value,
124
+ selectedRangeItems,
125
+ selectedStac,
126
+ filters,
127
+ );
128
+
129
+ if (!mapLayers?.length) {
130
+ console.warn("[eodash] No map layers generated for the animation.");
131
+ return;
132
+ }
133
+
134
+ generate({
135
+ mapLayers,
136
+ });
137
+ };
138
+
139
+ onMounted(() => {
140
+ const parentDiv = timesliderEl.value?.parentElement;
141
+ const layoutItem = parentDiv?.parentElement;
142
+ if (parentDiv && layoutItem && animate) {
143
+ parentDiv.style.overflow = "visible";
144
+ layoutItem.style.overflow = "visible";
145
+ }
146
+ });
147
+ </script>
148
+ <style scoped>
149
+ eox-itemfilter {
150
+ --inline-container-height: 40px;
151
+ }
152
+ </style>
@@ -0,0 +1,279 @@
1
+ import { createLayersConfig } from "^/EodashMap/methods/create-layers-config";
2
+ import { eodashCollections } from "@/utils/states";
3
+ import axios from "@/plugins/axios";
4
+ import { mapEl } from "@/store/states";
5
+ import { removeLayers, sanitizeBbox } from "@/eodashSTAC/helpers";
6
+ import { getLayers } from "@/store/actions";
7
+
8
+ /**
9
+ * @param {string} stacEndpoint
10
+ * @param {[string, string]} selectedRange
11
+ * @param {import("../types").TimelineExportEventDetail["selectedRangeItems"]} selectedRangeItems
12
+ * @param {import("vue").Ref<import("stac-ts").StacCollection|null>} selectedStac
13
+ * @param {Record<string, import("../types").Filter>} filters
14
+ */
15
+ export async function createAnimationLayers(
16
+ stacEndpoint,
17
+ selectedRange,
18
+ selectedRangeItems,
19
+ selectedStac,
20
+ filters,
21
+ ) {
22
+ if (eodashCollections[0].isAPI) {
23
+ return await createAPILayers(
24
+ stacEndpoint,
25
+ { min: selectedRange[0], max: selectedRange[1] },
26
+ mapEl.value?.lonLatExtent,
27
+ selectedStac,
28
+ filters,
29
+ );
30
+ }
31
+ const { collections: hiddenCollections, layers: hiddenLayers } =
32
+ getHiddenLayers([...getLayers()]);
33
+
34
+ return await Promise.all(
35
+ Object.values(selectedRangeItems).flatMap(async (itemSet) => {
36
+ /** @type {Array<{ layers: Record<string, any>[]; date: string }>} */
37
+ const mapLayersArr = [];
38
+ for (const dateItem of itemSet) {
39
+ await createLayersConfig(
40
+ selectedStac.value,
41
+ eodashCollections.filter(
42
+ (collection) =>
43
+ !hiddenCollections.includes(collection.collectionStac?.id ?? ""),
44
+ ),
45
+ dateItem.originalDate,
46
+ ).then((layers) => {
47
+ //@ts-expect-error createLayersConfig is not typed strictly
48
+ layers = removeLayers(layers, hiddenLayers);
49
+ //@ts-expect-error createLayersConfig is not typed strictly
50
+ layers = restoreLayersVisibility(layers);
51
+ layers = anonimizeLayersCORS(layers);
52
+ mapLayersArr.push({
53
+ layers,
54
+ date: dateItem.originalDate,
55
+ });
56
+ });
57
+ }
58
+ return mapLayersArr;
59
+ }),
60
+ ).then((results) => results.flat());
61
+ }
62
+ /**
63
+ *
64
+ * @param {string} stacEndpoint
65
+ * @param {{min: string, max: string}} date
66
+ * @param {number[] | undefined} bbox
67
+ * @param {import("vue").Ref<import("stac-ts").StacCollection|null>} selectedStac
68
+ * @param {Record<string, import("../types").Filter>} filters
69
+ * @return {Promise<Array<{ layers: Record<string, any>[]; date: string }>>}
70
+ */
71
+ async function createAPILayers(
72
+ stacEndpoint,
73
+ date = { min: "", max: "" },
74
+ bbox,
75
+ selectedStac,
76
+ filters,
77
+ ) {
78
+ if (!bbox) {
79
+ return [];
80
+ }
81
+ const url = new URL(stacEndpoint + "/search");
82
+ url.searchParams.set("limit", "100");
83
+ url.searchParams.set("collections", selectedStac.value?.id ?? "");
84
+ url.searchParams.set(
85
+ "datetime",
86
+ `${new Date(date.min).toISOString()}/${new Date(date.max).toISOString()}`,
87
+ );
88
+ url.searchParams.set("bbox", sanitizeBbox(bbox).join(","));
89
+
90
+ const stacFilter = buildStacFilters(filters);
91
+ if (stacFilter) {
92
+ url.searchParams.set("filter", stacFilter);
93
+ }
94
+
95
+ /** @type {import("stac-ts").StacItem[]} */
96
+ const items = await axios
97
+ .get(url.href)
98
+ .then((res) => res.data.features)
99
+ .catch((err) => {
100
+ console.error("[eodash] Error fetching items for animation:", err);
101
+ return [];
102
+ });
103
+ if (!items || !items.length) {
104
+ console.warn("[eodash] No items found for animation.");
105
+ return [];
106
+ }
107
+ const { collections: hiddenCollections, layers: hiddenLayers } =
108
+ getHiddenLayers([...getLayers()]);
109
+ return await Promise.all(
110
+ items.map(async (item) => {
111
+ /** @type {Array<{ layers: Record<string, any>[]; date: string }>} */
112
+ const mapLayersArr = [];
113
+ await createLayersConfig(
114
+ selectedStac.value,
115
+ eodashCollections.filter(
116
+ (collection) =>
117
+ !hiddenCollections.includes(collection.collectionStac?.id ?? ""),
118
+ ),
119
+ item,
120
+ ).then((layers) => {
121
+ //@ts-expect-error createLayersConfig is not typed strictly
122
+ layers = removeLayers(layers, hiddenLayers);
123
+ //@ts-expect-error createLayersConfig is not typed strictly
124
+ layers = restoreLayersVisibility(layers);
125
+ layers = anonimizeLayersCORS(layers);
126
+ mapLayersArr.push({
127
+ layers,
128
+ date: /** @type {string} */ (item.properties.datetime),
129
+ });
130
+ return mapLayersArr;
131
+ });
132
+ return mapLayersArr;
133
+ }),
134
+ ).then((results) => results.flat());
135
+ }
136
+ /**
137
+ *
138
+ * @param {Record<string, any>[]} layers
139
+ * @returns {Record<string, any>[]}
140
+ */
141
+ export function anonimizeLayersCORS(layers) {
142
+ return layers.map((layer) => {
143
+ if (layer.type === "Group") {
144
+ layer.layers = anonimizeLayersCORS(layer.layers);
145
+ return layer;
146
+ }
147
+ if (layer.source) {
148
+ layer.source.crossOrigin = "anonymous";
149
+ }
150
+ return layer;
151
+ });
152
+ }
153
+ /**
154
+ * returns the list of layers that has visibility hidden
155
+ * @param {import("@eox/map").EoxLayer[]} layers
156
+ * @returns {{ collections: string[]; layers: string[] }}
157
+ */
158
+ export function getHiddenLayers(layers) {
159
+ /** @type {{ collections: string[]; layers: string[] }} */
160
+ const result = { collections: [], layers: [] };
161
+
162
+ for (const layer of layers) {
163
+ // check inner layers if it's a group layer first
164
+ if (layer.type === "Group" && Array.isArray(layer.layers)) {
165
+ const childResult = getHiddenLayers(layer.layers);
166
+ for (const col of childResult.collections) {
167
+ if (!result.collections.includes(col)) {
168
+ result.collections.push(col);
169
+ }
170
+ }
171
+ for (const lyr of childResult.layers) {
172
+ if (!result.layers.includes(lyr)) {
173
+ result.layers.push(lyr);
174
+ }
175
+ }
176
+ }
177
+
178
+ if (!layer.properties?.id) {
179
+ continue;
180
+ }
181
+
182
+ const olLayer = mapEl.value?.getLayerById(layer.properties?.id);
183
+ if (!olLayer) {
184
+ continue;
185
+ }
186
+
187
+ if (olLayer.getVisible() === false) {
188
+ const refId = layer.properties.id;
189
+ if (refId) {
190
+ if (refId.includes(";:;")) {
191
+ // Check if this looks like a typical eodash collection ID with separator
192
+ const parts = refId.split(";:;");
193
+ if (parts.length > 2) {
194
+ const prefix = parts[0];
195
+ if (!result.collections.includes(prefix)) {
196
+ result.collections.push(prefix);
197
+ }
198
+ } else {
199
+ // It has a separator but might just be a base layer like `layerId;:;EPSG`
200
+ if (!result.layers.includes(refId)) {
201
+ result.layers.push(refId);
202
+ }
203
+ }
204
+ } else {
205
+ if (!result.layers.includes(refId)) {
206
+ result.layers.push(refId);
207
+ }
208
+ }
209
+ }
210
+ }
211
+ }
212
+
213
+ return result;
214
+ }
215
+
216
+ /**
217
+ * Iterates through a list of layers and updates layer.properties.visible to true
218
+ * if it is set to false
219
+ * @param {import("@eox/map").EoxLayer[]} layers
220
+ * @returns {import("@eox/map").EoxLayer[]}
221
+ */
222
+ export function restoreLayersVisibility(layers) {
223
+ for (const layer of layers) {
224
+ if (layer.properties && layer.properties.visible === false) {
225
+ layer.properties.visible = true;
226
+ }
227
+
228
+ if (layer.type === "Group" && Array.isArray(layer.layers)) {
229
+ restoreLayersVisibility(layer.layers);
230
+ }
231
+ }
232
+ return layers;
233
+ }
234
+
235
+ /**
236
+ * Build STAC API filter string from TimeSlider filters
237
+ * @param {Record<string, import("../types").Filter>} filters
238
+ * @returns {string}
239
+ */
240
+ export function buildStacFilters(filters) {
241
+ if (!filters) return "";
242
+
243
+ /** @type {string[]} */
244
+ const stacFilters = [];
245
+
246
+ Object.values(filters).forEach((filter) => {
247
+ if (!filter || !filter.key) return;
248
+
249
+ // strip 'properties.' from key if present
250
+ const propName = filter.key.startsWith("properties.")
251
+ ? filter.key.replace("properties.", "")
252
+ : filter.key;
253
+
254
+ if (filter.type === "range" && filter.state) {
255
+ if (
256
+ filter.state.min !== undefined &&
257
+ filter.state.min > (filter.min ?? -Infinity)
258
+ ) {
259
+ stacFilters.push(`${propName}>=${filter.state.min}`);
260
+ }
261
+ if (
262
+ filter.state.max !== undefined &&
263
+ filter.state.max < (filter.max ?? Infinity)
264
+ ) {
265
+ stacFilters.push(`${propName}<=${filter.state.max}`);
266
+ }
267
+ } else if (filter.type === "multiselect" && filter.stringifiedState) {
268
+ if (filter.stringifiedState.length > 0) {
269
+ stacFilters.push(`${propName} IN (${filter.stringifiedState})`);
270
+ }
271
+ } else if (filter.type === "select" && filter.stringifiedState) {
272
+ if (filter.stringifiedState) {
273
+ stacFilters.push(`${propName}='${filter.stringifiedState}'`);
274
+ }
275
+ }
276
+ });
277
+
278
+ return stacFilters.join(" AND ");
279
+ }
@@ -0,0 +1,64 @@
1
+ export interface TimelineSelectionEventDetail {
2
+ date: [string, string];
3
+ instances: {
4
+ // this is inaccurate, the type should include all possible sources and layers,
5
+ layer: import("ol/layer/Layer").default;
6
+ source: import("ol/source/Source").default;
7
+ };
8
+ filters: Record<string, Filter>;
9
+ selectedItems: {
10
+ [layerId: string]: SelectedItem[];
11
+ };
12
+ }
13
+ export interface SelectedItem {
14
+ className: string;
15
+ date: string;
16
+ group: string;
17
+ // unique UUID for this item, generated by the timeline component
18
+ id: string;
19
+ itemId: string;
20
+ local: string;
21
+ originalDate: string;
22
+ property: string;
23
+ start: string;
24
+ type: string;
25
+ utc: string;
26
+ }
27
+
28
+ export interface TimelineExportEventDetail {
29
+ eoxMapConfig: {
30
+ layers: Record<string, any>[];
31
+ zoom: number;
32
+ center: [number, number];
33
+ };
34
+ filters: Record<string, Filter>;
35
+ instances: {
36
+ layer: import("ol/layer/Layer").default;
37
+ source: import("ol/source/Source").default;
38
+ };
39
+ selectedRangeItems: {
40
+ [layerId: string]: SelectedItem[];
41
+ };
42
+ generate: (args: {
43
+ mapLayers: Array<{ layers: Record<string, any>[]; date: string }>;
44
+ center?: [number, number];
45
+ zoom?: number;
46
+ }) => Promise<void>;
47
+ }
48
+
49
+ export interface Filter {
50
+ key: string;
51
+ title: string;
52
+ type: "range" | "multiselect" | "select";
53
+ expanded: boolean;
54
+ min: number;
55
+ max: number;
56
+ step: number;
57
+ // this state is mainly for range filters, select and multiselect to be added.
58
+ state: {
59
+ min: number;
60
+ max: number;
61
+ };
62
+ dirty: boolean;
63
+ stringifiedState: string;
64
+ }