@eodash/eodash 5.0.0-alpha → 5.0.0-alpha.1.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.
Files changed (66) hide show
  1. package/bin/app.js +16 -147
  2. package/bin/cli.js +57 -0
  3. package/bin/serverConfig.js +134 -0
  4. package/bin/update.js +17 -0
  5. package/bin/utils.js +33 -0
  6. package/core/App.vue +21 -0
  7. package/core/components/DashboardLayout.vue +58 -0
  8. package/core/components/DynamicWebComponent.vue +68 -0
  9. package/core/components/Footer.vue +31 -0
  10. package/core/components/Header.vue +38 -0
  11. package/core/components/IframeWrapper.vue +11 -0
  12. package/core/components/MobileLayout.vue +79 -0
  13. package/core/composables/DefineConfig.js +44 -0
  14. package/core/composables/DefineWidgets.js +118 -0
  15. package/core/composables/index.js +147 -0
  16. package/core/eodashConfig.js +136 -0
  17. package/core/main.js +4 -0
  18. package/core/plugins/index.js +27 -0
  19. package/core/plugins/router.js +20 -0
  20. package/core/plugins/vuetify.js +27 -0
  21. package/core/render.js +13 -0
  22. package/core/store/Actions.js +28 -0
  23. package/core/store/Keys.js +6 -0
  24. package/core/store/States.js +12 -0
  25. package/core/store/index.js +23 -0
  26. package/core/store/stac.js +61 -0
  27. package/core/types.d.ts +333 -0
  28. package/core/views/Dashboard.vue +49 -0
  29. package/core/vite-env.d.ts +35 -0
  30. package/package.json +20 -21
  31. package/widgets/WidgetsContainer.vue +46 -0
  32. package/dist/.gitkeep +0 -0
  33. package/dist/assets/Dashboard-4233cc52.css +0 -1
  34. package/dist/assets/Dashboard-d7d438a6.js +0 -1
  35. package/dist/assets/DashboardLayout-5ab6c4a5.js +0 -29
  36. package/dist/assets/DashboardLayout-739135c5.css +0 -1
  37. package/dist/assets/DynamicWebComponent-1b7b527a.js +0 -1
  38. package/dist/assets/Footer-0fe1887a.css +0 -1
  39. package/dist/assets/Footer-7e1ca735.js +0 -1
  40. package/dist/assets/Header-9cac598d.css +0 -1
  41. package/dist/assets/Header-ae17296c.js +0 -1
  42. package/dist/assets/IframeWrapper-b2c05ffd.js +0 -1
  43. package/dist/assets/MobileLayout-1b3cb89b.js +0 -1
  44. package/dist/assets/MobileLayout-ad647682.css +0 -1
  45. package/dist/assets/VMain-d6216866.css +0 -1
  46. package/dist/assets/VMain-f6b3f120.js +0 -1
  47. package/dist/assets/WidgetsContainer-cdad3d50.js +0 -1
  48. package/dist/assets/color-6039ab34.js +0 -1
  49. package/dist/assets/eox-chart-3b122ba4.js +0 -142
  50. package/dist/assets/eox-itemfilter-a63da0da.js +0 -981
  51. package/dist/assets/eox-jsonform-98c2af62.js +0 -239
  52. package/dist/assets/eox-layercontrol-f5e35702.js +0 -1126
  53. package/dist/assets/eox-map-7f82b0d4.js +0 -178
  54. package/dist/assets/eox-stacinfo-65a8d8f3.js +0 -388
  55. package/dist/assets/eox-timecontrol-4be63aa2.js +0 -237
  56. package/dist/assets/index-52c9d989.js +0 -34
  57. package/dist/assets/index-5d2400e5.css +0 -5
  58. package/dist/assets/materialdesignicons-webfont-48d3eec6.woff +0 -0
  59. package/dist/assets/materialdesignicons-webfont-861aea05.eot +0 -0
  60. package/dist/assets/materialdesignicons-webfont-bd725a7a.ttf +0 -0
  61. package/dist/assets/materialdesignicons-webfont-e52d60f6.woff2 +0 -0
  62. package/dist/assets/ssrBoot-0b8754a9.css +0 -1
  63. package/dist/assets/ssrBoot-d383eb61.js +0 -1
  64. package/dist/assets/webfontloader-523643f5.js +0 -1
  65. package/dist/index.html +0 -17
  66. package/dist/types/index.d.ts +0 -124
@@ -0,0 +1,61 @@
1
+ import { defineStore } from 'pinia';
2
+ import { inject, ref } from 'vue';
3
+ import axios from 'axios';
4
+ import { useAbsoluteUrl } from '@/composables/index';
5
+ import { eodashConfigKey } from '@/store/Keys';
6
+
7
+ export const useSTAcStore = defineStore('stac', () => {
8
+ /**
9
+ * links of the root STAC catalog
10
+ * @type {import("vue").Ref<import('stac-ts').StacLink[]|null>}
11
+ */
12
+ const stac = ref(null);
13
+
14
+ /**
15
+ * selected STAC object.
16
+ * @type {import('vue').Ref<import('stac-ts').StacCatalog |
17
+ * import('stac-ts').StacCollection |import('stac-ts').StacItem
18
+ * | null>}
19
+ */
20
+ const selectedStac = ref(null);
21
+
22
+
23
+ const eodashConfig = /** @type {EodashConfig} */(inject(eodashConfigKey));
24
+
25
+ /**
26
+ * fetches root stac catalog and assign it to `stac`
27
+ * @async
28
+ * @param {StacEndpoint} [url = eodashConfig.stacEndpoint]
29
+ * @returns {Promise<void>}
30
+ * @see {@link stac}
31
+ */
32
+ async function loadSTAC(url = eodashConfig.stacEndpoint) {
33
+ await axios.get(url).then(resp => {
34
+ const links = /** @type {import('stac-ts').StacCatalog} */(resp.data).links.map(link => {
35
+ if (!link.title) {
36
+ link.title = `${link.rel} ${link.href}`
37
+ }
38
+ return link
39
+ })
40
+ stac.value = links;
41
+ }).catch(err => console.error(err));
42
+ }
43
+
44
+ /**
45
+ * fetches selected stac object and assign it to `selectedStac`
46
+ * @async
47
+ * @param {string} relativePath - stac link href
48
+ * @returns {Promise<void>}
49
+ * @see {@link selectedStac}
50
+ */
51
+ async function loadSelectedSTAC(relativePath = '') {
52
+
53
+ const absoluteUrl = useAbsoluteUrl(relativePath);
54
+
55
+ await axios.get(absoluteUrl.value).then(resp => {
56
+ selectedStac.value = resp.data;
57
+ }).catch(err => console.error(err));
58
+ }
59
+
60
+ return { stac, loadSTAC, loadSelectedSTAC, selectedStac };
61
+ });
@@ -0,0 +1,333 @@
1
+ import { useSTAcStore } from "@/store/stac"
2
+ import type { Router } from "vue-router";
3
+ import type { StacCatalog, StacCollection, StacItem } from "stac-ts";
4
+ import { defineCompiletimeConfig } from "./composables/DefineConfig";
5
+
6
+ declare global {
7
+ /**
8
+ * Web Component configuration
9
+ */
10
+ interface WebComponentProps<T extends ExecutionTime = "compiletime"> {
11
+ /** Web component definition file URL*/
12
+ link: T extends 'runtime' ? string : (string | (() => Promise));
13
+ /** Exported Constructor, needs to be provided if the web component is not registered by the `link` provided */
14
+ constructorProp?: string
15
+ /** Custom tag name */
16
+ tagName: `${string}-${string}`
17
+ /** Object defining all the properties and attributes of the web component */
18
+ properties?: Record<string, any>
19
+ /**
20
+ * Function that is triggered when the web component is mounted in the DOM.
21
+ * @param el - web component
22
+ * @param store - return value of the core STAC pinia store in `/core/store/stac.ts`
23
+ */
24
+ onMounted?: (el: Element | null, store: ReturnType<typeof useSTAcStore>, router: Router) => (Promise<void> | void)
25
+ /**
26
+ * Function that is triggered when the web component is unmounted from the DOM.
27
+ * @param el - web component
28
+ * @param store - return value of the core STAC pinia store in `/core/store/stac.ts`
29
+ */
30
+ onUnmounted?: (el: Element | null, store: ReturnType<typeof useSTAcStore>, router: Router) => (Promise<void> | void)
31
+ }
32
+
33
+
34
+ /** @ignore */
35
+ interface WidgetsContainerProps {
36
+ widgets: Omit<WidgetConfig, 'layout'>[]
37
+ }
38
+
39
+ // eodash config types:
40
+ /**
41
+ * Widget type: `web-component` specification. The web component definition is imported using the `widget.link` property either from
42
+ * an external endpoint, or an installed node_module.
43
+ * Installed node_module web components import should be mapped in `/core/modulesMap.ts`,
44
+ * then setting `widget.link`:`(import-map-key)` and `node_module`:`true`
45
+ */
46
+ interface WebComponentConfig<T extends ExecutionTime = "compiletime"> {
47
+ /**
48
+ * Unique Identifier, triggers rerender when using `defineWidget`
49
+ **/
50
+ id: number | string | symbol
51
+ /**
52
+ * Widget title
53
+ */
54
+ title: string
55
+ /**
56
+ * Widget position and size.
57
+ */
58
+ layout: {
59
+ /**
60
+ * Horizontal start position. Integer (1 - 12)
61
+ */
62
+ x: number
63
+ /**
64
+ * Vertical start position. Integer (1 - 12)
65
+ */
66
+ y: number
67
+ /**
68
+ * Width. Integer (1 - 12)
69
+ */
70
+ w: number
71
+ /**
72
+ * Height. Integer (1 - 12)
73
+ */
74
+ h: number
75
+ }
76
+ widget: WebComponentProps<T>
77
+ /**
78
+ * Widget type
79
+ */
80
+ type: 'web-component'
81
+ }
82
+
83
+ /**
84
+ * Widget type: `internal` specification.
85
+ * Internal widgets are Vue components inside the `/widgets` directory.
86
+ */
87
+ interface InternalComponentConfig {
88
+ /**
89
+ * Unique Identifier, triggers rerender when using `defineWidget`
90
+ **/
91
+ id: number | string | symbol
92
+ /**
93
+ * Widget title
94
+ */
95
+ title: string
96
+ /**
97
+ * Widget position and size.
98
+ */
99
+ layout: {
100
+ /**
101
+ * Horizontal start position. Integer (1 - 12)
102
+ */
103
+ x: number
104
+ /**
105
+ * Vertical start position. Integer (1 - 12)
106
+ */
107
+ y: number
108
+ /**
109
+ * Width. Integer (1 - 12)
110
+ */
111
+ w: number
112
+ /**
113
+ * Height. Integer (1 - 12)
114
+ */
115
+ h: number
116
+ }
117
+ widget: {
118
+ /**
119
+ * Internal Vue Component file name without the extention .vue
120
+ */
121
+ name: string;
122
+ /**
123
+ * Specified Vue component props
124
+ */
125
+ props?: Record<string, unknown>
126
+ }
127
+ /**
128
+ * Widget type.
129
+ */
130
+ type: 'internal'
131
+ }
132
+
133
+ /**
134
+ * Widget type: `iframe` specification.
135
+ * Renders an external HTML file as a widget.
136
+ */
137
+ interface IFrameConfig {
138
+ /**
139
+ * Unique Identifier, triggers rerender when using `defineWidget`
140
+ **/
141
+ id: number | string | symbol
142
+ /**
143
+ * Widget title
144
+ */
145
+ title: string
146
+ /**
147
+ * Widget position and size.
148
+ */
149
+ layout: {
150
+ /**
151
+ * Horizontal start position. Integer (1 - 12)
152
+ */
153
+ x: number
154
+ /**
155
+ * Vertical start position. Integer (1 - 12)
156
+ */
157
+ y: number
158
+ /**
159
+ * Width. Integer (1 - 12)
160
+ */
161
+ w: number
162
+ /**
163
+ * Height. Integer (1 - 12)
164
+ */
165
+ h: number
166
+ }
167
+ widget: {
168
+ /**
169
+ * The URL of the page to embed
170
+ */
171
+ src: string
172
+ }
173
+ /**
174
+ * Widget type
175
+ */
176
+ type: 'iframe'
177
+ }
178
+ interface FunctionalWidget<T extends ExecutionTime = "compiletime"> {
179
+ /**
180
+ * Provides a functional definition of the widget,
181
+ * gets triggered whenever a stac object is selected.
182
+ * @param selectedSTAC - currently selected stac object
183
+ */
184
+ defineWidget: (selectedSTAC: StacCatalog | StacCollection | StacItem | null) => Omit<StaticWidget<T>, 'layout'>
185
+ layout: {
186
+ /**
187
+ * Horizontal start position. Integer (1 - 12)
188
+ */
189
+ x: number
190
+ /**
191
+ * Vertical start position. Integer (1 - 12)
192
+ */
193
+ y: number
194
+ /**
195
+ * Width. Integer (1 - 12)
196
+ */
197
+ w: number
198
+ /**
199
+ * Height. Integer (1 - 12)
200
+ */
201
+ h: number
202
+ }
203
+ }
204
+ type StaticWidget<T extends ExecutionTime = "compiletime"> = WebComponentConfig<T> | InternalComponentConfig | IFrameConfig
205
+ type WidgetConfig<T extends ExecutionTime = "compiletime"> = StaticWidget<T> | FunctionalWidget<T>
206
+
207
+
208
+ type BackgroundWidgetConfig<T extends ExecutionTime = "compiletime"> = Omit<WebComponentConfig<T>, 'layout' | 'title'> | Omit<InternalComponentConfig, 'layout' | 'title'> | Omit<IFrameConfig, 'layout' | 'title'> | Omit<FunctionalWidget, 'layout'>
209
+ /**
210
+ * Dashboard rendered widgets configuration specification.
211
+ * 3 types of widgets are supported: `"iframe"`, `"internal"`, and `"web-component"`.
212
+ * A specific configuration should be provided based on the type of the widget.
213
+ */
214
+ interface TemplateConfig<T extends ExecutionTime = "compiletime"> {
215
+ /**
216
+ * Gap between widgets
217
+ */
218
+ gap?: number;
219
+ /**
220
+ * Widget rendered as the dashboard background.
221
+ * Has the same specifications of [WidgetConfig](../readme#widgetconfig) without the `title` and `layout` properties
222
+ */
223
+ background?: BackgroundWidgetConfig<T>
224
+ /**
225
+ * Array of widgets that will be rendered as dashboard panels.
226
+ */
227
+ widgets: WidgetConfig<T>[]
228
+ }
229
+
230
+ type ExternalURL = `${'https://' | 'http://'}${string}`;
231
+ type InternalRoute = `/${string}`
232
+ type StacEndpoint = `${'https://' | 'http://'}${string}/catalog.json`
233
+
234
+ type ExecutionTime = "runtime" | "compiletime";
235
+
236
+ /**
237
+ * Eodash configuration specification.
238
+ */
239
+ interface EodashConfig<T extends ExecutionTime = "compiletime"> {
240
+ /**
241
+ * Configuration ID that defines the route of the dashboard.
242
+ * Rendered dashboard can be accessed on route `/dashboard/config-id`
243
+ */
244
+ id: string;
245
+ /**
246
+ * Root STAC catalog endpoint
247
+ **/
248
+ stacEndpoint: StacEndpoint
249
+ /**
250
+ * Renderes to navigation buttons on the app header.
251
+ **/
252
+ routes?: Array<{
253
+ /**
254
+ * button title
255
+ **/
256
+ title: string,
257
+ /**
258
+ * external URL or inner path to navigate to.
259
+ **/
260
+ to: ExternalURL | InternalRoute
261
+ }>
262
+ /**
263
+ * Brand specifications.
264
+ */
265
+ brand: {
266
+ /**
267
+ * Automatically fetches the specified font family from google fonts. if the `link` property is specified
268
+ * the font family will be fetched from the provided source instead.
269
+ */
270
+ font?: {
271
+ /**
272
+ * Link to stylesheet that defines font-face.
273
+ */
274
+ link?: string;
275
+ /**
276
+ * Font family. Use FVD notation to include families https://github.com/typekit/fvd
277
+ */
278
+ family: string
279
+ }
280
+ /**
281
+ * Title that will be shown in the app header
282
+ */
283
+ name: string;
284
+ /**
285
+ * Alias that will be shown in the app footer if specified.
286
+ */
287
+ shortName?: string
288
+ /**
289
+ * brand logo
290
+ */
291
+ logo?: string;
292
+ /**
293
+ * Dashboard theme as a custom vuetifyJs theme.
294
+ */
295
+ theme?: ThemeDefinition
296
+ }
297
+ /**
298
+ * Rendered widgets configuration
299
+ */
300
+ template: TemplateConfig<T>
301
+ }
302
+ /////////
303
+
304
+ /// eodash store types
305
+ interface EodashStore {
306
+ /**
307
+ * Stateful Reactive variables
308
+ */
309
+ states: {
310
+ /**
311
+ * Currently selected STAC endpoint
312
+ */
313
+ currentUrl: Ref<string>
314
+ /**
315
+ * OpenLayers map instance
316
+ */
317
+ mapInstance: Ref<Map | null>
318
+ }
319
+ // consider removing the actions ?
320
+ actions: {
321
+ loadFont: (family?: string, link?: string) => Promise<string>;
322
+ };
323
+ /**
324
+ * Pinia store definition used to navigate the root STAC catalog.
325
+ */
326
+ stac: {
327
+ useSTAcStore: typeof useSTAcStore
328
+ }
329
+ }
330
+ ///////
331
+ }
332
+ export type { EodashConfig, EodashStore }
333
+ export declare const defineConfig: typeof defineCompiletimeConfig
@@ -0,0 +1,49 @@
1
+ <template>
2
+ <HeaderComponent />
3
+ <TemplateComponent :style="`height: calc(100dvh - ${mainRect['top'] + mainRect['bottom']}px)`" />
4
+ <FooterComponent />
5
+ </template>
6
+
7
+ <script setup>
8
+ import { useEodashRuntimeConfig } from "@/composables/DefineConfig";
9
+ import { useUpdateTheme } from "@/composables";
10
+ import { useSTAcStore } from '@/store/stac';
11
+ import { defineAsyncComponent } from "vue";
12
+ import { useDisplay, useLayout } from "vuetify/lib/framework.mjs";
13
+ import { loadFont } from '@/store/Actions'
14
+ import { onUnmounted } from "vue";
15
+
16
+
17
+ const eodashConfig = await useEodashRuntimeConfig()
18
+
19
+ const theme = useUpdateTheme('dashboardTheme', eodashConfig.brand?.theme)
20
+ theme.global.name.value = 'dashboardTheme'
21
+
22
+ const fontFamily = await loadFont(eodashConfig.brand?.font?.family, eodashConfig.brand?.font?.link)
23
+
24
+ const { loadSTAC } = useSTAcStore()
25
+ await loadSTAC()
26
+ const { smAndDown } = useDisplay()
27
+ const TemplateComponent = smAndDown.value ?
28
+ defineAsyncComponent(() => import(`@/components/MobileLayout.vue`)) :
29
+ defineAsyncComponent(() => import(`@/components/DashboardLayout.vue`))
30
+
31
+ const HeaderComponent = defineAsyncComponent(() => import(`@/components/Header.vue`))
32
+ const FooterComponent = defineAsyncComponent(() => import(`@/components/Footer.vue`))
33
+ const { mainRect } = useLayout()
34
+
35
+ onUnmounted(() => {
36
+ theme.global.name.value = 'light'
37
+ })
38
+
39
+ import.meta.hot?.on('reload', () => {
40
+ window.location.reload()
41
+ })
42
+
43
+ </script>
44
+
45
+ <style scoped lang="scss">
46
+ * {
47
+ font-family: v-bind('fontFamily');
48
+ }
49
+ </style>
@@ -0,0 +1,35 @@
1
+ /// <reference types="vite/client" />
2
+
3
+ declare module '*.vue' {
4
+ import type { DefineComponent } from 'vue'
5
+ const component: DefineComponent<{}, {}, any>
6
+ export default component
7
+ }
8
+ declare interface Window {
9
+ eodashStore: EodashStore
10
+ }
11
+ declare module '@eox/itemfilter' {
12
+ export const EOxItemFilter: CustomElementConstructor
13
+ }
14
+ declare module '@eox/stacinfo' {
15
+ export const EOxStacInfo: CustomElementConstructor
16
+ }
17
+ declare module '@eox/map' {
18
+ export const EOxMap: CustomElementConstructor
19
+ }
20
+ declare module '@eox/chart' {
21
+ export const EOxChart: CustomElementConstructor
22
+ }
23
+ declare module '@eox/layercontrol' {
24
+ export const EOxLayerControl: CustomElementConstructor
25
+ }
26
+ declare module '@eox/timecontrol' {
27
+ export const EOxTimeControl: CustomElementConstructor
28
+ }
29
+ declare module '@eox/jsonform' {
30
+ export const EOxJSONForm: CustomElementConstructor
31
+ }
32
+ declare module 'user:config' {
33
+ const config: EodashConfig;
34
+ export default config
35
+ }
package/package.json CHANGED
@@ -1,15 +1,23 @@
1
1
  {
2
2
  "name": "@eodash/eodash",
3
- "version": "5.0.0-alpha",
3
+ "version": "5.0.0-alpha.1.1",
4
4
  "type": "module",
5
- "types": "dist/types/index.d.ts",
5
+ "types": "./core/types.d.ts",
6
6
  "files": [
7
- "dist"
7
+ "core",
8
+ "bin",
9
+ "widgets"
8
10
  ],
9
- "browser": "./dist/index.html",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./core/types.d.ts",
14
+ "default": "./core/main.js"
15
+ }
16
+ },
17
+ "browser": "./core/main.js",
10
18
  "scripts": {
11
- "dev": "vite",
12
- "build": "vite build && vite build -c vite-lib.config.js",
19
+ "dev": "npx eodash dev",
20
+ "build": "npx eodash build",
13
21
  "check": "vue-tsc --noEmit --skipLibCheck && eslint .",
14
22
  "check:lint": "eslint .",
15
23
  "check:types": "vue-tsc --noEmit --skipLibCheck",
@@ -18,50 +26,41 @@
18
26
  "docs:generate": "typedoc --plugin typedoc-plugin-markdown core/store/Types.ts --tsconfig tsconfig.json --out docs --readme none"
19
27
  },
20
28
  "dependencies": {
21
- "@eox/chart": "^2.0.0-beta2",
22
- "@eox/drawtools": "^0.6.1",
23
- "@eox/itemfilter": "^0.12.1",
24
- "@eox/jsonform": "^0.2.1",
25
- "@eox/layercontrol": "^0.15.1",
26
29
  "@eox/layout": "^0.1.0",
27
- "@eox/map": "^1.1.0",
28
30
  "@eox/stacinfo": "^0.3.0",
29
- "@eox/timecontrol": "^0.3.0",
30
31
  "@mdi/font": "7.0.96",
32
+ "@vitejs/plugin-vue": "^5.0.0",
31
33
  "animated-details": "gist:2912bb049fa906671807415eb0e87188",
32
34
  "axios": "^1.6.2",
33
- "chokidar": "^3.6.0",
34
35
  "core-js": "^3.29.0",
35
- "express": "^4.18.2",
36
36
  "pinia": "^2.0.0",
37
37
  "roboto-fontface": "*",
38
- "vite": "^4.2.0",
38
+ "vite": "^5.1.5",
39
+ "vite-plugin-virtual": "^0.3.0",
40
+ "vite-plugin-vuetify": "^2.0.0",
39
41
  "vue": "^3.2.0",
40
42
  "vue-router": "^4.0.0",
41
43
  "vuetify": "^3.5.1",
42
44
  "webfontloader": "^1.6.28",
43
- "ws": "^8.16.0"
45
+ "sass": "^1.60.0"
44
46
  },
45
47
  "devDependencies": {
46
48
  "@babel/types": "^7.21.4",
47
49
  "@types/openlayers": "^4.6.23",
48
50
  "@types/webfontloader": "^1.6.38",
49
- "@vitejs/plugin-vue": "^4.0.0",
50
51
  "@vue/eslint-config-typescript": "^11.0.0",
51
52
  "eslint": "^8.56.0",
52
53
  "eslint-plugin-vue": "^9.19.2",
53
- "sass": "^1.60.0",
54
54
  "stac-ts": "^1.0.3",
55
55
  "typedoc": "^0.25.7",
56
56
  "typedoc-plugin-markdown": "^3.17.1",
57
57
  "typescript": "^5.0.0",
58
58
  "unplugin-fonts": "^1.0.3",
59
59
  "vite-plugin-dts": "^3.7.3",
60
- "vite-plugin-vuetify": "^1.0.0",
61
60
  "vue-eslint-parser": "^9.3.2",
62
61
  "vue-tsc": "^1.2.0"
63
62
  },
64
63
  "bin": {
65
64
  "eodash": "./bin/app.js"
66
65
  }
67
- }
66
+ }
@@ -0,0 +1,46 @@
1
+ <template>
2
+ <details is="animated-details" v-for="mod, idx in importedWidgets" ref="detailsEls" :key="idx" class="overflow-auto"
3
+ exclusive>
4
+ <summary ref="summaryEls">{{ mod.value.title }}</summary>
5
+ <span :style="{ height: widgetHeight }" class="d-flex flex-column">
6
+ <component :is="mod.value.component" v-bind="mod.value.props" />
7
+ </span>
8
+ </details>
9
+ </template>
10
+ <script setup>
11
+ import { useDefineWidgets } from '@/composables/DefineWidgets';
12
+ import { onMounted } from 'vue';
13
+ import { ref } from 'vue';
14
+ import { useLayout } from 'vuetify/lib/framework.mjs';
15
+ import 'animated-details'
16
+
17
+ const props = defineProps({
18
+ widgets: {
19
+ /** @type {import('vue').PropType<Omit<WidgetConfig,'layout'>[]>} */
20
+ type: Array,
21
+ required: true,
22
+ }
23
+ })
24
+
25
+ const importedWidgets = useDefineWidgets(props.widgets)
26
+
27
+ /**
28
+ * details elements template ref
29
+ * @type {import('vue').Ref<HTMLDetailsElement[]>}
30
+ **/
31
+ const detailsEls = ref([])
32
+ /**
33
+ * summary elements template ref
34
+ * @type {import('vue').Ref<HTMLDetailsElement[]>}
35
+ **/
36
+ const summaryEls = ref([])
37
+ const widgetHeight = ref('')
38
+ const summariesHeights = ref(0)
39
+
40
+
41
+ onMounted(() => {
42
+ summariesHeights.value = summaryEls.value.reduce((acc, el) => acc += el.clientHeight, 0)
43
+ const { mainRect } = useLayout()
44
+ widgetHeight.value = ((detailsEls.value[0].parentElement?.scrollHeight ?? 0) - summariesHeights.value - mainRect.value['top']) + 'px'
45
+ })
46
+ </script>
package/dist/.gitkeep DELETED
File without changes
@@ -1 +0,0 @@
1
- *[data-v-f69fa805]{font-family:var(--c5aa553c)}
@@ -1 +0,0 @@
1
- import{i as D,e as T,_ as s,u as C,w as i,a as A,b as O,c as w,d as c,f as R,o as x,g as L,h as P,j as d,k as a,n as V,F as j,l as I}from"./index-52c9d989.js";const S=async()=>{const t=D(T);try{const e=(await s(()=>import(new URL("/config.js",self.location).href),[])).default;Object.keys(t).forEach(o=>{t[o]=e[o]})}catch(e){console.error(e)}return t};const k=(t,e)=>{const o=t.__vccOpts||t;for(const[n,_]of e)o[n]=_;return o},F={__name:"Dashboard",async setup(t){var u;let e,o;C(r=>({c5aa553c:a(h)}));const n=([e,o]=i(()=>S()),e=await e,o(),e),_=A("dashboardTheme",(u=n.brand)==null?void 0:u.theme);_.global.name.value="dashboardTheme";const h=([e,o]=i(()=>{var r,l,f,p;return I((l=(r=n.brand)==null?void 0:r.font)==null?void 0:l.family,(p=(f=n.brand)==null?void 0:f.font)==null?void 0:p.link)}),e=await e,o(),e),{loadSTAC:y}=O();[e,o]=i(()=>y()),await e,o();const{smAndDown:b}=w(),g=b.value?c(()=>s(()=>import("./MobileLayout-1b3cb89b.js"),["assets/MobileLayout-1b3cb89b.js","assets/index-52c9d989.js","assets/index-5d2400e5.css","assets/VMain-f6b3f120.js","assets/ssrBoot-d383eb61.js","assets/color-6039ab34.js","assets/ssrBoot-0b8754a9.css","assets/VMain-d6216866.css","assets/MobileLayout-ad647682.css"])):c(()=>s(()=>import("./DashboardLayout-5ab6c4a5.js"),["assets/DashboardLayout-5ab6c4a5.js","assets/index-52c9d989.js","assets/index-5d2400e5.css","assets/VMain-f6b3f120.js","assets/ssrBoot-d383eb61.js","assets/color-6039ab34.js","assets/ssrBoot-0b8754a9.css","assets/VMain-d6216866.css","assets/DashboardLayout-739135c5.css"])),v=c(()=>s(()=>import("./Header-ae17296c.js"),["assets/Header-ae17296c.js","assets/index-52c9d989.js","assets/index-5d2400e5.css","assets/color-6039ab34.js","assets/ssrBoot-d383eb61.js","assets/ssrBoot-0b8754a9.css","assets/Header-9cac598d.css"])),E=c(()=>s(()=>import("./Footer-7e1ca735.js"),["assets/Footer-7e1ca735.js","assets/index-52c9d989.js","assets/index-5d2400e5.css","assets/color-6039ab34.js","assets/Footer-0fe1887a.css"])),{mainRect:m}=R();return x(()=>{_.global.name.value="light"}),(r,l)=>(L(),P(j,null,[d(a(v)),d(a(g),{style:V(`height: calc(100dvh - ${a(m).top+a(m).bottom}px)`)},null,8,["style"]),d(a(E))],64))}},U=k(F,[["__scopeId","data-v-f69fa805"]]),B=Object.freeze(Object.defineProperty({__proto__:null,default:U},Symbol.toStringTag,{value:"Module"}));export{B as D,k as _};
@@ -1,29 +0,0 @@
1
- import{i as w,e as k,x as v,L as C,g as r,y as d,z as g,E as m,k as e,A as y,B as A,C as L,h as _,F as E,D as B,j as b,n as V,J as $}from"./index-52c9d989.js";import{u as f,V as D}from"./VMain-f6b3f120.js";import{_ as I}from"./Dashboard-d7d438a6.js";import{V as M,a as z}from"./ssrBoot-d383eb61.js";import"./color-6039ab34.js";class H extends HTMLElement{static get observedAttributes(){return["gap"]}constructor(){super(),this.attachShadow({mode:"open"}),this.render()}render(){this.shadowRoot.innerHTML=`
2
- <style>
3
- :host {
4
- display: grid;
5
- padding: ${this.getAttribute("gap")||0}px;
6
- height: 100%;
7
- box-sizing: border-box;
8
- gap: ${this.getAttribute("gap")||"0"}px;
9
- grid-template-columns: repeat(12, 1fr);
10
- grid-template-rows: repeat(12, 1fr);
11
- }
12
- </style>
13
- <slot></slot>
14
- `}attributeChangedCallback(o,a,t){a!==t&&(this[o]=t),this.render()}}class P extends HTMLElement{static get observedAttributes(){return["x","y","w","h"]}constructor(){super(),this.attachShadow({mode:"open"}),this.render()}render(){this.shadowRoot.innerHTML=`
15
- <style>
16
- :host {
17
- background: lightgrey;
18
- border: 1px solid darkgrey;
19
- border-radius: 4px;
20
- padding: 4px 8px;
21
- overflow: hidden;
22
-
23
-
24
- grid-column: ${parseInt(this.getAttribute("x"))+1} / span ${this.getAttribute("w")};
25
- grid-row: ${parseInt(this.getAttribute("y"))+1} / span ${this.getAttribute("h")};
26
- }
27
- </style>
28
- <slot></slot>
29
- `}attributeChangedCallback(o,a,t){a!==t&&(this[o]=t),this.render()}}customElements.define("eox-layout",H);customElements.define("eox-layout-item",P);const S=["gap"],T={class:"bg-widget",x:"0",y:"0",h:"12",w:"12"},R=["x","y","h","w"],W={__name:"DashboardLayout",setup(u){var p,h;const o=w(k),[a]=f([(p=o.template)==null?void 0:p.background]),t=(h=o.template)==null?void 0:h.widgets,l=f(t),c=v([]),{slideBtns:n,slideInOut:x}=C(c,t);return(j,F)=>(r(),d(D,null,{default:g(()=>[m("eox-layout",{gap:e(o).template.gap??2},[m("eox-layout-item",T,[(r(),d(y(e(a).component),A(L(e(a).props)),null,16))]),(r(!0),_(E,null,B(e(t),(i,s)=>(r(),_("eox-layout-item",{ref_for:!0,ref_key:"itemEls",ref:c,key:s,class:"custom-widget",x:i.layout.x,y:i.layout.y,h:i.layout.h,w:i.layout.w},[b(M,{position:"absolute",variant:"tonal",style:V(e(n)[s].style),class:"slide-btn",onClick:N=>e(x)(s)},{default:g(()=>[b(z,{icon:e(n)[s].active?e(n)[s].icon.in:e(n)[s].icon.out},null,8,["icon"])]),_:2},1032,["style","onClick"]),(r(),d(y(e(l)[s].value.component),$({key:e(l)[s].value.id},e(l)[s].value.props),null,16))],8,R))),128))],8,S)]),_:1}))}},Q=I(W,[["__scopeId","data-v-66a736e2"]]);export{Q as default};
@@ -1 +0,0 @@
1
- eox-layout-item[data-v-66a736e2]{background:rgb(var(--v-theme-surface))}.bg-widget[data-v-66a736e2]{z-index:0}.custom-widget[data-v-66a736e2]{position:relative;overflow:visible;z-index:1}
@@ -1 +0,0 @@
1
- import{w as p,b as d,x as f,ac as E,a6 as y,o as v,g as u,h as w,y as x,J as P,A as g,_ as t}from"./index-52c9d989.js";const A={class:"d-flex flex-column fill-height overflow-auto"},T={__name:"DynamicWebComponent",props:{link:{type:String,required:!0},constructorProp:String,tagName:{type:String,required:!0},properties:{type:Object,default:()=>({})},onMounted:Function,onUnmounted:Function},async setup(a){let n,i;const e=a,s={"@eox/itemfilter":async()=>await t(()=>import("./eox-itemfilter-a63da0da.js"),[]),"@eox/stacinfo":async()=>await t(()=>import("./eox-stacinfo-65a8d8f3.js"),[]),"@eox/map":async()=>await t(()=>import("./eox-map-7f82b0d4.js"),[]),"@eox/chart":async()=>await t(()=>import("./eox-chart-3b122ba4.js"),[]),"@eox/jsonform":async()=>await t(()=>import("./eox-jsonform-98c2af62.js"),[]),"@eox/layercontrol":async()=>await t(()=>import("./eox-layercontrol-f5e35702.js"),[]),"@eox/timecontrol":async()=>await t(()=>import("./eox-timecontrol-4be63aa2.js"),[])},m=async()=>e.link in s?await s[e.link]():await t(()=>import(e.link),[]),l=([n,i]=p(()=>m().catch(r=>{console.error(r)})),n=await n,i(),n);if(!customElements.get(e.tagName)&&e.constructorProp){const r=l[e.constructorProp];customElements.define(e.tagName,r)}const c=d(),o=f(null),_=E();return y(()=>{e.onMounted&&o.value&&e.onMounted(o.value,c,_)}),v(()=>{e.onUnmounted&&o.value&&e.onUnmounted(o.value,c,_)}),(r,D)=>(u(),w("span",A,[(u(),x(g(a.tagName),P(a.properties,{ref_key:"elementRef",ref:o}),null,16))]))}};export{T as default};
@@ -1 +0,0 @@
1
- .footer-text[data-v-e72ddfbf]{font-size:.8rem}.v-footer{align-items:center;display:flex;flex:1 1 auto;padding:8px 16px;position:relative;transition:.2s cubic-bezier(.4,0,.2,1);transition-property:height,width,transform,max-width,left,right,top,bottom;border-color:rgba(var(--v-border-color),var(--v-border-opacity));border-style:solid;border-width:0;box-shadow:0 0 0 0 var(--v-shadow-key-umbra-opacity, rgba(0, 0, 0, .2)),0 0 0 0 var(--v-shadow-key-penumbra-opacity, rgba(0, 0, 0, .14)),0 0 0 0 var(--v-shadow-key-ambient-opacity, rgba(0, 0, 0, .12));border-radius:0;background:rgb(var(--v-theme-surface));color:rgba(var(--v-theme-on-surface),var(--v-high-emphasis-opacity))}.v-footer--border{border-width:thin;box-shadow:none}.v-footer--absolute{position:absolute}.v-footer--fixed{position:fixed}.v-footer--rounded{border-radius:4px}
@@ -1 +0,0 @@
1
- import{q as y,r as b,a7 as k,a1 as C,s as x,a2 as F,V as h,M as I,ar as S,t,aa as P,Q as V,j as w,a0 as B,x as R,i as z,e as N,c as T,g as D,y as j,z as E,E as u,I as H,G as g,k as _,aw as L,ax as M}from"./index-52c9d989.js";import{_ as q}from"./Dashboard-d7d438a6.js";import{c as A,d as G,a as K,m as O,u as Q,e as U,f as Y,b as $}from"./color-6039ab34.js";const J=y({app:Boolean,color:String,height:{type:[Number,String],default:"auto"},...A(),...b(),...G(),...k(),...K(),...O({tag:"footer"}),...C()},"VFooter"),W=x()({name:"VFooter",props:J(),setup(e,r){let{slots:a}=r;const{themeClasses:n}=F(e),{backgroundColorClasses:l,backgroundColorStyles:o}=Q(h(e,"color")),{borderClasses:s}=U(e),{elevationClasses:c}=Y(e),{roundedClasses:i}=$(e),d=I(32),{resizeRef:p}=S(f=>{f.length&&(d.value=f[0].target.clientHeight)}),m=t(()=>e.height==="auto"?d.value:parseInt(e.height,10)),{layoutItemStyles:v}=P({id:e.name,order:t(()=>parseInt(e.order,10)),position:t(()=>"bottom"),layoutSize:m,elementSize:t(()=>e.height==="auto"?void 0:m.value),active:t(()=>e.app),absolute:h(e,"absolute")});return V(()=>w(e.tag,{ref:p,class:["v-footer",n.value,l.value,s.value,c.value,i.value,e.class],style:[o.value,e.app?v.value:{height:B(e.height)},e.style]},a)),{}}}),X=e=>(L("data-v-e72ddfbf"),e=e(),M(),e),Z=X(()=>u("p",{class:"pt-0 footer-text"}," Phasellus feugiat arcu sapien, et iaculis ipsum elementum sit amet. Mauris cursus commodo interdum. ",-1)),ee={class:"footer-text"},te={__name:"Footer",setup(e){var o,s;const r=R(null),a=z(N),n=((o=a.brand)==null?void 0:o.shortName)??((s=a.brand)==null?void 0:s.name),{mdAndDown:l}=T();return(c,i)=>(D(),j(W,{ref_key:"footer",ref:r,height:_(l)?"48px":"auto",color:"secondary",app:"",class:"d-flex justify-space-between"},{default:E(()=>[Z,u("div",ee,[H(g(new Date().getFullYear())+" — ",1),u("strong",null,g(_(n)),1)])]),_:1},8,["height"]))}},re=q(te,[["__scopeId","data-v-e72ddfbf"]]);export{re as default};