@eodash/eodash 5.0.0-alpha.2.1 → 5.0.0-alpha.2.10
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 +36 -3
- package/core/client/App.vue +26 -0
- package/core/client/SuspensedDashboard.ce.vue +105 -0
- package/core/client/asWebComponent.d.ts +23 -0
- package/core/client/asWebComponent.js +12 -0
- package/core/client/components/DashboardLayout.vue +77 -0
- package/core/client/components/DynamicWebComponent.vue +68 -0
- package/core/client/components/ErrorAlert.vue +36 -0
- package/core/{components → client/components}/Footer.vue +34 -15
- package/core/client/components/Header.vue +19 -0
- package/core/client/components/IframeWrapper.vue +11 -0
- package/core/client/components/Loading.vue +37 -0
- package/core/client/components/MobileLayout.vue +109 -0
- package/core/client/composables/DefineEodash.js +67 -0
- package/core/client/composables/DefineWidgets.js +161 -0
- package/core/client/composables/index.js +136 -0
- package/core/client/eodash.js +136 -0
- package/core/client/main.js +2 -0
- package/core/client/plugins/index.js +20 -0
- package/core/client/plugins/vuetify.js +35 -0
- package/core/client/render.js +12 -0
- package/core/client/store/Actions.js +62 -0
- package/core/client/store/States.js +21 -0
- package/core/client/store/index.js +20 -0
- package/core/client/store/stac.js +81 -0
- package/core/client/types.d.ts +287 -0
- package/core/client/utils/eodashSTAC.js +337 -0
- package/core/client/utils/helpers.js +172 -0
- package/core/client/utils/index.js +51 -0
- package/core/{utils → client/utils}/keys.js +2 -2
- package/core/client/views/Dashboard.vue +116 -0
- package/core/client/vite-env.d.ts +39 -0
- package/dist/client/DashboardLayout-C_3q8Y10.js +156 -0
- package/dist/{DynamicWebComponent-BrHVTesn.js → client/DynamicWebComponent-IiTTLBt-.js} +11 -11
- package/dist/client/EodashDatePicker-DgC1lccp.js +252 -0
- package/dist/{eox-itemfilter-DcQkRD2l.js → client/EodashItemFilter-DoWZGe6r.js} +1515 -1381
- package/dist/client/EodashMap-C96D3LLv.js +114352 -0
- package/dist/client/EodashMapBtns-DDtzV94u.js +50 -0
- package/dist/client/ExportState-CduS2mFs.js +558 -0
- package/dist/client/Footer-DHQcutCv.js +115 -0
- package/dist/client/Header-DC0y7rLK.js +350 -0
- package/dist/{IframeWrapper-Dd9zrX9s.js → client/IframeWrapper-BK-10FbS.js} +4 -4
- package/dist/client/MobileLayout-BpLoMY4i.js +945 -0
- package/dist/client/PopUp-CNMCWL0z.js +300 -0
- package/dist/client/VImg-DT7eb8V-.js +291 -0
- package/dist/client/VMain-OenWyy46.js +39 -0
- package/dist/client/VOverlay-x3UXpKhr.js +972 -0
- package/dist/{WidgetsContainer-DxfCu0I3.js → client/WidgetsContainer-qMUwtN0W.js} +24 -17
- package/dist/client/asWebComponent-DQrnLsI2.js +20404 -0
- package/dist/{basedecoder-Qm25PwVp-CHo5Pomv.js → client/basedecoder-DHcBySSe-BmCFNFnw.js} +5 -6
- package/dist/{decoder-kAoyGIq9-BBR5CgzS.js → client/decoder-Cth6J7EK-CtUoHA6r.js} +1 -1
- package/dist/client/deflate-BXt-9JA_-CWfClgpK.js +10 -0
- package/dist/client/eo-dash.js +6 -0
- package/dist/client/eox-jsonform-DCErgjhw.js +17515 -0
- package/dist/client/eox-layercontrol-D0Ht7Mag.js +21298 -0
- package/dist/client/eox-stacinfo-l7ALSV90.js +13969 -0
- package/dist/client/forwardRefs-CpNjL95t.js +185 -0
- package/dist/client/helpers-KCSgmfim.js +1417 -0
- package/dist/{index-DTkOfh2g.js → client/index-DopVrUzM.js} +22 -21
- package/dist/{jpeg-DNfUpLwy-Fjan-04T.js → client/jpeg-BAgeD1d3-oeHbFPUL.js} +5 -6
- package/dist/{lerc-C9VL9kri-cIdbW0sg.js → client/lerc-BgbQqdFI-D986ErVw.js} +37 -39
- package/dist/{lzw-BOMhmEDy-Dboc93VO.js → client/lzw-LAGDNbSC-DkP96qO9.js} +1 -1
- package/dist/{packbits-DaUD6MLm-Bu1PoTGa.js → client/packbits-BlDR4Kj5-C66n1-zr.js} +1 -1
- package/dist/{pako.esm-C3kYPGGQ-BMki8cQY.js → client/pako.esm-CB1uQYY0-DB0PYm1P.js} +6 -12
- package/dist/{raw-CcGKjn8q-DFOt-i8n.js → client/raw-CMGvRjfu-BRi6E4i1.js} +1 -1
- package/dist/{ssrBoot-D-b4-M19.js → client/ssrBoot-DkjdOWvj.js} +1 -1
- package/dist/client/style.css +5 -0
- package/dist/client/transition-BtJHh7JK.js +34 -0
- package/dist/{webfontloader-CyOFAuFB.js → client/webfontloader-qotgY98I.js} +56 -92
- package/dist/{webimage-D2c098k3-DLj1LQxB.js → client/webimage-BM_pbLN3-L2cGWK5l.js} +1 -1
- package/dist/node/cli.js +20 -0
- package/dist/node/main.js +2 -0
- package/dist/node/types.d.ts +47 -0
- package/package.json +54 -51
- package/widgets/EodashDatePicker.vue +145 -40
- package/widgets/EodashItemFilter.vue +73 -38
- package/widgets/EodashMap.vue +210 -37
- package/widgets/EodashMapBtns.vue +50 -0
- package/widgets/ExportState.vue +112 -0
- package/widgets/PopUp.vue +40 -0
- package/widgets/WidgetsContainer.vue +47 -27
- package/bin/app.js +0 -22
- package/bin/cli.js +0 -62
- package/bin/main.js +0 -9
- package/bin/serverConfig.js +0 -165
- package/bin/types.d.ts +0 -52
- package/bin/utils.js +0 -103
- package/core/App.vue +0 -19
- package/core/SuspensedDashboard.ce.vue +0 -65
- package/core/asWebComponent.d.ts +0 -18
- package/core/asWebComponent.js +0 -12
- package/core/components/DashboardLayout.vue +0 -44
- package/core/components/DynamicWebComponent.vue +0 -68
- package/core/components/Header.vue +0 -14
- package/core/components/IframeWrapper.vue +0 -11
- package/core/components/Loading.vue +0 -27
- package/core/components/MobileLayout.vue +0 -49
- package/core/composables/DefineEodash.js +0 -57
- package/core/composables/DefineWidgets.js +0 -129
- package/core/composables/index.js +0 -219
- package/core/eodash.js +0 -100
- package/core/main.js +0 -2
- package/core/plugins/index.js +0 -18
- package/core/plugins/vuetify.js +0 -30
- package/core/render.js +0 -13
- package/core/store/Actions.js +0 -0
- package/core/store/States.js +0 -21
- package/core/store/index.js +0 -17
- package/core/store/stac.js +0 -63
- package/core/types.d.ts +0 -356
- package/core/utils/eodashSTAC.js +0 -164
- package/core/utils/helpers.js +0 -40
- package/core/utils/index.js +0 -28
- package/core/views/Dashboard.vue +0 -59
- package/core/vite-env.d.ts +0 -31
- package/dist/DashboardLayout-Dp8AnYD9.js +0 -141
- package/dist/EodashDatePicker-D_udZ26j.js +0 -1645
- package/dist/EodashItemFilter-BLAGx2UD.js +0 -51
- package/dist/EodashMap-Bxl_aqY2.js +0 -53405
- package/dist/Footer-AohCH8U7.js +0 -118
- package/dist/Header-DC50S6GR.js +0 -609
- package/dist/MobileLayout-CgToA7Gp.js +0 -523
- package/dist/VBtn-Bz7ruRUg.js +0 -1106
- package/dist/VMain-BHfWJU2j.js +0 -35
- package/dist/asWebComponent-C8rb3b1D.js +0 -11323
- package/dist/color-DpYEub1f.js +0 -115
- package/dist/deflate-Be2Arps5-hDqMz3RA.js +0 -10
- package/dist/dimensions-CJaGeSrj.js +0 -53
- package/dist/eo-dash.js +0 -6
- package/dist/eox-map-BJ9SIixs.js +0 -36205
- package/dist/eox-stacinfo-B-YrT7Ug.js +0 -13698
- package/dist/forwardRefs-Bxeu9Obx.js +0 -142
- package/dist/index-Sa2Vg_gx.js +0 -65
- package/dist/style.css +0 -5
- /package/dist/{.gitkeep → client/.gitkeep} +0 -0
- /package/dist/{_commonjsHelpers-DaMA6jEr.js → client/_commonjsHelpers-DaMA6jEr.js} +0 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import store from "@/store";
|
|
2
|
+
import { eodashKey } from "@/utils/keys";
|
|
3
|
+
import { inject } from "vue";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Sets user defined instance on runtime. Consumes `/@fs/config.js` and assign
|
|
7
|
+
* it to `eodash`
|
|
8
|
+
*
|
|
9
|
+
* @async
|
|
10
|
+
* @param {string | undefined} runtimeConfig
|
|
11
|
+
* @returns {Promise<import("@/types").Eodash>}
|
|
12
|
+
* @see {@linkplain '@/eodash.js'}
|
|
13
|
+
*/
|
|
14
|
+
export const useEodashRuntime = async (runtimeConfig) => {
|
|
15
|
+
const eodash = /** @type {import("@/types").Eodash} */ (inject(eodashKey));
|
|
16
|
+
/** @param {import("@/types").Eodash} config */
|
|
17
|
+
const assignInstance = (config) => {
|
|
18
|
+
/** @type {(keyof import("@/types").Eodash)[]} */ (
|
|
19
|
+
Object.keys(eodash)
|
|
20
|
+
).forEach((key) => {
|
|
21
|
+
//@ts-expect-error to do
|
|
22
|
+
eodash[key] = config[key];
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
if (runtimeConfig) {
|
|
27
|
+
assignInstance(
|
|
28
|
+
(
|
|
29
|
+
await import(
|
|
30
|
+
/* @vite-ignore */ new URL(runtimeConfig, import.meta.url).href
|
|
31
|
+
)
|
|
32
|
+
).default,
|
|
33
|
+
);
|
|
34
|
+
return eodash;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
const configJs = "/config.js";
|
|
39
|
+
assignInstance(
|
|
40
|
+
(await import(/* @vite-ignore */ new URL(configJs, import.meta.url).href))
|
|
41
|
+
.default,
|
|
42
|
+
);
|
|
43
|
+
} catch {
|
|
44
|
+
try {
|
|
45
|
+
assignInstance(
|
|
46
|
+
await import("user:config").then(async (m) => await m["default"]),
|
|
47
|
+
);
|
|
48
|
+
} catch {
|
|
49
|
+
console.error("no dashboard configuration defined");
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return eodash;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @param {((
|
|
57
|
+
* store: import("@/types").EodashStore,
|
|
58
|
+
* ) => Promise<import("@/types").Eodash>)
|
|
59
|
+
* | import("@/types").Eodash} config
|
|
60
|
+
*/
|
|
61
|
+
export const createEodash = async (config) => {
|
|
62
|
+
if (config instanceof Function) {
|
|
63
|
+
return await config(store);
|
|
64
|
+
} else {
|
|
65
|
+
return config;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { defineAsyncComponent, reactive, shallowRef, watch } from "vue";
|
|
2
|
+
import { useSTAcStore } from "@/store/stac";
|
|
3
|
+
import { storeToRefs } from "pinia";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {{
|
|
7
|
+
* component: import("vue").Component | null;
|
|
8
|
+
* props: Record<string, unknown>;
|
|
9
|
+
* title: string;
|
|
10
|
+
* id: string | number | symbol;
|
|
11
|
+
* layout: { x: number; y: number; h: number; w: number };
|
|
12
|
+
* }} DefinedWidget
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/** @typedef {import("vue").ShallowRef<DefinedWidget>} ReactiveDefinedWidget */
|
|
16
|
+
|
|
17
|
+
const internalWidgets = (() => {
|
|
18
|
+
/** @type {Record<string, () => Promise<import("vue").Component>>} */
|
|
19
|
+
const importMap = {
|
|
20
|
+
...import.meta.glob("^/**/*.vue"),
|
|
21
|
+
...import.meta.glob("user:widgets/**/*.vue"),
|
|
22
|
+
};
|
|
23
|
+
for (const key in importMap) {
|
|
24
|
+
const newKey = /** @type {string} */ (key.split("/").at(-1)).slice(0, -4);
|
|
25
|
+
Object.defineProperty(
|
|
26
|
+
importMap,
|
|
27
|
+
newKey,
|
|
28
|
+
/** @type {PropertyDescriptor} */ (
|
|
29
|
+
Object.getOwnPropertyDescriptor(importMap, key)
|
|
30
|
+
),
|
|
31
|
+
);
|
|
32
|
+
delete importMap[key];
|
|
33
|
+
}
|
|
34
|
+
return importMap;
|
|
35
|
+
})();
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Composable that converts widgets Configurations to defined imported widgets
|
|
39
|
+
*
|
|
40
|
+
* @param {(
|
|
41
|
+
* | import("@/types").Widget
|
|
42
|
+
* | import("@/types").BackgroundWidget
|
|
43
|
+
* | Omit<import("@/types").Widget, "layout">
|
|
44
|
+
* | undefined
|
|
45
|
+
* )[]
|
|
46
|
+
* | undefined} widgetConfigs
|
|
47
|
+
* @returns {ReactiveDefinedWidget[]}
|
|
48
|
+
*/
|
|
49
|
+
export const useDefineWidgets = (widgetConfigs) => {
|
|
50
|
+
/** @type {ReactiveDefinedWidget[]} */
|
|
51
|
+
const definedWidgets = [];
|
|
52
|
+
|
|
53
|
+
for (const config of widgetConfigs ?? []) {
|
|
54
|
+
/** @type {ReactiveDefinedWidget} */
|
|
55
|
+
const definedWidget = shallowRef({
|
|
56
|
+
component: null,
|
|
57
|
+
props: {},
|
|
58
|
+
title: "",
|
|
59
|
+
id: Symbol(),
|
|
60
|
+
layout: { x: 0, y: 0, h: 0, w: 0 },
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
if ("defineWidget" in (config ?? {})) {
|
|
64
|
+
const { selectedStac } = storeToRefs(useSTAcStore());
|
|
65
|
+
watch(
|
|
66
|
+
selectedStac,
|
|
67
|
+
(updatedStac) => {
|
|
68
|
+
let definedConfig =
|
|
69
|
+
/** @type {import("@/types").FunctionalWidget} */ (
|
|
70
|
+
config
|
|
71
|
+
)?.defineWidget(updatedStac);
|
|
72
|
+
if (definedConfig) {
|
|
73
|
+
definedConfig = reactive(definedConfig);
|
|
74
|
+
}
|
|
75
|
+
definedWidget.value =
|
|
76
|
+
definedWidget.value.id === definedConfig?.id
|
|
77
|
+
? definedWidget.value
|
|
78
|
+
: getWidgetDefinition(definedConfig);
|
|
79
|
+
},
|
|
80
|
+
{ immediate: true },
|
|
81
|
+
);
|
|
82
|
+
} else {
|
|
83
|
+
definedWidget.value = getWidgetDefinition(
|
|
84
|
+
/** @type {import("@/types").StaticWidget} */ (config),
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
definedWidgets.push(definedWidget);
|
|
88
|
+
}
|
|
89
|
+
return definedWidgets;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Converts a static widget configuration to a defined imported widget
|
|
94
|
+
*
|
|
95
|
+
* @param {import("@/types").StaticWidget
|
|
96
|
+
* | Omit<import("@/types").StaticWidget, "layout">
|
|
97
|
+
* | undefined
|
|
98
|
+
* | null} [config]
|
|
99
|
+
* @returns {DefinedWidget}
|
|
100
|
+
*/
|
|
101
|
+
const getWidgetDefinition = (config) => {
|
|
102
|
+
/** @type {DefinedWidget} */
|
|
103
|
+
const importedWidget = {
|
|
104
|
+
component: null,
|
|
105
|
+
props: {},
|
|
106
|
+
title: "",
|
|
107
|
+
id: Symbol(),
|
|
108
|
+
layout: reactive({ x: 0, y: 0, h: 0, w: 0 }),
|
|
109
|
+
};
|
|
110
|
+
switch (config?.type) {
|
|
111
|
+
case "internal":
|
|
112
|
+
importedWidget.component = defineAsyncComponent({
|
|
113
|
+
loader:
|
|
114
|
+
internalWidgets[
|
|
115
|
+
/** @type {import("@/types").InternalComponentWidget} * */ (config)
|
|
116
|
+
?.widget.name
|
|
117
|
+
],
|
|
118
|
+
suspensible: true,
|
|
119
|
+
});
|
|
120
|
+
importedWidget.props = reactive(
|
|
121
|
+
/** @type {import("@/types").InternalComponentWidget} * */ (config)
|
|
122
|
+
?.widget.properties ?? {},
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
break;
|
|
126
|
+
|
|
127
|
+
case "web-component":
|
|
128
|
+
importedWidget.component = defineAsyncComponent({
|
|
129
|
+
loader: () => import("@/components/DynamicWebComponent.vue"),
|
|
130
|
+
suspensible: true,
|
|
131
|
+
});
|
|
132
|
+
importedWidget.props = reactive(config.widget);
|
|
133
|
+
|
|
134
|
+
break;
|
|
135
|
+
case "iframe":
|
|
136
|
+
importedWidget.component = defineAsyncComponent({
|
|
137
|
+
loader: () => import("@/components/IframeWrapper.vue"),
|
|
138
|
+
suspensible: true,
|
|
139
|
+
});
|
|
140
|
+
importedWidget.props = reactive(config.widget);
|
|
141
|
+
break;
|
|
142
|
+
|
|
143
|
+
default:
|
|
144
|
+
if (!config) {
|
|
145
|
+
return importedWidget;
|
|
146
|
+
} else {
|
|
147
|
+
console.error("Widget type not found");
|
|
148
|
+
}
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
importedWidget.title = config?.title ?? "";
|
|
152
|
+
importedWidget.id = config?.id ?? importedWidget.id;
|
|
153
|
+
|
|
154
|
+
if ("layout" in config) {
|
|
155
|
+
importedWidget.layout.x = config.layout.x;
|
|
156
|
+
importedWidget.layout.y = config.layout.y;
|
|
157
|
+
importedWidget.layout.h = config.layout.h;
|
|
158
|
+
importedWidget.layout.w = config.layout.w;
|
|
159
|
+
}
|
|
160
|
+
return importedWidget;
|
|
161
|
+
};
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
// functions of this folder can only be consumed inside setup stores,
|
|
2
|
+
// setup functions or vue composition api components
|
|
3
|
+
|
|
4
|
+
import { currentUrl, indicator, mapPosition } from "@/store/States";
|
|
5
|
+
import eodash from "@/eodash";
|
|
6
|
+
import { useTheme } from "vuetify/lib/framework.mjs";
|
|
7
|
+
import { onMounted, watch } from "vue";
|
|
8
|
+
import { useSTAcStore } from "@/store/stac";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Creates an absolute URL from a relative link and assignes it to `currentUrl`
|
|
12
|
+
*
|
|
13
|
+
* @param {string} [rel=''] Default is `''`
|
|
14
|
+
* @param {string} [base=eodash.stacEndpoint] - Base URL, default value is the
|
|
15
|
+
* root stac catalog. Default is `eodash.stacEndpoint`
|
|
16
|
+
* @returns {import("vue").Ref<string>} - Returns `currentUrl`
|
|
17
|
+
* @see {@link '@/store/States.js'}
|
|
18
|
+
*/
|
|
19
|
+
export const useAbsoluteUrl = (rel = "", base = eodash.stacEndpoint) => {
|
|
20
|
+
if (!rel || rel.includes("http")) {
|
|
21
|
+
currentUrl.value = base;
|
|
22
|
+
return currentUrl;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const st = base.split("/");
|
|
26
|
+
const arr = rel.split("/");
|
|
27
|
+
st.pop();
|
|
28
|
+
|
|
29
|
+
for (let i = 0; i < arr.length; i++) {
|
|
30
|
+
if (arr[i] == ".") continue;
|
|
31
|
+
if (arr[i] == "..") st.pop();
|
|
32
|
+
else st.push(arr[i]);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
currentUrl.value = st.join("/");
|
|
36
|
+
return currentUrl;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Updates an existing Vuetify theme. updates only the values provided in the
|
|
41
|
+
* `ThemeDefinition`
|
|
42
|
+
*
|
|
43
|
+
* @param {string} themeName - Name of the theme to be updated
|
|
44
|
+
* @param {import("vuetify").ThemeDefinition} [themeDefinition={}] - New
|
|
45
|
+
* defintion to be updated to. Default is `{}`
|
|
46
|
+
* @returns {import("vuetify").ThemeInstance}
|
|
47
|
+
*/
|
|
48
|
+
export const useUpdateTheme = (themeName, themeDefinition = {}) => {
|
|
49
|
+
const theme = useTheme();
|
|
50
|
+
|
|
51
|
+
/** @type {(keyof import("vuetify").ThemeDefinition)[]} */ (
|
|
52
|
+
Object.keys(themeDefinition)
|
|
53
|
+
).forEach((key) => {
|
|
54
|
+
if (key === "dark") {
|
|
55
|
+
theme.themes.value[themeName][key] = /** @type {Boolean} */ (
|
|
56
|
+
themeDefinition[key]
|
|
57
|
+
);
|
|
58
|
+
} else {
|
|
59
|
+
//@ts-expect-error to do
|
|
60
|
+
theme.themes.value[themeName][key] = {
|
|
61
|
+
...theme.themes.value[themeName][key],
|
|
62
|
+
...themeDefinition[key],
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
return theme;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/** Composable that syncs store and URLSearchParameters */
|
|
70
|
+
|
|
71
|
+
export const useURLSearchParametersSync = () => {
|
|
72
|
+
onMounted(async () => {
|
|
73
|
+
// Analyze currently set url params when first loaded and set them in the store
|
|
74
|
+
if ("URLSearchParams" in window) {
|
|
75
|
+
const searchParams = new URLSearchParams(window.location.search);
|
|
76
|
+
/** @type {number | undefined} */
|
|
77
|
+
let x,
|
|
78
|
+
/** @type {number | undefined} */
|
|
79
|
+
y,
|
|
80
|
+
/** @type {number | undefined} */
|
|
81
|
+
z;
|
|
82
|
+
searchParams.forEach(async (value, key) => {
|
|
83
|
+
if (key === "indicator") {
|
|
84
|
+
const { loadSelectedSTAC, stac } = useSTAcStore();
|
|
85
|
+
const match = stac?.find((link) => link.id == value);
|
|
86
|
+
if (match) {
|
|
87
|
+
await loadSelectedSTAC(match.href);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (key === "x") {
|
|
91
|
+
x = Number(value);
|
|
92
|
+
}
|
|
93
|
+
if (key === "y") {
|
|
94
|
+
y = Number(value);
|
|
95
|
+
}
|
|
96
|
+
if (key === "z") {
|
|
97
|
+
z = Number(value);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
if (x && y && z) {
|
|
101
|
+
mapPosition.value = [x, y, z];
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
watch(
|
|
105
|
+
[indicator, mapPosition],
|
|
106
|
+
([updatedIndicator, updatedMapPosition]) => {
|
|
107
|
+
if ("URLSearchParams" in window) {
|
|
108
|
+
const searchParams = new URLSearchParams(window.location.search);
|
|
109
|
+
if (updatedIndicator !== "") {
|
|
110
|
+
searchParams.set("indicator", updatedIndicator);
|
|
111
|
+
}
|
|
112
|
+
if (updatedMapPosition && updatedMapPosition.length === 3) {
|
|
113
|
+
searchParams.set("x", updatedMapPosition[0]?.toFixed(4) ?? "");
|
|
114
|
+
searchParams.set("y", updatedMapPosition[1]?.toFixed(4) ?? "");
|
|
115
|
+
searchParams.set("z", updatedMapPosition[2]?.toFixed(4) ?? "");
|
|
116
|
+
}
|
|
117
|
+
const newRelativePathQuery =
|
|
118
|
+
window.location.pathname + "?" + searchParams.toString();
|
|
119
|
+
history.pushState(null, "", newRelativePathQuery);
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
);
|
|
123
|
+
});
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
/** @param {import("vue").Ref<HTMLElement|null>} root - components root element ref*/
|
|
127
|
+
export const makePanelTransparent = (root) => {
|
|
128
|
+
onMounted(() => {
|
|
129
|
+
const eoxItem = root.value?.parentElement;
|
|
130
|
+
if (eoxItem?.tagName === "EOX-LAYOUT-ITEM") {
|
|
131
|
+
eoxItem.classList.remove("bg-surface");
|
|
132
|
+
eoxItem.style.background = "transparent";
|
|
133
|
+
eoxItem.style.border = "transparent";
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
};
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { reactive } from "vue";
|
|
2
|
+
import { currentUrl } from "./store/States";
|
|
3
|
+
/**
|
|
4
|
+
* Reactive Edoash Instance Object. provided globally in the app, and used as an
|
|
5
|
+
* intermediate object to make user defined instances config reactive.
|
|
6
|
+
*
|
|
7
|
+
* @type {import("./types").Eodash}
|
|
8
|
+
*/
|
|
9
|
+
export const eodash = reactive({
|
|
10
|
+
id: "demo",
|
|
11
|
+
stacEndpoint:
|
|
12
|
+
"https://eodashcatalog.eox.at/test-style/trilateral/catalog.json",
|
|
13
|
+
brand: {
|
|
14
|
+
noLayout: true,
|
|
15
|
+
name: "Demo",
|
|
16
|
+
theme: {
|
|
17
|
+
colors: {
|
|
18
|
+
primary: "#fff",
|
|
19
|
+
secondary: "#fff",
|
|
20
|
+
surface: "#fff",
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
footerText: "Demo configuration of eodash client",
|
|
24
|
+
},
|
|
25
|
+
template: {
|
|
26
|
+
loading: {
|
|
27
|
+
id: Symbol(),
|
|
28
|
+
type: "web-component",
|
|
29
|
+
widget: {
|
|
30
|
+
// https://uiball.com/ldrs/
|
|
31
|
+
link: "https://cdn.jsdelivr.net/npm/ldrs/dist/auto/mirage.js",
|
|
32
|
+
tagName: "l-mirage",
|
|
33
|
+
properties: {
|
|
34
|
+
class: "align-self-center justify-self-center",
|
|
35
|
+
size: "120",
|
|
36
|
+
speed: "2.5",
|
|
37
|
+
color: "#004170",
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
background: {
|
|
42
|
+
id: Symbol(),
|
|
43
|
+
type: "internal",
|
|
44
|
+
widget: {
|
|
45
|
+
name: "EodashMap",
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
widgets: [
|
|
49
|
+
{
|
|
50
|
+
id: Symbol(),
|
|
51
|
+
type: "internal",
|
|
52
|
+
title: "Indicators",
|
|
53
|
+
layout: { x: 0, y: 0, w: 3, h: 8 },
|
|
54
|
+
widget: {
|
|
55
|
+
name: "EodashItemFilter",
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: Symbol(),
|
|
60
|
+
type: "web-component",
|
|
61
|
+
title: "Layer Control",
|
|
62
|
+
layout: { x: 0, y: 8, w: 3, h: 4 },
|
|
63
|
+
widget: {
|
|
64
|
+
link: async () => {
|
|
65
|
+
await import("@eox/layercontrol");
|
|
66
|
+
await import("@eox/jsonform");
|
|
67
|
+
},
|
|
68
|
+
tagName: "eox-layercontrol",
|
|
69
|
+
properties: {
|
|
70
|
+
for: "eox-map",
|
|
71
|
+
class: "pa-4",
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
defineWidget: (selectedSTAC) => {
|
|
77
|
+
return selectedSTAC
|
|
78
|
+
? {
|
|
79
|
+
id: "Information",
|
|
80
|
+
title: "Information",
|
|
81
|
+
layout: { x: 9, y: 0, w: 3, h: 12 },
|
|
82
|
+
type: "web-component",
|
|
83
|
+
widget: {
|
|
84
|
+
link: async () => await import("@eox/stacinfo"),
|
|
85
|
+
properties: {
|
|
86
|
+
for: currentUrl,
|
|
87
|
+
allowHtml: "true",
|
|
88
|
+
styleOverride:
|
|
89
|
+
"#properties li > .value {font-weight: normal !important;}",
|
|
90
|
+
header: "[]",
|
|
91
|
+
subheader: "[]",
|
|
92
|
+
properties: '["description"]',
|
|
93
|
+
featured: "[]",
|
|
94
|
+
footer: "[]",
|
|
95
|
+
},
|
|
96
|
+
tagName: "eox-stacinfo",
|
|
97
|
+
},
|
|
98
|
+
}
|
|
99
|
+
: null;
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
defineWidget: (selectedSTAC) => {
|
|
104
|
+
return selectedSTAC
|
|
105
|
+
? {
|
|
106
|
+
id: "Datepicker",
|
|
107
|
+
type: "internal",
|
|
108
|
+
layout: { x: 5, y: 10, w: 1, h: 1 },
|
|
109
|
+
title: "Datepicker",
|
|
110
|
+
widget: {
|
|
111
|
+
name: "EodashDatePicker",
|
|
112
|
+
},
|
|
113
|
+
}
|
|
114
|
+
: null;
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
defineWidget: (selected) => {
|
|
119
|
+
return selected
|
|
120
|
+
? {
|
|
121
|
+
id: "Buttons",
|
|
122
|
+
layout: { x: 8, y: 0, w: 1, h: 1 },
|
|
123
|
+
title: "Buttons",
|
|
124
|
+
type: "internal",
|
|
125
|
+
widget: {
|
|
126
|
+
name: "EodashMapBtns",
|
|
127
|
+
},
|
|
128
|
+
}
|
|
129
|
+
: null;
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
],
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
export default eodash;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import vuetify from "./vuetify";
|
|
2
|
+
import { createPinia } from "pinia";
|
|
3
|
+
import eodash from "@/eodash";
|
|
4
|
+
import VCalendar from "v-calendar";
|
|
5
|
+
import { eodashKey } from "@/utils/keys";
|
|
6
|
+
import store from "../store";
|
|
7
|
+
|
|
8
|
+
export const pinia = createPinia();
|
|
9
|
+
|
|
10
|
+
/** @param {import("vue").App} app */
|
|
11
|
+
export function registerPlugins(app) {
|
|
12
|
+
window.eodashStore = store;
|
|
13
|
+
|
|
14
|
+
app
|
|
15
|
+
.use(vuetify)
|
|
16
|
+
.use(pinia)
|
|
17
|
+
// Use plugin with optional defaults
|
|
18
|
+
.use(VCalendar, {})
|
|
19
|
+
.provide(eodashKey, eodash);
|
|
20
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugins/vuetify.ts
|
|
3
|
+
*
|
|
4
|
+
* Framework documentation: https://vuetifyjs.com`
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Styles
|
|
8
|
+
import "vuetify/styles";
|
|
9
|
+
|
|
10
|
+
import { createVuetify } from "vuetify";
|
|
11
|
+
import { mdiChevronLeft, mdiChevronRight, mdiMenuDown } from "@mdi/js";
|
|
12
|
+
|
|
13
|
+
const vuetify = createVuetify({
|
|
14
|
+
icons: {
|
|
15
|
+
aliases: {
|
|
16
|
+
// mapping v-date-picker and v-tabs default icons to `@mdi/js`
|
|
17
|
+
next: [mdiChevronRight],
|
|
18
|
+
prev: [mdiChevronLeft],
|
|
19
|
+
subgroup: [mdiMenuDown],
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
theme: {
|
|
23
|
+
themes: {
|
|
24
|
+
dashboardTheme: {},
|
|
25
|
+
light: {
|
|
26
|
+
colors: {
|
|
27
|
+
primary: "#1867C0",
|
|
28
|
+
secondary: "#5CBBF6",
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
export default vuetify;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { registeredProjections } from "@/store/States";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Returns the current layers of the `eox-map`
|
|
5
|
+
* @param {string} [el="eox-map"] - `eox-map` element selector
|
|
6
|
+
* @returns {object[]}
|
|
7
|
+
*/
|
|
8
|
+
export const getLayers = (el = "eox-map") =>
|
|
9
|
+
customElements.get("eo-dash")
|
|
10
|
+
? document
|
|
11
|
+
.querySelector("eo-dash")
|
|
12
|
+
?.shadowRoot?.querySelector(el)
|
|
13
|
+
//@ts-expect-error `layers` doesn't exist on type element
|
|
14
|
+
?.layers.toReversed()
|
|
15
|
+
: //@ts-expect-error `layers` doesn't exist on type element
|
|
16
|
+
document.querySelector(el)?.layers.toReversed();
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Register EPSG projection in `eox-map`
|
|
20
|
+
* @param {string|number} [code]*/
|
|
21
|
+
export const registerProjection = async (code) => {
|
|
22
|
+
code = typeof code === "number" ? `EPSG:${code}` : code;
|
|
23
|
+
if (!code || registeredProjections.includes(code)) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const eoxMap =
|
|
27
|
+
/** @type {HTMLElement & Record<string,any> | null | undefined} */ (
|
|
28
|
+
customElements.get("eo-dash")
|
|
29
|
+
? document
|
|
30
|
+
.querySelector("eo-dash")
|
|
31
|
+
?.shadowRoot?.querySelector("eox-map")
|
|
32
|
+
: document.querySelector("eox-map")
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
registeredProjections.push(code);
|
|
36
|
+
await eoxMap?.registerProjectionFromCode(code);
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Change `eox-map` projection from an `EPSG` code
|
|
40
|
+
* @param {string|number} [code]*/
|
|
41
|
+
export const changeMapProjection = async (code) => {
|
|
42
|
+
code = typeof code === "number" ? `EPSG:${code}` : code;
|
|
43
|
+
const eoxMap =
|
|
44
|
+
/** @type {HTMLElement & Record<string,any> | null | undefined} */ (
|
|
45
|
+
customElements.get("eo-dash")
|
|
46
|
+
? document
|
|
47
|
+
.querySelector("eo-dash")
|
|
48
|
+
?.shadowRoot?.querySelector("eox-map")
|
|
49
|
+
: document.querySelector("eox-map")
|
|
50
|
+
);
|
|
51
|
+
if (!code) {
|
|
52
|
+
eoxMap?.setAttribute("projection", "EPSG:3857");
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (!registeredProjections.includes(code)) {
|
|
57
|
+
await registerProjection(code);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
code = eoxMap?.getAttribute("projection") === code ? "EPSG:3857" : code;
|
|
61
|
+
eoxMap?.setAttribute("projection", code);
|
|
62
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ref } from "vue";
|
|
2
|
+
|
|
3
|
+
/** Currently selected STAC endpoint */
|
|
4
|
+
export const currentUrl = ref("");
|
|
5
|
+
/** Currently selected datetime */
|
|
6
|
+
export const datetime = ref(new Date().toISOString());
|
|
7
|
+
|
|
8
|
+
/** Currently selected indicator */
|
|
9
|
+
export const indicator = ref("");
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Current map position
|
|
13
|
+
*
|
|
14
|
+
* @type {import("vue").Ref<(number | undefined)[]>}
|
|
15
|
+
*/
|
|
16
|
+
export const mapPosition = ref([]);
|
|
17
|
+
|
|
18
|
+
export const registeredProjections = ["EPSG:4326", "EPSG:3857"];
|
|
19
|
+
|
|
20
|
+
/** available projection to be rendered by `EodashMap` */
|
|
21
|
+
export const availableMapProjection = ref("");
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
//export all actions, states, and pinia stores
|
|
2
|
+
|
|
3
|
+
const storesImport = import.meta.glob("../store/**.js", { eager: true });
|
|
4
|
+
|
|
5
|
+
const store = /** @type {import("@/types").EodashStore} */ (
|
|
6
|
+
(() => {
|
|
7
|
+
const stores = {};
|
|
8
|
+
for (const [filePath, importedstore] of Object.entries(storesImport)) {
|
|
9
|
+
const storeType =
|
|
10
|
+
filePath.split("/").at(-1)?.slice(0, -3).toLowerCase() ?? "";
|
|
11
|
+
if (!["keys"].includes(storeType)) {
|
|
12
|
+
//@ts-expect-error `importedstore` cant be typed individually
|
|
13
|
+
stores[storeType] = importedstore;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return stores;
|
|
17
|
+
})()
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
export default store;
|