@eodash/eodash 5.0.0-alpha.1 → 5.0.0-alpha.1.11
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/README.md +1 -1
- package/bin/cli.js +20 -23
- package/bin/serverConfig.js +20 -11
- package/bin/utils.js +81 -9
- package/core/components/DashboardLayout.vue +6 -6
- package/core/components/DynamicWebComponent.vue +3 -3
- package/core/components/Footer.vue +5 -4
- package/core/components/Header.vue +6 -6
- package/core/components/MobileLayout.vue +6 -7
- package/core/composables/DefineEodash.js +45 -0
- package/core/composables/DefineWidgets.js +7 -7
- package/core/composables/index.js +2 -2
- package/core/{eodashConfig.js → eodash.js} +5 -5
- package/core/main.js +2 -2
- package/core/plugins/index.js +3 -3
- package/core/plugins/router.js +1 -1
- package/core/store/Keys.js +2 -2
- package/core/store/index.js +5 -11
- package/core/store/stac.js +4 -4
- package/core/types.d.ts +280 -264
- package/core/views/Dashboard.vue +3 -2
- package/core/vite-env.d.ts +3 -21
- package/package.json +6 -6
- package/widgets/WidgetsContainer.vue +1 -1
- package/bin/update.js +0 -19
- package/core/composables/DefineConfig.js +0 -44
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ npm run preview
|
|
|
20
20
|
.
|
|
21
21
|
├── core # Main source code that hosts the microfrontends and renders the dashboard
|
|
22
22
|
├── docs # Documentation files
|
|
23
|
-
├── widgets #
|
|
23
|
+
├── widgets # Vue componenets as internal widgets.
|
|
24
24
|
├── public # Statically served directory
|
|
25
25
|
└── README.md
|
|
26
26
|
|
package/bin/cli.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { build, createServer, preview } from "vite"
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
rootPath, appPath, buildTargetPath,
|
|
6
|
+
userConfig, runtimeConfigPath,
|
|
7
|
+
} from "./utils.js";
|
|
5
8
|
import { writeFile, rm, cp } from "fs/promises";
|
|
6
|
-
import { update } from "./update.js";
|
|
7
9
|
import { indexHtml, serverConfig } from "./serverConfig.js";
|
|
8
10
|
import path from "path";
|
|
9
11
|
import { existsSync } from "fs";
|
|
10
12
|
|
|
11
13
|
|
|
12
|
-
|
|
13
14
|
export const createDevServer = async () => {
|
|
14
15
|
const server = await createServer(await serverConfig({ mode: 'development', command: 'serve' }))
|
|
15
16
|
await server.listen()
|
|
@@ -20,38 +21,34 @@ export const createDevServer = async () => {
|
|
|
20
21
|
export const buildApp = async () => {
|
|
21
22
|
const htmlPath = path.join(appPath, '/index.html')
|
|
22
23
|
await writeFile(htmlPath, indexHtml).then(async () => {
|
|
23
|
-
await
|
|
24
|
-
await build(
|
|
24
|
+
const config = await serverConfig({ mode: 'production', command: 'build' });
|
|
25
|
+
await build(config)
|
|
26
|
+
|
|
27
|
+
if (existsSync(runtimeConfigPath)) {
|
|
28
|
+
await cp(runtimeConfigPath, path.join(buildTargetPath, 'config.js'),
|
|
29
|
+
{ recursive: true }).catch((e) => {
|
|
30
|
+
console.error(e)
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
|
|
25
34
|
await rm(htmlPath).catch(() => {
|
|
26
35
|
console.error('failed to remove index.html')
|
|
27
36
|
})
|
|
28
|
-
const appPublicPath = path.join(appPath, './public')
|
|
29
|
-
if (appPath.includes('node_modules') && existsSync(appPublicPath)) {
|
|
30
|
-
await rm(appPublicPath, { recursive: true }).catch((e) => {
|
|
31
|
-
console.error(e)
|
|
32
|
-
})
|
|
33
|
-
}
|
|
34
37
|
})
|
|
35
|
-
|
|
36
|
-
if (appPath.includes('node_modules')) {
|
|
37
|
-
await cp(appPath + 'dist', buildTargetPath, { recursive: true }).then(() => {
|
|
38
|
-
console.info('dashboard built successfully')
|
|
39
|
-
}).catch((e) => {
|
|
40
|
-
console.error(e)
|
|
41
|
-
})
|
|
42
|
-
}
|
|
43
38
|
}
|
|
44
39
|
|
|
45
40
|
|
|
46
41
|
export async function previewApp() {
|
|
47
42
|
const previewServer = await preview({
|
|
48
|
-
root:
|
|
43
|
+
root: rootPath,
|
|
44
|
+
base: userConfig.base ?? '',
|
|
49
45
|
preview: {
|
|
50
|
-
port: 8080,
|
|
51
|
-
open:
|
|
46
|
+
port: userConfig.port ?? 8080,
|
|
47
|
+
open: userConfig.open,
|
|
48
|
+
host: userConfig.host
|
|
52
49
|
},
|
|
53
50
|
build: {
|
|
54
|
-
outDir: buildTargetPath
|
|
51
|
+
outDir: buildTargetPath,
|
|
55
52
|
}
|
|
56
53
|
})
|
|
57
54
|
previewServer.printUrls()
|
package/bin/serverConfig.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
3
|
import vue from '@vitejs/plugin-vue';
|
|
6
4
|
import vuetify, { transformAssetUrls } from 'vite-plugin-vuetify';
|
|
7
5
|
import virtual, { updateVirtualModule } from 'vite-plugin-virtual'
|
|
8
6
|
import { fileURLToPath, URL } from 'url';
|
|
9
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
runtimeConfigPath,
|
|
9
|
+
appPath, entryPath,
|
|
10
|
+
cachePath, publicPath, userConfig,
|
|
11
|
+
buildTargetPath
|
|
12
|
+
} from "./utils.js";
|
|
10
13
|
import { readFile } from "fs/promises";
|
|
11
14
|
import { defineConfig, searchForWorkspaceRoot } from "vite"
|
|
12
15
|
import { getUserModules } from './utils.js';
|
|
@@ -36,8 +39,8 @@ export const indexHtml = `
|
|
|
36
39
|
let virtualPlugin = null;
|
|
37
40
|
export const serverConfig = /** @type {import('vite').UserConfigFnPromise}*/(defineConfig(async ({ mode, command }) => {
|
|
38
41
|
return {
|
|
39
|
-
base: '',
|
|
40
|
-
cacheDir:
|
|
42
|
+
base: userConfig.base ?? '',
|
|
43
|
+
cacheDir: cachePath,
|
|
41
44
|
plugins: [
|
|
42
45
|
vue({
|
|
43
46
|
template: {
|
|
@@ -66,20 +69,26 @@ export const serverConfig = /** @type {import('vite').UserConfigFnPromise}*/(def
|
|
|
66
69
|
extensions: ['.js', '.json', '.jsx', '.mjs', '.ts', '.tsx', '.vue'],
|
|
67
70
|
},
|
|
68
71
|
server: {
|
|
69
|
-
|
|
72
|
+
warmup: {
|
|
73
|
+
clientFiles: [path.join(appPath, "core/**")]
|
|
74
|
+
},
|
|
75
|
+
port: userConfig.port ?? 3000,
|
|
76
|
+
open: userConfig.open,
|
|
70
77
|
fs: {
|
|
71
78
|
allow: [searchForWorkspaceRoot(process.cwd())]
|
|
72
79
|
},
|
|
73
|
-
|
|
80
|
+
host: userConfig.host
|
|
74
81
|
},
|
|
75
82
|
root: fileURLToPath(new URL('..', import.meta.url)),
|
|
76
83
|
optimizeDeps: mode === "development" ? {
|
|
77
84
|
include: ["webfontloader", "vuetify", "vue", "pinia"],
|
|
78
85
|
noDiscovery: true,
|
|
79
86
|
} : {},
|
|
80
|
-
|
|
87
|
+
/** @type {string|false} */
|
|
88
|
+
publicDir: userConfig.publicDir === false ? false : publicPath,
|
|
81
89
|
build: {
|
|
82
|
-
outDir:
|
|
90
|
+
outDir: buildTargetPath,
|
|
91
|
+
emptyOutDir: true,
|
|
83
92
|
rollupOptions: {
|
|
84
93
|
input: fileURLToPath(new URL(command === 'build' ? '../index.html' : '../core/main.js', import.meta.url)),
|
|
85
94
|
},
|
|
@@ -94,12 +103,12 @@ export const serverConfig = /** @type {import('vite').UserConfigFnPromise}*/(def
|
|
|
94
103
|
* @type {import("vite").ServerHook}
|
|
95
104
|
*/
|
|
96
105
|
async function configureServer(server) {
|
|
97
|
-
server.watcher.add([
|
|
106
|
+
server.watcher.add([entryPath, runtimeConfigPath])
|
|
98
107
|
|
|
99
108
|
server.watcher.on('change', async (path) => {
|
|
100
109
|
if (path == runtimeConfigPath) {
|
|
101
110
|
server.hot.send('reload')
|
|
102
|
-
} else if (
|
|
111
|
+
} else if (path === entryPath) {
|
|
103
112
|
updateVirtualModule(virtualPlugin, 'user:config',
|
|
104
113
|
await getUserModules().then(modules => modules['user:config']))
|
|
105
114
|
}
|
package/bin/utils.js
CHANGED
|
@@ -1,24 +1,96 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { readFile } from 'fs/promises';
|
|
4
|
-
import { existsSync } from 'fs';
|
|
4
|
+
import { existsSync, readFileSync } from 'fs';
|
|
5
5
|
import path from 'path';
|
|
6
6
|
import { fileURLToPath } from 'url';
|
|
7
|
+
import { searchForWorkspaceRoot } from 'vite';
|
|
8
|
+
import { Command } from 'commander';
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export const execPath = fileURLToPath(new URL(process.cwd(), import.meta.url));
|
|
11
|
-
export const dotEodashPath = path.join(execPath, "/.eodash");
|
|
12
|
-
export const runtimeConfigPath = path.join(dotEodashPath, "./config.runtime.js");
|
|
13
|
-
export const compiletimeConfigPath = path.join(dotEodashPath, "/config.js");
|
|
14
|
-
export const buildTargetPath = path.join(dotEodashPath, '/dist')
|
|
10
|
+
export const rootPath = searchForWorkspaceRoot(process.cwd());
|
|
11
|
+
const cli = new Command('eodash')
|
|
15
12
|
|
|
13
|
+
const pkg = JSON.parse(
|
|
14
|
+
readFileSync(
|
|
15
|
+
path.join(rootPath, 'package.json')
|
|
16
|
+
, 'utf-8')
|
|
17
|
+
);
|
|
16
18
|
|
|
19
|
+
/**
|
|
20
|
+
* CLI flags object
|
|
21
|
+
* @typedef {Object} Options
|
|
22
|
+
* @property {string | false} publicDir
|
|
23
|
+
* @property {string} outDir
|
|
24
|
+
* @property {string} entryPoint
|
|
25
|
+
* @property {string} cacheDir
|
|
26
|
+
* @property {string} runtime
|
|
27
|
+
* @property {string} base
|
|
28
|
+
* @property {string | number} port
|
|
29
|
+
* @property {boolean} open
|
|
30
|
+
* @property {boolean | string} host
|
|
31
|
+
* @property {string} config
|
|
32
|
+
*/
|
|
33
|
+
cli.version(pkg.version, '-v, --version', 'output the current version')
|
|
34
|
+
.option('--publicDir <path>', 'path to statically served assets folder')
|
|
35
|
+
.option('--no-publicDir', 'stop serving static assets')
|
|
36
|
+
.option('--outDir <path>', 'minified output folder')
|
|
37
|
+
.option('-e, --entryPoint <path>', 'file exporting `defineConfig`')
|
|
38
|
+
.option('--cacheDir <path>', 'cache folder')
|
|
39
|
+
.option('-r, --runtime <path>', 'file exporting eodash client runtime config')
|
|
40
|
+
.option('-b, --base <path>', 'base public path')
|
|
41
|
+
.option('-p, --port <port>', 'serving port')
|
|
42
|
+
.option('-o, --open', 'open default browser when the server starts')
|
|
43
|
+
.option('-c, --config <path>', 'path to eodash server and build configuration file')
|
|
44
|
+
.option('--host [IP address]', 'specify which IP addresses the server should listen on')
|
|
45
|
+
.option('--no-host', 'do not expose server to the network')
|
|
46
|
+
.parse(process.argv)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
export const userConfig = await getUserConfig(cli.opts(), process.argv?.[2])
|
|
50
|
+
|
|
51
|
+
export const appPath = fileURLToPath(new URL("..", import.meta.url)),
|
|
52
|
+
publicPath = userConfig.publicDir ? path.resolve(rootPath, userConfig.publicDir) : path.join(rootPath, './public'),
|
|
53
|
+
srcPath = path.join(rootPath, "/src"),
|
|
54
|
+
runtimeConfigPath = userConfig.runtime ? path.resolve(rootPath, userConfig.runtime) : path.join(srcPath, "./runtime.js"),
|
|
55
|
+
entryPath = userConfig.entryPoint ? path.resolve(rootPath, userConfig.entryPoint) : path.join(srcPath, "/main.js"),
|
|
56
|
+
dotEodashPath = path.join(rootPath, "/.eodash"),
|
|
57
|
+
buildTargetPath = userConfig.outDir ? path.resolve(rootPath, userConfig.outDir) : path.join(dotEodashPath, '/dist'),
|
|
58
|
+
cachePath = userConfig.cacheDir ? path.resolve(rootPath, userConfig.cacheDir) : path.join(dotEodashPath, 'cache');
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @param {Options} options
|
|
63
|
+
* @param {string | undefined} command
|
|
64
|
+
*/
|
|
65
|
+
async function getUserConfig(options, command) {
|
|
66
|
+
let eodashCLiConfigFile = options.config ? path.resolve(rootPath, options.config) : path.join(rootPath, 'eodash.config.js');
|
|
67
|
+
/** @type {import("../core/types").EodashConfig} */
|
|
68
|
+
let config = {};
|
|
69
|
+
if (existsSync(eodashCLiConfigFile)) {
|
|
70
|
+
config = await import(eodashCLiConfigFile).then(config => config.default).catch(err => {
|
|
71
|
+
console.error(err);
|
|
72
|
+
})
|
|
73
|
+
} else {
|
|
74
|
+
eodashCLiConfigFile = null
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
base: options.base ?? config?.base,
|
|
79
|
+
port: Number(options.port ?? config?.[command]?.port),
|
|
80
|
+
host: options.host ?? config?.[/**@type {"dev"|"preview"} */(command)]?.host,
|
|
81
|
+
open: options.open ?? config?.[/**@type {"dev"|"preview"} */(command)]?.open,
|
|
82
|
+
cacheDir: options.cacheDir ?? config?.cacheDir,
|
|
83
|
+
entryPoint: options.entryPoint ?? config?.entryPoint,
|
|
84
|
+
outDir: options.outDir ?? config?.outDir,
|
|
85
|
+
publicDir: options.publicDir ?? config?.publicDir,
|
|
86
|
+
runtime: options.runtime ?? config?.runtime
|
|
87
|
+
}
|
|
88
|
+
}
|
|
17
89
|
|
|
18
90
|
export const getUserModules = async () => {
|
|
19
91
|
/** @type {Record<string,string>} */
|
|
20
92
|
let userModules = {}
|
|
21
|
-
const indexJs = await readFile(
|
|
93
|
+
const indexJs = await readFile(entryPath, 'utf-8').catch(() => {
|
|
22
94
|
if (!existsSync(runtimeConfigPath)) {
|
|
23
95
|
console.error(new Error("no eodash configuration found"))
|
|
24
96
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-main>
|
|
3
|
-
<eox-layout :gap="
|
|
3
|
+
<eox-layout :gap="eodash.template.gap ?? 2">
|
|
4
4
|
<eox-layout-item class="bg-widget" x="0" y="0" h="12" w="12">
|
|
5
5
|
<component :is="bgWidget.component" v-bind="bgWidget.props" />
|
|
6
6
|
</eox-layout-item>
|
|
@@ -18,19 +18,19 @@
|
|
|
18
18
|
</eox-layout>
|
|
19
19
|
</v-main>
|
|
20
20
|
</template>
|
|
21
|
-
<script setup
|
|
22
|
-
import {
|
|
21
|
+
<script setup>
|
|
22
|
+
import { eodashKey } from '@/store/Keys';
|
|
23
23
|
import { inject } from 'vue';
|
|
24
24
|
import { useDefineWidgets } from '@/composables/DefineWidgets'
|
|
25
25
|
import { useSlidePanels } from '@/composables'
|
|
26
26
|
import { ref } from 'vue';
|
|
27
27
|
import '@eox/layout'
|
|
28
28
|
|
|
29
|
-
const
|
|
29
|
+
const eodash = /** @type {import("@/types").Eodash} */ (inject(eodashKey))
|
|
30
30
|
|
|
31
|
-
const [bgWidget] = useDefineWidgets([
|
|
31
|
+
const [bgWidget] = useDefineWidgets([eodash.template?.background])
|
|
32
32
|
|
|
33
|
-
const widgetsConfig =
|
|
33
|
+
const widgetsConfig = eodash.template?.widgets
|
|
34
34
|
|
|
35
35
|
const importedWidgets = useDefineWidgets(widgetsConfig)
|
|
36
36
|
/**
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
import { ref } from 'vue';
|
|
14
14
|
import { useRouter } from 'vue-router';
|
|
15
15
|
|
|
16
|
-
const props = /** @type {WebComponentProps} */(defineProps({
|
|
16
|
+
const props = /** @type {import("@/types").WebComponentProps} */(defineProps({
|
|
17
17
|
link: {
|
|
18
18
|
type: [String, Function],
|
|
19
19
|
required: true
|
|
@@ -37,9 +37,9 @@ const props = /** @type {WebComponentProps} */(defineProps({
|
|
|
37
37
|
const getWebComponent = async () => typeof props.link === 'string' ?
|
|
38
38
|
await import( /* @vite-ignore */props.link) : await props.link()
|
|
39
39
|
|
|
40
|
-
const imported = await getWebComponent().catch(e => {
|
|
40
|
+
const imported = !customElements.get(props.tagName) ? await getWebComponent().catch(e => {
|
|
41
41
|
console.error(e)
|
|
42
|
-
})
|
|
42
|
+
}) : null
|
|
43
43
|
|
|
44
44
|
const defined = customElements.get(props.tagName)
|
|
45
45
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<v-footer ref="footer" :height="mdAndDown ? '48px' : 'auto'" color="secondary" app
|
|
2
|
+
<v-footer ref="footer" :height="mdAndDown ? '48px' : 'auto'" color="secondary" app
|
|
3
|
+
class="d-flex justify-space-between">
|
|
3
4
|
<p class="pt-0 footer-text">
|
|
4
5
|
Phasellus feugiat arcu sapien, et iaculis ipsum elementum sit amet. Mauris cursus commodo interdum.
|
|
5
6
|
</p>
|
|
@@ -9,7 +10,7 @@
|
|
|
9
10
|
</v-footer>
|
|
10
11
|
</template>
|
|
11
12
|
<script setup>
|
|
12
|
-
import {
|
|
13
|
+
import { eodashKey } from '@/store/Keys';
|
|
13
14
|
import { ref } from 'vue';
|
|
14
15
|
import { inject } from 'vue';
|
|
15
16
|
import { useDisplay } from 'vuetify/lib/framework.mjs';
|
|
@@ -19,9 +20,9 @@ import { useDisplay } from 'vuetify/lib/framework.mjs';
|
|
|
19
20
|
* @type {import('vue').Ref<import('vuetify/lib/components/index.mjs').VFooter | null>}
|
|
20
21
|
*/
|
|
21
22
|
const footer = ref(null)
|
|
22
|
-
const
|
|
23
|
+
const eodash = /** @type {import("@/types").Eodash} */(inject(eodashKey))
|
|
23
24
|
|
|
24
|
-
const title =
|
|
25
|
+
const title = eodash.brand?.shortName ?? eodash.brand?.name
|
|
25
26
|
const { mdAndDown } = useDisplay()
|
|
26
27
|
</script>
|
|
27
28
|
<style scoped lang='scss'>
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-app-bar color="primary">
|
|
3
3
|
<v-app-bar-title class="cursor-pointer">{{ title }}</v-app-bar-title>
|
|
4
|
-
<v-toolbar-items v-if="
|
|
5
|
-
<v-btn v-for="route in
|
|
4
|
+
<v-toolbar-items v-if="eodash.routes">
|
|
5
|
+
<v-btn v-for="route in eodash.routes" :key="route.to" variant="text" @click="navigateTo(route.to)">
|
|
6
6
|
{{ route.title }}
|
|
7
7
|
</v-btn>
|
|
8
8
|
</v-toolbar-items>
|
|
9
|
-
<v-img class="mx-12 logo" :src="
|
|
9
|
+
<v-img class="mx-12 logo" :src="eodash.brand?.logo" />
|
|
10
10
|
</v-app-bar>
|
|
11
11
|
</template>
|
|
12
12
|
<script setup>
|
|
13
|
-
import {
|
|
13
|
+
import { eodashKey } from '@/store/Keys';
|
|
14
14
|
import { inject } from 'vue';
|
|
15
15
|
import { useRouter } from 'vue-router';
|
|
16
16
|
|
|
17
|
-
const
|
|
17
|
+
const eodash = /** @type {import("@/types").Eodash} */(inject(eodashKey))
|
|
18
18
|
|
|
19
|
-
const title =
|
|
19
|
+
const title = eodash.brand?.name
|
|
20
20
|
|
|
21
21
|
const { push } = useRouter()
|
|
22
22
|
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
<v-row no-gutters class="d-flex justify-center align-end">
|
|
7
7
|
<v-col v-for="(importedWidget, idx) in importedWidgets" :key="idx" :cols="cols"
|
|
8
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"
|
|
9
|
+
<span class="d-flex pa-2 justify-center ma-0 panel-header align-center fill-width"
|
|
10
|
+
@click="handleSelection(idx)">
|
|
10
11
|
{{ importedWidget.value.title }}
|
|
11
12
|
</span>
|
|
12
13
|
<div v-show="activeIdx === idx" class="overlay align-self-end overflow-auto pa-2">
|
|
@@ -19,17 +20,17 @@
|
|
|
19
20
|
</v-main>
|
|
20
21
|
</template>
|
|
21
22
|
<script setup>
|
|
22
|
-
import {
|
|
23
|
+
import { eodashKey } from '@/store/Keys';
|
|
23
24
|
import { inject } from 'vue';
|
|
24
25
|
import { useDefineWidgets } from '@/composables/DefineWidgets'
|
|
25
26
|
import { ref } from 'vue';
|
|
26
27
|
|
|
27
|
-
const
|
|
28
|
+
const eodash = /** @type {import("@/types").Eodash} */(inject(eodashKey));
|
|
28
29
|
|
|
29
30
|
//import widgets
|
|
30
|
-
const widgetsConfig =
|
|
31
|
+
const widgetsConfig = eodash.template.widgets
|
|
31
32
|
const importedWidgets = useDefineWidgets(widgetsConfig)
|
|
32
|
-
const [bgWidget] = useDefineWidgets([
|
|
33
|
+
const [bgWidget] = useDefineWidgets([eodash.template?.background])
|
|
33
34
|
|
|
34
35
|
|
|
35
36
|
|
|
@@ -74,6 +75,4 @@ const handleSelection = (idx) => {
|
|
|
74
75
|
.close-btn {
|
|
75
76
|
justify-self: end;
|
|
76
77
|
}
|
|
77
|
-
|
|
78
|
-
//
|
|
79
78
|
</style>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { eodashKey } from "@/store/Keys"
|
|
2
|
+
import { inject } from "vue"
|
|
3
|
+
import store from '@/store'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Sets user defined instance on runtime.
|
|
7
|
+
* Consumes `/@fs/config.js` and assign it to `eodash`
|
|
8
|
+
* @async
|
|
9
|
+
* @returns {Promise<import("@/types").Eodash>}
|
|
10
|
+
* @see {@linkplain '@/eodash.js'}
|
|
11
|
+
*/
|
|
12
|
+
export const useEodashRuntime = async () => {
|
|
13
|
+
const eodash = /** @type {import("@/types").Eodash} */(inject(eodashKey))
|
|
14
|
+
/**
|
|
15
|
+
* @param {import("@/types").Eodash} config
|
|
16
|
+
*/
|
|
17
|
+
const assignInstance = (config) => {
|
|
18
|
+
/** @type {(keyof import("@/types").Eodash)[]} */(Object.keys(eodash))
|
|
19
|
+
.forEach((key) => {
|
|
20
|
+
//@ts-expect-error
|
|
21
|
+
eodash[key] = config[key]
|
|
22
|
+
})
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
assignInstance(
|
|
27
|
+
(await import( /* @vite-ignore */new URL('/config.js', import.meta.url).href)).default
|
|
28
|
+
)
|
|
29
|
+
} catch {
|
|
30
|
+
try {
|
|
31
|
+
assignInstance(await import("user:config").then(async m => await m['default']))
|
|
32
|
+
} catch {
|
|
33
|
+
console.error('no dashboard configuration defined')
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return eodash
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @param {(store:import("@/types").EodashStore)=> import("@/types").Eodash
|
|
41
|
+
* | Promise<import("@/types").Eodash>} configCallback
|
|
42
|
+
*/
|
|
43
|
+
export const createEodash = async (configCallback) => {
|
|
44
|
+
return await configCallback(store)
|
|
45
|
+
}
|
|
@@ -27,8 +27,8 @@ const internalWidgets = import.meta.glob('^/**/*.vue')
|
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
29
|
* Composable that converts widgets Configurations to defined imported widgets
|
|
30
|
-
* @param { (
|
|
31
|
-
* WidgetsContainerProps['widgets'] | undefined} widgetConfigs
|
|
30
|
+
* @param { (import("@/types").Widget | import("@/types").BackgroundWidget | undefined)[] |
|
|
31
|
+
* import("@/types").WidgetsContainerProps['widgets'] | undefined} widgetConfigs
|
|
32
32
|
* @returns {Array<ReactiveDefinedWidget>}
|
|
33
33
|
**/
|
|
34
34
|
export const useDefineWidgets = (widgetConfigs) => {
|
|
@@ -52,13 +52,13 @@ export const useDefineWidgets = (widgetConfigs) => {
|
|
|
52
52
|
if ('defineWidget' in (config ?? {})) {
|
|
53
53
|
const { selectedStac } = storeToRefs(useSTAcStore())
|
|
54
54
|
watch(selectedStac, (updatedStac) => {
|
|
55
|
-
const definedConfig = reactive(/** @type {FunctionalWidget} */
|
|
55
|
+
const definedConfig = reactive(/** @type {import("@/types").FunctionalWidget} */
|
|
56
56
|
(config)?.defineWidget(updatedStac))
|
|
57
57
|
definedWidget.value = definedWidget.value.id === definedConfig.id ?
|
|
58
58
|
definedWidget.value : getWidgetDefinition(definedConfig);
|
|
59
59
|
}, { immediate: true })
|
|
60
60
|
} else {
|
|
61
|
-
definedWidget.value = getWidgetDefinition(/** @type {StaticWidget} */(config))
|
|
61
|
+
definedWidget.value = getWidgetDefinition(/** @type {import("@/types").StaticWidget} */(config))
|
|
62
62
|
}
|
|
63
63
|
definedWidgets.push(definedWidget)
|
|
64
64
|
}
|
|
@@ -68,7 +68,7 @@ export const useDefineWidgets = (widgetConfigs) => {
|
|
|
68
68
|
|
|
69
69
|
/**
|
|
70
70
|
* Converts a static widget configuration to a defined imported widget
|
|
71
|
-
* @param {StaticWidget| Omit<StaticWidget, "layout">| undefined} config
|
|
71
|
+
* @param {import("@/types").StaticWidget| Omit<import("@/types").StaticWidget, "layout">| undefined} config
|
|
72
72
|
* @returns {DefinedWidget}
|
|
73
73
|
**/
|
|
74
74
|
const getWidgetDefinition = (config) => {
|
|
@@ -84,10 +84,10 @@ const getWidgetDefinition = (config) => {
|
|
|
84
84
|
switch (config?.type) {
|
|
85
85
|
case 'internal':
|
|
86
86
|
importedWidget.component = defineAsyncComponent({
|
|
87
|
-
loader: internalWidgets[`/widgets/${/** @type {
|
|
87
|
+
loader: internalWidgets[`/widgets/${/** @type {import("@/types").InternalComponentWidget} **/(config)?.widget.name}.vue`],
|
|
88
88
|
suspensible: true
|
|
89
89
|
})
|
|
90
|
-
importedWidget.props = reactive(/** @type {
|
|
90
|
+
importedWidget.props = reactive(/** @type {import("@/types").InternalComponentWidget} **/(config)?.widget.props ?? {})
|
|
91
91
|
|
|
92
92
|
break;
|
|
93
93
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
import { reactive } from "vue"
|
|
5
5
|
import { currentUrl } from "@/store/States"
|
|
6
|
-
import eodashConfig from "@/
|
|
6
|
+
import eodashConfig from "@/eodash"
|
|
7
7
|
import { useTheme } from "vuetify/lib/framework.mjs"
|
|
8
8
|
|
|
9
9
|
|
|
@@ -40,7 +40,7 @@ export const useAbsoluteUrl = (rel = '', base = eodashConfig.stacEndpoint) => {
|
|
|
40
40
|
/**
|
|
41
41
|
* Adds slide in and out functionality to Elements
|
|
42
42
|
* @param {import('vue').Ref<HTMLElement[]|null>} elements - elements to add the functionality to
|
|
43
|
-
* @param {
|
|
43
|
+
* @param {import("@/types").Widget[]} configs
|
|
44
44
|
*/
|
|
45
45
|
export const useSlidePanels = (elements, configs) => {
|
|
46
46
|
|
|
@@ -6,11 +6,11 @@ import { currentUrl, mapInstance } from './store/States';
|
|
|
6
6
|
let handleMoveEnd = null;
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
* Reactive Edoash
|
|
10
|
-
* and used as an intermediate object to make user defined
|
|
11
|
-
* @type {
|
|
9
|
+
* Reactive Edoash Instance Object. provided globally in the app,
|
|
10
|
+
* and used as an intermediate object to make user defined instances config reactive.
|
|
11
|
+
* @type {import("./types").Eodash}
|
|
12
12
|
*/
|
|
13
|
-
const
|
|
13
|
+
const eodash = reactive({
|
|
14
14
|
id: 'demo',
|
|
15
15
|
stacEndpoint: 'https://eurodatacube.github.io/eodash-catalog/RACE/catalog.json',
|
|
16
16
|
routes: [],
|
|
@@ -133,4 +133,4 @@ const eodashConfig = reactive({
|
|
|
133
133
|
});
|
|
134
134
|
|
|
135
135
|
|
|
136
|
-
export default
|
|
136
|
+
export default eodash;
|
package/core/main.js
CHANGED
package/core/plugins/index.js
CHANGED
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
import vuetify from './vuetify';
|
|
9
9
|
import router from './router';
|
|
10
10
|
import { createPinia } from 'pinia';
|
|
11
|
-
import
|
|
12
|
-
import {
|
|
11
|
+
import eodash from '@/eodash';
|
|
12
|
+
import { eodashKey } from '@/store/Keys';
|
|
13
13
|
import store from '../store';
|
|
14
14
|
|
|
15
15
|
export const pinia = createPinia();
|
|
@@ -23,5 +23,5 @@ export function registerPlugins(app) {
|
|
|
23
23
|
app.use(vuetify)
|
|
24
24
|
.use(router)
|
|
25
25
|
.use(pinia)
|
|
26
|
-
.provide(
|
|
26
|
+
.provide(eodashKey, eodash);
|
|
27
27
|
}
|
package/core/plugins/router.js
CHANGED
package/core/store/Keys.js
CHANGED
package/core/store/index.js
CHANGED
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
//export all actions, states, and pinia stores
|
|
2
|
-
/**
|
|
3
|
-
* @template {keyof EodashStore} [K = keyof EodashStore]
|
|
4
|
-
* @typedef {Record<K,EodashStore[K]>} EodashStoreImports
|
|
5
|
-
*/
|
|
6
2
|
|
|
7
|
-
const storesImport =
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const store = (() => {
|
|
12
|
-
const stores = /** @type {EodashStore}*/({});
|
|
3
|
+
const storesImport = import.meta.glob('../store/**.js', { eager: true })
|
|
4
|
+
|
|
5
|
+
const store = /** @type {import("@/types").EodashStore} */((() => {
|
|
6
|
+
const stores = {}
|
|
13
7
|
for (const [filePath, importedstore] of Object.entries(storesImport)) {
|
|
14
8
|
const storeType = filePath.split('/').at(-1)?.slice(0, -3).toLowerCase() ?? ''
|
|
15
9
|
if (!['keys'].includes(storeType)) {
|
|
@@ -18,6 +12,6 @@ const store = (() => {
|
|
|
18
12
|
}
|
|
19
13
|
}
|
|
20
14
|
return stores;
|
|
21
|
-
})();
|
|
15
|
+
})());
|
|
22
16
|
|
|
23
17
|
export default store;
|
package/core/store/stac.js
CHANGED
|
@@ -2,7 +2,7 @@ import { defineStore } from 'pinia';
|
|
|
2
2
|
import { inject, ref } from 'vue';
|
|
3
3
|
import axios from 'axios';
|
|
4
4
|
import { useAbsoluteUrl } from '@/composables/index';
|
|
5
|
-
import {
|
|
5
|
+
import { eodashKey } from '@/store/Keys';
|
|
6
6
|
|
|
7
7
|
export const useSTAcStore = defineStore('stac', () => {
|
|
8
8
|
/**
|
|
@@ -20,16 +20,16 @@ export const useSTAcStore = defineStore('stac', () => {
|
|
|
20
20
|
const selectedStac = ref(null);
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
const
|
|
23
|
+
const eodash = /** @type {import("@/types").Eodash} */(inject(eodashKey));
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* fetches root stac catalog and assign it to `stac`
|
|
27
27
|
* @async
|
|
28
|
-
* @param {StacEndpoint} [url =
|
|
28
|
+
* @param {import("@/types").StacEndpoint} [url = eodash.stacEndpoint]
|
|
29
29
|
* @returns {Promise<void>}
|
|
30
30
|
* @see {@link stac}
|
|
31
31
|
*/
|
|
32
|
-
async function loadSTAC(url =
|
|
32
|
+
async function loadSTAC(url = eodash.stacEndpoint) {
|
|
33
33
|
await axios.get(url).then(resp => {
|
|
34
34
|
const links = /** @type {import('stac-ts').StacCatalog} */(resp.data).links.map(link => {
|
|
35
35
|
if (!link.title) {
|