@eodash/eodash 5.0.0 → 5.2.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 (162) hide show
  1. package/README.md +1 -0
  2. package/core/client/App.vue +8 -2
  3. package/core/client/asWebComponent.js +5 -5
  4. package/core/client/components/DashboardLayout.vue +43 -26
  5. package/core/client/components/EodashOverlay.vue +5 -6
  6. package/core/client/components/ErrorAlert.vue +2 -2
  7. package/core/client/components/Footer.vue +4 -4
  8. package/core/client/components/Header.vue +3 -3
  9. package/core/client/components/MobileLayout.vue +47 -27
  10. package/core/client/composables/DefineEodash.js +38 -43
  11. package/core/client/composables/DefineTemplate.js +4 -2
  12. package/core/client/composables/DefineWidgets.js +14 -8
  13. package/core/client/composables/index.js +273 -23
  14. package/core/client/eodashSTAC/EodashCollection.js +84 -62
  15. package/core/client/eodashSTAC/createLayers.js +30 -0
  16. package/core/client/eodashSTAC/helpers.js +159 -28
  17. package/core/client/eodashSTAC/parquet.js +145 -0
  18. package/core/client/eodashSTAC/triggers.js +6 -3
  19. package/core/client/plugins/index.js +4 -3
  20. package/core/client/plugins/vuetify.js +3 -0
  21. package/core/client/store/actions.js +21 -4
  22. package/core/client/store/stac.js +93 -56
  23. package/core/client/store/states.js +15 -5
  24. package/core/client/types.ts +59 -43
  25. package/core/client/utils/index.js +79 -0
  26. package/core/client/utils/keys.js +2 -2
  27. package/core/client/utils/states.js +30 -5
  28. package/core/client/views/Dashboard.vue +36 -32
  29. package/core/client/vite-env.d.ts +7 -0
  30. package/dist/client/{DashboardLayout-CkWvOMOW.js → DashboardLayout-Dq9Kfe6O.js} +24 -13
  31. package/dist/client/{DynamicWebComponent-DYBbpvUK.js → DynamicWebComponent-DCBMXskE.js} +1 -1
  32. package/dist/client/{EodashDatePicker-CALmW3SI.js → EodashDatePicker-DtngxU6s.js} +59 -32
  33. package/dist/client/{EodashItemFilter-DlQiE713.js → EodashItemFilter-ClQebJQt.js} +20 -10
  34. package/dist/client/{EodashLayerControl-DEzEbft7.js → EodashLayerControl-BLBds28C.js} +29 -16
  35. package/dist/client/EodashLayoutSwitcher-DQ8SfVDd.js +61 -0
  36. package/dist/client/EodashMapBtns-B89_YBDw.js +326 -0
  37. package/dist/client/{EodashStacInfo-DPPxDkF6.js → EodashStacInfo-Dt1nF06x.js} +3 -18
  38. package/dist/client/{EodashTools-CUaL9s4H.js → EodashTools-DV5ykmWc.js} +13 -13
  39. package/dist/client/{ExportState-DjyIZVhl.js → ExportState-B6zZQUmE.js} +57 -52
  40. package/dist/client/{Footer-DyL0JoWt.js → Footer-DNhXs8k6.js} +15 -13
  41. package/dist/client/{Header-B5Dgty9l.js → Header-BjhN5JY4.js} +32 -28
  42. package/dist/client/MobileLayout-JelB6w1G.js +118 -0
  43. package/dist/client/{PopUp-BfB8s_ki.js → PopUp-CgpvNr3o.js} +18 -10
  44. package/dist/client/ProcessList-vecpxThi.js +198 -0
  45. package/dist/client/{VImg-FD1WVphJ.js → VImg-CETuikH2.js} +221 -26
  46. package/dist/client/{VMain-DJKG4SvM.js → VMain-Ci9DyaGU.js} +7 -7
  47. package/dist/client/{VTooltip-CfeefrXI.js → VTooltip-J4ac48X7.js} +12 -10
  48. package/dist/client/{WidgetsContainer-C2TaTdb6.js → WidgetsContainer-CCML4TyV.js} +1 -1
  49. package/dist/client/asWebComponent-ZyEzWOOf.js +19092 -0
  50. package/dist/client/async-B7jIrM53.js +804 -0
  51. package/dist/client/eo-dash.js +1 -1
  52. package/dist/client/{VOverlay-BzOdRu9h.js → forwardRefs-BQclvjMq.js} +332 -28
  53. package/dist/client/handling-BS24aG1q.js +1227 -0
  54. package/dist/client/helpers-wXK7Ywio.js +4556 -0
  55. package/dist/client/index-4UCzZi8B.js +376 -0
  56. package/dist/client/{index-4CT7Tz83.js → index-9KR-G20t.js} +2 -2
  57. package/dist/client/{index-CIHH_3dW.js → index-B2XpdgR6.js} +227 -86
  58. package/dist/client/material-symbols-outlined.woff2 +0 -0
  59. package/dist/client/material-symbols-rounded.woff2 +0 -0
  60. package/dist/client/material-symbols-sharp.woff2 +0 -0
  61. package/dist/client/material-symbols-subset.woff2 +0 -0
  62. package/dist/client/{ssrBoot-BP7SYRyC.js → ssrBoot-Zgc_Ttvi.js} +2 -2
  63. package/dist/client/templates.js +840 -0
  64. package/dist/client/transition-yBii4fu6.js +40 -0
  65. package/dist/node/cli.js +16 -6
  66. package/dist/node/types.d.ts +1 -1
  67. package/dist/types/core/client/App.vue.d.ts +2 -2
  68. package/dist/types/core/client/asWebComponent.d.ts +1 -1
  69. package/dist/types/core/client/components/DynamicWebComponent.vue.d.ts +1 -3
  70. package/dist/types/core/client/components/Footer.vue.d.ts +1 -105
  71. package/dist/types/core/client/components/IframeWrapper.vue.d.ts +1 -1
  72. package/dist/types/core/client/components/MobileLayout.vue.d.ts +1 -324
  73. package/dist/types/core/client/composables/DefineEodash.d.ts +2 -2
  74. package/dist/types/core/client/composables/DefineTemplate.d.ts +1 -1
  75. package/dist/types/core/client/composables/DefineWidgets.d.ts +4 -4
  76. package/dist/types/core/client/composables/index.d.ts +24 -2
  77. package/dist/types/core/client/eodashSTAC/EodashCollection.d.ts +9 -6
  78. package/dist/types/core/client/eodashSTAC/helpers.d.ts +25 -5
  79. package/dist/types/core/client/eodashSTAC/parquet.d.ts +2 -0
  80. package/dist/types/core/client/plugins/vuetify.d.ts +7 -4
  81. package/dist/types/core/client/store/actions.d.ts +3 -2
  82. package/dist/types/core/client/store/stac.d.ts +16 -13
  83. package/dist/types/core/client/store/states.d.ts +14 -4
  84. package/dist/types/core/client/types.d.ts +46 -31
  85. package/dist/types/core/client/utils/index.d.ts +2 -0
  86. package/dist/types/core/client/utils/keys.d.ts +4 -4
  87. package/dist/types/core/client/utils/states.d.ts +59 -47
  88. package/dist/types/core/client/views/Dashboard.vue.d.ts +2 -2
  89. package/dist/types/templates/baseConfig.d.ts +4 -0
  90. package/dist/types/templates/compare.d.ts +185 -0
  91. package/dist/types/templates/expert.d.ts +147 -0
  92. package/dist/types/templates/index.d.ts +6 -0
  93. package/dist/types/templates/light.d.ts +154 -0
  94. package/dist/types/widgets/EodashDatePicker.vue.d.ts +1 -458
  95. package/dist/types/widgets/EodashItemFilter.vue.d.ts +3 -3
  96. package/dist/types/widgets/EodashLayerControl.vue.d.ts +14 -7
  97. package/dist/types/widgets/EodashLayoutSwitcher.vue.d.ts +1 -3
  98. package/dist/types/widgets/{EodashMapBtns.vue.d.ts → EodashMap/EodashMapBtns.vue.d.ts} +12 -8
  99. package/dist/types/widgets/EodashMap/index.vue.d.ts +9 -4
  100. package/dist/types/widgets/EodashProcess/ProcessList.vue.d.ts +8 -1
  101. package/dist/types/widgets/EodashProcess/index.vue.d.ts +8 -4
  102. package/dist/types/widgets/EodashProcess/methods/async.d.ts +19 -18
  103. package/dist/types/widgets/EodashProcess/methods/composables.d.ts +3 -2
  104. package/dist/types/widgets/EodashProcess/methods/custom-endpoints/chart/index.d.ts +1 -0
  105. package/dist/types/widgets/EodashProcess/methods/custom-endpoints/chart/sentinelhub-endpoint.d.ts +6 -0
  106. package/dist/types/widgets/EodashProcess/methods/custom-endpoints/chart/veda-endpoint.d.ts +4 -0
  107. package/dist/types/widgets/EodashProcess/methods/custom-endpoints/layers/eoxhub-workspaces-endpoint.d.ts +5 -0
  108. package/dist/types/widgets/EodashProcess/methods/custom-endpoints/layers/index.d.ts +1 -0
  109. package/dist/types/widgets/EodashProcess/methods/handling.d.ts +12 -5
  110. package/dist/types/widgets/EodashProcess/methods/outputs.d.ts +72 -41
  111. package/dist/types/widgets/EodashProcess/methods/utils.d.ts +41 -21
  112. package/dist/types/widgets/EodashProcess/states.d.ts +11 -0
  113. package/dist/types/widgets/EodashProcess/types.d.ts +41 -0
  114. package/dist/types/widgets/EodashStacInfo.vue.d.ts +14 -14
  115. package/dist/types/widgets/EodashTools.vue.d.ts +3 -3
  116. package/dist/types/widgets/ExportState.vue.d.ts +1 -1
  117. package/dist/types/widgets/PopUp.vue.d.ts +11 -16
  118. package/dist/types/widgets/WidgetsContainer.vue.d.ts +3 -6
  119. package/package.json +55 -45
  120. package/templates/baseConfig.js +68 -0
  121. package/templates/compare.js +142 -0
  122. package/templates/expert.js +124 -0
  123. package/templates/index.js +8 -0
  124. package/templates/light.js +139 -0
  125. package/widgets/EodashDatePicker.vue +80 -31
  126. package/widgets/EodashItemFilter.vue +26 -11
  127. package/widgets/EodashLayerControl.vue +20 -11
  128. package/widgets/EodashLayoutSwitcher.vue +6 -3
  129. package/widgets/EodashMap/EodashMapBtns.vue +269 -0
  130. package/widgets/EodashMap/index.vue +255 -45
  131. package/widgets/EodashMap/methods/create-layers-config.js +4 -3
  132. package/widgets/EodashMap/methods/index.js +33 -23
  133. package/widgets/EodashProcess/ProcessList.vue +47 -11
  134. package/widgets/EodashProcess/index.vue +55 -20
  135. package/widgets/EodashProcess/methods/async.js +99 -60
  136. package/widgets/EodashProcess/methods/composables.js +21 -14
  137. package/widgets/EodashProcess/methods/custom-endpoints/chart/index.js +35 -0
  138. package/widgets/EodashProcess/methods/custom-endpoints/chart/sentinelhub-endpoint.js +275 -0
  139. package/widgets/EodashProcess/methods/custom-endpoints/chart/veda-endpoint.js +132 -0
  140. package/widgets/EodashProcess/methods/custom-endpoints/layers/eoxhub-workspaces-endpoint.js +94 -0
  141. package/widgets/EodashProcess/methods/custom-endpoints/layers/index.js +33 -0
  142. package/widgets/EodashProcess/methods/handling.js +127 -80
  143. package/widgets/EodashProcess/methods/outputs.js +376 -125
  144. package/widgets/EodashProcess/methods/utils.js +442 -10
  145. package/widgets/EodashProcess/states.js +13 -0
  146. package/widgets/EodashProcess/types.ts +46 -0
  147. package/widgets/EodashStacInfo.vue +2 -17
  148. package/widgets/EodashTools.vue +13 -13
  149. package/widgets/WidgetsContainer.vue +1 -1
  150. package/core/client/eodash.js +0 -454
  151. package/dist/client/EodashLayoutSwitcher-CDeCV8F-.js +0 -52
  152. package/dist/client/EodashMapBtns-CktQCfa-.js +0 -131
  153. package/dist/client/MobileLayout-CRsg_5Q4.js +0 -1217
  154. package/dist/client/ProcessList-DTefwQZx.js +0 -484
  155. package/dist/client/asWebComponent-CLhcT715.js +0 -12479
  156. package/dist/client/eo-dash.css +0 -5
  157. package/dist/client/forwardRefs-Bon_Kku1.js +0 -245
  158. package/dist/client/index-Bm9cbtx5.js +0 -201
  159. package/dist/client/index-DiGDvTQU.js +0 -780
  160. package/dist/client/transition-C5I57hn6.js +0 -37
  161. package/dist/types/core/client/eodash.d.ts +0 -8
  162. package/widgets/EodashMapBtns.vue +0 -113
@@ -1,45 +1,88 @@
1
1
  <template>
2
- <eox-map-compare
3
- class="fill-height fill-width overflow-none"
4
- .enabled="showCompare"
5
- >
6
- <eox-map
2
+ <span>
3
+ <eox-map-compare
7
4
  class="fill-height fill-width overflow-none"
8
- slot="first"
9
- ref="eoxMap"
10
- id="main"
11
- .animationOptions="animationOptions"
12
- .center="initialCenter"
13
- .zoom="initialZoom"
14
- .layers="eoxMapLayers"
15
- .controls="controls"
5
+ .enabled="showCompare"
16
6
  >
17
- <eox-map-tooltip
18
- :style="mainTooltipStyles"
19
- .propertyTransform="tooltipPropertyTransform('main')"
20
- />
21
- </eox-map>
22
- <eox-map
23
- class="fill-height fill-width overflow-none"
24
- id="compare"
25
- slot="second"
26
- ref="compareMap"
27
- .layers="eoxMapCompareLayers"
7
+ <eox-map
8
+ class="fill-height fill-width overflow-none"
9
+ slot="first"
10
+ ref="eoxMap"
11
+ id="main"
12
+ .animationOptions="animationOptions"
13
+ .center="initialCenter"
14
+ .zoom="initialZoom"
15
+ .layers="eoxMapLayers"
16
+ .controls="controls"
17
+ >
18
+ <eox-map-tooltip
19
+ :style="mainTooltipStyles"
20
+ .propertyTransform="tooltipPropertyTransform('main')"
21
+ />
22
+ </eox-map>
23
+ <eox-map
24
+ class="fill-height fill-width overflow-none"
25
+ id="compare"
26
+ slot="second"
27
+ ref="compareMap"
28
+ .layers="eoxMapCompareLayers"
29
+ >
30
+ <eox-map-tooltip
31
+ :style="compareTooltipStyles"
32
+ .propertyTransform="tooltipPropertyTransform('compare')"
33
+ />
34
+ </eox-map>
35
+ </eox-map-compare>
36
+ <div
37
+ v-if="enableCursorCoordinates"
38
+ id="cursor-coordinates"
39
+ ref="cursor-coords"
40
+ />
41
+ <span v-if="enableScaleLine" id="scale-line" ref="scale-line" />
42
+ <div
43
+ class="map-buttons-container"
44
+ :style="`margin: ${btnsPosition.gap}px 0 ${btnsPosition.gap}px 0`"
28
45
  >
29
- <eox-map-tooltip
30
- :style="compareTooltipStyles"
31
- .propertyTransform="tooltipPropertyTransform('compare')"
46
+ <EodashMapBtns
47
+ :style="{
48
+ gridColumn: indicator || compareIndicator ? responsiveX : '12',
49
+ gridRow: responsiveY,
50
+ }"
51
+ :exportMap="(indicator || compareIndicator) ? btnsProps.exportMap : false"
52
+ :changeProjection="
53
+ (indicator || compareIndicator) ? btnsProps.changeProjection : false
54
+ "
55
+ :compareIndicators="
56
+ (indicator || compareIndicator) ? btnsProps.compareIndicators : false
57
+ "
58
+ :backToPOIs="
59
+ (indicator || compareIndicator) ? btnsProps.backToPOIs : false
60
+ "
61
+ :enableSearch="
62
+ (indicator || compareIndicator) ? btnsProps.enableSearch : false
63
+ "
64
+ :enableZoom="
65
+ (indicator || compareIndicator) ? btnsProps.enableZoom : false
66
+ "
32
67
  />
33
- </eox-map>
34
- </eox-map-compare>
68
+ </div>
69
+ </span>
35
70
  </template>
36
71
  <script setup>
37
72
  import "@eox/map";
38
73
  import "@eox/map/src/plugins/advancedLayersAndSources";
39
- import { computed, onMounted, ref, toRaw } from "vue";
40
- import { datetime, mapEl, mapPosition, mapCompareEl } from "@/store/states";
74
+ import { computed, onMounted, ref, toRaw, useTemplateRef } from "vue";
75
+ import {
76
+ datetime,
77
+ mapEl,
78
+ mapPosition,
79
+ mapCompareEl,
80
+ indicator,
81
+ compareIndicator,
82
+ } from "@/store/states";
41
83
  import { storeToRefs } from "pinia";
42
84
  import { useSTAcStore } from "@/store/stac";
85
+ import { useDisplay } from "vuetify";
43
86
  import {
44
87
  eodashCollections,
45
88
  eodashCompareCollections,
@@ -53,6 +96,7 @@ import {
53
96
  } from "^/EodashMap/methods";
54
97
  import { inAndOut } from "ol/easing.js";
55
98
  import mustache from "mustache";
99
+ import EodashMapBtns from "^/EodashMap/EodashMapBtns.vue";
56
100
 
57
101
  const props = defineProps({
58
102
  enableCompare: {
@@ -63,32 +107,129 @@ const props = defineProps({
63
107
  center: {
64
108
  //@ts-expect-error todo
65
109
  type: Array,
66
- default: () => [15, 48],
110
+ default: () => [mapPosition.value?.[0] ?? 15, mapPosition.value?.[1] ?? 48],
67
111
  },
68
112
  zoom: {
69
113
  type: Number,
70
- default: 4,
114
+ default: mapPosition.value?.[2] ?? 4,
71
115
  },
72
116
  zoomToExtent: {
73
117
  type: Boolean,
74
118
  default: true,
75
119
  },
120
+ enableCursorCoordinates: {
121
+ type: Boolean,
122
+ default: true,
123
+ },
124
+ enableScaleLine: {
125
+ type: Boolean,
126
+ default: true,
127
+ },
128
+ btnsPosition: {
129
+ type: Object,
130
+ default: () => ({
131
+ x: "12/9/10",
132
+ y: 1,
133
+ gap: 16,
134
+ }),
135
+ },
136
+ btns: {
137
+ type: Object,
138
+ default: () => ({
139
+ enableExportMap: true,
140
+ enableChangeProjection: true,
141
+ enableCompareIndicators: true,
142
+ enableBackToPOIs: true,
143
+ enableSearch: true,
144
+ enableZoom: true,
145
+ }),
146
+ },
76
147
  });
77
148
 
149
+ // Responsive positioning logic
150
+ const { width } = useDisplay();
151
+
152
+ /**
153
+ * Parse responsive string values (e.g., "1/5/10") into values for different screen sizes
154
+ * Breakpoints: [0, 960, 1920] based on properties passed to eox-layout in DashboardLayout.vue
155
+ * @param {string | number} value
156
+ * @returns {number}
157
+ */
158
+ const parseResponsiveValue = (value) => {
159
+ if (typeof value === "number") {
160
+ return value;
161
+ }
162
+ if (typeof value === "string") {
163
+ const parts = value.split("/");
164
+ const currentWidth = width.value;
165
+
166
+ if (currentWidth < 960) {
167
+ return parseInt(parts[0]) || 1;
168
+ } else if (currentWidth < 1920) {
169
+ return parseInt(parts[1] || parts[0]) || 1;
170
+ } else {
171
+ return parseInt(parts[2] || parts[1] || parts[0]) || 1;
172
+ }
173
+ }
174
+ return 1;
175
+ };
176
+
177
+ const responsiveX = computed(() => parseResponsiveValue(props.btnsPosition.x));
178
+ const responsiveY = computed(() => parseResponsiveValue(props.btnsPosition.y));
179
+ const btnsProps = computed(() => ({
180
+ exportMap: props.btns.enableExportMap ?? true,
181
+ changeProjection: props.btns.enableChangeProjection ?? true,
182
+ compareIndicators: props.btns.enableCompareIndicators ?? true,
183
+ backToPOIs: props.btns.enableBackToPOIs ?? true,
184
+ enableSearch: props.btns.enableSearch ?? true,
185
+ enableZoom: props.btns.enableZoom ?? true,
186
+ }));
187
+
188
+ // Prepare containers for scale line and cursor coordinates
189
+ const scaleLineRef = useTemplateRef("scale-line");
190
+ const cursorCoordsRef = useTemplateRef("cursor-coords");
191
+
78
192
  /** @type {import("vue").Ref<Exclude<import("@/types").EodashStyleJson["tooltip"], undefined>>} */
79
193
  const tooltipProperties = ref([]);
80
194
  /** @type {import("vue").Ref<Exclude<import("@/types").EodashStyleJson["tooltip"], undefined>>} */
81
195
  const compareTooltipProperties = ref([]);
82
- /** @type {import("@eox/map").EOxMap["controls"]} */
83
- const controls = {
84
- Attribution: {
85
- collapsible: true,
86
- },
87
- };
88
- const initialCenter = toRaw([
89
- mapPosition.value?.[0] ?? props.center?.[0],
90
- mapPosition.value?.[1] ?? props.center?.[1],
91
- ]);
196
+ /** @type {import("vue").ComputedRef<{
197
+ Attribution: { collapsible: boolean };
198
+ ScaleLine?: { target: HTMLElement };
199
+ MousePosition?: { projection: string; coordinateFormat: (c: [number, number]) => string; target: HTMLElement };
200
+ }>} */
201
+ const controls = computed(() => {
202
+ /** @type {{
203
+ Attribution: { collapsible: boolean };
204
+ ScaleLine?: { target: HTMLElement };
205
+ MousePosition?: { projection: string; coordinateFormat: (c: [number, number]) => string; target: HTMLElement };
206
+ }} */
207
+ const controlsObj = {
208
+ Attribution: {
209
+ collapsible: true,
210
+ },
211
+ };
212
+
213
+ if (props.enableScaleLine && scaleLineRef.value) {
214
+ controlsObj.ScaleLine = {
215
+ target: scaleLineRef.value,
216
+ };
217
+ }
218
+
219
+ if (props.enableCursorCoordinates && cursorCoordsRef.value) {
220
+ controlsObj.MousePosition = {
221
+ projection: "EPSG:4326",
222
+ coordinateFormat: (/** @type {[number, number]} */ c) => {
223
+ return `${c[1].toFixed(3)} °N, ${c[0].toFixed(3)} °E`;
224
+ },
225
+ target: cursorCoordsRef.value,
226
+ };
227
+ }
228
+
229
+ return controlsObj;
230
+ });
231
+
232
+ const initialCenter = toRaw(props.center);
92
233
  const initialZoom = toRaw(mapPosition.value?.[2] ?? props.zoom);
93
234
  /** @type {import("vue").Ref<Record<string,any>[]>} */
94
235
  const eoxMapLayers = ref([
@@ -142,7 +283,6 @@ onMounted(() => {
142
283
  if (props.enableCompare) {
143
284
  useInitMap(
144
285
  compareMap,
145
- //@ts-expect-error todo selectedStac as collection
146
286
  selectedCompareStac,
147
287
  eodashCompareCollections,
148
288
  datetime,
@@ -156,7 +296,6 @@ onMounted(() => {
156
296
 
157
297
  useInitMap(
158
298
  eoxMap,
159
- //@ts-expect-error todo selectedStac as collection
160
299
  selectedStac,
161
300
  eodashCollections,
162
301
  datetime,
@@ -215,3 +354,74 @@ const tooltipPropertyTransform = (map) => {
215
354
  };
216
355
  };
217
356
  </script>
357
+
358
+ <style scoped>
359
+ #cursor-coordinates {
360
+ position: fixed;
361
+ left: 24px;
362
+ bottom: 54px; /* Tighter spacing: watermark at 6px + ~48px */
363
+ color: rgba(0, 0, 0, 0.9);
364
+ font-size: 11px;
365
+ font-family: var(--eox-body-font-family);
366
+ background: #fffe;
367
+ border-radius: 4px;
368
+ border: none;
369
+ padding: 0px 3px;
370
+ max-height: 24px;
371
+ }
372
+
373
+ @media (max-width: 959px) {
374
+ #cursor-coordinates {
375
+ display: none; /* Hidden in mobile mode */
376
+ }
377
+ }
378
+
379
+ #scale-line {
380
+ position: fixed;
381
+ left: 24px;
382
+ bottom: 28px; /* Tighter spacing: watermark at 6px + ~22px */
383
+ color: #fff;
384
+ }
385
+
386
+ @media (max-width: 959px) {
387
+ #scale-line {
388
+ bottom: 102px; /* Adjusted for mobile bottom nav - closer to coordinates */
389
+ }
390
+ }
391
+
392
+ :deep(.ol-scale-line) {
393
+ background: #fffe !important;
394
+ border-radius: 4px !important;
395
+ border: none !important;
396
+ padding: 0px 3px 3px 3px !important;
397
+ font-size: 10px !important;
398
+ font-family: var(--eox-body-font-family);
399
+ max-height: 20px;
400
+ }
401
+ :deep(.ol-scale-line-inner) {
402
+ display: flex;
403
+ justify-content: center;
404
+ border: 1px solid rgba(0, 0, 0, 0.5) !important;
405
+ border-top: none !important;
406
+ color: #333 !important;
407
+ font-weight: 500 !important;
408
+ transform: translateY(1px);
409
+ }
410
+
411
+ .map-buttons-container {
412
+ position: fixed;
413
+ top: 0;
414
+ left: 0;
415
+ width: 100%;
416
+ height: 100%;
417
+ display: grid;
418
+ grid-template-columns: repeat(12, 1fr);
419
+ grid-template-rows: repeat(12, 1fr);
420
+ pointer-events: none;
421
+ z-index: 1;
422
+ }
423
+
424
+ .map-buttons-container > * {
425
+ pointer-events: auto;
426
+ }
427
+ </style>
@@ -53,9 +53,10 @@ export const createLayersConfig = async (
53
53
  const indicatorLayers =
54
54
  //@ts-expect-error indicator is collection
55
55
  await EodashCollection.getIndicatorLayers(selectedIndicator);
56
- const geodbLayer = EodashCollection.getGeoDBLayer(eodashCols);
57
- if (geodbLayer) {
58
- dataLayers.layers.unshift(geodbLayer);
56
+ const observationPointsLayer =
57
+ EodashCollection.getObservationPointsLayer(eodashCols);
58
+ if (observationPointsLayer) {
59
+ dataLayers.layers.unshift(observationPointsLayer);
59
60
  }
60
61
  const baseLayers = {
61
62
  type: "Group",
@@ -1,13 +1,12 @@
1
1
  import { createLayersConfig } from "./create-layers-config";
2
2
  import { setMapProjFromCol } from "@/eodashSTAC/triggers";
3
- import { nextTick, onMounted, onUnmounted, watch } from "vue";
3
+ import { onMounted, onUnmounted, watch } from "vue";
4
4
  import log from "loglevel";
5
5
  import { useSTAcStore } from "@/store/stac";
6
6
  import { storeToRefs } from "pinia";
7
- import { useEventBus } from "@vueuse/core";
8
- import { eoxLayersKey } from "@/utils/keys";
9
- import { posIsSetFromUrl } from "@/utils/states";
10
- import { useOnLayersUpdate } from "@/composables";
7
+ import { isFirstLoad } from "@/utils/states";
8
+ import { useEmitLayersUpdate, useOnLayersUpdate } from "@/composables";
9
+ import { mapPosition } from "@/store/states";
11
10
  /**
12
11
  * Holder for previous compare map view as it is overwritten by sync
13
12
  * @type { import("ol").View | null} mapElement
@@ -35,9 +34,6 @@ export const useHandleMapMoveEnd = (mapElement, mapPosition) => {
35
34
  !Number.isNaN(z)
36
35
  ) {
37
36
  mapPosition.value = [lonlat[0], lonlat[1], z];
38
- if (posIsSetFromUrl.value) {
39
- posIsSetFromUrl.value = false;
40
- }
41
37
  }
42
38
  };
43
39
 
@@ -79,7 +75,6 @@ export const useInitMap = (
79
75
  eodashCols.values,
80
76
  datetime.value,
81
77
  );
82
- const layersEvent = useEventBus(eoxLayersKey);
83
78
 
84
79
  const stopIndicatorWatcher = watch(
85
80
  [selectedIndicator, datetime],
@@ -132,9 +127,14 @@ export const useInitMap = (
132
127
  JSON.parse(JSON.stringify(layersCollection)),
133
128
  );
134
129
  mapLayers.value = layersCollection;
135
- await nextTick(() => {
136
- layersEvent.emit("time:updated", mapLayers.value);
137
- });
130
+
131
+ useEmitLayersUpdate(
132
+ mapElement.value?.id === "compare"
133
+ ? "compareTime:updated"
134
+ : "time:updated",
135
+ mapElement.value,
136
+ layersCollection,
137
+ );
138
138
  return;
139
139
  }
140
140
 
@@ -158,7 +158,8 @@ export const useInitMap = (
158
158
  }
159
159
  if (
160
160
  endInterval !== null &&
161
- endInterval.toISOString() !== datetime.value
161
+ endInterval.toISOString() !== datetime.value &&
162
+ !isFirstLoad.value
162
163
  ) {
163
164
  datetime.value = endInterval.toISOString();
164
165
  }
@@ -169,7 +170,11 @@ export const useInitMap = (
169
170
  if (
170
171
  mapElement?.value?.id === "main" &&
171
172
  updatedStac.extent?.spatial.bbox &&
172
- !posIsSetFromUrl.value
173
+ !(
174
+ isFirstLoad.value &&
175
+ mapPosition.value?.[0] &&
176
+ mapPosition.value?.[1]
177
+ )
173
178
  ) {
174
179
  // Sanitize extent,
175
180
  const b = updatedStac.extent?.spatial.bbox[0];
@@ -189,9 +194,6 @@ export const useInitMap = (
189
194
  (mapElement.value).zoomExtent = reprojExtent;
190
195
  }
191
196
  }
192
- if (posIsSetFromUrl.value) {
193
- posIsSetFromUrl.value = false;
194
- }
195
197
 
196
198
  log.debug(
197
199
  "Assigned layers",
@@ -199,11 +201,13 @@ export const useInitMap = (
199
201
  );
200
202
  mapLayers.value = layersCollection;
201
203
  // Emit event to update layers
202
- await nextTick(() => {
203
- mapElement.value?.updateComplete.then(() => {
204
- layersEvent.emit("layers:updated", mapLayers.value);
205
- });
206
- });
204
+ await useEmitLayersUpdate(
205
+ mapElement.value?.id === "compare"
206
+ ? "compareLayers:updated"
207
+ : "layers:updated",
208
+ mapElement.value,
209
+ mapLayers.value,
210
+ );
207
211
  }
208
212
  },
209
213
  { immediate: true },
@@ -218,8 +222,14 @@ export const useInitMap = (
218
222
  * @param {import("@/eodashSTAC/EodashCollection").EodashCollection[]} eodashCols
219
223
  * @param {import("vue").Ref<Exclude<import("@/types").EodashStyleJson["tooltip"],undefined>>} tooltipProperties
220
224
  */
225
+
221
226
  export const useUpdateTooltipProperties = (eodashCols, tooltipProperties) => {
222
- useOnLayersUpdate(async () => {
227
+ useOnLayersUpdate(async (evt, _payload) => {
228
+ if (evt.includes("compare")) {
229
+ // TODO: support compare map tooltips
230
+ // Do not update tooltip properties on compare map
231
+ return;
232
+ }
223
233
  const tooltips = [];
224
234
  for (const ec of eodashCols) {
225
235
  tooltips.push(...(await ec.getToolTipProperties()));
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div>
3
3
  <v-table
4
- v-if="jobs.length"
4
+ v-if="currentJobs.length"
5
5
  density="compact"
6
6
  style="background-color: transparent"
7
7
  >
@@ -15,16 +15,23 @@
15
15
  </tr>
16
16
  </thead>
17
17
  <tbody>
18
- <tr v-for="item in jobs" :key="item.date">
18
+ <tr v-for="item in currentJobs" :key="item.jobID">
19
19
  <td>
20
- {{ new Date(item.job_start_datetime).toISOString().slice(0, 16) }}
20
+ <a
21
+ class="processUrl"
22
+ target="_blank"
23
+ :href="getJobStatusUrl(item.jobID, currentIndicator)"
24
+ >{{
25
+ new Date(item.job_start_datetime).toISOString().slice(0, 16)
26
+ }}</a
27
+ >
21
28
  </td>
22
29
  <td>{{ item.status }}</td>
23
30
  <td style="padding: 0px">
24
31
  <v-btn
25
32
  :disabled="item.status !== 'successful'"
26
33
  color="primary"
27
- @click="loadProcess(item, selectedStac)"
34
+ @click="loadProcess(item, currentStac, mapElement)"
28
35
  :icon="[mdiUploadBox]"
29
36
  variant="text"
30
37
  v-tooltip="'Load results to map'"
@@ -35,7 +42,7 @@
35
42
  <v-btn
36
43
  :disabled="item.status !== 'successful'"
37
44
  color="primary"
38
- @click="downloadPreviousResults(item, selectedStac)"
45
+ @click="downloadPreviousResults(item, currentStac)"
39
46
  :icon="[mdiDownloadBox]"
40
47
  variant="text"
41
48
  v-tooltip="'Download results'"
@@ -45,7 +52,13 @@
45
52
  <td style="padding: 0px">
46
53
  <v-btn
47
54
  color="#ff5252"
48
- @click="deleteJob(item)"
55
+ @click="
56
+ deleteJob(
57
+ toRef(() => currentJobs),
58
+ item,
59
+ currentIndicator,
60
+ )
61
+ "
49
62
  :icon="[mdiTrashCanOutline]"
50
63
  variant="text"
51
64
  v-tooltip="'Remove job'"
@@ -59,24 +72,47 @@
59
72
  </template>
60
73
  <script setup>
61
74
  import { mdiUploadBox, mdiDownloadBox, mdiTrashCanOutline } from "@mdi/js";
62
- import { onMounted, toRefs } from "vue";
75
+ import { onMounted, toRef, toRefs } from "vue";
63
76
  import { useSTAcStore } from "@/store/stac";
64
- import { indicator } from "@/store/states";
77
+ import { compareIndicator, indicator } from "@/store/states";
65
78
  import {
66
79
  deleteJob,
67
80
  downloadPreviousResults,
68
- jobs,
69
81
  loadProcess,
70
82
  updateJobsStatus,
83
+ getJobStatusUrl,
71
84
  } from "./methods/async";
85
+ import { useOnLayersUpdate } from "@/composables";
86
+ import { compareJobs, jobs } from "./states";
87
+ const { enableCompare, mapElement } = defineProps({
88
+ enableCompare: {
89
+ type: Boolean,
90
+ default: false,
91
+ },
92
+ mapElement: {
93
+ /** @type {import("vue").PropType<import("@eox/map").EOxMap | null>} */
94
+ type: Object,
95
+ default: () => null,
96
+ },
97
+ });
98
+ const { selectedStac, selectedCompareStac } = toRefs(useSTAcStore());
99
+ const currentJobs = enableCompare ? compareJobs : jobs;
100
+ const currentIndicator = enableCompare ? compareIndicator : indicator;
101
+ const currentStac = enableCompare ? selectedCompareStac : selectedStac;
72
102
 
73
- const { selectedStac } = toRefs(useSTAcStore());
103
+ onMounted(() => {
104
+ updateJobsStatus(currentJobs, currentIndicator.value);
105
+ });
74
106
 
75
- onMounted(() => updateJobsStatus(jobs, indicator));
107
+ useOnLayersUpdate(() => updateJobsStatus(currentJobs, currentIndicator.value));
76
108
  </script>
77
109
  <style lang="scss">
78
110
  div.v-table__wrapper {
79
111
  overflow: hidden !important;
80
112
  height: max-content !important;
81
113
  }
114
+ .processUrl {
115
+ text-decoration: none;
116
+ color: var(--v-theme-primary);
117
+ }
82
118
  </style>