@eodash/eodash 5.0.0-alpha.1.9 → 5.0.0-alpha.2.1
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.
- package/LICENSE +21 -0
- package/README.md +1 -1
- package/bin/cli.js +15 -8
- package/bin/main.js +9 -0
- package/bin/serverConfig.js +58 -29
- package/bin/types.d.ts +52 -0
- package/bin/utils.js +70 -20
- package/core/App.vue +10 -12
- package/core/SuspensedDashboard.ce.vue +65 -0
- package/core/asWebComponent.d.ts +18 -0
- package/core/asWebComponent.js +12 -0
- package/core/components/DashboardLayout.vue +11 -25
- package/core/components/DynamicWebComponent.vue +6 -6
- package/core/components/Footer.vue +11 -12
- package/core/components/Header.vue +5 -29
- package/core/components/Loading.vue +27 -0
- package/core/components/MobileLayout.vue +34 -63
- package/core/composables/DefineEodash.js +57 -0
- package/core/composables/DefineWidgets.js +26 -15
- package/core/composables/index.js +139 -67
- package/core/eodash.js +100 -0
- package/core/main.js +2 -4
- package/core/plugins/index.js +3 -12
- package/core/plugins/vuetify.js +5 -2
- package/core/store/Actions.js +0 -28
- package/core/store/States.js +12 -3
- package/core/store/stac.js +7 -5
- package/core/types.d.ts +149 -124
- package/core/utils/eodashSTAC.js +164 -0
- package/core/utils/helpers.js +40 -0
- package/core/utils/index.js +28 -0
- package/core/utils/keys.js +6 -0
- package/core/views/Dashboard.vue +33 -23
- package/core/vite-env.d.ts +16 -2
- package/dist/.gitkeep +0 -0
- package/dist/DashboardLayout-Dp8AnYD9.js +141 -0
- package/dist/DynamicWebComponent-BrHVTesn.js +57 -0
- package/dist/EodashDatePicker-D_udZ26j.js +1645 -0
- package/dist/EodashItemFilter-BLAGx2UD.js +51 -0
- package/dist/EodashMap-Bxl_aqY2.js +53405 -0
- package/dist/Footer-AohCH8U7.js +118 -0
- package/dist/Header-DC50S6GR.js +609 -0
- package/dist/IframeWrapper-Dd9zrX9s.js +19 -0
- package/dist/MobileLayout-CgToA7Gp.js +523 -0
- package/dist/VBtn-Bz7ruRUg.js +1106 -0
- package/dist/VMain-BHfWJU2j.js +35 -0
- package/dist/WidgetsContainer-DxfCu0I3.js +122 -0
- package/dist/_commonjsHelpers-DaMA6jEr.js +8 -0
- package/dist/asWebComponent-C8rb3b1D.js +11323 -0
- package/dist/basedecoder-Qm25PwVp-CHo5Pomv.js +89 -0
- package/dist/color-DpYEub1f.js +115 -0
- package/dist/decoder-kAoyGIq9-BBR5CgzS.js +10 -0
- package/dist/deflate-Be2Arps5-hDqMz3RA.js +10 -0
- package/dist/dimensions-CJaGeSrj.js +53 -0
- package/dist/eo-dash.js +6 -0
- package/dist/eox-itemfilter-DcQkRD2l.js +7537 -0
- package/dist/eox-map-BJ9SIixs.js +36205 -0
- package/dist/eox-stacinfo-B-YrT7Ug.js +13698 -0
- package/dist/forwardRefs-Bxeu9Obx.js +142 -0
- package/dist/index-DTkOfh2g.js +152 -0
- package/dist/index-Sa2Vg_gx.js +65 -0
- package/dist/jpeg-DNfUpLwy-Fjan-04T.js +515 -0
- package/dist/lerc-C9VL9kri-cIdbW0sg.js +1029 -0
- package/dist/lzw-BOMhmEDy-Dboc93VO.js +84 -0
- package/dist/packbits-DaUD6MLm-Bu1PoTGa.js +24 -0
- package/dist/pako.esm-C3kYPGGQ-BMki8cQY.js +1087 -0
- package/dist/raw-CcGKjn8q-DFOt-i8n.js +9 -0
- package/dist/ssrBoot-D-b4-M19.js +17 -0
- package/dist/style.css +5 -0
- package/dist/webfontloader-CyOFAuFB.js +471 -0
- package/dist/webimage-D2c098k3-DLj1LQxB.js +19 -0
- package/package.json +40 -12
- package/widgets/EodashDatePicker.vue +56 -0
- package/widgets/EodashItemFilter.vue +60 -0
- package/widgets/EodashMap.vue +82 -0
- package/widgets/WidgetsContainer.vue +1 -1
- package/core/composables/DefineConfig.js +0 -45
- package/core/eodashConfig.js +0 -136
- package/core/plugins/router.js +0 -20
- package/core/store/Keys.js +0 -6
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-footer ref="footer" :height="mdAndDown ? '48px' : 'auto'" color="secondary" app
|
|
3
3
|
class="d-flex justify-space-between">
|
|
4
|
-
<p class="pt-0
|
|
5
|
-
|
|
4
|
+
<p class="pt-0" style="font-size: 0.8rem;">
|
|
5
|
+
{{ eodash.brand.footerText ?? "" }}
|
|
6
6
|
</p>
|
|
7
|
-
<div
|
|
8
|
-
|
|
7
|
+
<div>
|
|
8
|
+
<a href="https://github.com/eodash/eodash" class="text-white" target="_blank">eodash</a> by
|
|
9
|
+
<a href="https://eox.at" target="_blank" class="text-white">
|
|
10
|
+
<img :src='`data:image/svg+xml;base64,${base64Logo}`' height="11px">
|
|
11
|
+
</a>
|
|
9
12
|
</div>
|
|
10
13
|
</v-footer>
|
|
11
14
|
</template>
|
|
12
15
|
<script setup>
|
|
13
|
-
import {
|
|
16
|
+
import { eodashKey } from '@/utils/keys';
|
|
14
17
|
import { ref } from 'vue';
|
|
15
18
|
import { inject } from 'vue';
|
|
16
19
|
import { useDisplay } from 'vuetify/lib/framework.mjs';
|
|
@@ -20,13 +23,9 @@ import { useDisplay } from 'vuetify/lib/framework.mjs';
|
|
|
20
23
|
* @type {import('vue').Ref<import('vuetify/lib/components/index.mjs').VFooter | null>}
|
|
21
24
|
*/
|
|
22
25
|
const footer = ref(null)
|
|
23
|
-
const
|
|
26
|
+
const eodash = /** @type {import("@/types").Eodash} */(inject(eodashKey))
|
|
24
27
|
|
|
25
|
-
const title = eodashConfig.brand?.shortName ?? eodashConfig.brand?.name
|
|
26
28
|
const { mdAndDown } = useDisplay()
|
|
29
|
+
const eoxLogo = `<svg width="100%" height="100%" viewBox="0 0 355 85" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;"><g id="ink_ext_XXXXXX"><path id="path5076" d="M152.986,40.52l-0.75,-0.019l-0.737,-0.056l-0.725,-0.093l-0.713,-0.127l-0.7,-0.162l-0.7,-0.196l-0.675,-0.228l-0.65,-0.261l-0.65,-0.292l-0.625,-0.319l-0.612,-0.352l-0.588,-0.377l-0.562,-0.407l-0.55,-0.431l-0.538,-0.457l-0.5,-0.481l-0.487,-0.505l-0.45,-0.528l-0.438,-0.55l-0.4,-0.57l-0.375,-0.59l-0.35,-0.609l-0.325,-0.627l-0.287,-0.645l-0.263,-0.66l-0.225,-0.676l-0.2,-0.69l-0.162,-0.704l-0.125,-0.717l-0.1,-0.728l-0.05,-0.739l-0.025,-0.748c0,-8.023 6.512,-14.532 14.537,-14.532c8.038,0 14.538,6.509 14.538,14.532c0,8.036 -6.5,14.544 -14.538,14.544Z" style="fill:none;"/><path id="path5078" d="M165.748,-0.002c-42.009,0 -76.06,18.985 -76.06,42.402c0,13.268 10.921,25.102 28.021,32.875c-8.081,-5.487 -13.403,-12.973 -14.584,-21.859c-2.685,-20.186 16.83,-40.82 45.148,-49.615c-14.687,6.665 -24.923,21.427 -24.923,38.599c0,23.218 18.648,42.046 41.773,42.383c-0.037,0.005 -0.087,0.015 -0.137,0.02c0.263,0 0.512,0.009 0.762,0.009c42.013,0 76.076,-18.984 76.076,-42.412c0,-13.261 -10.937,-25.097 -28.037,-32.871l0.75,0.522l0.736,0.531l0.713,0.543l0.7,0.555l0.687,0.566l0.664,0.578l0.649,0.588l0.625,0.6l0.613,0.609l0.588,0.621l0.574,0.631l0.562,0.643l0.538,0.652l0.513,0.662l0.5,0.672l0.475,0.684l0.449,0.693l0.438,0.703l0.425,0.713l0.387,0.723l0.375,0.73l0.352,0.74l0.336,0.75l0.3,0.76l0.287,0.77l0.264,0.777l0.25,0.787l0.211,0.795l0.188,0.805l0.175,0.812l0.151,0.82l0.125,0.831c2.675,20.19 -16.838,40.825 -45.151,49.619c14.688,-6.665 24.926,-21.426 24.926,-38.614c0,-23.202 -18.65,-42.026 -41.775,-42.367c0.05,-0.005 0.1,-0.015 0.15,-0.025c-0.262,0 -0.526,-0.01 -0.789,-0.01Zm-13.248,11.314c7.817,0 14.25,6.433 14.25,14.25c0,0.001 0,0.001 0,0.001c0,7.817 -6.433,14.249 -14.25,14.249c-7.817,0 -14.25,-6.432 -14.25,-14.249c0,-0.001 0,-0.001 0,-0.001c0,-7.817 6.433,-14.25 14.25,-14.25Z" style="fill:#fff;fill-rule:nonzero;"/><path id="path5080" d="M213.786,9.529l0.75,0.521l0.738,0.532l0.712,0.544l0.7,0.555l0.688,0.566l0.662,0.577l0.65,0.588l0.625,0.6l0.613,0.61l0.587,0.62l0.575,0.631l0.563,0.643l0.537,0.652l0.513,0.663l0.5,0.672l0.475,0.684l0.45,0.692l0.437,0.703l0.425,0.712l0.388,0.723l0.375,0.731l0.35,0.741l0.337,0.75l0.3,0.76l0.288,0.769l0.262,0.777l0.25,0.786l0.213,0.797l0.187,0.804l0.175,0.812l0.15,0.821l0.125,0.83c2.675,20.19 -16.837,40.825 -45.15,49.619c14.688,-6.665 24.925,-21.426 24.925,-38.614c0,-23.202 -18.65,-42.025 -41.775,-42.367c0.05,-0.005 0.1,-0.015 0.15,-0.025c-0.262,0 -0.525,-0.01 -0.787,-0.01c-42.01,0 -76.062,18.985 -76.062,42.402c0,13.268 10.922,25.103 28.022,32.876c-8.081,-5.487 -13.403,-12.973 -14.584,-21.859c-2.685,-20.187 16.831,-40.82 45.149,-49.615c-14.688,6.665 -24.925,21.426 -24.925,38.598c0,23.218 18.65,42.046 41.775,42.383c-0.038,0.005 -0.088,0.015 -0.138,0.02c0.263,0 0.513,0.01 0.763,0.01c42.012,-0.001 76.075,-18.985 76.075,-42.413c0,-13.261 -10.938,-25.097 -28.038,-32.871Z" style="fill:none;"/><path id="path5082" d="M354.323,82.586l-41.999,-42.002l38.524,-38.515l-29.913,0l-23.562,23.559l-23.563,-23.559l-29.924,0l38.525,38.515l-42,42.002l29.913,0l27.049,-27.046l27.05,27.046l29.9,0" style="fill:#fff;fill-rule:nonzero;"/><path id="path5084" d="M354.323,82.586l-41.999,-42.002l38.524,-38.515l-29.913,0l-23.562,23.559l-23.563,-23.559l-29.924,0l38.525,38.515l-42,42.002l29.913,0l27.049,-27.046l27.05,27.046l29.9,0Z" style="fill:none;"/><path id="path5086" d="M0,2.069l75.033,0l0,16.489l-51.629,0l0,14.931l40.258,0l0,16.495l-40.258,0l0,16.05l53.124,0l0,16.488l-76.528,0l0,-80.453" style="fill:#fff;fill-rule:nonzero;"/><path id="path5088" d="M0,2.069l75.033,0l0,16.489l-51.629,0l0,14.931l40.258,0l0,16.495l-40.258,0l0,16.05l53.124,0l0,16.488l-76.528,0l0,-80.453Z" style="fill:none;"/></g></svg>`
|
|
30
|
+
const base64Logo = window.btoa(eoxLogo)
|
|
27
31
|
</script>
|
|
28
|
-
<style scoped lang='scss'>
|
|
29
|
-
.footer-text {
|
|
30
|
-
font-size: 0.8rem;
|
|
31
|
-
}
|
|
32
|
-
</style>
|
|
@@ -1,38 +1,14 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-app-bar color="primary">
|
|
3
|
-
<v-app-bar-title
|
|
4
|
-
<v-
|
|
5
|
-
<v-btn v-for="route in eodashConfig.routes" :key="route.to" variant="text" @click="navigateTo(route.to)">
|
|
6
|
-
{{ route.title }}
|
|
7
|
-
</v-btn>
|
|
8
|
-
</v-toolbar-items>
|
|
9
|
-
<v-img class="mx-12 logo" :src="eodashConfig.brand?.logo" />
|
|
3
|
+
<v-app-bar-title>{{ title }}</v-app-bar-title>
|
|
4
|
+
<v-img class="mx-12" style="max-width: 140px;" :src="eodash.brand?.logo" />
|
|
10
5
|
</v-app-bar>
|
|
11
6
|
</template>
|
|
12
7
|
<script setup>
|
|
13
|
-
import {
|
|
8
|
+
import { eodashKey } from '@/utils/keys';
|
|
14
9
|
import { inject } from 'vue';
|
|
15
|
-
import { useRouter } from 'vue-router';
|
|
16
10
|
|
|
17
|
-
const
|
|
11
|
+
const eodash = /** @type {import("@/types").Eodash} */(inject(eodashKey))
|
|
18
12
|
|
|
19
|
-
const title =
|
|
20
|
-
|
|
21
|
-
const { push } = useRouter()
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* @param {string} to
|
|
25
|
-
*/
|
|
26
|
-
const navigateTo = (to) => {
|
|
27
|
-
if (to.toLowerCase().startsWith('http')) {
|
|
28
|
-
window.open(to, '_self')
|
|
29
|
-
} else {
|
|
30
|
-
push(to)
|
|
31
|
-
}
|
|
32
|
-
}
|
|
13
|
+
const title = eodash.brand?.name
|
|
33
14
|
</script>
|
|
34
|
-
<style scoped lang='scss'>
|
|
35
|
-
.logo {
|
|
36
|
-
max-width: 140px;
|
|
37
|
-
}
|
|
38
|
-
</style>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-row class="d-flex justify-center align-center ">
|
|
3
|
+
<v-col class="flex-column justify-center align-center">
|
|
4
|
+
<Suspense>
|
|
5
|
+
<component v-if="loading.component" :is="loading.component" v-bind="loading.props"></component>
|
|
6
|
+
<div v-else class="text-center">
|
|
7
|
+
Loading...
|
|
8
|
+
</div>
|
|
9
|
+
<template #fallback>
|
|
10
|
+
<div class="text-center">
|
|
11
|
+
Loading...
|
|
12
|
+
</div>
|
|
13
|
+
</template>
|
|
14
|
+
</Suspense>
|
|
15
|
+
</v-col>
|
|
16
|
+
</v-row>
|
|
17
|
+
</template>
|
|
18
|
+
<script setup>
|
|
19
|
+
import { inject } from 'vue';
|
|
20
|
+
import { eodashKey } from '@/utils/keys';
|
|
21
|
+
import { useDefineWidgets } from '@/composables/DefineWidgets';
|
|
22
|
+
|
|
23
|
+
const eodash = /** @type {import("@/types").Eodash} */ (inject(eodashKey))
|
|
24
|
+
|
|
25
|
+
const [loading] = useDefineWidgets([eodash.template.loading])
|
|
26
|
+
|
|
27
|
+
</script>
|
|
@@ -1,78 +1,49 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<v-main class="overflow-
|
|
2
|
+
<v-main class="overflow-hidden" style="height: 91dvh;">
|
|
3
|
+
|
|
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="{
|
|
8
|
+
bottom: tabsHeightFromBtm, position: 'absolute', overflow: 'hidden',
|
|
9
|
+
width: '100%', left: 0, top: mainRect.top + 'px', zIndex: 1, background: 'rgb(var(--v-theme-surface))'
|
|
10
|
+
}">
|
|
11
|
+
<v-btn icon variant="text" style="height: 5%;position: relative;" @click="activeIdx = -1">✕</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>
|
|
15
|
+
|
|
16
|
+
<v-tabs ref="tabs" align-tabs="center" bg-color="surface"
|
|
17
|
+
:style="{ position: 'relative', bottom: (mainRect.bottom || 48) + 'px', zIndex: 10 }" show-arrows
|
|
18
|
+
v-model="activeIdx">
|
|
19
|
+
<v-tab v-for="(importedWidget, idx) in importedWidgets" :key="idx" :value="idx">
|
|
20
|
+
{{ importedWidget.value.title }}
|
|
21
|
+
</v-tab>
|
|
22
|
+
</v-tabs>
|
|
3
23
|
|
|
4
|
-
<component :is="bgWidget.component" v-bind="bgWidget.props"></component>
|
|
5
|
-
|
|
6
|
-
<v-row no-gutters class="d-flex justify-center align-end">
|
|
7
|
-
<v-col v-for="(importedWidget, idx) in importedWidgets" :key="idx" :cols="cols"
|
|
8
|
-
class="flex-column fill-height fill-width elevation-1 align-start ma-0 justify-center">
|
|
9
|
-
<span class="d-flex pa-2 justify-center ma-0 panel-header align-center fill-width"
|
|
10
|
-
@click="handleSelection(idx)">
|
|
11
|
-
{{ importedWidget.value.title }}
|
|
12
|
-
</span>
|
|
13
|
-
<div v-show="activeIdx === idx" class="overlay align-self-end overflow-auto pa-2">
|
|
14
|
-
<v-btn icon variant="text" class="close-btn" @click="activeIdx = -1">✕</v-btn>
|
|
15
|
-
<component :key="importedWidget.value.id" :is="importedWidget.value.component" v-show="activeIdx === idx"
|
|
16
|
-
v-bind="importedWidget.value.props" />
|
|
17
|
-
</div>
|
|
18
|
-
</v-col>
|
|
19
|
-
</v-row>
|
|
20
24
|
</v-main>
|
|
21
25
|
</template>
|
|
22
26
|
<script setup>
|
|
23
|
-
import {
|
|
24
|
-
import { inject } from 'vue';
|
|
27
|
+
import { eodashKey } from '@/utils/keys';
|
|
28
|
+
import { inject, ref, onMounted } from 'vue';
|
|
25
29
|
import { useDefineWidgets } from '@/composables/DefineWidgets'
|
|
26
|
-
import {
|
|
30
|
+
import { useLayout } from "vuetify"
|
|
27
31
|
|
|
28
|
-
const
|
|
32
|
+
const eodash = /** @type {import("@/types").Eodash} */(inject(eodashKey));
|
|
29
33
|
|
|
30
34
|
//import widgets
|
|
31
|
-
const widgetsConfig =
|
|
35
|
+
const widgetsConfig = eodash.template.widgets
|
|
32
36
|
const importedWidgets = useDefineWidgets(widgetsConfig)
|
|
33
|
-
const [bgWidget] = useDefineWidgets([
|
|
34
|
-
|
|
35
|
-
|
|
37
|
+
const [bgWidget] = useDefineWidgets([eodash.template?.background])
|
|
36
38
|
|
|
37
|
-
|
|
38
|
-
* number of flex columns
|
|
39
|
-
*/
|
|
40
|
-
const cols = importedWidgets.length / 12
|
|
39
|
+
const { mainRect } = useLayout()
|
|
41
40
|
|
|
42
|
-
/**
|
|
43
|
-
* index of the active tab
|
|
44
|
-
*/
|
|
45
41
|
const activeIdx = ref(-1)
|
|
46
42
|
|
|
47
|
-
/**
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
43
|
+
/** @type {import("vue").Ref<import("vuetify/components").VTabs|null>} */
|
|
44
|
+
const tabs = ref(null)
|
|
45
|
+
const tabsHeightFromBtm = ref('')
|
|
46
|
+
onMounted(() => {
|
|
47
|
+
tabsHeightFromBtm.value = mainRect.value.bottom + (/** @type {HTMLElement} */(tabs.value?.$el)?.clientHeight ?? 0) + "px"
|
|
48
|
+
})
|
|
53
49
|
</script>
|
|
54
|
-
<style scoped lang='scss'>
|
|
55
|
-
.panel-header {
|
|
56
|
-
height: auto;
|
|
57
|
-
margin: 0;
|
|
58
|
-
width: 100%;
|
|
59
|
-
position: relative;
|
|
60
|
-
bottom: 64px;
|
|
61
|
-
z-index: 10;
|
|
62
|
-
background: rgb(var(--v-theme-background));
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
.overlay {
|
|
66
|
-
position: absolute;
|
|
67
|
-
width: 100%;
|
|
68
|
-
left: 0;
|
|
69
|
-
top: 64px;
|
|
70
|
-
bottom: 64px;
|
|
71
|
-
z-index: 1;
|
|
72
|
-
background: rgb(var(--v-theme-background));
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
.close-btn {
|
|
76
|
-
justify-self: end;
|
|
77
|
-
}
|
|
78
|
-
</style>
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import store from "@/store";
|
|
2
|
+
import { eodashKey } from "@/utils/keys";
|
|
3
|
+
import { inject } from "vue";
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Sets user defined instance on runtime.
|
|
9
|
+
* Consumes `/@fs/config.js` and assign it to `eodash`
|
|
10
|
+
* @async
|
|
11
|
+
* @returns {Promise<import("@/types").Eodash>}
|
|
12
|
+
* @param {string | undefined} runtimeConfig
|
|
13
|
+
* @see {@linkplain '@/eodash.js'}
|
|
14
|
+
*/
|
|
15
|
+
export const useEodashRuntime = async (runtimeConfig) => {
|
|
16
|
+
const eodash = /** @type {import("@/types").Eodash} */(inject(eodashKey))
|
|
17
|
+
/**
|
|
18
|
+
* @param {import("@/types").Eodash} config
|
|
19
|
+
*/
|
|
20
|
+
const assignInstance = (config) => {
|
|
21
|
+
/** @type {(keyof import("@/types").Eodash)[]} */(Object.keys(eodash))
|
|
22
|
+
.forEach((key) => {
|
|
23
|
+
//@ts-expect-error
|
|
24
|
+
eodash[key] = config[key]
|
|
25
|
+
})
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (runtimeConfig) {
|
|
29
|
+
assignInstance((await import( /* @vite-ignore */new URL(runtimeConfig, import.meta.url).href)).default);
|
|
30
|
+
return eodash
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
assignInstance(
|
|
35
|
+
(await import( /* @vite-ignore */new URL('/config.js', import.meta.url).href)).default
|
|
36
|
+
)
|
|
37
|
+
} catch {
|
|
38
|
+
try {
|
|
39
|
+
assignInstance(await import("user:config").then(async m => await m['default']))
|
|
40
|
+
} catch {
|
|
41
|
+
console.error('no dashboard configuration defined')
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return eodash
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @param {((store:import("@/types").EodashStore)=> Promise<import("@/types").Eodash>)
|
|
49
|
+
* | import("@/types").Eodash} config
|
|
50
|
+
*/
|
|
51
|
+
export const createEodash = async (config) => {
|
|
52
|
+
if (config instanceof Function) {
|
|
53
|
+
return await config(store)
|
|
54
|
+
} else {
|
|
55
|
+
return config
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { defineAsyncComponent, reactive, shallowRef, watch } from 'vue'
|
|
2
2
|
import { useSTAcStore } from '@/store/stac'
|
|
3
3
|
import { storeToRefs } from 'pinia'
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
import Loading from '@/components/Loading.vue';
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* @typedef {{
|
|
@@ -17,17 +16,27 @@ import { storeToRefs } from 'pinia'
|
|
|
17
16
|
* @typedef {import('vue').ShallowRef<DefinedWidget>} ReactiveDefinedWidget
|
|
18
17
|
*/
|
|
19
18
|
|
|
19
|
+
const internalWidgets = (() => {
|
|
20
|
+
/**
|
|
21
|
+
* @type {Record<string,() => Promise<import('vue').Component>>}
|
|
22
|
+
*/
|
|
23
|
+
const importMap = {
|
|
24
|
+
...import.meta.glob('^/**/*.vue'),
|
|
25
|
+
...import.meta.glob("user:widgets/**/*.vue")
|
|
26
|
+
}
|
|
27
|
+
for (const key in importMap) {
|
|
28
|
+
const newKey = /** @type {string} */(key.split('/').at(-1)).slice(0, -4)
|
|
29
|
+
Object.defineProperty(importMap, newKey,
|
|
30
|
+
/** @type {PropertyDescriptor} */(Object.getOwnPropertyDescriptor(importMap, key)));
|
|
31
|
+
delete importMap[key];
|
|
32
|
+
}
|
|
33
|
+
return importMap
|
|
34
|
+
})();
|
|
20
35
|
|
|
21
36
|
|
|
22
|
-
/**
|
|
23
|
-
* import map to all vue components inside `widgets` directory.
|
|
24
|
-
* @type {Record<string,() => Promise<import('vue').Component>>}
|
|
25
|
-
*/
|
|
26
|
-
const internalWidgets = import.meta.glob('^/**/*.vue')
|
|
27
|
-
|
|
28
37
|
/**
|
|
29
38
|
* Composable that converts widgets Configurations to defined imported widgets
|
|
30
|
-
* @param { (import("@/types").
|
|
39
|
+
* @param { (import("@/types").Widget | import("@/types").BackgroundWidget | undefined)[] |
|
|
31
40
|
* import("@/types").WidgetsContainerProps['widgets'] | undefined} widgetConfigs
|
|
32
41
|
* @returns {Array<ReactiveDefinedWidget>}
|
|
33
42
|
**/
|
|
@@ -46,7 +55,6 @@ export const useDefineWidgets = (widgetConfigs) => {
|
|
|
46
55
|
props: {},
|
|
47
56
|
title: '',
|
|
48
57
|
id: Symbol(),
|
|
49
|
-
no: '4'
|
|
50
58
|
})
|
|
51
59
|
|
|
52
60
|
if ('defineWidget' in (config ?? {})) {
|
|
@@ -84,17 +92,19 @@ const getWidgetDefinition = (config) => {
|
|
|
84
92
|
switch (config?.type) {
|
|
85
93
|
case 'internal':
|
|
86
94
|
importedWidget.component = defineAsyncComponent({
|
|
87
|
-
loader: internalWidgets[
|
|
88
|
-
suspensible: true
|
|
95
|
+
loader: internalWidgets[/** @type {import("@/types").InternalComponentWidget} **/(config)?.widget.name],
|
|
96
|
+
suspensible: true,
|
|
97
|
+
loadingComponent: Loading
|
|
89
98
|
})
|
|
90
|
-
importedWidget.props = reactive(/** @type {import("@/types").
|
|
99
|
+
importedWidget.props = reactive(/** @type {import("@/types").InternalComponentWidget} **/(config)?.widget.properties ?? {})
|
|
91
100
|
|
|
92
101
|
break;
|
|
93
102
|
|
|
94
103
|
case 'web-component':
|
|
95
104
|
importedWidget.component = defineAsyncComponent({
|
|
96
105
|
loader: () => import('@/components/DynamicWebComponent.vue'),
|
|
97
|
-
suspensible: true
|
|
106
|
+
suspensible: true,
|
|
107
|
+
loadingComponent: Loading
|
|
98
108
|
})
|
|
99
109
|
importedWidget.props = reactive(config.widget)
|
|
100
110
|
|
|
@@ -102,7 +112,8 @@ const getWidgetDefinition = (config) => {
|
|
|
102
112
|
case 'iframe':
|
|
103
113
|
importedWidget.component = defineAsyncComponent({
|
|
104
114
|
loader: () => import('@/components/IframeWrapper.vue'),
|
|
105
|
-
suspensible: true
|
|
115
|
+
suspensible: true,
|
|
116
|
+
loadingComponent: Loading
|
|
106
117
|
})
|
|
107
118
|
importedWidget.props = reactive(config.widget)
|
|
108
119
|
break;
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
// functions of this folder can only be consumed inside setup stores,
|
|
2
2
|
// setup functions or vue composition api components
|
|
3
3
|
|
|
4
|
-
import { reactive } from "vue"
|
|
5
|
-
import { currentUrl } from "@/store/States"
|
|
6
|
-
import
|
|
7
|
-
import { useTheme } from "vuetify/lib/framework.mjs"
|
|
8
|
-
|
|
4
|
+
import { reactive } from "vue";
|
|
5
|
+
import { currentUrl, indicator, mapPosition } from "@/store/States";
|
|
6
|
+
import eodash from "@/eodash";
|
|
7
|
+
import { useTheme } from "vuetify/lib/framework.mjs";
|
|
8
|
+
import { onMounted, watch } from "vue";
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Creates an absolute URL from a relative link and assignes it to `currentUrl`
|
|
12
12
|
* @param {string} [rel = '']
|
|
13
|
-
* @param {string} [base =
|
|
13
|
+
* @param {string} [base = eodash.stacEndpoint] - base URL, default value is the root stac catalog
|
|
14
14
|
* @returns {import('vue').Ref<string>} - returns `currentUrl`
|
|
15
15
|
* @see {@link '@/store/States.js'}
|
|
16
16
|
*/
|
|
17
|
-
export const useAbsoluteUrl = (rel =
|
|
18
|
-
if (!rel || rel.includes(
|
|
19
|
-
currentUrl.value = base
|
|
20
|
-
return currentUrl
|
|
17
|
+
export const useAbsoluteUrl = (rel = "", base = eodash.stacEndpoint) => {
|
|
18
|
+
if (!rel || rel.includes("http")) {
|
|
19
|
+
currentUrl.value = base;
|
|
20
|
+
return currentUrl;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
const st = base.split("/");
|
|
@@ -25,102 +25,122 @@ export const useAbsoluteUrl = (rel = '', base = eodashConfig.stacEndpoint) => {
|
|
|
25
25
|
st.pop();
|
|
26
26
|
|
|
27
27
|
for (let i = 0; i < arr.length; i++) {
|
|
28
|
-
if (arr[i] == ".")
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
st.pop();
|
|
32
|
-
else
|
|
33
|
-
st.push(arr[i]);
|
|
28
|
+
if (arr[i] == ".") continue;
|
|
29
|
+
if (arr[i] == "..") st.pop();
|
|
30
|
+
else st.push(arr[i]);
|
|
34
31
|
}
|
|
35
32
|
|
|
36
33
|
currentUrl.value = st.join("/");
|
|
37
|
-
return currentUrl
|
|
38
|
-
}
|
|
34
|
+
return currentUrl;
|
|
35
|
+
};
|
|
39
36
|
|
|
40
37
|
/**
|
|
41
38
|
* Adds slide in and out functionality to Elements
|
|
42
39
|
* @param {import('vue').Ref<HTMLElement[]|null>} elements - elements to add the functionality to
|
|
43
|
-
* @param {import("@/types").
|
|
40
|
+
* @param {import("@/types").Widget[]} configs
|
|
44
41
|
*/
|
|
45
42
|
export const useSlidePanels = (elements, configs) => {
|
|
46
|
-
|
|
47
43
|
/**
|
|
48
44
|
* Sliding direction
|
|
49
45
|
*/
|
|
50
|
-
const slideDirs = configs.map(m =>
|
|
46
|
+
const slideDirs = configs.map((m) =>
|
|
47
|
+
m.layout.x == 0
|
|
48
|
+
? "left"
|
|
49
|
+
: m.layout.x == 12 - m.layout.w
|
|
50
|
+
? "right"
|
|
51
|
+
: m.layout.y < 6
|
|
52
|
+
? "up"
|
|
53
|
+
: "down"
|
|
54
|
+
);
|
|
51
55
|
|
|
52
56
|
/**
|
|
53
57
|
* Array of sliding button's style and icons
|
|
54
58
|
*/
|
|
55
|
-
const slideBtns = slideDirs.map(
|
|
56
|
-
const btn = reactive({
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
const slideBtns = slideDirs.map((dir, idx) => {
|
|
60
|
+
const btn = reactive({
|
|
61
|
+
style: {},
|
|
62
|
+
icon: { in: "", out: "" },
|
|
63
|
+
active: false,
|
|
64
|
+
enabled: true,
|
|
65
|
+
});
|
|
66
|
+
if (configs[idx].slidable === false) {
|
|
67
|
+
btn.enabled = false;
|
|
68
|
+
return btn;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
switch (dir) {
|
|
72
|
+
case "left":
|
|
73
|
+
btn.style = { top: "50%", right: "-11%" };
|
|
74
|
+
btn.icon.in = "mdi-chevron-double-right";
|
|
75
|
+
btn.icon.out = "mdi-chevron-double-left";
|
|
62
76
|
|
|
63
77
|
break;
|
|
64
|
-
case
|
|
65
|
-
btn.style = {
|
|
66
|
-
btn.icon.in =
|
|
67
|
-
btn.icon.out =
|
|
78
|
+
case "right":
|
|
79
|
+
btn.style = { top: "50%", left: "-11%" };
|
|
80
|
+
btn.icon.in = "mdi-chevron-double-left";
|
|
81
|
+
btn.icon.out = "mdi-chevron-double-right";
|
|
68
82
|
|
|
69
83
|
break;
|
|
70
|
-
case
|
|
71
|
-
btn.style = {
|
|
72
|
-
btn.icon.in =
|
|
73
|
-
btn.icon.out =
|
|
84
|
+
case "up":
|
|
85
|
+
btn.style = { right: "50%", bottom: "-17%" };
|
|
86
|
+
btn.icon.in = "mdi-chevron-double-down";
|
|
87
|
+
btn.icon.out = "mdi-chevron-double-up";
|
|
74
88
|
|
|
75
89
|
break;
|
|
76
|
-
case
|
|
77
|
-
btn.style = {
|
|
78
|
-
btn.icon.in =
|
|
79
|
-
btn.icon.out =
|
|
90
|
+
case "down":
|
|
91
|
+
btn.style = { right: "50%", top: "-17%" };
|
|
92
|
+
btn.icon.in = "mdi-chevron-double-up";
|
|
93
|
+
btn.icon.out = "mdi-chevron-double-down";
|
|
80
94
|
break;
|
|
81
95
|
|
|
82
96
|
default:
|
|
83
|
-
console.error(
|
|
97
|
+
console.error("sliding error");
|
|
84
98
|
break;
|
|
85
99
|
}
|
|
86
|
-
return btn
|
|
87
|
-
})
|
|
100
|
+
return btn;
|
|
101
|
+
});
|
|
88
102
|
|
|
89
103
|
/**
|
|
90
104
|
* Transforms the element's position based on the direction
|
|
91
105
|
* @param {number} idx - index of the pressed element
|
|
92
106
|
*/
|
|
93
107
|
const slideInOut = (idx) => {
|
|
94
|
-
const parentStyle = /** @type {CSSStyleDeclaration} */ (
|
|
108
|
+
const parentStyle = /** @type {CSSStyleDeclaration} */ (
|
|
109
|
+
elements.value?.[idx].style
|
|
110
|
+
);
|
|
95
111
|
if (parentStyle?.transform.length) {
|
|
96
|
-
slideBtns[idx].active = false
|
|
112
|
+
slideBtns[idx].active = false;
|
|
97
113
|
parentStyle.transform = "";
|
|
98
114
|
} else {
|
|
99
|
-
slideBtns[idx].active = true
|
|
100
|
-
parentStyle.transition = "transform 0.3s ease-in-out"
|
|
115
|
+
slideBtns[idx].active = true;
|
|
116
|
+
parentStyle.transition = "transform 0.3s ease-in-out";
|
|
101
117
|
switch (slideDirs[idx]) {
|
|
102
|
-
case
|
|
103
|
-
parentStyle.transform = "translateX(-100%)"
|
|
118
|
+
case "left":
|
|
119
|
+
parentStyle.transform = "translateX(-100%)";
|
|
104
120
|
break;
|
|
105
|
-
case
|
|
106
|
-
parentStyle.transform = "translateX(100%)"
|
|
121
|
+
case "right":
|
|
122
|
+
parentStyle.transform = "translateX(100%)";
|
|
107
123
|
break;
|
|
108
|
-
case
|
|
109
|
-
parentStyle.transform = `translateY(-${(
|
|
124
|
+
case "up":
|
|
125
|
+
parentStyle.transform = `translateY(-${(configs[idx].layout.y / configs[idx].layout.h) * 100 + 100
|
|
126
|
+
}%)`;
|
|
110
127
|
break;
|
|
111
|
-
case
|
|
112
|
-
parentStyle.transform = `translateY(${(
|
|
128
|
+
case "down":
|
|
129
|
+
parentStyle.transform = `translateY(${(Math.max(0, 12 - configs[idx].layout.y - configs[idx].layout.h) /
|
|
130
|
+
configs[idx].layout.h) *
|
|
131
|
+
100 +
|
|
132
|
+
100
|
|
133
|
+
}%)`;
|
|
113
134
|
break;
|
|
114
135
|
|
|
115
136
|
default:
|
|
116
|
-
console.error(
|
|
137
|
+
console.error("sliding error");
|
|
117
138
|
break;
|
|
118
139
|
}
|
|
119
140
|
}
|
|
120
|
-
}
|
|
121
|
-
return { slideBtns, slideInOut }
|
|
122
|
-
}
|
|
123
|
-
|
|
141
|
+
};
|
|
142
|
+
return { slideBtns, slideInOut };
|
|
143
|
+
};
|
|
124
144
|
|
|
125
145
|
/**
|
|
126
146
|
* Updates an existing Vuetify theme.
|
|
@@ -132,16 +152,68 @@ export const useSlidePanels = (elements, configs) => {
|
|
|
132
152
|
export const useUpdateTheme = (themeName, themeDefinition = {}) => {
|
|
133
153
|
const theme = useTheme();
|
|
134
154
|
|
|
135
|
-
/** @type {Array<keyof import('vuetify').ThemeDefinition>} */(
|
|
136
|
-
|
|
137
|
-
|
|
155
|
+
/** @type {Array<keyof import('vuetify').ThemeDefinition>} */ (
|
|
156
|
+
Object.keys(themeDefinition)
|
|
157
|
+
).forEach((key) => {
|
|
158
|
+
if (key === "dark") {
|
|
159
|
+
theme.themes.value[themeName][key] = /** @type {Boolean} */ (
|
|
160
|
+
themeDefinition[key]
|
|
161
|
+
);
|
|
138
162
|
} else {
|
|
139
163
|
//@ts-expect-error
|
|
140
164
|
theme.themes.value[themeName][key] = {
|
|
141
165
|
...theme.themes.value[themeName][key],
|
|
142
|
-
...themeDefinition[key]
|
|
166
|
+
...themeDefinition[key],
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
return theme;
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Composable that syncs store and URLSearchParameters
|
|
175
|
+
*/
|
|
176
|
+
|
|
177
|
+
export const useURLSearchParametersSync = () => {
|
|
178
|
+
onMounted(() => {
|
|
179
|
+
// Analyze currently set url params when first loaded and set them in the store
|
|
180
|
+
if ('URLSearchParams' in window) {
|
|
181
|
+
const searchParams = new URLSearchParams(window.location.search);
|
|
182
|
+
let x, y, z;
|
|
183
|
+
searchParams.forEach((value, key) => {
|
|
184
|
+
if (key === "indicator") {
|
|
185
|
+
indicator.value = value;
|
|
186
|
+
}
|
|
187
|
+
if (key === "x") {
|
|
188
|
+
x = value;
|
|
189
|
+
}
|
|
190
|
+
if (key === "y") {
|
|
191
|
+
y = value;
|
|
192
|
+
}
|
|
193
|
+
if (key === "z") {
|
|
194
|
+
z = value;
|
|
195
|
+
}
|
|
196
|
+
})
|
|
197
|
+
if (x !== undefined && y !== undefined && z !== undefined) {
|
|
198
|
+
mapPosition.value = [x, y, z];
|
|
143
199
|
}
|
|
144
200
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
201
|
+
watch(
|
|
202
|
+
[indicator, mapPosition],
|
|
203
|
+
([updatedIndicator, updatedMapPosition]) => {
|
|
204
|
+
if ('URLSearchParams' in window) {
|
|
205
|
+
const searchParams = new URLSearchParams(window.location.search);
|
|
206
|
+
if (updatedIndicator !== "") {
|
|
207
|
+
searchParams.set("indicator", updatedIndicator);
|
|
208
|
+
}
|
|
209
|
+
if (updatedMapPosition && updatedMapPosition.length === 3) {
|
|
210
|
+
searchParams.set("x", updatedMapPosition[0]?.toFixed(4) ?? '');
|
|
211
|
+
searchParams.set("y", updatedMapPosition[1]?.toFixed(4) ?? '');
|
|
212
|
+
searchParams.set("z", updatedMapPosition[2]?.toFixed(4) ?? '');
|
|
213
|
+
}
|
|
214
|
+
const newRelativePathQuery = window.location.pathname + '?' + searchParams.toString();
|
|
215
|
+
history.pushState(null, '', newRelativePathQuery);
|
|
216
|
+
}
|
|
217
|
+
})
|
|
218
|
+
});
|
|
219
|
+
};
|