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

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 (48) hide show
  1. package/README.md +11 -1
  2. package/bin/types.d.ts +1 -0
  3. package/bin/utils.js +1 -1
  4. package/core/App.vue +12 -4
  5. package/core/SuspensedDashboard.ce.vue +13 -5
  6. package/core/components/DashboardLayout.vue +14 -22
  7. package/core/components/ErrorAlert.vue +19 -0
  8. package/core/components/Loading.vue +12 -1
  9. package/core/components/MobileLayout.vue +19 -11
  10. package/core/composables/DefineWidgets.js +11 -5
  11. package/core/composables/index.js +16 -13
  12. package/core/eodash.js +0 -2
  13. package/core/plugins/vuetify.js +9 -3
  14. package/core/store/stac.js +6 -2
  15. package/core/types.d.ts +9 -23
  16. package/core/views/Dashboard.vue +13 -2
  17. package/dist/DashboardLayout-lzEvtalW.js +148 -0
  18. package/dist/{DynamicWebComponent-BrHVTesn.js → DynamicWebComponent-CgDh2csQ.js} +12 -12
  19. package/dist/EodashDatePicker-bIyNUYaG.js +1653 -0
  20. package/dist/{EodashItemFilter-BLAGx2UD.js → EodashItemFilter-CpgyrJRX.js} +2 -2
  21. package/dist/{EodashMap-Bxl_aqY2.js → EodashMap-CyR-Ldpk.js} +4 -4
  22. package/dist/Footer-C2sIHSym.js +118 -0
  23. package/dist/{Header-DC50S6GR.js → Header-DFz2BUnp.js} +222 -226
  24. package/dist/{IframeWrapper-Dd9zrX9s.js → IframeWrapper-Csep3rMg.js} +1 -1
  25. package/dist/MobileLayout-CXNJL_q6.js +984 -0
  26. package/dist/VMain-COrg6UtF.js +39 -0
  27. package/dist/{WidgetsContainer-DxfCu0I3.js → WidgetsContainer-XA6_dKOm.js} +16 -16
  28. package/dist/asWebComponent-fqvymeM-.js +13092 -0
  29. package/dist/{decoder-kAoyGIq9-BBR5CgzS.js → decoder-kAoyGIq9-DjQanfeo.js} +1 -1
  30. package/dist/eo-dash.js +2 -2
  31. package/dist/{index-DTkOfh2g.js → index-Cskxla5D.js} +75 -43
  32. package/dist/index-Zv5eTiB6.js +34 -0
  33. package/dist/{lerc-C9VL9kri-cIdbW0sg.js → lerc-C9VL9kri-O4muG-MO.js} +1 -1
  34. package/dist/{ssrBoot-D-b4-M19.js → ssrBoot-DCCAW5xY.js} +3 -3
  35. package/dist/style.css +2 -2
  36. package/package.json +3 -3
  37. package/widgets/EodashDatePicker.vue +1 -0
  38. package/widgets/WidgetsContainer.vue +7 -5
  39. package/dist/DashboardLayout-Dp8AnYD9.js +0 -141
  40. package/dist/EodashDatePicker-D_udZ26j.js +0 -1645
  41. package/dist/Footer-AohCH8U7.js +0 -118
  42. package/dist/MobileLayout-CgToA7Gp.js +0 -523
  43. package/dist/VBtn-Bz7ruRUg.js +0 -1106
  44. package/dist/VMain-BHfWJU2j.js +0 -35
  45. package/dist/asWebComponent-C8rb3b1D.js +0 -11323
  46. package/dist/color-DpYEub1f.js +0 -115
  47. package/dist/dimensions-CJaGeSrj.js +0 -53
  48. package/dist/index-Sa2Vg_gx.js +0 -65
package/README.md CHANGED
@@ -18,9 +18,19 @@ 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
+ ├── bin # CLI source code
22
+ ├── core # Client source code that hosts the microfrontends and renders the dashboard
22
23
  ├── docs # Documentation files
24
+ ├── tests # CLI and component tests folder
23
25
  ├── widgets # Vue componenets as internal widgets.
24
26
  ├── public # Statically served directory
25
27
  └── README.md
26
28
 
29
+
30
+ ## Writing commits
31
+ 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).
32
+
33
+ The most important prefixes you should have in mind are:
34
+ * fix: which represents bug fixes, and correlates to a SemVer patch.
35
+ * feat: which represents a new feature, and correlates to a SemVer minor.
36
+ * feat!:, or fix!:, refactor!:, etc., which represent a breaking change (indicated by the !) and will result in a SemVer major.
package/bin/types.d.ts CHANGED
@@ -40,6 +40,7 @@ export interface EodashConfig {
40
40
  * File exporting eodash client runtime config
41
41
  */
42
42
  runtime?: string
43
+ /** set a custom path for importing user defined internal widgets */
43
44
  widgets?: string
44
45
  /** builds eodash as a web component library */
45
46
  lib?: boolean
package/bin/utils.js CHANGED
@@ -63,7 +63,7 @@ export const appPath = fileURLToPath(new URL("..", import.meta.url)),
63
63
  cachePath = userConfig.cacheDir ? path.resolve(rootPath, userConfig.cacheDir) : path.join(dotEodashPath, 'cache');
64
64
 
65
65
 
66
- export const logger = createLogger()
66
+ export const logger = createLogger(undefined, { prefix: '[eodash]' })
67
67
 
68
68
  /**
69
69
  * @param {Options} options
package/core/App.vue CHANGED
@@ -1,19 +1,27 @@
1
1
  <template>
2
2
  <v-app>
3
3
  <Suspense>
4
- <!-- main content -->
4
+
5
5
  <Dashboard />
6
6
 
7
- <!-- loading state -->
8
7
  <template #fallback>
9
- <Loading />
8
+ <ErrorAlert v-model="error" />
10
9
  </template>
11
10
  </Suspense>
12
11
  </v-app>
13
12
  </template>
14
13
 
15
14
  <script setup>
16
- import Loading from '@/components/Loading.vue';
17
15
  import Dashboard from '@/views/Dashboard.vue';
16
+ import ErrorAlert from './components/ErrorAlert.vue';
17
+ import { onErrorCaptured, ref } from 'vue';
18
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
+ })
19
27
  </script>
@@ -2,20 +2,19 @@
2
2
  <v-app>
3
3
  <Suspense>
4
4
  <Dashboard :on-template-mount="setStylesFromHead" :config="config" />
5
+
5
6
  <template #fallback>
6
- <div style="height: 100dvh; display: flex; align-items: center; justify-content: center;">
7
- <Loading />
8
- </div>
7
+ <ErrorAlert @vue:mounted="setStylesFromHead()" v-model="error" />
9
8
  </template>
10
9
  </Suspense>
11
10
  </v-app>
12
11
  </template>
13
12
  <script setup>
14
13
  import Dashboard from '@/views/Dashboard.vue';
15
- import { createApp, getCurrentInstance } from "vue"
14
+ import { createApp, getCurrentInstance, onErrorCaptured, ref } from "vue"
16
15
  import { registerPlugins } from '@/plugins';
17
16
  import { eodashKey } from '@/utils/keys';
18
- import Loading from '@/components/Loading.vue';
17
+ import ErrorAlert from '@/components/ErrorAlert.vue';
19
18
 
20
19
  defineProps({
21
20
  config: {
@@ -62,4 +61,13 @@ ${//@ts-expect-error
62
61
  styleSheet.replaceSync(stylesStr.replaceAll(":root", ":host"))
63
62
  eodashComponent?.shadowRoot?.adoptedStyleSheets.push(styleSheet)
64
63
  }
64
+
65
+ const error = ref('')
66
+ onErrorCaptured((e, comp, info) => {
67
+ error.value = `
68
+ ${e}.
69
+ component: ${comp?.$.type.name}.
70
+ info: ${info}.
71
+ `
72
+ })
65
73
  </script>
@@ -1,21 +1,22 @@
1
1
  <template>
2
2
  <v-main>
3
3
  <eox-layout :gap="eodash.template.gap ?? 2">
4
- <eox-layout-item style="z-index: 0;" x="0" y="0" h="12" w="12">
5
- <component id="bg-widget" :is="bgWidget.component" v-bind="bgWidget.props" />
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>
6
8
  </eox-layout-item>
7
- <eox-layout-item v-for="(config, idx) in widgetsConfig" ref="itemEls" :key="idx"
8
- style="position: relative; overflow: visible; z-index: 1; border-radius: 0px; background: rgb(var(--v-theme-surface))"
9
- :x="config.layout.x" :y="config.layout.y" :h="config.layout.h" :w="config.layout.w">
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">
10
13
 
11
- <v-btn v-if="slideBtns[idx].enabled" position="absolute" variant="tonal" :style="slideBtns[idx].style"
12
- class="slide-btn" @click="slideInOut(idx)">
13
- <v-icon :icon="slideBtns[idx].active ? slideBtns[idx].icon.in : slideBtns[idx].icon.out" />
14
- </v-btn>
15
- <component :key="importedWidgets[idx].value.id" :is="importedWidgets[idx].value.component"
16
- v-bind="importedWidgets[idx].value.props" />
17
-
18
- </eox-layout-item>
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>
19
20
  </eox-layout>
20
21
  </v-main>
21
22
  </template>
@@ -23,8 +24,6 @@
23
24
  import { eodashKey } from '@/utils/keys';
24
25
  import { inject } from 'vue';
25
26
  import { useDefineWidgets } from '@/composables/DefineWidgets'
26
- import { useSlidePanels } from '@/composables'
27
- import { ref } from 'vue';
28
27
  import '@eox/layout'
29
28
 
30
29
  const eodash = /** @type {import("@/types").Eodash} */ (inject(eodashKey))
@@ -34,11 +33,4 @@ const [bgWidget] = useDefineWidgets([eodash.template?.background])
34
33
  const widgetsConfig = eodash.template?.widgets
35
34
 
36
35
  const importedWidgets = useDefineWidgets(widgetsConfig)
37
- /**
38
- * Layout items template ref
39
- * @type {import('vue').Ref<HTMLElement[]>}
40
- */
41
- const itemEls = ref([])
42
-
43
- const { slideBtns, slideInOut } = useSlidePanels(itemEls, widgetsConfig)
44
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:
package/core/eodash.js CHANGED
@@ -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
+ // remapping 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 };
package/core/types.d.ts CHANGED
@@ -23,7 +23,7 @@ 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
@@ -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,10 +1,11 @@
1
1
  <template>
2
2
  <HeaderComponent v-if="!eodash.brand.noLayout" />
3
+ <ErrorAlert v-model="error" />
3
4
  <Suspense>
4
5
  <TemplateComponent @vue:mounted="onTemplateMount?.()"
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>
@@ -16,10 +17,11 @@
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: {
@@ -56,4 +58,13 @@ onMounted(() => {
56
58
  htmlTag.style.overflow = 'hidden';
57
59
  })
58
60
 
61
+ const error = ref('')
62
+ onErrorCaptured((e, comp, info) => {
63
+ error.value = `
64
+ error: ${e}.
65
+ component: ${comp?.$.type.name}.
66
+ info: ${info}.
67
+ `
68
+ })
69
+
59
70
  </script>