@eodash/eodash 5.0.0-alpha → 5.0.0-alpha.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/bin/app.js +16 -147
- package/bin/cli.js +58 -0
- package/bin/serverConfig.js +130 -0
- package/bin/update.js +19 -0
- package/bin/utils.js +28 -0
- package/core/App.vue +21 -0
- package/core/components/DashboardLayout.vue +58 -0
- package/core/components/DynamicWebComponent.vue +68 -0
- package/core/components/Footer.vue +31 -0
- package/core/components/Header.vue +38 -0
- package/core/components/IframeWrapper.vue +11 -0
- package/core/components/MobileLayout.vue +79 -0
- package/core/composables/DefineConfig.js +44 -0
- package/core/composables/DefineWidgets.js +118 -0
- package/core/composables/index.js +147 -0
- package/core/eodashConfig.js +136 -0
- package/core/main.js +4 -0
- package/core/plugins/index.js +27 -0
- package/core/plugins/router.js +20 -0
- package/core/plugins/vuetify.js +27 -0
- package/core/render.js +13 -0
- package/core/store/Actions.js +28 -0
- package/core/store/Keys.js +6 -0
- package/core/store/States.js +12 -0
- package/core/store/index.js +23 -0
- package/core/store/stac.js +61 -0
- package/core/types.d.ts +333 -0
- package/core/views/Dashboard.vue +49 -0
- package/core/vite-env.d.ts +35 -0
- package/package.json +20 -21
- package/widgets/WidgetsContainer.vue +46 -0
- package/dist/.gitkeep +0 -0
- package/dist/assets/Dashboard-4233cc52.css +0 -1
- package/dist/assets/Dashboard-d7d438a6.js +0 -1
- package/dist/assets/DashboardLayout-5ab6c4a5.js +0 -29
- package/dist/assets/DashboardLayout-739135c5.css +0 -1
- package/dist/assets/DynamicWebComponent-1b7b527a.js +0 -1
- package/dist/assets/Footer-0fe1887a.css +0 -1
- package/dist/assets/Footer-7e1ca735.js +0 -1
- package/dist/assets/Header-9cac598d.css +0 -1
- package/dist/assets/Header-ae17296c.js +0 -1
- package/dist/assets/IframeWrapper-b2c05ffd.js +0 -1
- package/dist/assets/MobileLayout-1b3cb89b.js +0 -1
- package/dist/assets/MobileLayout-ad647682.css +0 -1
- package/dist/assets/VMain-d6216866.css +0 -1
- package/dist/assets/VMain-f6b3f120.js +0 -1
- package/dist/assets/WidgetsContainer-cdad3d50.js +0 -1
- package/dist/assets/color-6039ab34.js +0 -1
- package/dist/assets/eox-chart-3b122ba4.js +0 -142
- package/dist/assets/eox-itemfilter-a63da0da.js +0 -981
- package/dist/assets/eox-jsonform-98c2af62.js +0 -239
- package/dist/assets/eox-layercontrol-f5e35702.js +0 -1126
- package/dist/assets/eox-map-7f82b0d4.js +0 -178
- package/dist/assets/eox-stacinfo-65a8d8f3.js +0 -388
- package/dist/assets/eox-timecontrol-4be63aa2.js +0 -237
- package/dist/assets/index-52c9d989.js +0 -34
- package/dist/assets/index-5d2400e5.css +0 -5
- package/dist/assets/materialdesignicons-webfont-48d3eec6.woff +0 -0
- package/dist/assets/materialdesignicons-webfont-861aea05.eot +0 -0
- package/dist/assets/materialdesignicons-webfont-bd725a7a.ttf +0 -0
- package/dist/assets/materialdesignicons-webfont-e52d60f6.woff2 +0 -0
- package/dist/assets/ssrBoot-0b8754a9.css +0 -1
- package/dist/assets/ssrBoot-d383eb61.js +0 -1
- package/dist/assets/webfontloader-523643f5.js +0 -1
- package/dist/index.html +0 -17
- package/dist/types/index.d.ts +0 -124
package/bin/app.js
CHANGED
|
@@ -1,153 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import { preview } from 'vite'
|
|
5
|
-
import express from "express";
|
|
6
|
-
import * as chokidar from "chokidar"
|
|
7
|
-
import { copyFile, cp, readFile, writeFile } from "fs/promises";
|
|
8
|
-
import { WebSocketServer } from 'ws';
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
// global paths
|
|
12
|
-
const __appPath = fileURLToPath(new URL("../", import.meta.url));
|
|
13
|
-
const __execPath = fileURLToPath(new URL(process.cwd(), import.meta.url));
|
|
14
|
-
const __configPath = __execPath + "/config.js";
|
|
15
|
-
|
|
3
|
+
import { buildApp, createDevServer, previewApp } from './cli.js'
|
|
16
4
|
|
|
5
|
+
const command = process.argv?.[2];
|
|
17
6
|
(async () => {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
7
|
+
switch (command) {
|
|
8
|
+
case "dev":
|
|
9
|
+
await createDevServer();
|
|
10
|
+
break;
|
|
11
|
+
case "build":
|
|
12
|
+
await buildApp();
|
|
13
|
+
break;
|
|
14
|
+
case "preview":
|
|
15
|
+
await previewApp();
|
|
16
|
+
break;
|
|
17
|
+
|
|
18
|
+
default:
|
|
19
|
+
console.error('command not found')
|
|
20
|
+
break;
|
|
24
21
|
}
|
|
25
22
|
})();
|
|
26
|
-
|
|
27
|
-
async function update() {
|
|
28
|
-
// 1. copy public
|
|
29
|
-
const publicPath = __execPath + "/public"
|
|
30
|
-
const distPath = __appPath + "dist"
|
|
31
|
-
await cp(publicPath, distPath, { recursive: true }).catch(err => {
|
|
32
|
-
console.error(err)
|
|
33
|
-
})
|
|
34
|
-
// 2. copy config
|
|
35
|
-
const appConfigPath = __appPath + "dist/config.js";
|
|
36
|
-
await copyFile(__configPath, appConfigPath).catch(err => {
|
|
37
|
-
console.error(err)
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const wsClientScript = `<script type="module">
|
|
42
|
-
const client = new WebSocket("ws://localhost:3333/");
|
|
43
|
-
client.onerror = function (e) {
|
|
44
|
-
console.error('WebSocket Client Error', e);
|
|
45
|
-
};
|
|
46
|
-
client.onopen = function () {
|
|
47
|
-
console.info('client connected');
|
|
48
|
-
};
|
|
49
|
-
client.onclose = function () {
|
|
50
|
-
console.info('client closed');
|
|
51
|
-
};
|
|
52
|
-
client.onmessage = function (evt) {
|
|
53
|
-
if (evt.data === 'reload') {
|
|
54
|
-
window.location.reload()
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
</script>`
|
|
58
|
-
|
|
59
|
-
async function dev() {
|
|
60
|
-
// copy files to app
|
|
61
|
-
await update();
|
|
62
|
-
// inject ws client for dev
|
|
63
|
-
await injectInHTML(wsClientScript)
|
|
64
|
-
// create static server
|
|
65
|
-
const server = express();
|
|
66
|
-
server.use(express.static(__appPath + "dist"));
|
|
67
|
-
|
|
68
|
-
server.listen(3000, () => {
|
|
69
|
-
console.info(`server is running on http://localhost:3000`);
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
server.all("*", (req, res) => {
|
|
73
|
-
// handle query
|
|
74
|
-
const params = new URLSearchParams(req.query).toString()
|
|
75
|
-
// redirect to the app
|
|
76
|
-
res.redirect(`${params.length ? '/?' + params : '/'}`)
|
|
77
|
-
})
|
|
78
|
-
|
|
79
|
-
// create files watcher
|
|
80
|
-
const watcher = chokidar.watch(__execPath + '/**/**.js', {
|
|
81
|
-
ignored: ["**/node_modules/**", __execPath + "/app/**", __appPath + '**/**.**'],
|
|
82
|
-
depth: 2
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
// create ws server for reloading
|
|
86
|
-
const wsServer = new WebSocketServer({ port: 3333 });
|
|
87
|
-
|
|
88
|
-
let websocket = null
|
|
89
|
-
wsServer.on('connection', (ws) => {
|
|
90
|
-
websocket = ws
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
// reload on change
|
|
94
|
-
watcher.on('change', async (path) => {
|
|
95
|
-
if (path === __configPath) {
|
|
96
|
-
await update()
|
|
97
|
-
websocket.send('reload')
|
|
98
|
-
console.info(`updated config.js ✨`)
|
|
99
|
-
}
|
|
100
|
-
})
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
async function buildApp() {
|
|
106
|
-
await update()
|
|
107
|
-
// remove injected script before copying to exec path
|
|
108
|
-
await injectInHTML(wsClientScript, true)
|
|
109
|
-
await cp(__appPath + 'dist', __execPath + '/app', { recursive: true }).catch(err => {
|
|
110
|
-
console.error(err)
|
|
111
|
-
})
|
|
112
|
-
console.info(`built successfully`)
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
async function previewApp() {
|
|
116
|
-
const previewServer = await preview({
|
|
117
|
-
root: __execPath,
|
|
118
|
-
preview: {
|
|
119
|
-
port: 8080,
|
|
120
|
-
open: true,
|
|
121
|
-
},
|
|
122
|
-
build: {
|
|
123
|
-
outDir: 'app'
|
|
124
|
-
}
|
|
125
|
-
})
|
|
126
|
-
previewServer.printUrls()
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
async function injectInHTML(injected, remove) {
|
|
131
|
-
const htmlPath = __appPath + 'dist/index.html'
|
|
132
|
-
const updatedHtml = await readFile(htmlPath, 'utf8').then(data => {
|
|
133
|
-
let html = ''
|
|
134
|
-
if (remove) {
|
|
135
|
-
html = data.replace(injected, '')
|
|
136
|
-
} else {
|
|
137
|
-
if (!data.includes(injected)) {
|
|
138
|
-
const splitHtml = data.split("\n")
|
|
139
|
-
splitHtml.splice(splitHtml.indexOf("</body>"), 0, injected);
|
|
140
|
-
html = splitHtml.join("\n")
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
return html
|
|
144
|
-
}).catch(err => {
|
|
145
|
-
throw err
|
|
146
|
-
})
|
|
147
|
-
|
|
148
|
-
if (updatedHtml.length) {
|
|
149
|
-
await writeFile(htmlPath, updatedHtml).catch(err => {
|
|
150
|
-
throw err;
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
}
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { build, createServer, preview } from "vite"
|
|
4
|
+
import { execPath, appPath, buildTargetPath } from "./utils.js";
|
|
5
|
+
import { writeFile, rm, cp } from "fs/promises";
|
|
6
|
+
import { update } from "./update.js";
|
|
7
|
+
import { indexHtml, serverConfig } from "./serverConfig.js";
|
|
8
|
+
import path from "path";
|
|
9
|
+
import { existsSync } from "fs";
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
export const createDevServer = async () => {
|
|
14
|
+
const server = await createServer(await serverConfig({ mode: 'development', command: 'serve' }))
|
|
15
|
+
await server.listen()
|
|
16
|
+
server.printUrls()
|
|
17
|
+
server.bindCLIShortcuts({ print: true })
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const buildApp = async () => {
|
|
21
|
+
const htmlPath = path.join(appPath, '/index.html')
|
|
22
|
+
await writeFile(htmlPath, indexHtml).then(async () => {
|
|
23
|
+
await update()
|
|
24
|
+
await build(await serverConfig({ mode: 'production', command: 'build' }))
|
|
25
|
+
await rm(htmlPath).catch(() => {
|
|
26
|
+
console.error('failed to remove index.html')
|
|
27
|
+
})
|
|
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
|
+
})
|
|
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
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
export async function previewApp() {
|
|
47
|
+
const previewServer = await preview({
|
|
48
|
+
root: execPath,
|
|
49
|
+
preview: {
|
|
50
|
+
port: 8080,
|
|
51
|
+
open: true,
|
|
52
|
+
},
|
|
53
|
+
build: {
|
|
54
|
+
outDir: buildTargetPath
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
previewServer.printUrls()
|
|
58
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
import vue from '@vitejs/plugin-vue';
|
|
6
|
+
import vuetify, { transformAssetUrls } from 'vite-plugin-vuetify';
|
|
7
|
+
import virtual, { updateVirtualModule } from 'vite-plugin-virtual'
|
|
8
|
+
import { fileURLToPath, URL } from 'url';
|
|
9
|
+
import { execPath, runtimeConfigPath, appPath, dotEodashPath, compiletimeConfigPath } from "./utils.js";
|
|
10
|
+
import { readFile } from "fs/promises";
|
|
11
|
+
import { defineConfig, searchForWorkspaceRoot } from "vite"
|
|
12
|
+
import { getUserModules } from './utils.js';
|
|
13
|
+
import { existsSync } from 'fs';
|
|
14
|
+
import path from "path";
|
|
15
|
+
|
|
16
|
+
export const indexHtml = `
|
|
17
|
+
<!DOCTYPE html>
|
|
18
|
+
<html lang="en">
|
|
19
|
+
|
|
20
|
+
<head>
|
|
21
|
+
<meta charset="UTF-8" />
|
|
22
|
+
<link rel="icon" href="/favicon.ico" />
|
|
23
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
24
|
+
<title>Welcome to Eodash v5</title>
|
|
25
|
+
</head>
|
|
26
|
+
|
|
27
|
+
<body>
|
|
28
|
+
<div id="app"></div>
|
|
29
|
+
<script type="module" src="${path.resolve(`/@fs/${appPath}/core/render.js`)}"></script>
|
|
30
|
+
</body>
|
|
31
|
+
</html>`
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @type {import('vite').Plugin | null}
|
|
35
|
+
*/
|
|
36
|
+
let virtualPlugin = null;
|
|
37
|
+
export const serverConfig = /** @type {import('vite').UserConfigFnPromise}*/(defineConfig(async ({ mode, command }) => {
|
|
38
|
+
return {
|
|
39
|
+
base: '',
|
|
40
|
+
cacheDir: dotEodashPath + '/cache',
|
|
41
|
+
plugins: [
|
|
42
|
+
vue({
|
|
43
|
+
template: {
|
|
44
|
+
transformAssetUrls,
|
|
45
|
+
compilerOptions: {
|
|
46
|
+
isCustomElement: (tag) => !tag.includes('v-') && tag.includes('-')
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
}),
|
|
50
|
+
// https://github.com/vuetifyjs/vuetify-loader/tree/master/packages/vite-plugin#readme
|
|
51
|
+
vuetify({
|
|
52
|
+
autoImport: true,
|
|
53
|
+
}),
|
|
54
|
+
(mode === "development" && {
|
|
55
|
+
name: "inject-html",
|
|
56
|
+
configureServer
|
|
57
|
+
}),
|
|
58
|
+
virtualPlugin = virtual(await getUserModules())
|
|
59
|
+
],
|
|
60
|
+
define: { 'process.env': {} },
|
|
61
|
+
resolve: {
|
|
62
|
+
alias: {
|
|
63
|
+
'@': fileURLToPath(new URL('../core', import.meta.url)),
|
|
64
|
+
'^': fileURLToPath(new URL('../widgets', import.meta.url)),
|
|
65
|
+
},
|
|
66
|
+
extensions: ['.js', '.json', '.jsx', '.mjs', '.ts', '.tsx', '.vue'],
|
|
67
|
+
},
|
|
68
|
+
server: {
|
|
69
|
+
port: 3000,
|
|
70
|
+
fs: {
|
|
71
|
+
allow: [searchForWorkspaceRoot(process.cwd())]
|
|
72
|
+
},
|
|
73
|
+
open: '/'
|
|
74
|
+
},
|
|
75
|
+
root: fileURLToPath(new URL('..', import.meta.url)),
|
|
76
|
+
optimizeDeps: mode === "development" ? {
|
|
77
|
+
include: ["webfontloader", "vuetify", "vue", "pinia"],
|
|
78
|
+
noDiscovery: true,
|
|
79
|
+
} : {},
|
|
80
|
+
publicDir: command === 'build' ? path.join(appPath, './public') : path.join(execPath, '/public'),
|
|
81
|
+
build: {
|
|
82
|
+
outDir: 'dist',
|
|
83
|
+
rollupOptions: {
|
|
84
|
+
input: fileURLToPath(new URL(command === 'build' ? '../index.html' : '../core/main.js', import.meta.url)),
|
|
85
|
+
},
|
|
86
|
+
target: "esnext"
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}));
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* @type {import("vite").ServerHook}
|
|
95
|
+
*/
|
|
96
|
+
async function configureServer(server) {
|
|
97
|
+
server.watcher.add([compiletimeConfigPath, runtimeConfigPath])
|
|
98
|
+
|
|
99
|
+
server.watcher.on('change', async (path) => {
|
|
100
|
+
if (path == runtimeConfigPath) {
|
|
101
|
+
server.hot.send('reload')
|
|
102
|
+
} else if (!path.includes('node_modules') && path.includes('.eodash')) {
|
|
103
|
+
updateVirtualModule(virtualPlugin, 'user:config',
|
|
104
|
+
await getUserModules().then(modules => modules['user:config']))
|
|
105
|
+
}
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
return () => {
|
|
109
|
+
server.middlewares.use(async (req, res, next) => {
|
|
110
|
+
if (req.originalUrl === '/@fs/config.js' && existsSync(runtimeConfigPath)) {
|
|
111
|
+
await readFile(runtimeConfigPath).then(runtimeConfig => {
|
|
112
|
+
res.statusCode = 200
|
|
113
|
+
res.setHeader('Content-Type', 'text/javascript')
|
|
114
|
+
res.write(runtimeConfig)
|
|
115
|
+
res.end()
|
|
116
|
+
})
|
|
117
|
+
return
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (req.url?.endsWith('.html')) {
|
|
121
|
+
res.statusCode = 200
|
|
122
|
+
res.setHeader('Content-Type', 'text/html')
|
|
123
|
+
const html = await server.transformIndexHtml(req.url, indexHtml, req.originalUrl)
|
|
124
|
+
res.end(html)
|
|
125
|
+
return
|
|
126
|
+
}
|
|
127
|
+
next()
|
|
128
|
+
})
|
|
129
|
+
}
|
|
130
|
+
}
|
package/bin/update.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { cp } from "fs/promises";
|
|
2
|
+
import { execPath, appPath, runtimeConfigPath } from "./utils.js";
|
|
3
|
+
import { existsSync } from "fs";
|
|
4
|
+
import path from "path";
|
|
5
|
+
|
|
6
|
+
export async function update() {
|
|
7
|
+
const execPublicPath = path.join(execPath, "/public"),
|
|
8
|
+
appPublicPath = path.join(appPath, "/public")
|
|
9
|
+
if (execPublicPath !== appPublicPath) {
|
|
10
|
+
await cp(execPublicPath, appPublicPath, { recursive: true }).catch(err => {
|
|
11
|
+
console.error(err)
|
|
12
|
+
})
|
|
13
|
+
if (existsSync(runtimeConfigPath)) {
|
|
14
|
+
await cp(runtimeConfigPath, path.join(appPath, '/public/config.js')).catch((e) => {
|
|
15
|
+
console.error(e)
|
|
16
|
+
})
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
package/bin/utils.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { readFile } from 'fs/promises';
|
|
4
|
+
import { existsSync } from 'fs';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import { fileURLToPath } from 'url';
|
|
7
|
+
|
|
8
|
+
// global paths
|
|
9
|
+
export const appPath = fileURLToPath(new URL("..", import.meta.url));
|
|
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')
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
export const getUserModules = async () => {
|
|
19
|
+
/** @type {Record<string,string>} */
|
|
20
|
+
let userModules = {}
|
|
21
|
+
const indexJs = await readFile(compiletimeConfigPath, 'utf-8').catch(() => {
|
|
22
|
+
if (!existsSync(runtimeConfigPath)) {
|
|
23
|
+
console.error(new Error("no eodash configuration found"))
|
|
24
|
+
}
|
|
25
|
+
})
|
|
26
|
+
userModules['user:config'] = typeof indexJs === 'string' ? indexJs : ''
|
|
27
|
+
return userModules
|
|
28
|
+
}
|
package/core/App.vue
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-app>
|
|
3
|
+
<RouterView v-slot="{ Component }">
|
|
4
|
+
<template v-if="Component">
|
|
5
|
+
<Suspense>
|
|
6
|
+
<!-- main content -->
|
|
7
|
+
<component :is="Component"></component>
|
|
8
|
+
|
|
9
|
+
<!-- loading state -->
|
|
10
|
+
<template #fallback>
|
|
11
|
+
Loading...
|
|
12
|
+
</template>
|
|
13
|
+
</Suspense>
|
|
14
|
+
</template>
|
|
15
|
+
</RouterView>
|
|
16
|
+
</v-app>
|
|
17
|
+
</template>
|
|
18
|
+
|
|
19
|
+
<script setup>
|
|
20
|
+
//
|
|
21
|
+
</script>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-main>
|
|
3
|
+
<eox-layout :gap="eodashConfig.template.gap ?? 2">
|
|
4
|
+
<eox-layout-item class="bg-widget" x="0" y="0" h="12" w="12">
|
|
5
|
+
<component :is="bgWidget.component" v-bind="bgWidget.props" />
|
|
6
|
+
</eox-layout-item>
|
|
7
|
+
<eox-layout-item v-for="(config, idx) in widgetsConfig" ref="itemEls" :key="idx" class="custom-widget"
|
|
8
|
+
:x="config.layout.x" :y="config.layout.y" :h="config.layout.h" :w="config.layout.w">
|
|
9
|
+
|
|
10
|
+
<v-btn position="absolute" variant="tonal" :style="slideBtns[idx].style" class="slide-btn"
|
|
11
|
+
@click="slideInOut(idx)">
|
|
12
|
+
<v-icon :icon="slideBtns[idx].active ? slideBtns[idx].icon.in : slideBtns[idx].icon.out" />
|
|
13
|
+
</v-btn>
|
|
14
|
+
<component :key="importedWidgets[idx].value.id" :is="importedWidgets[idx].value.component"
|
|
15
|
+
v-bind="importedWidgets[idx].value.props" />
|
|
16
|
+
|
|
17
|
+
</eox-layout-item>
|
|
18
|
+
</eox-layout>
|
|
19
|
+
</v-main>
|
|
20
|
+
</template>
|
|
21
|
+
<script setup >
|
|
22
|
+
import { eodashConfigKey } from '@/store/Keys';
|
|
23
|
+
import { inject } from 'vue';
|
|
24
|
+
import { useDefineWidgets } from '@/composables/DefineWidgets'
|
|
25
|
+
import { useSlidePanels } from '@/composables'
|
|
26
|
+
import { ref } from 'vue';
|
|
27
|
+
import '@eox/layout'
|
|
28
|
+
|
|
29
|
+
const eodashConfig = /** @type {EodashConfig} */ (inject(eodashConfigKey))
|
|
30
|
+
|
|
31
|
+
const [bgWidget] = useDefineWidgets([eodashConfig.template?.background])
|
|
32
|
+
|
|
33
|
+
const widgetsConfig = eodashConfig.template?.widgets
|
|
34
|
+
|
|
35
|
+
const importedWidgets = useDefineWidgets(widgetsConfig)
|
|
36
|
+
/**
|
|
37
|
+
* Layout items template ref
|
|
38
|
+
* @type {import('vue').Ref<HTMLElement[]>}
|
|
39
|
+
*/
|
|
40
|
+
const itemEls = ref([])
|
|
41
|
+
|
|
42
|
+
const { slideBtns, slideInOut } = useSlidePanels(itemEls, widgetsConfig)
|
|
43
|
+
</script>
|
|
44
|
+
<style scoped>
|
|
45
|
+
eox-layout-item {
|
|
46
|
+
background: rgb(var(--v-theme-surface))
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.bg-widget {
|
|
50
|
+
z-index: 0;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.custom-widget {
|
|
54
|
+
position: relative;
|
|
55
|
+
overflow: visible;
|
|
56
|
+
z-index: 1;
|
|
57
|
+
}
|
|
58
|
+
</style>
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<span class="d-flex flex-column fill-height overflow-auto">
|
|
3
|
+
<component :is="tagName" v-bind="properties" ref="elementRef" />
|
|
4
|
+
</span>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script async setup>
|
|
8
|
+
import { useSTAcStore } from '@/store/stac';
|
|
9
|
+
import {
|
|
10
|
+
onUnmounted as whenUnMounted,
|
|
11
|
+
onMounted as whenMounted
|
|
12
|
+
} from 'vue';
|
|
13
|
+
import { ref } from 'vue';
|
|
14
|
+
import { useRouter } from 'vue-router';
|
|
15
|
+
|
|
16
|
+
const props = /** @type {WebComponentProps} */(defineProps({
|
|
17
|
+
link: {
|
|
18
|
+
type: [String, Function],
|
|
19
|
+
required: true
|
|
20
|
+
},
|
|
21
|
+
constructorProp: String,
|
|
22
|
+
tagName: {
|
|
23
|
+
type: String,
|
|
24
|
+
required: true
|
|
25
|
+
},
|
|
26
|
+
properties: {
|
|
27
|
+
type: Object,
|
|
28
|
+
default: () => {
|
|
29
|
+
return {}
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
onMounted: Function,
|
|
33
|
+
onUnmounted: Function
|
|
34
|
+
}))
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
const getWebComponent = async () => typeof props.link === 'string' ?
|
|
38
|
+
await import( /* @vite-ignore */props.link) : await props.link()
|
|
39
|
+
|
|
40
|
+
const imported = await getWebComponent().catch(e => {
|
|
41
|
+
console.error(e)
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
const defined = customElements.get(props.tagName)
|
|
45
|
+
|
|
46
|
+
// if the imported link doesn't define the custom tag provided
|
|
47
|
+
if (!defined && props.constructorProp) {
|
|
48
|
+
const Constructor = imported[props.constructorProp]
|
|
49
|
+
customElements.define(props.tagName, Constructor)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const store = useSTAcStore()
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @template {HTMLElement} CE
|
|
56
|
+
* @type {import('vue').Ref<CE|null>}
|
|
57
|
+
*/
|
|
58
|
+
const elementRef = ref(null)
|
|
59
|
+
const router = useRouter()
|
|
60
|
+
|
|
61
|
+
whenMounted(() => {
|
|
62
|
+
props.onMounted?.(elementRef.value, store, router)
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
whenUnMounted(() => {
|
|
66
|
+
props.onUnmounted?.(elementRef.value, store, router)
|
|
67
|
+
})
|
|
68
|
+
</script>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-footer ref="footer" :height="mdAndDown ? '48px' : 'auto'" color="secondary" app class="d-flex justify-space-between">
|
|
3
|
+
<p class="pt-0 footer-text">
|
|
4
|
+
Phasellus feugiat arcu sapien, et iaculis ipsum elementum sit amet. Mauris cursus commodo interdum.
|
|
5
|
+
</p>
|
|
6
|
+
<div class="footer-text">
|
|
7
|
+
{{ new Date().getFullYear() }} — <strong>{{ title }}</strong>
|
|
8
|
+
</div>
|
|
9
|
+
</v-footer>
|
|
10
|
+
</template>
|
|
11
|
+
<script setup>
|
|
12
|
+
import { eodashConfigKey } from '@/store/Keys';
|
|
13
|
+
import { ref } from 'vue';
|
|
14
|
+
import { inject } from 'vue';
|
|
15
|
+
import { useDisplay } from 'vuetify/lib/framework.mjs';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Footer template ref
|
|
19
|
+
* @type {import('vue').Ref<import('vuetify/lib/components/index.mjs').VFooter | null>}
|
|
20
|
+
*/
|
|
21
|
+
const footer = ref(null)
|
|
22
|
+
const eodashConfig = /** @type {EodashConfig} */(inject(eodashConfigKey))
|
|
23
|
+
|
|
24
|
+
const title = eodashConfig.brand?.shortName ?? eodashConfig.brand?.name
|
|
25
|
+
const { mdAndDown } = useDisplay()
|
|
26
|
+
</script>
|
|
27
|
+
<style scoped lang='scss'>
|
|
28
|
+
.footer-text {
|
|
29
|
+
font-size: 0.8rem;
|
|
30
|
+
}
|
|
31
|
+
</style>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-app-bar color="primary">
|
|
3
|
+
<v-app-bar-title class="cursor-pointer">{{ title }}</v-app-bar-title>
|
|
4
|
+
<v-toolbar-items v-if="eodashConfig.routes">
|
|
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" />
|
|
10
|
+
</v-app-bar>
|
|
11
|
+
</template>
|
|
12
|
+
<script setup>
|
|
13
|
+
import { eodashConfigKey } from '@/store/Keys';
|
|
14
|
+
import { inject } from 'vue';
|
|
15
|
+
import { useRouter } from 'vue-router';
|
|
16
|
+
|
|
17
|
+
const eodashConfig = /** @type {EodashConfig} */(inject(eodashConfigKey))
|
|
18
|
+
|
|
19
|
+
const title = eodashConfig.brand?.name
|
|
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
|
+
}
|
|
33
|
+
</script>
|
|
34
|
+
<style scoped lang='scss'>
|
|
35
|
+
.logo {
|
|
36
|
+
max-width: 140px;
|
|
37
|
+
}
|
|
38
|
+
</style>
|