@eodash/eodash 5.0.0-rc.3 → 5.1.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 (155) 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 +42 -25
  5. package/core/client/components/EodashOverlay.vue +1 -1
  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 +9 -10
  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 +80 -47
  15. package/core/client/eodashSTAC/helpers.js +136 -27
  16. package/core/client/eodashSTAC/parquet.js +145 -0
  17. package/core/client/eodashSTAC/triggers.js +6 -3
  18. package/core/client/plugins/index.js +4 -3
  19. package/core/client/plugins/vuetify.js +3 -0
  20. package/core/client/store/actions.js +21 -4
  21. package/core/client/store/stac.js +93 -56
  22. package/core/client/store/states.js +15 -5
  23. package/core/client/types.ts +59 -43
  24. package/core/client/utils/index.js +79 -0
  25. package/core/client/utils/keys.js +2 -2
  26. package/core/client/utils/states.js +30 -5
  27. package/core/client/views/Dashboard.vue +36 -32
  28. package/core/client/vite-env.d.ts +7 -0
  29. package/dist/client/{DashboardLayout-t_PavJPO.js → DashboardLayout-ByVs1DrY.js} +23 -12
  30. package/dist/client/{DynamicWebComponent-y07rVJch.js → DynamicWebComponent-C3W7HSQm.js} +1 -1
  31. package/dist/client/{EodashDatePicker-CcOfyzGD.js → EodashDatePicker-BIAf1sMT.js} +59 -32
  32. package/dist/client/{EodashItemFilter-B9HCvIMi.js → EodashItemFilter-DPznh8UB.js} +20 -10
  33. package/dist/client/{EodashLayerControl-KStn7Nb_.js → EodashLayerControl-Bhxjw4V2.js} +29 -16
  34. package/dist/client/EodashLayoutSwitcher-C5qTEffW.js +61 -0
  35. package/dist/client/EodashMapBtns-WoGq8MuV.js +173 -0
  36. package/dist/client/{EodashStacInfo-C_hDy6Pd.js → EodashStacInfo-CSvvF2jI.js} +3 -18
  37. package/dist/client/{EodashTools-BXflvRf8.js → EodashTools-Cv1SXQ5y.js} +13 -13
  38. package/dist/client/{ExportState-C0QRemK1.js → ExportState-D-iuwaad.js} +58 -52
  39. package/dist/client/{Footer-7VGyGUAs.js → Footer-CyF0zRAk.js} +15 -13
  40. package/dist/client/{Header-BQJnXHYq.js → Header-CgD8jDKU.js} +33 -28
  41. package/dist/client/{MobileLayout-b8nQ-Vyl.js → MobileLayout-EKQ_kpSh.js} +69 -60
  42. package/dist/client/{PopUp-DgNrh9Df.js → PopUp-BsYLvWch.js} +19 -10
  43. package/dist/client/ProcessList-C2xsLU2_.js +191 -0
  44. package/dist/client/{VImg-D4eT3IQ1.js → VImg-OHe8YTs2.js} +24 -24
  45. package/dist/client/{VMain-C3hN2-H3.js → VMain-PryTLU4a.js} +7 -7
  46. package/dist/client/{VOverlay-tAeNygaA.js → VOverlay-yUn7p-Uf.js} +64 -27
  47. package/dist/client/{VTooltip-B0Q3iHMZ.js → VTooltip-DZ0fjpB3.js} +13 -10
  48. package/dist/client/{WidgetsContainer-CtDHfCYf.js → WidgetsContainer-B9LBadcC.js} +1 -1
  49. package/dist/client/asWebComponent-By_7_JjS.js +19193 -0
  50. package/dist/client/async-DkSu_u2K.js +740 -0
  51. package/dist/client/eo-dash.js +1 -1
  52. package/dist/client/{forwardRefs-CIFAqXaZ.js → forwardRefs-BXxrv98s.js} +31 -4
  53. package/dist/client/handling-CgmFXkW6.js +1212 -0
  54. package/dist/client/helpers-Dy0Q13tP.js +4534 -0
  55. package/dist/client/{index-DvcUndod.js → index-BuhOHXKv.js} +2 -4
  56. package/dist/client/{index-BQ16n4Sk.js → index-Ch_HchK3.js} +39 -32
  57. package/dist/client/{index-Cv7HBz49.js → index-Dqj4tbx2.js} +2 -2
  58. package/dist/client/index-skjhlH8u.js +376 -0
  59. package/dist/client/{ssrBoot-BP7SYRyC.js → ssrBoot-Zgc_Ttvi.js} +2 -2
  60. package/dist/client/templates.js +850 -0
  61. package/dist/client/transition-C98Yn4Vo.js +40 -0
  62. package/dist/node/cli.js +16 -6
  63. package/dist/node/types.d.ts +1 -1
  64. package/dist/types/core/client/App.vue.d.ts +2 -2
  65. package/dist/types/core/client/asWebComponent.d.ts +1 -1
  66. package/dist/types/core/client/components/DynamicWebComponent.vue.d.ts +1 -3
  67. package/dist/types/core/client/components/Footer.vue.d.ts +1 -105
  68. package/dist/types/core/client/components/IframeWrapper.vue.d.ts +1 -1
  69. package/dist/types/core/client/components/MobileLayout.vue.d.ts +1 -324
  70. package/dist/types/core/client/composables/DefineEodash.d.ts +2 -2
  71. package/dist/types/core/client/composables/DefineTemplate.d.ts +1 -1
  72. package/dist/types/core/client/composables/DefineWidgets.d.ts +4 -4
  73. package/dist/types/core/client/composables/index.d.ts +24 -2
  74. package/dist/types/core/client/eodashSTAC/EodashCollection.d.ts +9 -6
  75. package/dist/types/core/client/eodashSTAC/helpers.d.ts +20 -5
  76. package/dist/types/core/client/eodashSTAC/parquet.d.ts +2 -0
  77. package/dist/types/core/client/plugins/vuetify.d.ts +7 -4
  78. package/dist/types/core/client/store/actions.d.ts +3 -2
  79. package/dist/types/core/client/store/stac.d.ts +16 -13
  80. package/dist/types/core/client/store/states.d.ts +14 -4
  81. package/dist/types/core/client/types.d.ts +45 -30
  82. package/dist/types/core/client/utils/index.d.ts +2 -0
  83. package/dist/types/core/client/utils/keys.d.ts +4 -4
  84. package/dist/types/core/client/utils/states.d.ts +59 -47
  85. package/dist/types/core/client/views/Dashboard.vue.d.ts +2 -2
  86. package/dist/types/templates/baseConfig.d.ts +4 -0
  87. package/dist/types/templates/compare.d.ts +210 -0
  88. package/dist/types/templates/expert.d.ts +151 -0
  89. package/dist/types/templates/index.d.ts +6 -0
  90. package/dist/types/templates/light.d.ts +145 -0
  91. package/dist/types/widgets/EodashDatePicker.vue.d.ts +1 -458
  92. package/dist/types/widgets/EodashItemFilter.vue.d.ts +3 -3
  93. package/dist/types/widgets/EodashLayerControl.vue.d.ts +14 -7
  94. package/dist/types/widgets/EodashLayoutSwitcher.vue.d.ts +1 -3
  95. package/dist/types/widgets/EodashMap/index.vue.d.ts +1 -4
  96. package/dist/types/widgets/EodashMapBtns.vue.d.ts +8 -8
  97. package/dist/types/widgets/EodashProcess/ProcessList.vue.d.ts +8 -1
  98. package/dist/types/widgets/EodashProcess/index.vue.d.ts +8 -4
  99. package/dist/types/widgets/EodashProcess/methods/async.d.ts +18 -18
  100. package/dist/types/widgets/EodashProcess/methods/composables.d.ts +3 -2
  101. package/dist/types/widgets/EodashProcess/methods/custom-endpoints/chart/index.d.ts +1 -0
  102. package/dist/types/widgets/EodashProcess/methods/custom-endpoints/chart/sentinelhub-endpoint.d.ts +6 -0
  103. package/dist/types/widgets/EodashProcess/methods/custom-endpoints/chart/veda-endpoint.d.ts +4 -0
  104. package/dist/types/widgets/EodashProcess/methods/custom-endpoints/layers/eoxhub-workspaces-endpoint.d.ts +5 -0
  105. package/dist/types/widgets/EodashProcess/methods/custom-endpoints/layers/index.d.ts +1 -0
  106. package/dist/types/widgets/EodashProcess/methods/handling.d.ts +12 -5
  107. package/dist/types/widgets/EodashProcess/methods/outputs.d.ts +72 -41
  108. package/dist/types/widgets/EodashProcess/methods/utils.d.ts +41 -21
  109. package/dist/types/widgets/EodashProcess/states.d.ts +11 -0
  110. package/dist/types/widgets/EodashProcess/types.d.ts +41 -0
  111. package/dist/types/widgets/EodashStacInfo.vue.d.ts +14 -14
  112. package/dist/types/widgets/EodashTools.vue.d.ts +3 -3
  113. package/dist/types/widgets/ExportState.vue.d.ts +1 -1
  114. package/dist/types/widgets/PopUp.vue.d.ts +11 -16
  115. package/dist/types/widgets/WidgetsContainer.vue.d.ts +3 -6
  116. package/package.json +53 -45
  117. package/templates/baseConfig.js +68 -0
  118. package/templates/compare.js +162 -0
  119. package/templates/expert.js +123 -0
  120. package/templates/index.js +8 -0
  121. package/templates/light.js +130 -0
  122. package/widgets/EodashDatePicker.vue +80 -31
  123. package/widgets/EodashItemFilter.vue +26 -11
  124. package/widgets/EodashLayerControl.vue +20 -11
  125. package/widgets/EodashLayoutSwitcher.vue +6 -3
  126. package/widgets/EodashMap/index.vue +3 -8
  127. package/widgets/EodashMap/methods/create-layers-config.js +4 -3
  128. package/widgets/EodashMap/methods/index.js +33 -23
  129. package/widgets/EodashMapBtns.vue +83 -41
  130. package/widgets/EodashProcess/ProcessList.vue +34 -10
  131. package/widgets/EodashProcess/index.vue +55 -20
  132. package/widgets/EodashProcess/methods/async.js +77 -59
  133. package/widgets/EodashProcess/methods/composables.js +21 -14
  134. package/widgets/EodashProcess/methods/custom-endpoints/chart/index.js +35 -0
  135. package/widgets/EodashProcess/methods/custom-endpoints/chart/sentinelhub-endpoint.js +275 -0
  136. package/widgets/EodashProcess/methods/custom-endpoints/chart/veda-endpoint.js +116 -0
  137. package/widgets/EodashProcess/methods/custom-endpoints/layers/eoxhub-workspaces-endpoint.js +94 -0
  138. package/widgets/EodashProcess/methods/custom-endpoints/layers/index.js +33 -0
  139. package/widgets/EodashProcess/methods/handling.js +127 -80
  140. package/widgets/EodashProcess/methods/outputs.js +376 -125
  141. package/widgets/EodashProcess/methods/utils.js +398 -10
  142. package/widgets/EodashProcess/states.js +13 -0
  143. package/widgets/EodashProcess/types.ts +46 -0
  144. package/widgets/EodashStacInfo.vue +2 -17
  145. package/widgets/EodashTools.vue +13 -13
  146. package/widgets/WidgetsContainer.vue +1 -1
  147. package/core/client/eodash.js +0 -454
  148. package/dist/client/EodashLayoutSwitcher-DqeFO3RN.js +0 -52
  149. package/dist/client/EodashMapBtns-5BF27qJB.js +0 -131
  150. package/dist/client/ProcessList-C62SOVO6.js +0 -484
  151. package/dist/client/asWebComponent-BJ2NWunV.js +0 -12479
  152. package/dist/client/eo-dash.css +0 -5
  153. package/dist/client/index-Da5xXX6Q.js +0 -780
  154. package/dist/client/transition-Cdb4K27U.js +0 -37
  155. package/dist/types/core/client/eodash.d.ts +0 -8
@@ -1,9 +1,11 @@
1
1
  <template>
2
- <div ref="rootRef" class="d-flex flex-column align-end justify-end my-3 pa-2">
2
+ <div ref="rootRef" class="d-flex flex-column align-end">
3
3
  <v-btn
4
4
  v-if="exportMap"
5
5
  class="map-btn"
6
6
  :icon="[mdiMapPlus]"
7
+ size="small"
8
+ v-tooltip:bottom="'Extract Storytelling configuration'"
7
9
  @click="showMapState = !showMapState"
8
10
  />
9
11
  <ExportState v-if="exportMap" v-model="showMapState" />
@@ -11,82 +13,122 @@
11
13
  <v-btn
12
14
  class="map-btn"
13
15
  :icon="[mdiEarthBox]"
16
+ size="small"
17
+ v-tooltip:bottom="'Change map projection'"
14
18
  v-if="changeProjection && !!availableMapProjection"
15
19
  @click="changeMapProjection(availableMapProjection)"
16
20
  />
17
21
  <v-btn
18
22
  class="map-btn"
19
23
  :icon="[compareIcon]"
24
+ size="small"
25
+ v-tooltip:bottom="'Compare mode'"
20
26
  v-if="compareIndicators"
21
27
  @click="onCompareClick"
22
28
  />
29
+ <v-btn
30
+ class="map-btn"
31
+ :icon="[mdiStarFourPointsCircleOutline]"
32
+ size="small"
33
+ v-tooltip:bottom="'back to POIs'"
34
+ v-if="backToPOIs && (poi || comparePoi)"
35
+ @click="loadPOiIndicator()"
36
+ />
23
37
  <PopUp
24
38
  v-model="showCompareIndicators"
25
39
  :maxWidth="popupWidth"
26
- :maxHeight="popupHeight"
40
+ :width="popupWidth"
41
+ :max-height="popupHeight"
42
+ :height="popupHeight"
27
43
  >
28
44
  <EodashItemFilter
29
45
  :enableCompare="true"
30
- filters-title=""
31
- results-title="Select an indicator to compare"
32
- :filter-properties="[]"
46
+ :enableHighlighting="false"
47
+ resultType="cards"
48
+ style="--select-filter-max-items: 8"
49
+ filters-title="Select an indicator to compare"
50
+ subTitleProperty="subtitle"
51
+ imageProperty="thumbnail"
52
+ aggregateResults="collection_group"
53
+ results-title=""
33
54
  @select="onSelectCompareIndicator"
34
55
  />
35
56
  </PopUp>
36
57
  </div>
37
58
  </template>
38
59
  <script setup>
39
- import { makePanelTransparent } from "@/composables";
60
+ import { useTransparentPanel } from "@/composables";
40
61
  import { changeMapProjection, setActiveTemplate } from "@/store/actions";
41
- import { availableMapProjection } from "@/store/states";
42
- import { mdiCompare, mdiCompareRemove, mdiEarthBox, mdiMapPlus } from "@mdi/js";
62
+ import {
63
+ activeTemplate,
64
+ availableMapProjection,
65
+ comparePoi,
66
+ poi,
67
+ } from "@/store/states";
68
+ import {
69
+ mdiCompare,
70
+ mdiCompareRemove,
71
+ mdiEarthBox,
72
+ mdiMapPlus,
73
+ mdiStarFourPointsCircleOutline,
74
+ } from "@mdi/js";
43
75
  import ExportState from "^/ExportState.vue";
44
76
  import { computed, ref, triggerRef } from "vue";
45
77
  import PopUp from "./PopUp.vue";
46
78
  import EodashItemFilter from "./EodashItemFilter.vue";
47
- import { useDisplay } from "vuetify/lib/framework.mjs";
79
+ import { useDisplay } from "vuetify";
48
80
  import { useSTAcStore } from "@/store/stac";
49
81
  import { storeToRefs } from "pinia";
50
- import { switchToCompare } from "@/utils/states";
82
+ import { loadPOiIndicator } from "./EodashProcess/methods/handling";
51
83
 
52
- const { compareIndicators, changeProjection, exportMap } = defineProps({
53
- exportMap: {
54
- type: Boolean,
55
- default: true,
56
- },
57
- changeProjection: {
58
- type: Boolean,
59
- default: true,
60
- },
61
- compareIndicators: {
62
- /** @type {import("vue").PropType<boolean | {compareTemplate?:string;fallbackTemplate?:string}> }*/
63
- type: [Boolean, Object],
64
- default: true,
65
- },
66
- });
84
+ const { compareIndicators, changeProjection, exportMap, backToPOIs } =
85
+ defineProps({
86
+ exportMap: {
87
+ type: Boolean,
88
+ default: true,
89
+ },
90
+ changeProjection: {
91
+ type: Boolean,
92
+ default: true,
93
+ },
94
+ compareIndicators: {
95
+ /** @type {import("vue").PropType<boolean | {compareTemplate?:string;fallbackTemplate?:string}> }*/
96
+ type: [Boolean, Object],
97
+ default: true,
98
+ },
99
+ backToPOIs: {
100
+ type: Boolean,
101
+ default: true,
102
+ },
103
+ });
67
104
  const { selectedStac, selectedCompareStac } = storeToRefs(useSTAcStore());
105
+ const { resetSelectedCompareSTAC } = useSTAcStore();
68
106
  const { smAndDown } = useDisplay();
69
- const popupWidth = computed(() => (smAndDown ? "70%" : "500px"));
70
- const popupHeight = computed(() => (smAndDown ? "90%" : "500px"));
107
+ const popupWidth = computed(() => (smAndDown.value ? "80%" : "70%"));
108
+ const popupHeight = computed(() => (smAndDown.value ? "90%" : "70%"));
71
109
 
72
110
  const showMapState = ref(false);
73
111
  const showCompareIndicators = ref(false);
74
112
  const compareIcon = computed(() =>
75
- switchToCompare.value ? mdiCompare : mdiCompareRemove,
113
+ activeTemplate.value ===
114
+ ((typeof compareIndicators === "object" &&
115
+ compareIndicators?.compareTemplate) ||
116
+ "compare")
117
+ ? mdiCompareRemove
118
+ : mdiCompare,
76
119
  );
120
+
77
121
  const onCompareClick = () => {
78
- if (switchToCompare.value) {
79
- showCompareIndicators.value = !showCompareIndicators.value;
80
- } else {
81
- switchToCompare.value = true;
82
- const fallbackTemplate =
83
- (typeof compareIndicators === "object" &&
84
- compareIndicators.fallbackTemplate) ||
85
- "expert";
86
- selectedCompareStac.value = null;
87
- setActiveTemplate(fallbackTemplate);
88
- triggerRef(selectedStac);
89
- }
122
+ showCompareIndicators.value = !showCompareIndicators.value;
123
+
124
+ const fallbackTemplate =
125
+ (typeof compareIndicators === "object" &&
126
+ compareIndicators.fallbackTemplate) ||
127
+ "expert";
128
+ selectedCompareStac.value = null;
129
+ resetSelectedCompareSTAC();
130
+ setActiveTemplate(fallbackTemplate);
131
+ triggerRef(selectedStac);
90
132
  };
91
133
 
92
134
  /** @type {import("vue").Ref<HTMLDivElement|null>} */
@@ -101,7 +143,7 @@ const onSelectCompareIndicator = () => {
101
143
  showCompareIndicators.value = !showCompareIndicators.value;
102
144
  };
103
145
 
104
- makePanelTransparent(rootRef);
146
+ useTransparentPanel(rootRef);
105
147
  </script>
106
148
  <style scoped>
107
149
  .map-btn {
@@ -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,7 +15,7 @@
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
20
  {{ new Date(item.job_start_datetime).toISOString().slice(0, 16) }}
21
21
  </td>
@@ -24,7 +24,7 @@
24
24
  <v-btn
25
25
  :disabled="item.status !== 'successful'"
26
26
  color="primary"
27
- @click="loadProcess(item, selectedStac)"
27
+ @click="loadProcess(item, currentStac, mapElement)"
28
28
  :icon="[mdiUploadBox]"
29
29
  variant="text"
30
30
  v-tooltip="'Load results to map'"
@@ -35,7 +35,7 @@
35
35
  <v-btn
36
36
  :disabled="item.status !== 'successful'"
37
37
  color="primary"
38
- @click="downloadPreviousResults(item, selectedStac)"
38
+ @click="downloadPreviousResults(item, currentStac)"
39
39
  :icon="[mdiDownloadBox]"
40
40
  variant="text"
41
41
  v-tooltip="'Download results'"
@@ -45,7 +45,13 @@
45
45
  <td style="padding: 0px">
46
46
  <v-btn
47
47
  color="#ff5252"
48
- @click="deleteJob(item)"
48
+ @click="
49
+ deleteJob(
50
+ toRef(() => currentJobs),
51
+ item,
52
+ currentIndicator,
53
+ )
54
+ "
49
55
  :icon="[mdiTrashCanOutline]"
50
56
  variant="text"
51
57
  v-tooltip="'Remove job'"
@@ -59,20 +65,38 @@
59
65
  </template>
60
66
  <script setup>
61
67
  import { mdiUploadBox, mdiDownloadBox, mdiTrashCanOutline } from "@mdi/js";
62
- import { onMounted, toRefs } from "vue";
68
+ import { onMounted, toRef, toRefs } from "vue";
63
69
  import { useSTAcStore } from "@/store/stac";
64
- import { indicator } from "@/store/states";
70
+ import { compareIndicator, indicator } from "@/store/states";
65
71
  import {
66
72
  deleteJob,
67
73
  downloadPreviousResults,
68
- jobs,
69
74
  loadProcess,
70
75
  updateJobsStatus,
71
76
  } from "./methods/async";
77
+ import { useOnLayersUpdate } from "@/composables";
78
+ import { compareJobs, jobs } from "./states";
79
+ const { enableCompare, mapElement } = defineProps({
80
+ enableCompare: {
81
+ type: Boolean,
82
+ default: false,
83
+ },
84
+ mapElement: {
85
+ /** @type {import("vue").PropType<import("@eox/map").EOxMap | null>} */
86
+ type: Object,
87
+ default: () => null,
88
+ },
89
+ });
90
+ const { selectedStac, selectedCompareStac } = toRefs(useSTAcStore());
91
+ const currentJobs = enableCompare ? compareJobs : jobs;
92
+ const currentIndicator = enableCompare ? compareIndicator : indicator;
93
+ const currentStac = enableCompare ? selectedCompareStac : selectedStac;
72
94
 
73
- const { selectedStac } = toRefs(useSTAcStore());
95
+ onMounted(() => {
96
+ updateJobsStatus(currentJobs, currentIndicator.value);
97
+ });
74
98
 
75
- onMounted(() => updateJobsStatus(jobs, indicator));
99
+ useOnLayersUpdate(() => updateJobsStatus(currentJobs, currentIndicator.value));
76
100
  </script>
77
101
  <style lang="scss">
78
102
  div.v-table__wrapper {
@@ -1,9 +1,10 @@
1
1
  <template>
2
- <div ref="container" class="process-container">
3
- <ProcessList />
2
+ <div ref="container" class="pb-4">
3
+ <ProcessList :map-element="mapElement" :enable-compare="enableCompare" />
4
4
 
5
5
  <eox-jsonform
6
6
  v-if="jsonformSchema"
7
+ :key="jsonformKey"
7
8
  ref="jsonformEl"
8
9
  .schema="jsonformSchema"
9
10
  ></eox-jsonform>
@@ -14,12 +15,14 @@
14
15
  .dataValues="toRaw(chartData)"
15
16
  @click:item="onChartClick"
16
17
  :style="chartStyles"
18
+ .opt="vegaEmbedOptions"
17
19
  />
18
- <div style="text-align: right">
20
+ <div class="mt-4 text-right">
19
21
  <v-btn
20
- v-if="!autoExec"
22
+ v-if="showExecBtn"
21
23
  :loading="loading"
22
24
  style="margin-right: 20px"
25
+ :append-icon="[mdiCogPlayOutline]"
23
26
  @click="startProcess"
24
27
  color="primary"
25
28
  >
@@ -28,6 +31,7 @@
28
31
  <v-btn
29
32
  v-if="processResults.length && isProcessed && !isAsync"
30
33
  color="primary"
34
+ :append-icon="[mdiDownloadCircleOutline]"
31
35
  @click="downloadResults"
32
36
  >
33
37
  Download
@@ -45,10 +49,29 @@ import { computed, ref, toRaw, useTemplateRef } from "vue";
45
49
  import ProcessList from "./ProcessList.vue";
46
50
  import { handleProcesses, onChartClick } from "./methods/handling";
47
51
  import { useInitProcess, useAutoExec } from "./methods/composables";
48
- import { jobs, updateJobsStatus } from "./methods/async";
49
- import { indicator } from "@/store/states";
52
+ import { updateJobsStatus } from "./methods/async";
53
+ import {
54
+ compareIndicator,
55
+ indicator,
56
+ mapCompareEl,
57
+ mapEl,
58
+ } from "@/store/states";
50
59
  import { download } from "./methods/utils";
51
-
60
+ import { compareJobs, jobs } from "./states";
61
+ import { mdiCogPlayOutline, mdiDownloadCircleOutline } from "@mdi/js";
62
+
63
+ const { enableCompare, vegaEmbedOptions } = defineProps({
64
+ enableCompare: {
65
+ type: Boolean,
66
+ default: false,
67
+ },
68
+ vegaEmbedOptions: {
69
+ type: Object,
70
+ default() {
71
+ return { actions: true };
72
+ },
73
+ },
74
+ });
52
75
  /** @type {import("vue").Ref<import("vega").Spec|null>} */
53
76
  const chartSpec = ref(null);
54
77
 
@@ -78,11 +101,25 @@ const isPolling = ref(false);
78
101
  /** @type {import("vue").Ref<any[]>} */
79
102
  const processResults = ref([]);
80
103
 
81
- const { selectedStac } = storeToRefs(useSTAcStore());
104
+ const showExecBtn = computed(
105
+ () =>
106
+ !autoExec.value &&
107
+ (!!jsonformSchema.value || !!chartSpec.value) &&
108
+ !!jsonformEl.value,
109
+ );
110
+ const { selectedStac, selectedCompareStac } = storeToRefs(useSTAcStore());
111
+ const currentSelectedStac = enableCompare ? selectedCompareStac : selectedStac;
112
+ const mapElement = enableCompare ? mapCompareEl : mapEl;
113
+ const currentIndicator = enableCompare ? compareIndicator : indicator;
114
+ const currentJobs = enableCompare ? compareJobs : jobs;
115
+
116
+ const jsonformKey = computed(
117
+ () => currentIndicator.value + mapElement.value?.id,
118
+ );
82
119
 
83
120
  useInitProcess({
84
- //@ts-expect-error TODO
85
- selectedStac,
121
+ selectedStac: currentSelectedStac,
122
+ mapElement: mapElement.value,
86
123
  jsonformEl,
87
124
  jsonformSchema,
88
125
  chartSpec,
@@ -104,7 +141,7 @@ const downloadResults = () => {
104
141
  : result;
105
142
  fileName = fileName.includes("?") ? fileName.split("?")[0] : fileName;
106
143
  } else {
107
- fileName = selectedStac.value?.id + "_process_results.json";
144
+ fileName = currentSelectedStac.value?.id + "_process_results.json";
108
145
  }
109
146
  download(fileName, result);
110
147
  });
@@ -141,25 +178,25 @@ const startProcess = async () => {
141
178
  processResults.value = [];
142
179
 
143
180
  await handleProcesses({
181
+ jobs: currentJobs,
182
+ selectedStac: currentSelectedStac,
144
183
  jsonformEl,
145
184
  jsonformSchema,
146
185
  chartSpec,
147
186
  chartData,
148
187
  loading,
149
- //@ts-expect-error TODO
150
- selectedStac,
151
- isProcessed,
152
188
  isPolling,
153
189
  processResults,
190
+ mapElement: mapElement.value,
154
191
  });
155
192
 
156
193
  isProcessed.value = true;
157
- if (isAsync.value) updateJobsStatus(jobs, indicator);
194
+ if (isAsync.value) updateJobsStatus(currentJobs, currentIndicator.value);
158
195
  };
159
196
  useAutoExec(autoExec, jsonformEl, jsonformSchema, startProcess);
160
197
 
161
198
  const chartStyles = computed(() => {
162
- /** @type {Record<string,string> }*/
199
+ /** @type {Record<string,string>} */
163
200
  const styles = {};
164
201
  if (!chartSpec.value?.["height"]) {
165
202
  styles["height"] =
@@ -173,14 +210,12 @@ const chartStyles = computed(() => {
173
210
  });
174
211
  </script>
175
212
  <style>
176
- .process-container {
177
- height: 100%;
178
- overflow-y: auto;
179
- }
180
213
  eox-chart {
181
214
  --background-color: transparent;
215
+ padding-top: 1em;
182
216
  }
183
217
  eox-jsonform {
184
218
  padding: 0.7em;
219
+ min-height: 0px;
185
220
  }
186
221
  </style>
@@ -1,39 +1,45 @@
1
- import { indicator, mapEl } from "@/store/states";
1
+ import { compareIndicator, indicator } from "@/store/states";
2
+ // we don't want to use the caching axios instance here
2
3
  import axios from "axios";
3
- import { ref } from "vue";
4
- import { createLayerDefinition, download } from "./utils";
4
+ import {
5
+ applyProcessLayersToMap,
6
+ creatAsyncProcessLayerDefinitions,
7
+ download,
8
+ extractAsyncResults,
9
+ } from "./utils";
5
10
  import log from "loglevel";
6
- import { getLayers } from "@/store/actions";
7
-
8
- /**
9
- * The list of job result from the server
10
- * {job_start_datetime: string, job_end_datetime: string,status: string}
11
- * @type {import("vue").Ref<any[]>}
12
- **/
13
- export const jobs = ref([]);
14
11
 
15
12
  /**
16
13
  * Polls the process status and fetches a result item when the process is successful.
17
14
  *
18
15
  * @param {Object} params - Parameters for polling the process status.
16
+ * @param {import("vue").Ref<import("../types").AsyncJob[]>} params.jobs - The list of jobs to update.
19
17
  * @param {string} params.processUrl - The URL of the process JSON report.
20
18
  * @param {import("vue").Ref<boolean>} params.isPolling - checks wether the polling should continue
21
19
  * @param {number} [params.pollInterval=5000] - The interval (in milliseconds) between polling attempts.
22
20
  * @param {number} [params.maxRetries=60] - The maximum number of polling attempts.
23
- * @returns {Promise<JSON>} The fetched results JSON.
21
+ * @param {boolean} [params.enableCompare=false] - Whether to enable comparison mode, affecting the indicator used.
22
+ * @returns {Promise<import("../types").EOxHubProcessResults>} The fetched results JSON.
24
23
  * @throws {Error} If the process does not complete successfully within the maximum retries.
25
24
  */
26
25
  export async function pollProcessStatus({
26
+ jobs,
27
27
  processUrl,
28
28
  isPolling,
29
29
  pollInterval = 10000,
30
30
  maxRetries = 560,
31
+ enableCompare = false,
31
32
  }) {
32
33
  let retries = 0;
33
34
  isPolling.value = true;
35
+ // Ensure the jobs status is updated after the job has started and before polling
34
36
  setTimeout(() => {
35
- updateJobsStatus(jobs, indicator);
37
+ updateJobsStatus(
38
+ jobs,
39
+ enableCompare ? compareIndicator.value : indicator.value,
40
+ );
36
41
  }, 500);
42
+
37
43
  while (retries < maxRetries && isPolling.value) {
38
44
  try {
39
45
  // Fetch the process JSON report
@@ -89,14 +95,19 @@ export async function pollProcessStatus({
89
95
 
90
96
  /**
91
97
  *
92
- * @param {*} jobs
93
- * @param {*} indicator
98
+ * @param {import("vue").Ref<import("../types").AsyncJob[]>} jobs
99
+ * @param {string} indicator
94
100
  */
95
101
  export async function updateJobsStatus(jobs, indicator) {
96
102
  /** @type {string[]} */
97
- const jobsUrls = JSON.parse(localStorage.getItem(indicator.value) || "[]");
103
+ const jobsUrls = JSON.parse(localStorage.getItem(indicator) || "[]");
104
+ /** @type {import("../types").AsyncJob[]} */
98
105
  const jobResults = await Promise.all(
99
- jobsUrls.map((url) => fetch(url).then((response) => response.json())),
106
+ jobsUrls.map((url) =>
107
+ axios
108
+ .get(url, { params: { t: Date.now() } })
109
+ .then((response) => response.data),
110
+ ),
100
111
  );
101
112
  jobResults.sort((a, b) => {
102
113
  return (
@@ -109,26 +120,35 @@ export async function updateJobsStatus(jobs, indicator) {
109
120
 
110
121
  /**
111
122
  * Removes a job from the local storage and updates the job status
112
- * @param {*} jobObject
123
+ * @param {import("vue").Ref<import("../types").AsyncJob[]>} jobs
124
+ * @param {import("../types").AsyncJob} jobObject
125
+ * @param {string} indicator
113
126
  */
114
- export const deleteJob = async (jobObject) => {
127
+ export const deleteJob = async (jobs, jobObject, indicator) => {
115
128
  /** @type {string[]} */
116
- const jobsUrls = JSON.parse(localStorage.getItem(indicator.value) || "[]");
129
+ const jobsUrls = JSON.parse(localStorage.getItem(indicator) || "[]");
117
130
  const newJobs = jobsUrls.filter((url) => !url.includes(jobObject.jobID));
118
- localStorage.setItem(indicator.value, JSON.stringify(newJobs));
119
- updateJobsStatus(jobs, indicator);
131
+ localStorage.setItem(indicator, JSON.stringify(newJobs));
132
+ await updateJobsStatus(jobs, indicator);
120
133
  };
121
134
 
122
135
  /**
123
136
  * Downloads an existing process results
124
- * @param {*} jobObject
125
- * @param {*} selectedStac
137
+ * @param {import("../types").AsyncJob} jobObject
138
+ * @param {import("stac-ts").StacCollection | null} selectedStac
126
139
  */
127
140
  export const downloadPreviousResults = async (jobObject, selectedStac) => {
128
- /** @type {any[]} */
141
+ /** @type {string[]} */
129
142
  const results = [];
130
- await fetch(jobObject.links[1].href)
131
- .then((response) => response.json())
143
+ const link = jobObject.links.find(
144
+ (link) => link.rel.includes("results") && link.type == "application/json",
145
+ );
146
+ if (!link) {
147
+ return;
148
+ }
149
+ await axios
150
+ .get(link.href)
151
+ .then((response) => response.data)
132
152
  .then((data) => {
133
153
  results.push(...data.urls);
134
154
  });
@@ -153,20 +173,21 @@ export const downloadPreviousResults = async (jobObject, selectedStac) => {
153
173
  * Load the process results and update the map layers.
154
174
  *
155
175
  * @async
156
- * @param {*} jobObject
157
- * @param {*} selectedStac
176
+ * @param {import("../types").AsyncJob} jobObject
177
+ * @param {import("stac-ts").StacCollection | null} selectedStac
178
+ * @param {import("@eox/map").EOxMap | null} mapElement
158
179
  */
159
- export const loadProcess = async (jobObject, selectedStac) => {
160
- /** @type {any[]} */
161
- const results = [];
162
- await axios
180
+ export const loadProcess = async (jobObject, selectedStac, mapElement) => {
181
+ /** @type {import("../types").EOxHubProcessResults} */
182
+ const results = await axios
163
183
  .get(jobObject.links[1].href)
164
- .then((response) => results.push(response.data));
184
+ .then((response) => response.data);
165
185
 
166
186
  await loadPreviousProcess({
167
187
  selectedStac,
168
188
  results,
169
189
  jobId: jobObject.jobID,
190
+ mapElement,
170
191
  });
171
192
  };
172
193
 
@@ -175,35 +196,32 @@ export const loadProcess = async (jobObject, selectedStac) => {
175
196
  *
176
197
  * @param {Object} params
177
198
  * @param {import("stac-ts").StacCollection | null} params.selectedStac
178
- * @param {any[]} params.results
179
199
  * @param {string} params.jobId
200
+ * @param {import("../types").EOxHubProcessResults} params.results
201
+ * @param {import("@eox/map").EOxMap | null} params.mapElement
180
202
  */
181
- export async function loadPreviousProcess({ selectedStac, results, jobId }) {
182
- const geotiffLinks = selectedStac?.links.filter(
183
- (link) => link.rel === "service" && link.type === "image/tiff",
184
- );
185
- // const stacProjection = selectedStac
186
- const geotiffLayer = await createLayerDefinition(
187
- geotiffLinks?.[0],
188
- selectedStac?.id ?? "",
189
- results?.[0].urls,
190
- //@ts-expect-error TODO
191
- selectedStac?.["eodash:mapProjection"]?.["name"] ?? null,
192
- jobId,
203
+ export async function loadPreviousProcess({
204
+ selectedStac,
205
+ results,
206
+ jobId,
207
+ mapElement,
208
+ }) {
209
+ const asyncLink = selectedStac?.links.find(
210
+ (link) => link.rel === "service" && link.endpoint == "eoxhub_workspaces",
193
211
  );
212
+ if (!asyncLink) {
213
+ return;
214
+ }
194
215
 
195
- log.debug("rendered layers after loading previous process:", geotiffLayer);
216
+ const unifiedResult = extractAsyncResults(results);
196
217
 
197
- if (geotiffLayer) {
198
- const layers = [...(geotiffLayer ? [geotiffLayer] : [])];
199
- let currentLayers = [...getLayers()];
200
- let analysisGroup = currentLayers.find((l) =>
201
- l.properties.id.includes("AnalysisGroup"),
202
- );
203
- analysisGroup?.layers.push(...layers);
218
+ const layers = await creatAsyncProcessLayerDefinitions(
219
+ unifiedResult,
220
+ asyncLink,
221
+ selectedStac,
222
+ jobId,
223
+ );
204
224
 
205
- if (mapEl.value) {
206
- mapEl.value.layers = [...currentLayers];
207
- }
208
- }
225
+ log.debug("rendered layers after loading previous process:", layers);
226
+ applyProcessLayersToMap(mapElement, layers);
209
227
  }