@eodash/eodash 5.0.0-alpha.2.1 → 5.0.0-alpha.2.4

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 (94) hide show
  1. package/README.md +10 -1
  2. package/core/client/App.vue +27 -0
  3. package/core/client/SuspensedDashboard.ce.vue +91 -0
  4. package/core/client/components/DashboardLayout.vue +36 -0
  5. package/core/client/components/ErrorAlert.vue +19 -0
  6. package/core/{components → client/components}/Loading.vue +12 -1
  7. package/core/{components → client/components}/MobileLayout.vue +19 -11
  8. package/core/{composables → client/composables}/DefineWidgets.js +11 -5
  9. package/core/{composables → client/composables}/index.js +16 -13
  10. package/core/{eodash.js → client/eodash.js} +0 -2
  11. package/core/{plugins → client/plugins}/vuetify.js +9 -3
  12. package/core/{store → client/store}/stac.js +6 -2
  13. package/core/{types.d.ts → client/types.d.ts} +11 -25
  14. package/core/{views → client/views}/Dashboard.vue +35 -6
  15. package/dist/client/DashboardLayout-ZaSRMD1M.js +149 -0
  16. package/dist/{DynamicWebComponent-BrHVTesn.js → client/DynamicWebComponent-C4Hotc4H.js} +12 -12
  17. package/dist/client/EodashDatePicker-C4kKjxKy.js +1653 -0
  18. package/dist/{EodashItemFilter-BLAGx2UD.js → client/EodashItemFilter-cBHC0YEM.js} +2 -2
  19. package/dist/{EodashMap-Bxl_aqY2.js → client/EodashMap-CGrQjZ1P.js} +2490 -2496
  20. package/dist/client/Footer-pS636dEP.js +118 -0
  21. package/dist/{Header-DC50S6GR.js → client/Header-DQuaLdjl.js} +225 -229
  22. package/dist/{IframeWrapper-Dd9zrX9s.js → client/IframeWrapper-Cg3GMmfW.js} +1 -1
  23. package/dist/client/MobileLayout-BLXFBWI_.js +987 -0
  24. package/dist/client/VMain-BHYlmRic.js +39 -0
  25. package/dist/{WidgetsContainer-DxfCu0I3.js → client/WidgetsContainer-dje9QSk0.js} +18 -18
  26. package/dist/client/asWebComponent-Bvb3xkxI.js +13311 -0
  27. package/dist/{decoder-kAoyGIq9-BBR5CgzS.js → client/decoder-HRvnjnEI-BQ2rajuJ.js} +1 -1
  28. package/dist/client/eo-dash.js +6 -0
  29. package/dist/{eox-map-BJ9SIixs.js → client/eox-map-C3DL31fp.js} +1882 -1809
  30. package/dist/client/eox-stacinfo-l7ALSV90.js +13969 -0
  31. package/dist/{index-DTkOfh2g.js → client/index-CaDDfJYE.js} +75 -43
  32. package/dist/client/index-DlNICb3T.js +34 -0
  33. package/dist/{lerc-C9VL9kri-cIdbW0sg.js → client/lerc-_E46UbWQ-Beu35ovS.js} +1 -1
  34. package/dist/{ssrBoot-D-b4-M19.js → client/ssrBoot-Dd7m-btU.js} +3 -3
  35. package/dist/client/style.css +5 -0
  36. package/dist/node/cli.js +20 -0
  37. package/dist/node/main.js +2 -0
  38. package/{bin → dist/node}/types.d.ts +3 -2
  39. package/package.json +22 -20
  40. package/widgets/EodashDatePicker.vue +1 -0
  41. package/widgets/EodashItemFilter.vue +1 -1
  42. package/widgets/WidgetsContainer.vue +7 -5
  43. package/bin/app.js +0 -22
  44. package/bin/cli.js +0 -62
  45. package/bin/main.js +0 -9
  46. package/bin/serverConfig.js +0 -165
  47. package/bin/utils.js +0 -103
  48. package/core/App.vue +0 -19
  49. package/core/SuspensedDashboard.ce.vue +0 -65
  50. package/core/components/DashboardLayout.vue +0 -44
  51. package/dist/DashboardLayout-Dp8AnYD9.js +0 -141
  52. package/dist/EodashDatePicker-D_udZ26j.js +0 -1645
  53. package/dist/Footer-AohCH8U7.js +0 -118
  54. package/dist/MobileLayout-CgToA7Gp.js +0 -523
  55. package/dist/VBtn-Bz7ruRUg.js +0 -1106
  56. package/dist/VMain-BHfWJU2j.js +0 -35
  57. package/dist/asWebComponent-C8rb3b1D.js +0 -11323
  58. package/dist/color-DpYEub1f.js +0 -115
  59. package/dist/dimensions-CJaGeSrj.js +0 -53
  60. package/dist/eo-dash.js +0 -6
  61. package/dist/eox-stacinfo-B-YrT7Ug.js +0 -13698
  62. package/dist/index-Sa2Vg_gx.js +0 -65
  63. package/dist/style.css +0 -5
  64. /package/core/{asWebComponent.d.ts → client/asWebComponent.d.ts} +0 -0
  65. /package/core/{asWebComponent.js → client/asWebComponent.js} +0 -0
  66. /package/core/{components → client/components}/DynamicWebComponent.vue +0 -0
  67. /package/core/{components → client/components}/Footer.vue +0 -0
  68. /package/core/{components → client/components}/Header.vue +0 -0
  69. /package/core/{components → client/components}/IframeWrapper.vue +0 -0
  70. /package/core/{composables → client/composables}/DefineEodash.js +0 -0
  71. /package/core/{main.js → client/main.js} +0 -0
  72. /package/core/{plugins → client/plugins}/index.js +0 -0
  73. /package/core/{render.js → client/render.js} +0 -0
  74. /package/core/{store → client/store}/Actions.js +0 -0
  75. /package/core/{store → client/store}/States.js +0 -0
  76. /package/core/{store → client/store}/index.js +0 -0
  77. /package/core/{utils → client/utils}/eodashSTAC.js +0 -0
  78. /package/core/{utils → client/utils}/helpers.js +0 -0
  79. /package/core/{utils → client/utils}/index.js +0 -0
  80. /package/core/{utils → client/utils}/keys.js +0 -0
  81. /package/core/{vite-env.d.ts → client/vite-env.d.ts} +0 -0
  82. /package/dist/{.gitkeep → client/.gitkeep} +0 -0
  83. /package/dist/{_commonjsHelpers-DaMA6jEr.js → client/_commonjsHelpers-DaMA6jEr.js} +0 -0
  84. /package/dist/{basedecoder-Qm25PwVp-CHo5Pomv.js → client/basedecoder-Qm25PwVp-CHo5Pomv.js} +0 -0
  85. /package/dist/{deflate-Be2Arps5-hDqMz3RA.js → client/deflate-Be2Arps5-hDqMz3RA.js} +0 -0
  86. /package/dist/{eox-itemfilter-DcQkRD2l.js → client/eox-itemfilter-DcQkRD2l.js} +0 -0
  87. /package/dist/{forwardRefs-Bxeu9Obx.js → client/forwardRefs-Bxeu9Obx.js} +0 -0
  88. /package/dist/{jpeg-DNfUpLwy-Fjan-04T.js → client/jpeg-DNfUpLwy-Fjan-04T.js} +0 -0
  89. /package/dist/{lzw-BOMhmEDy-Dboc93VO.js → client/lzw-BOMhmEDy-Dboc93VO.js} +0 -0
  90. /package/dist/{packbits-DaUD6MLm-Bu1PoTGa.js → client/packbits-DaUD6MLm-Bu1PoTGa.js} +0 -0
  91. /package/dist/{pako.esm-C3kYPGGQ-BMki8cQY.js → client/pako.esm-C3kYPGGQ-BMki8cQY.js} +0 -0
  92. /package/dist/{raw-CcGKjn8q-DFOt-i8n.js → client/raw-CcGKjn8q-DFOt-i8n.js} +0 -0
  93. /package/dist/{webfontloader-CyOFAuFB.js → client/webfontloader-CyOFAuFB.js} +0 -0
  94. /package/dist/{webimage-D2c098k3-DLj1LQxB.js → client/webimage-D2c098k3-DLj1LQxB.js} +0 -0
package/README.md CHANGED
@@ -18,9 +18,18 @@ npm run preview
18
18
 
19
19
  ## Folder Structure
20
20
  .
21
- ├── core # Main source code that hosts the microfrontends and renders the dashboard
21
+ ├── core # CLI & Client source code
22
22
  ├── docs # Documentation files
23
+ ├── tests # CLI & Client component tests folder
23
24
  ├── widgets # Vue componenets as internal widgets.
24
25
  ├── public # Statically served directory
25
26
  └── README.md
26
27
 
28
+
29
+ ## Writing commits
30
+ To ensure clear communication with the package consumers and enable machine-readable commits, we adhere to [The Conventional Commits](https://www.conventionalcommits.org/) specification that allows the generation of [semVer](https://semver.org) releases and associated change logs using [googleapis/release-please](https://github.com/googleapis/release-please).
31
+
32
+ The most important prefixes you should have in mind are:
33
+ * fix: which represents bug fixes, and correlates to a SemVer patch.
34
+ * feat: which represents a new feature, and correlates to a SemVer minor.
35
+ * feat!:, or fix!:, refactor!:, etc., which represent a breaking change (indicated by the !) and will result in a SemVer major.
@@ -0,0 +1,27 @@
1
+ <template>
2
+ <v-app>
3
+ <Suspense>
4
+
5
+ <Dashboard />
6
+
7
+ <template #fallback>
8
+ <ErrorAlert v-model="error" />
9
+ </template>
10
+ </Suspense>
11
+ </v-app>
12
+ </template>
13
+
14
+ <script setup>
15
+ import Dashboard from '@/views/Dashboard.vue';
16
+ import ErrorAlert from './components/ErrorAlert.vue';
17
+ import { onErrorCaptured, ref } from 'vue';
18
+
19
+ const error = ref('')
20
+ onErrorCaptured((e, inst, info) => {
21
+ error.value = `
22
+ ${e}.
23
+ component: ${inst?.$.type.name}.
24
+ info: ${info}.
25
+ `
26
+ })
27
+ </script>
@@ -0,0 +1,91 @@
1
+ <template>
2
+ <v-app ref="vAppRef">
3
+ <Suspense>
4
+ <Dashboard :on-template-mount="setStylesFromHead" :config="config" />
5
+
6
+ <template #fallback>
7
+ <ErrorAlert @vue:mounted="setStylesFromHead()" v-model="error" />
8
+ </template>
9
+ </Suspense>
10
+ </v-app>
11
+ </template>
12
+ <script setup>
13
+ import Dashboard from '@/views/Dashboard.vue';
14
+ import { createApp, getCurrentInstance, onErrorCaptured, ref } from "vue"
15
+ import { registerPlugins } from '@/plugins';
16
+ import { eodashKey } from '@/utils/keys';
17
+ import ErrorAlert from '@/components/ErrorAlert.vue';
18
+
19
+ defineProps({
20
+ config: {
21
+ type: String,
22
+ }
23
+ });
24
+
25
+ /** @type { import("vue").Ref<import("vuetify/components").VApp| null > } */
26
+ const vAppRef = ref(null)
27
+ const app = createApp({})
28
+ registerPlugins(app)
29
+
30
+ const inst = getCurrentInstance()
31
+ //@ts-expect-error
32
+ Object.assign(inst.appContext, app._context)
33
+ //@ts-expect-error
34
+ Object.assign(inst.provides, app._context.provides)
35
+
36
+ /** @param {import("vue").Ref<HTMLElement | import("vue").ComponentPublicInstance>[]} [hiddenElements] */
37
+ function setStylesFromHead(hiddenElements) {
38
+ const eodashShadowRoot = vAppRef.value?.$el.getRootNode()
39
+ const styleSheet = new CSSStyleSheet()
40
+ const head = document.querySelector('head')
41
+ let stylesStr = ''
42
+
43
+ Array.from(head?.children ?? []).forEach((child) => {
44
+ if (child.getAttribute('type') === 'text/css') {
45
+ stylesStr += `\n ${child.innerHTML}`
46
+ return
47
+ }
48
+
49
+ if (child.tagName == 'LINK' && child.getAttribute('rel')?.includes('stylesheet')) {
50
+ eodashShadowRoot?.appendChild(child.cloneNode(true))
51
+ }
52
+ });
53
+
54
+ stylesStr += `\n * {
55
+ font-family:${
56
+ //@ts-expect-error
57
+ /** @type {import("@/types").Eodash} */ (inst.provides[eodashKey])?.brand.font?.family ?? 'Roboto'}
58
+ }
59
+ ${//@ts-expect-error
60
+ /** @type {import("@/types").Eodash} */ (inst.provides[eodashKey]).brand.noLayout ?
61
+ `div.v-application__wrap {
62
+ min-height: fit-content;
63
+ }`: ""}
64
+ `
65
+ styleSheet.replaceSync(stylesStr.replaceAll(":root", ":host"))
66
+ eodashShadowRoot?.adoptedStyleSheets.push(styleSheet);
67
+
68
+ //@ts-expect-error
69
+ if (hiddenElements && !(/** @type {import("@/types").Eodash} */ (inst.provides[eodashKey])?.brand.noLayout)) {
70
+ hiddenElements.forEach(element => {
71
+ if (element.value) {
72
+ if (element.value instanceof HTMLElement) {
73
+ element.value.style.opacity = "1"
74
+ } else {
75
+ /** @type {HTMLElement} */
76
+ (element.value.$el).style.opacity = "1"
77
+ }
78
+ }
79
+ })
80
+ }
81
+ }
82
+
83
+ const error = ref('')
84
+ onErrorCaptured((e, comp, info) => {
85
+ error.value = `
86
+ ${e}.
87
+ component: ${comp?.$.type.name}.
88
+ info: ${info}.
89
+ `
90
+ })
91
+ </script>
@@ -0,0 +1,36 @@
1
+ <template>
2
+ <v-main>
3
+ <eox-layout :gap="eodash.template.gap ?? 2">
4
+ <eox-layout-item v-if="bgWidget.component" style="z-index: 0;" x="0" y="0" h="12" w="12">
5
+ <Suspense suspensible>
6
+ <component id="bg-widget" :is="bgWidget.component" v-bind="bgWidget.props" />
7
+ </Suspense>
8
+ </eox-layout-item>
9
+ <template v-for="(config, idx) in widgetsConfig" :key="idx">
10
+ <eox-layout-item v-if="importedWidgets[idx].value.component"
11
+ style="position: relative; overflow: visible; z-index: 1; border-radius: 0px; background: rgb(var(--v-theme-surface))"
12
+ :x="config.layout.x" :y="config.layout.y" :h="config.layout.h" :w="config.layout.w">
13
+
14
+ <Suspense suspensible>
15
+ <component :key="importedWidgets[idx].value.id" :is="importedWidgets[idx].value.component"
16
+ v-bind="importedWidgets[idx].value.props" />
17
+ </Suspense>
18
+ </eox-layout-item>
19
+ </template>
20
+ </eox-layout>
21
+ </v-main>
22
+ </template>
23
+ <script setup>
24
+ import { eodashKey } from '@/utils/keys';
25
+ import { inject } from 'vue';
26
+ import { useDefineWidgets } from '@/composables/DefineWidgets'
27
+ import '@eox/layout'
28
+
29
+ const eodash = /** @type {import("@/types").Eodash} */ (inject(eodashKey))
30
+
31
+ const [bgWidget] = useDefineWidgets([eodash.template?.background])
32
+
33
+ const widgetsConfig = eodash.template?.widgets
34
+
35
+ const importedWidgets = useDefineWidgets(widgetsConfig)
36
+ </script>
@@ -0,0 +1,19 @@
1
+ <template>
2
+ <v-alert v-if="error" translate="yes" location="start bottom" type="error" position="fixed" @click:close="error = ''"
3
+ variant="elevated" :icon="[mdiAlertCircle]" style="z-index: 10000;" closable :close-icon="[mdiClose]">
4
+ {{ errorMessage }}
5
+ <details is="animated-details">
6
+ <summary> Error </summary>
7
+ {{ error }}
8
+ </details>
9
+ </v-alert>
10
+ </template>
11
+ <script setup>
12
+ import { eodashKey } from "@/utils/keys";
13
+ import { mdiClose, mdiAlertCircle } from "@mdi/js"
14
+ import { inject } from "vue";
15
+
16
+ const error = defineModel({ type: String, required: true })
17
+ const eodash = /** @type {import("@/types").Eodash} */(inject(eodashKey))
18
+ const errorMessage = eodash.brand.errorMessage ?? 'something went wrong, please try again later'
19
+ </script>
@@ -1,6 +1,7 @@
1
1
  <template>
2
2
  <v-row class="d-flex justify-center align-center ">
3
3
  <v-col class="flex-column justify-center align-center">
4
+ <ErrorAlert v-model="error" />
4
5
  <Suspense>
5
6
  <component v-if="loading.component" :is="loading.component" v-bind="loading.props"></component>
6
7
  <div v-else class="text-center">
@@ -16,12 +17,22 @@
16
17
  </v-row>
17
18
  </template>
18
19
  <script setup>
19
- import { inject } from 'vue';
20
+ import { inject, onErrorCaptured, ref } from 'vue';
20
21
  import { eodashKey } from '@/utils/keys';
21
22
  import { useDefineWidgets } from '@/composables/DefineWidgets';
23
+ import ErrorAlert from './ErrorAlert.vue';
22
24
 
23
25
  const eodash = /** @type {import("@/types").Eodash} */ (inject(eodashKey))
24
26
 
25
27
  const [loading] = useDefineWidgets([eodash.template.loading])
26
28
 
29
+ const error = ref('')
30
+ onErrorCaptured((e, inst, info) => {
31
+ error.value = `
32
+ ${e}.
33
+ component: ${inst?.$.type.name}.
34
+ info: ${info}.
35
+ `
36
+ })
37
+
27
38
  </script>
@@ -1,24 +1,32 @@
1
1
  <template>
2
2
  <v-main class="overflow-hidden" style="height: 91dvh;">
3
+ <Suspense suspensible>
4
+ <component id="bg-widget" v-if="bgWidget.component" :is="bgWidget.component" v-bind="bgWidget.props"></component>
5
+ </Suspense>
3
6
 
4
- <component id="bg-widget" :is="bgWidget.component" v-bind="bgWidget.props"></component>
5
-
6
- <div v-show="activeIdx === idx" id="overlay" class="pa-2" v-for="(importedWidget, idx) in importedWidgets"
7
- :key="idx" :style="{
7
+ <template v-for="(importedWidget, idx) in importedWidgets" :key="idx">
8
+ <div v-if="importedWidget.value.component" v-show="activeIdx === idx" id="overlay" class="pa-2" :style="{
8
9
  bottom: tabsHeightFromBtm, position: 'absolute', overflow: 'hidden',
9
10
  width: '100%', left: 0, top: mainRect.top + 'px', zIndex: 1, background: 'rgb(var(--v-theme-surface))'
10
11
  }">
11
- <v-btn icon variant="text" style="height: 5%;position: relative;" @click="activeIdx = -1">&#x2715;</v-btn>
12
- <component style="height: 94% !important;" :key="importedWidget.value.id" :is="importedWidget.value.component"
13
- v-show="activeIdx === idx" v-bind="importedWidget.value.props" />
14
- </div>
12
+ <v-btn icon variant="text" style="height: 5%;position: relative;" @click="activeIdx = -1">&#x2715;</v-btn>
13
+ <Suspense suspensible>
14
+ <div style="height: 90% !important;" v-show="activeIdx === idx">
15
+ <component :key="importedWidget.value.id" :is="importedWidget.value.component"
16
+ v-bind="importedWidget.value.props" />
17
+ </div>
18
+ </Suspense>
19
+ </div>
20
+ </template>
15
21
 
16
22
  <v-tabs ref="tabs" align-tabs="center" bg-color="surface"
17
23
  :style="{ position: 'relative', bottom: (mainRect.bottom || 48) + 'px', zIndex: 10 }" show-arrows
18
24
  v-model="activeIdx">
19
- <v-tab v-for="(importedWidget, idx) in importedWidgets" :key="idx" :value="idx">
20
- {{ importedWidget.value.title }}
21
- </v-tab>
25
+ <template v-for="(importedWidget, idx) in importedWidgets" :key="idx">
26
+ <v-tab v-if="importedWidget.value.component" :value="idx">
27
+ {{ importedWidget.value.title }}
28
+ </v-tab>
29
+ </template>
22
30
  </v-tabs>
23
31
 
24
32
  </v-main>
@@ -60,9 +60,11 @@ export const useDefineWidgets = (widgetConfigs) => {
60
60
  if ('defineWidget' in (config ?? {})) {
61
61
  const { selectedStac } = storeToRefs(useSTAcStore())
62
62
  watch(selectedStac, (updatedStac) => {
63
- const definedConfig = reactive(/** @type {import("@/types").FunctionalWidget} */
64
- (config)?.defineWidget(updatedStac))
65
- definedWidget.value = definedWidget.value.id === definedConfig.id ?
63
+ let definedConfig = /** @type {import("@/types").FunctionalWidget} */(config)?.defineWidget(updatedStac)
64
+ if (definedConfig) {
65
+ definedConfig = reactive(definedConfig)
66
+ }
67
+ definedWidget.value = definedWidget.value.id === definedConfig?.id ?
66
68
  definedWidget.value : getWidgetDefinition(definedConfig);
67
69
  }, { immediate: true })
68
70
  } else {
@@ -76,7 +78,7 @@ export const useDefineWidgets = (widgetConfigs) => {
76
78
 
77
79
  /**
78
80
  * Converts a static widget configuration to a defined imported widget
79
- * @param {import("@/types").StaticWidget| Omit<import("@/types").StaticWidget, "layout">| undefined} config
81
+ * @param {import("@/types").StaticWidget| Omit<import("@/types").StaticWidget, "layout">| undefined | null} config
80
82
  * @returns {DefinedWidget}
81
83
  **/
82
84
  const getWidgetDefinition = (config) => {
@@ -119,7 +121,11 @@ const getWidgetDefinition = (config) => {
119
121
  break;
120
122
 
121
123
  default:
122
- console.error('Widget type not found')
124
+ if (!config) {
125
+ return importedWidget
126
+ } else {
127
+ console.error('Widget type not found')
128
+ }
123
129
  break;
124
130
  }
125
131
  importedWidget.title = config?.title ?? ''
@@ -6,6 +6,7 @@ import { currentUrl, indicator, mapPosition } from "@/store/States";
6
6
  import eodash from "@/eodash";
7
7
  import { useTheme } from "vuetify/lib/framework.mjs";
8
8
  import { onMounted, watch } from "vue";
9
+ import { mdiChevronDoubleDown, mdiChevronDoubleLeft, mdiChevronDoubleRight, mdiChevronDoubleUp } from "@mdi/js"
9
10
 
10
11
  /**
11
12
  * Creates an absolute URL from a relative link and assignes it to `currentUrl`
@@ -56,41 +57,43 @@ export const useSlidePanels = (elements, configs) => {
56
57
  /**
57
58
  * Array of sliding button's style and icons
58
59
  */
59
- const slideBtns = slideDirs.map((dir, idx) => {
60
+ const slideBtns = slideDirs.map((dir, _idx) => {
60
61
  const btn = reactive({
61
62
  style: {},
62
63
  icon: { in: "", out: "" },
63
64
  active: false,
64
65
  enabled: true,
65
66
  });
66
- if (configs[idx].slidable === false) {
67
- btn.enabled = false;
68
- return btn;
69
- }
67
+
68
+ // temp removal of `slidable` from the widgets API
69
+ // if (configs[idx].slidable === false) {
70
+ // btn.enabled = false;
71
+ // return btn;
72
+ // }
70
73
 
71
74
  switch (dir) {
72
75
  case "left":
73
76
  btn.style = { top: "50%", right: "-11%" };
74
- btn.icon.in = "mdi-chevron-double-right";
75
- btn.icon.out = "mdi-chevron-double-left";
77
+ btn.icon.in = mdiChevronDoubleRight
78
+ btn.icon.out = mdiChevronDoubleLeft
76
79
 
77
80
  break;
78
81
  case "right":
79
82
  btn.style = { top: "50%", left: "-11%" };
80
- btn.icon.in = "mdi-chevron-double-left";
81
- btn.icon.out = "mdi-chevron-double-right";
83
+ btn.icon.in = mdiChevronDoubleLeft
84
+ btn.icon.out = mdiChevronDoubleRight
82
85
 
83
86
  break;
84
87
  case "up":
85
88
  btn.style = { right: "50%", bottom: "-17%" };
86
- btn.icon.in = "mdi-chevron-double-down";
87
- btn.icon.out = "mdi-chevron-double-up";
89
+ btn.icon.in = mdiChevronDoubleDown
90
+ btn.icon.out = mdiChevronDoubleUp
88
91
 
89
92
  break;
90
93
  case "down":
91
94
  btn.style = { right: "50%", top: "-17%" };
92
- btn.icon.in = "mdi-chevron-double-up";
93
- btn.icon.out = "mdi-chevron-double-down";
95
+ btn.icon.in = mdiChevronDoubleUp
96
+ btn.icon.out = mdiChevronDoubleDown
94
97
  break;
95
98
 
96
99
  default:
@@ -53,7 +53,6 @@ export const eodash = reactive({
53
53
  type: "internal",
54
54
  title: "itemfilter",
55
55
  layout: { x: 0, y: 0, w: 3, h: 12 },
56
- slidable: false,
57
56
  widget: {
58
57
  name: "EodashItemFilter",
59
58
  },
@@ -63,7 +62,6 @@ export const eodash = reactive({
63
62
  type: "internal",
64
63
  title: "datepicker",
65
64
  layout: { x: 5, y: 11, w: 2, h: 1 },
66
- slidable: false,
67
65
  widget: {
68
66
  name: "EodashDatePicker",
69
67
  properties: {
@@ -5,15 +5,21 @@
5
5
  */
6
6
 
7
7
  // Styles
8
- import '@mdi/font/css/materialdesignicons.css';
9
8
  import 'vuetify/styles';
10
9
 
11
10
 
12
11
  import { createVuetify } from 'vuetify';
13
- // import {} from "vuetify"
12
+ import { mdiChevronLeft, mdiChevronRight, mdiMenuDown } from "@mdi/js"
14
13
 
15
- // https://vuetifyjs.com/en/introduction/why-vuetify/#feature-guides
16
14
  const vuetify = createVuetify({
15
+ icons: {
16
+ aliases: {
17
+ // mapping v-date-picker and v-tabs default icons to `@mdi/js`
18
+ next: [mdiChevronRight],
19
+ prev: [mdiChevronLeft],
20
+ subgroup: [mdiMenuDown]
21
+ },
22
+ },
17
23
  theme: {
18
24
  themes: {
19
25
  dashboardTheme: {},
@@ -39,7 +39,9 @@ export const useSTAcStore = defineStore('stac', () => {
39
39
  return link
40
40
  })
41
41
  stac.value = links;
42
- }).catch(err => console.error(err));
42
+ }).catch(err => {
43
+ throw new Error("error loading assigned STAC endpoint", err)
44
+ });
43
45
  }
44
46
 
45
47
  /**
@@ -56,7 +58,9 @@ export const useSTAcStore = defineStore('stac', () => {
56
58
  await axios.get(absoluteUrl.value).then(resp => {
57
59
  selectedStac.value = resp.data;
58
60
  indicator.value = selectedStac.value?.id ?? "";
59
- }).catch(err => console.error(err));
61
+ }).catch(err => {
62
+ throw new Error("error loading the selected STAC", err)
63
+ });
60
64
  }
61
65
 
62
66
  return { stac, loadSTAC, loadSelectedSTAC, selectedStac };
@@ -23,17 +23,17 @@ export interface WebComponentProps<T extends ExecutionTime = "compiletime"> {
23
23
  constructorProp?: string
24
24
  tagName: `${string}-${string}`
25
25
  /** Object defining all the properties and attributes of the web component */
26
- properties?: Record<string, any>
26
+ properties?: Record<string, unknown>
27
27
  /**
28
28
  * Triggered when the web component is mounted in the DOM.
29
29
  * @param el - web component
30
- * @param store - return value of the core STAC pinia store in `/core/store/stac.ts`
30
+ * @param store - return value of the core STAC pinia store in `/core/client/store/stac.ts`
31
31
  */
32
32
  onMounted?: (el: Element | null, store: ReturnType<typeof import("./store/stac").useSTAcStore>) => (Promise<void> | void)
33
33
  /**
34
34
  * Triggered when the web component is unmounted from the DOM.
35
35
  * @param el - web component
36
- * @param store - return value of the core STAC pinia store in `/core/store/stac.ts`
36
+ * @param store - return value of the core STAC pinia store in `/core/client/store/stac.ts`
37
37
  */
38
38
  onUnmounted?: (el: Element | null, store: ReturnType<typeof import("./store/stac").useSTAcStore>) => (Promise<void> | void)
39
39
  }
@@ -41,7 +41,7 @@ export interface WebComponentProps<T extends ExecutionTime = "compiletime"> {
41
41
 
42
42
  /** @ignore */
43
43
  export interface WidgetsContainerProps {
44
- widgets: Omit<Widget, 'layout' | 'slidable'>[]
44
+ widgets: Omit<Widget, 'layout'>[]
45
45
  }
46
46
 
47
47
  // eodash types:
@@ -73,10 +73,6 @@ export interface WebComponentWidget<T extends ExecutionTime = "compiletime"> {
73
73
  */
74
74
  h: number
75
75
  },
76
- /**
77
- * Enable/Disable widget sliding.
78
- */
79
- slidable?: boolean
80
76
  widget: WebComponentProps<T>
81
77
  type: 'web-component'
82
78
  }
@@ -110,10 +106,6 @@ export interface InternalComponentWidget {
110
106
  */
111
107
  h: number
112
108
  }
113
- /**
114
- * Enable/Disable widget sliding.
115
- */
116
- slidable?: boolean
117
109
  widget: {
118
110
  /**
119
111
  * Internal Vue Components inside the [widgets](https://github.com/eodash/eodash/tree/main/widgets) folder. Referenced
@@ -159,10 +151,6 @@ export interface IFrameWidget {
159
151
  */
160
152
  h: number
161
153
  }
162
- /**
163
- * Enable/Disable widget sliding.
164
- */
165
- slidable?: boolean;
166
154
  widget: {
167
155
  /**
168
156
  * The URL of the page to embed
@@ -176,13 +164,13 @@ export interface IFrameWidget {
176
164
  */
177
165
  export interface FunctionalWidget<T extends ExecutionTime = "compiletime"> {
178
166
  /**
179
- * Provides a functional definition of the widget,
180
- * gets triggered whenever a STAC object is selected.
167
+ * Provides a functional definition of widgets,
168
+ * gets triggered whenever a STAC object is selected, and only renders the returned configuration
169
+ * if the `id` doesn't match the currently rendered `id`
181
170
  * @param selectedSTAC - Currently selected STAC object
182
171
  */
183
172
  defineWidget: (selectedSTAC: import("stac-ts").StacCatalog |
184
- import("stac-ts").StacCollection | import("stac-ts").StacItem
185
- | null) => Omit<StaticWidget<T>, 'layout' | 'slidable'>
173
+ import("stac-ts").StacCollection | import("stac-ts").StacItem | null) => Omit<StaticWidget<T>, 'layout' | 'slidable'> | undefined | null
186
174
  layout: {
187
175
  /**
188
176
  * Horizontal start position. Integer between 1 and 12
@@ -201,10 +189,6 @@ export interface FunctionalWidget<T extends ExecutionTime = "compiletime"> {
201
189
  */
202
190
  h: number
203
191
  }
204
- /**
205
- * Enable/Disable widget sliding.
206
- */
207
- slidable?: boolean
208
192
  }
209
193
  /**
210
194
  * @group Eodash
@@ -275,6 +259,8 @@ export interface Eodash<T extends ExecutionTime = "compiletime"> {
275
259
  brand: {
276
260
  /** Removes the dashboard layout */
277
261
  noLayout?: boolean
262
+ /** custom error message to alert the users if something crashes */
263
+ errorMessage?: string
278
264
  /**
279
265
  * Automatically fetches the specified font family from google fonts. if the [link](#font-link) property is specified
280
266
  * the font family will be fetched from the provided source instead.
@@ -348,7 +334,7 @@ export interface EodashStore {
348
334
  * the project's entry point should export this function as a default
349
335
  * to instantiate eodash
350
336
  * @group Eodash
351
- * @param configCallback
337
+ * @param config
352
338
  */
353
339
  export declare const createEodash: (config: ((store: EodashStore) => Eodash | Promise<Eodash>) | Eodash) => Eodash | Promise<Eodash>
354
340
 
@@ -1,25 +1,27 @@
1
1
  <template>
2
- <HeaderComponent v-if="!eodash.brand.noLayout" />
2
+ <HeaderComponent ref="headerRef" v-if="!eodash.brand.noLayout" />
3
+ <ErrorAlert v-model="error" />
3
4
  <Suspense>
4
- <TemplateComponent @vue:mounted="onTemplateMount?.()"
5
+ <TemplateComponent @vue:mounted="onTemplateMount?.(hiddenElements)"
5
6
  :style="`height: ${eodash.brand.noLayout ? (onTemplateMount ? '100%' : '90dvh') : 'calc(100dvh - ' + mainRect['top'] + mainRect['bottom'] + 'px)'}`" />
6
7
  <template #fallback>
7
- <div v-if="onTemplateMount" style="height: 100dvh; display: flex; align-items: center; justify-content: center;">
8
+ <div style="height: 100dvh; display: flex; align-items: center; justify-content: center;">
8
9
  <Loading />
9
10
  </div>
10
11
  </template>
11
12
  </Suspense>
12
- <FooterComponent v-if="!eodash.brand.noLayout" />
13
+ <FooterComponent ref="footerRef" v-if="!eodash.brand.noLayout" />
13
14
  </template>
14
15
 
15
16
  <script setup>
16
17
  import { useEodashRuntime } from "@/composables/DefineEodash";
17
18
  import { useURLSearchParametersSync, useUpdateTheme } from "@/composables";
18
19
  import { useSTAcStore } from '@/store/stac';
19
- import { defineAsyncComponent, onMounted } from "vue";
20
+ import { defineAsyncComponent, onErrorCaptured, onMounted, ref } from "vue";
20
21
  import { useDisplay, useLayout } from "vuetify/lib/framework.mjs";
21
22
  import { loadFont } from '@/utils'
22
23
  import Loading from "@/components/Loading.vue";
24
+ import ErrorAlert from "@/components/ErrorAlert.vue";
23
25
 
24
26
  const props = defineProps({
25
27
  config: {
@@ -29,7 +31,6 @@ const props = defineProps({
29
31
  type: Function
30
32
  }
31
33
  })
32
-
33
34
  const eodash = await useEodashRuntime(props.config)
34
35
 
35
36
  useURLSearchParametersSync();
@@ -51,9 +52,37 @@ const HeaderComponent = defineAsyncComponent(() => import(`@/components/Header.v
51
52
  const FooterComponent = defineAsyncComponent(() => import(`@/components/Footer.vue`))
52
53
  const { mainRect } = useLayout()
53
54
 
55
+ /** @type {import("vue").Ref<InstanceType<typeof
56
+ * import("@/components/Header.vue").default >|null>}
57
+ **/
58
+ const headerRef = ref(null);
59
+ /** @type {import("vue").Ref<InstanceType<typeof
60
+ * import("@/components/Footer.vue").default >|null>}
61
+ **/
62
+ const footerRef = ref(null);
63
+
64
+ const hiddenElements = [headerRef, footerRef]
65
+
54
66
  onMounted(() => {
55
67
  const htmlTag = /** @type {HTMLElement} */(document.querySelector('html'))
56
68
  htmlTag.style.overflow = 'hidden';
69
+
70
+ if (props.onTemplateMount && !eodash.brand.noLayout) {
71
+ hiddenElements.forEach(element => {
72
+ /** @type {HTMLElement} */
73
+ // @ts-expect-error
74
+ (element.value.$el).style.opacity = "0"
75
+ })
76
+ }
77
+ })
78
+
79
+ const error = ref('')
80
+ onErrorCaptured((e, comp, info) => {
81
+ error.value = `
82
+ error: ${e}.
83
+ component: ${comp?.$.type.name}.
84
+ info: ${info}.
85
+ `
57
86
  })
58
87
 
59
88
  </script>