@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
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <v-main class="pa-0">
3
3
  <eox-layout
4
- :mediaBreakpoints="[0, 960, 1920]"
4
+ :mediaBreakpoints="[0, 960, 1921]"
5
5
  :gap="gap"
6
6
  :style="layoutStyle"
7
7
  >
@@ -331,11 +331,12 @@ export const useGetTemplates = () => {
331
331
  };
332
332
 
333
333
  /**
334
- * Listens to the `layers:updated` and `time:updated` events and calls
334
+ * Subscribes to layers/time update events on the shared bus, with automatic
335
+ * cleanup on component unmount.
335
336
  *
336
337
  * @param {import("@vueuse/core").EventBusListener<
337
338
  * import("@/types").LayersEventBusKeys,
338
- * {layers:Record<string,any>[]| undefined}
339
+ * Record<string,any>[] | undefined
339
340
  * >} listener
340
341
  */
341
342
  export const useOnLayersUpdate = (listener) => {
@@ -348,6 +349,9 @@ export const useOnLayersUpdate = (listener) => {
348
349
  });
349
350
  };
350
351
  /**
352
+ * Emits a layers-update event on the shared bus once the map has applied its
353
+ * pending updates. Always pass the full layers array, not a partial subset.
354
+ *
351
355
  * @param {import("@/types").LayersEventBusKeys} event
352
356
  * @param {import("@eox/map").EOxMap | null} mapEl
353
357
  * @param {Record<string,any>[]} layers
@@ -15,11 +15,7 @@ import {
15
15
  extractLayerTimeValues,
16
16
  replaceLayer,
17
17
  } from "./helpers";
18
- import {
19
- getLayers,
20
- getCompareLayers,
21
- registerProjection,
22
- } from "@/store/actions";
18
+ import { getLayers, registerProjection } from "@/store/actions";
23
19
  import {
24
20
  createLayerFromRender,
25
21
  createLayersFromAssets,
@@ -28,8 +24,6 @@ import {
28
24
  import axios from "@/plugins/axios";
29
25
  import log from "loglevel";
30
26
  import { dataThemesBrands } from "@/utils/states";
31
- import { useEventBus } from "@vueuse/core";
32
- import { eoxLayersKey } from "@/utils/keys";
33
27
 
34
28
  export class EodashCollection {
35
29
  #collectionUrl = "";
@@ -403,12 +397,11 @@ export class EodashCollection {
403
397
  }
404
398
 
405
399
  /**
406
- *
407
400
  * @param {string} datetime
408
- * @param {string} layer
409
- * @param {string} map
401
+ * @param {string} layerId
402
+ * @param {import("@eox/map").EoxLayer[]} currentLayers
410
403
  */
411
- async updateLayerJson(datetime, layer, map) {
404
+ async updateLayerJson(datetime, layerId, currentLayers) {
412
405
  await this.fetchCollection();
413
406
  const datetimeProperty = getDatetimeProperty(
414
407
  await this.getItems(true, true),
@@ -443,12 +436,7 @@ export class EodashCollection {
443
436
  newLayers = await this.createLayersJson(specifiedLink);
444
437
  }
445
438
 
446
- let currentLayers = getLayers();
447
- if (map === "second") {
448
- currentLayers = getCompareLayers();
449
- }
450
-
451
- const oldLayer = findLayer(currentLayers, layer);
439
+ const oldLayer = findLayer(currentLayers, layerId);
452
440
 
453
441
  const toBeReplacedLayers = findLayersByLayerPrefix(currentLayers, oldLayer);
454
442
 
@@ -462,10 +450,6 @@ export class EodashCollection {
462
450
  newLayers,
463
451
  );
464
452
 
465
- // Emit event to update potential widget dependencies such as process layer ids
466
- const layersEvents = useEventBus(eoxLayersKey);
467
- layersEvents.emit("layertime:updated", newLayers);
468
-
469
453
  return updatedLayers;
470
454
  }
471
455
 
@@ -75,7 +75,9 @@ export async function createLayersFromAssets(
75
75
  geoTIFFIdx.push(idx);
76
76
  geoTIFFSources.push({
77
77
  url: assets[assetId].href,
78
- attributions: assets[assetId].attribution,
78
+ ...(assets[assetId].attribution
79
+ ? { attributions: assets[assetId].attribution }
80
+ : {}),
79
81
  });
80
82
  } else if (assets[assetId]?.type === "application/geodb+json") {
81
83
  const responseData = await (await fetch(assets[assetId].href)).json();
@@ -178,7 +180,9 @@ export async function createLayersFromAssets(
178
180
  type: "Vector",
179
181
  url: geoJSONURL,
180
182
  format: { type: "GeoJSON", dataProjection: projection },
181
- attributions: assets[assetName].attribution,
183
+ ...(assets[assetName].attribution
184
+ ? { attributions: assets[assetName].attribution }
185
+ : {}),
182
186
  },
183
187
  properties: {
184
188
  id: assetLayerId,
@@ -239,7 +243,9 @@ export async function createLayersFromAssets(
239
243
  ...urlsObject,
240
244
  type: "FlatGeoBuf",
241
245
  projection,
242
- attributions: assets[assetName].attribution,
246
+ ...(assets[assetName].attribution
247
+ ? { attributions: assets[assetName].attribution }
248
+ : {}),
243
249
  },
244
250
  properties: {
245
251
  id: assetLayerId,
@@ -385,7 +391,7 @@ export const createLayersFromLinks = async (
385
391
  tileGrid: {
386
392
  tileSize,
387
393
  },
388
- attributions: wmsLink.attribution,
394
+ ...(wmsLink.attribution ? { attributions: wmsLink.attribution } : {}),
389
395
  params: {
390
396
  LAYERS: wmsLink["wms:layers"],
391
397
  TILED: true,
@@ -496,7 +502,9 @@ export const createLayersFromLinks = async (
496
502
  tileGrid: {
497
503
  tileSize: [128, 128],
498
504
  },
499
- attributions: wmtsLink.attribution,
505
+ ...(wmtsLink.attribution
506
+ ? { attributions: wmtsLink.attribution }
507
+ : {}),
500
508
  dimensions: dimensionsWithoutStyle,
501
509
  },
502
510
  };
@@ -516,7 +524,9 @@ export const createLayersFromLinks = async (
516
524
  layer: wmtsLink["wmts:layer"],
517
525
  style: extractedStyle,
518
526
  ...(matrixSet ? { matrixSet } : {}),
519
- attributions: wmtsLink.attribution,
527
+ ...(wmtsLink.attribution
528
+ ? { attributions: wmtsLink.attribution }
529
+ : {}),
520
530
  dimensions: dimensionsWithoutStyle,
521
531
  },
522
532
  };
@@ -600,7 +610,7 @@ export const createLayersFromLinks = async (
600
610
  type: "XYZ",
601
611
  url: isUpscalingSupported ? xyzUrl.replace("{y}", "{y}@2x") : xyzUrl,
602
612
  projection: projectionCode,
603
- attributions: xyzLink.attribution,
613
+ ...(xyzLink.attribution ? { attributions: xyzLink.attribution } : {}),
604
614
  },
605
615
  };
606
616
  if (isUpscalingSupported) {
@@ -686,7 +696,9 @@ export const createLayersFromLinks = async (
686
696
  },
687
697
  url: href,
688
698
  projection: projectionCode,
689
- attributions: vectorTileLink.attribution,
699
+ ...(vectorTileLink.attribution
700
+ ? { attributions: vectorTileLink.attribution }
701
+ : {}),
690
702
  },
691
703
  interactions: [],
692
704
  ...(!style?.variables && { style }),
@@ -745,7 +757,9 @@ export const createLayersFromLinks = async (
745
757
  layerDatetime,
746
758
  mapboxStyle: href,
747
759
  projection: projectionCode,
748
- attributions: mapboxStyleDocumentLink.attribution,
760
+ ...(mapboxStyleDocumentLink.attribution
761
+ ? { attributions: mapboxStyleDocumentLink.attribution }
762
+ : {}),
749
763
  applyOptions,
750
764
  },
751
765
  interactions: [],
@@ -349,11 +349,11 @@ export const extractLayerTimeValues = (items, currentStep) => {
349
349
  export const findLayersByLayerPrefix = (layers, referenceLayer) => {
350
350
  const refId = referenceLayer?.properties?.id;
351
351
 
352
- if (typeof refId !== "string" || !refId.includes(";")) {
353
- throw new Error("Reference layer ID must contain a ';' separator.");
352
+ if (typeof refId !== "string" || !refId.includes(";:;")) {
353
+ throw new Error("Reference layer ID must contain a ';:;' separator.");
354
354
  }
355
355
 
356
- const prefix = refId.split(";")[0];
356
+ const prefix = refId.split(";:;")[0];
357
357
  const matches = [];
358
358
 
359
359
  for (const layer of layers) {
@@ -361,7 +361,7 @@ export const findLayersByLayerPrefix = (layers, referenceLayer) => {
361
361
  matches.push(...findLayersByLayerPrefix(layer.layers, referenceLayer));
362
362
  } else {
363
363
  const id = layer?.properties?.id;
364
- if (typeof id === "string" && id.startsWith(prefix)) {
364
+ if (typeof id === "string" && id.split(";:;")[0] === prefix) {
365
365
  matches.push(layer);
366
366
  }
367
367
  }
@@ -391,6 +391,39 @@ export const findLayer = (layers, layer) => {
391
391
  }
392
392
  };
393
393
 
394
+ /**
395
+ * Removes JSON layers by ID from the layer tree
396
+ * @param {import("@eox/map").EoxLayer[]} layers
397
+ * @param {string[]} layerIds
398
+ * @returns {import("@eox/map").EoxLayer[]}
399
+ **/
400
+ export const removeLayers = (layers, layerIds) => {
401
+ const result = [];
402
+ for (const layer of layers) {
403
+ // if the layer is hidden, do not include it without checking if it's a group
404
+ if (layer.properties?.id && layerIds.includes(layer.properties.id)) {
405
+ continue;
406
+ }
407
+ if (layer.type === "Group" && Array.isArray(layer.layers)) {
408
+ const newGroupLayers = removeLayers(layer.layers, layerIds);
409
+ // if the group is not hidden, add it with the updated layers (if any were removed)
410
+ result.push(
411
+ newGroupLayers !== layer.layers
412
+ ? { ...layer, layers: newGroupLayers }
413
+ : layer,
414
+ );
415
+ continue;
416
+ }
417
+
418
+ result.push(layer);
419
+ }
420
+
421
+ return result.length === layers.length &&
422
+ result.every((l, i) => l === layers[i])
423
+ ? layers
424
+ : result;
425
+ };
426
+
394
427
  /**
395
428
  * Removes one or more layers (by id) from a layer/group structure and inserts
396
429
  * new layers in place of the first removed one.
@@ -113,7 +113,7 @@ export interface TEodashDatePicker {
113
113
  export interface TEodashTimeSlider {
114
114
  name: "EodashTimeSlider";
115
115
  properties?: InstanceType<
116
- typeof import("^/EodashTimeSlider.vue").default
116
+ typeof import("^/EodashTimeSlider/index.vue").default
117
117
  >["$props"];
118
118
  }
119
119
 
@@ -382,6 +382,13 @@ export type Eodash = {
382
382
  theme?: import("vuetify").ThemeDefinition & {
383
383
  collectionsPalette?: string[];
384
384
  };
385
+ /** eox-feedback configuration */
386
+ feedback?: {
387
+ /** eox-feedback endpoint */
388
+ endpoint: string;
389
+ /** eox-feedback jsonform schema */
390
+ schema?: any;
391
+ };
385
392
  /** Text applied to the footer. */
386
393
  footerText?: string;
387
394
  };
@@ -71,6 +71,8 @@ export const loadFont = async (fontConfig, isWebComponent) => {
71
71
  eox-jsonform,
72
72
  eox-timecontrol,
73
73
  eox-itemfilter,
74
+ eox-geosearch,
75
+ eox-feedback,
74
76
  eox-chart,
75
77
  eox-stacinfo{
76
78
  --eox-body-font-family: ${bodyFamily};
@@ -108,6 +110,8 @@ export const loadFont = async (fontConfig, isWebComponent) => {
108
110
  eox-jsonform,
109
111
  eox-timecontrol,
110
112
  eox-itemfilter,
113
+ eox-feedback,
114
+ eox-geosearch,
111
115
  eox-chart,
112
116
  eox-stacinfo {
113
117
  --eox-header-font-family: ${headerFamily};
@@ -1,9 +1,9 @@
1
1
  import { openBlock, createBlock, withCtx, createElementVNode, unref, createElementBlock, normalizeStyle, Suspense, resolveDynamicComponent, mergeProps, createCommentVNode, Fragment, renderList, Transition } from 'vue';
2
2
  import '@eox/layout';
3
- import { _ as _export_sfc, u as useDefineTemplate } from './asWebComponent-DDt7V3Bl.js';
4
- import { V as VMain } from './VMain-D7_72mHr.js';
3
+ import { _ as _export_sfc, u as useDefineTemplate } from './asWebComponent-BHWpMuE3.js';
4
+ import { V as VMain } from './VMain-OKZNpcEG.js';
5
5
 
6
- const _style_0 = ".panel[data-v-9c8477cc]{position:relative;overflow:auto;z-index:1;pointer-events:none}.pointer[data-v-9c8477cc]{pointer-events:all}.bg-panel[data-v-9c8477cc]{z-index:0;border-radius:0!important}.fade-enter-active[data-v-9c8477cc],.fade-leave-active[data-v-9c8477cc]{transition:opacity .25s ease}.fade-enter-from[data-v-9c8477cc],.fade-leave-to[data-v-9c8477cc]{opacity:0}.bg-surface[data-v-9c8477cc],.bg-primary[data-v-9c8477cc]{backdrop-filter:blur(10px)!important;border-radius:8px;border:none;box-shadow:0 0 1px #18274b38,0 6px 12px -6px #18274b1f,0 8px 24px -4px #18274b14;max-height:100%;overflow:auto;scrollbar-color:rgba(var(--v-theme-on-surface),.2) transparent;scrollbar-width:thin}.bg-surface[data-v-9c8477cc]{background-color:rgba(var(--v-theme-surface),var(--v-surface-opacity, .8))!important}.bg-primary[data-v-9c8477cc]{background-color:rgba(var(--v-theme-primary),var(--v-primary-opacity, .8))!important}";
6
+ const _style_0 = ".panel[data-v-f357e3a7]{position:relative;overflow:auto;z-index:1;pointer-events:none}.pointer[data-v-f357e3a7]{pointer-events:all}.bg-panel[data-v-f357e3a7]{z-index:0;border-radius:0!important}.fade-enter-active[data-v-f357e3a7],.fade-leave-active[data-v-f357e3a7]{transition:opacity .25s ease}.fade-enter-from[data-v-f357e3a7],.fade-leave-to[data-v-f357e3a7]{opacity:0}.bg-surface[data-v-f357e3a7],.bg-primary[data-v-f357e3a7]{backdrop-filter:blur(10px)!important;border-radius:8px;border:none;box-shadow:0 0 1px #18274b38,0 6px 12px -6px #18274b1f,0 8px 24px -4px #18274b14;max-height:100%;overflow:auto;scrollbar-color:rgba(var(--v-theme-on-surface),.2) transparent;scrollbar-width:thin}.bg-surface[data-v-f357e3a7]{background-color:rgba(var(--v-theme-surface),var(--v-surface-opacity, .8))!important}.bg-primary[data-v-f357e3a7]{background-color:rgba(var(--v-theme-primary),var(--v-primary-opacity, .8))!important}";
7
7
 
8
8
  const _hoisted_1 = ["gap"];
9
9
  const _hoisted_2 = ["id", "h", "w", "x", "y"];
@@ -27,7 +27,7 @@ return (_ctx, _cache) => {
27
27
  return (openBlock(), createBlock(VMain, { class: "pa-0" }, {
28
28
  default: withCtx(() => [
29
29
  createElementVNode("eox-layout", {
30
- mediaBreakpoints: [0, 960, 1920],
30
+ mediaBreakpoints: [0, 960, 1921],
31
31
  gap: unref(gap),
32
32
  style: layoutStyle
33
33
  }, [
@@ -89,6 +89,6 @@ return (_ctx, _cache) => {
89
89
  }
90
90
 
91
91
  };
92
- const DashboardLayout = /*#__PURE__*/_export_sfc(_sfc_main, [['styles',[_style_0]],['__scopeId',"data-v-9c8477cc"]]);
92
+ const DashboardLayout = /*#__PURE__*/_export_sfc(_sfc_main, [['styles',[_style_0]],['__scopeId',"data-v-f357e3a7"]]);
93
93
 
94
94
  export { DashboardLayout as default };
@@ -1,5 +1,5 @@
1
1
  import { withAsyncContext, ref, onMounted, onUnmounted, openBlock, createElementBlock, createBlock, resolveDynamicComponent, mergeProps } from 'vue';
2
- import { H as useSTAcStore } from './asWebComponent-DDt7V3Bl.js';
2
+ import { H as useSTAcStore } from './asWebComponent-BHWpMuE3.js';
3
3
 
4
4
  const _hoisted_1 = { class: "d-flex flex-column fill-height overflow-auto" };
5
5
 
@@ -1,10 +1,10 @@
1
1
  import { computed, ref, useTemplateRef, onMounted, onBeforeUnmount, openBlock, createElementBlock, createElementVNode, withDirectives, unref, createCommentVNode, normalizeStyle, toRaw } from 'vue';
2
2
  import '@eox/chart';
3
- import { o as onChartClick } from './handling-C285F_Mq.js';
4
- import { Z as compareChartData, _ as chartData, O as compareChartSpec, N as chartSpec, M as areChartsSeparateLayout } from './helpers-CZFH0EVN.js';
5
- import { _ as _export_sfc, W as getOverlayParent } from './asWebComponent-DDt7V3Bl.js';
3
+ import { o as onChartClick } from './handling-BrcDDlgS.js';
4
+ import { Z as compareChartData, _ as chartData, N as compareChartSpec, M as chartSpec, L as areChartsSeparateLayout } from './helpers-DjZVl_WF.js';
5
+ import { _ as _export_sfc, U as getOverlayParent } from './asWebComponent-BHWpMuE3.js';
6
6
  import { mdiArrowCollapse, mdiArrowExpand } from '@mdi/js';
7
- import { T as Tooltip } from './index-DgOXD7wd.js';
7
+ import { T as Tooltip } from './index-CUjl-ZsI.js';
8
8
 
9
9
  const _style_0 = ".chart-frame[data-v-c9dee45e]{position:relative}.chart-toggle[data-v-c9dee45e]{position:absolute;top:18px;right:46px;z-index:2;cursor:pointer}";
10
10
 
@@ -1,11 +1,11 @@
1
1
  import { useCssVars, useTemplateRef, customRef, ref, computed, reactive, watch, onMounted, openBlock, createElementBlock, createVNode, unref, createSlots, withCtx, createElementVNode, withDirectives, createBlock, createCommentVNode, mergeProps, toHandlers } from 'vue';
2
2
  import { DatePicker } from 'v-calendar';
3
- import { _ as _export_sfc, G as useDisplay, H as useSTAcStore, I as useTransparentPanel, J as VBtn, K as VIcon, L as eodashCollections, M as eodashCompareCollections } from './asWebComponent-DDt7V3Bl.js';
4
- import { B as datetime } from './helpers-CZFH0EVN.js';
3
+ import { _ as _export_sfc, G as useDisplay, H as useSTAcStore, I as useTransparentPanel, J as VBtn, K as VIcon, L as eodashCollections, M as eodashCompareCollections } from './asWebComponent-BHWpMuE3.js';
4
+ import { A as datetime } from './helpers-DjZVl_WF.js';
5
5
  import { mdiRayEndArrow, mdiRayStartArrow } from '@mdi/js';
6
6
  import log from 'loglevel';
7
7
  import { storeToRefs } from 'pinia';
8
- import { T as Tooltip } from './index-DgOXD7wd.js';
8
+ import { T as Tooltip } from './index-CUjl-ZsI.js';
9
9
 
10
10
  const _style_0 = ".vc-popover-content{--vc-nav-hover-bg: rgba(var(--v-theme-on-surface), .1);--vc-nav-item-active-color: rgb(var(--v-theme-on-secondary));--vc-nav-item-active-bg: rgba(var(--v-theme-secondary), .8);--vc-focus-ring: 0 0 0 2px rgba(var(--v-theme-secondary), .5)}.vc-container{--vc-day-content-hover-bg: rgba(var(--v-theme-on-surface), .2);--vc-focus-ring: 0 0 0 2px rgba(var(--v-theme-secondary), .4);--vc-header-arrow-hover-bg: rgba(var(--v-theme-secondary), .1)}.vc-attr{--vc-accent-600: rgba(var(--v-theme-secondary), .8)}.datePicker{--vc-day-content-hover-bg: red}@media(min-width:960px){.datePicker{position:absolute;bottom:0;left:0;right:0;margin-inline:auto;width:fit-content}}.vc-day-content{color:#5e5e5e;font-weight:400}.vc-highlight-content-solid{color:#fff!important}.vc-popover-content-wrapper{transform:var(--v518b583c)!important}.vc-date-picker-content,.datePicker{backdrop-filter:blur(10px)!important;border-radius:8px;border:none;box-shadow:0 0 1px #18274b38,0 6px 12px -6px #18274b1f,0 8px 24px -4px #18274b14;background-color:rgba(var(--v-theme-surface),var(--v-surface-opacity, .8))!important}.vc-popover-caret.direction-top.align-left{clip-path:polygon(0% 0%,100% 0%,0% 100%,0% 100%)}.vc-bordered{border:none}";
11
11
 
@@ -1,5 +1,5 @@
1
1
  import { withAsyncContext, computed, ref, openBlock, createElementBlock, mergeProps, unref, createElementVNode, toDisplayString } from 'vue';
2
- import { _ as _export_sfc, H as useSTAcStore, T as isFirstLoad } from './asWebComponent-DDt7V3Bl.js';
2
+ import { _ as _export_sfc, H as useSTAcStore, S as isFirstLoad } from './asWebComponent-BHWpMuE3.js';
3
3
 
4
4
  const _style_0 = "eox-itemfilter[data-v-88d0abc7]{--form-flex-direction: row}@media(max-width:768px){eox-itemfilter[data-v-88d0abc7]{--form-flex-direction: column}}";
5
5
 
@@ -1,8 +1,8 @@
1
- import { withAsyncContext, computed, ref, openBlock, createElementBlock, mergeProps, unref, renderSlot, createElementVNode, toDisplayString, createCommentVNode } from 'vue';
1
+ import { withAsyncContext, computed, ref, watch, openBlock, createElementBlock, mergeProps, unref, renderSlot, createElementVNode, toDisplayString, createCommentVNode } from 'vue';
2
2
  import 'color-legend-element';
3
3
  import '@eox/timecontrol';
4
- import { S as mapCompareEl, i as mapEl, T as getColFromLayer } from './helpers-CZFH0EVN.js';
5
- import { _ as _export_sfc, H as useSTAcStore, P as layerControlFormValueCompare, Q as layerControlFormValue, M as eodashCompareCollections, L as eodashCollections } from './asWebComponent-DDt7V3Bl.js';
4
+ import { R as mapCompareEl, i as mapEl, S as getColFromLayer } from './helpers-DjZVl_WF.js';
5
+ import { _ as _export_sfc, H as useSTAcStore, P as layerControlFormValueCompare, Q as layerControlFormValue, R as useEmitLayersUpdate, M as eodashCompareCollections, L as eodashCollections } from './asWebComponent-BHWpMuE3.js';
6
6
  import { storeToRefs } from 'pinia';
7
7
 
8
8
  /**
@@ -1367,7 +1367,7 @@ const bandsEditorInterface = [
1367
1367
  },
1368
1368
  ];
1369
1369
 
1370
- const _style_0 = "eox-layercontrol[data-v-219e33f9]{overflow:auto}";
1370
+ const _style_0 = "eox-layercontrol[data-v-cd4de44c]{overflow:auto}";
1371
1371
 
1372
1372
  const _hoisted_1 = { class: "d-flex flex-column" };
1373
1373
  const _hoisted_2 = ["for", ".customEditorInterfaces"];
@@ -1425,6 +1425,7 @@ const config = {
1425
1425
  };
1426
1426
 
1427
1427
  const { selectedCompareStac, selectedStac } = storeToRefs(useSTAcStore());
1428
+
1428
1429
  const showControls = computed(() => {
1429
1430
  if (props.map === "second") {
1430
1431
  return mapCompareEl.value !== null && selectedCompareStac.value !== null;
@@ -1439,9 +1440,20 @@ const mapElement = props.map === "second" ? mapCompareEl : mapEl;
1439
1440
  /** @type { import("vue").Ref<HTMLElement & Record<string,any> | null>} */
1440
1441
  const eoxLayercontrol = ref(null);
1441
1442
 
1443
+ // eox-timecontrol re-fires datetime:updated after layer reassignment;
1444
+ // dedupe by (collectionId, datetime)
1445
+ const processedDatetimes = new Map();
1446
+ watch([selectedStac, selectedCompareStac], () => processedDatetimes.clear());
1447
+
1442
1448
  /** @param {CustomEvent<{layer:import('ol/layer').Layer; datetime:string;}>} evt */
1443
1449
  const handleDatetimeUpdate = async (evt) => {
1444
1450
  const { layer, datetime } = evt.detail;
1451
+ const collectionId = layer.get("id")?.split(";:;")[0] ?? layer.get("id");
1452
+ if (processedDatetimes.get(collectionId) === datetime) return;
1453
+ // First event per collection is eox-timecontrol's mount echo.
1454
+ const isFirstEvent = !processedDatetimes.has(collectionId);
1455
+ processedDatetimes.set(collectionId, datetime);
1456
+ if (isFirstEvent) return;
1445
1457
 
1446
1458
  const ec = await getColFromLayer(eodashCols, layer);
1447
1459
 
@@ -1452,9 +1464,10 @@ const handleDatetimeUpdate = async (evt) => {
1452
1464
  updatedLayers = await ec.updateLayerJson(
1453
1465
  datetime,
1454
1466
  layer.get("id"),
1455
- props.map,
1467
+ mapElement.value?.layers ?? [],
1456
1468
  );
1457
1469
  }
1470
+ if (!updatedLayers?.length) return;
1458
1471
  /** @type {Record<String,any>[] | undefined} */
1459
1472
  const dataLayers = updatedLayers?.find(
1460
1473
  (l) => l?.properties?.id === "AnalysisGroup",
@@ -1466,9 +1479,14 @@ const handleDatetimeUpdate = async (evt) => {
1466
1479
  dl.properties.layerControlExpand = true;
1467
1480
  dl.properties.layerControlToolsExpand = true;
1468
1481
  });
1469
- // assign layers to the map
1470
1482
  /** @type {HTMLElement & Record<string,any>} */
1471
1483
  (mapElement.value).layers = updatedLayers;
1484
+ // Emit after layer assignment so listeners resolve against the new layer.
1485
+ await useEmitLayersUpdate(
1486
+ props.map === "second" ? "compareLayertime:updated" : "layertime:updated",
1487
+ mapElement.value,
1488
+ updatedLayers,
1489
+ );
1472
1490
  }
1473
1491
  };
1474
1492
 
@@ -1526,6 +1544,6 @@ return (_ctx, _cache) => {
1526
1544
  }
1527
1545
 
1528
1546
  };
1529
- const EodashLayerControl = /*#__PURE__*/_export_sfc(_sfc_main, [['styles',[_style_0]],['__scopeId',"data-v-219e33f9"]]);
1547
+ const EodashLayerControl = /*#__PURE__*/_export_sfc(_sfc_main, [['styles',[_style_0]],['__scopeId',"data-v-cd4de44c"]]);
1530
1548
 
1531
1549
  export { EodashLayerControl as default };
@@ -1,8 +1,8 @@
1
1
  import { ref, openBlock, createElementBlock, unref, createBlock, withCtx, createVNode, mergeProps } from 'vue';
2
- import { D as activeTemplate } from './helpers-CZFH0EVN.js';
2
+ import { C as activeTemplate } from './helpers-DjZVl_WF.js';
3
3
  import { mdiViewDashboard } from '@mdi/js';
4
- import { G as useDisplay, I as useTransparentPanel, K as VIcon } from './asWebComponent-DDt7V3Bl.js';
5
- import { V as VTooltip } from './VTooltip-BbmvtvYw.js';
4
+ import { G as useDisplay, I as useTransparentPanel, K as VIcon } from './asWebComponent-BHWpMuE3.js';
5
+ import { V as VTooltip } from './VTooltip-CJw2FyWk.js';
6
6
 
7
7
  const _sfc_main = {
8
8
  __name: 'EodashLayoutSwitcher',