@vcmap/ui 6.1.0-rc.2 → 6.1.0-rc.4
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/config/base.config.json +6 -0
- package/config/clipping.config.json +384 -0
- package/config/cluster.config.json +106 -0
- package/config/concepts-show-case.config.json +4 -0
- package/config/projects.config.json +5 -2
- package/dist/assets/{cesium-57fbd309.js → cesium-bfb31a03.js} +438 -432
- package/dist/assets/cesium.js +1 -1
- package/dist/assets/{core-fd079400.js → core-28960288.js} +4913 -4516
- package/dist/assets/core.js +1 -1
- package/dist/assets/{ol-50dfef96.js → ol-338a87a3.js} +23518 -22404
- package/dist/assets/ol.js +1 -1
- package/dist/assets/ui-4ae4c67a.css +1 -0
- package/dist/assets/{ui-5135917c.js → ui-4ae4c67a.js} +13456 -12758
- package/dist/assets/ui.js +1 -1
- package/dist/assets/vue.js +1 -1
- package/dist/assets/{vuetify-f02b7bb9.css → vuetify-1f5b5c90.css} +2 -2
- package/dist/assets/{vuetify-f02b7bb9.js → vuetify-1f5b5c90.js} +8024 -7634
- package/dist/assets/vuetify.js +1 -1
- package/index.d.ts +38 -19
- package/index.js +35 -6
- package/lib/olLib.js +25 -3
- package/package.json +6 -6
- package/plugins/@vcmap-show-case/callback-tester/README.md +3 -0
- package/plugins/@vcmap-show-case/callback-tester/package.json +5 -0
- package/plugins/@vcmap-show-case/callback-tester/src/CallbackTester.vue +62 -0
- package/plugins/@vcmap-show-case/callback-tester/src/index.js +48 -0
- package/plugins/@vcmap-show-case/form-inputs-example/src/FormInputsExample.vue +1 -0
- package/src/actions/actionHelper.d.ts +1 -0
- package/src/actions/actionHelper.js +70 -19
- package/src/application/VcsApp.vue +83 -50
- package/src/application/VcsApp.vue.d.ts +24 -2
- package/src/application/VcsContainer.vue.d.ts +8 -0
- package/src/application/VcsObliqueFooter.vue +9 -3
- package/src/application/VcsSplashScreen.vue +37 -0
- package/src/application/VcsSplashScreen.vue.d.ts +6 -0
- package/src/application/positionDisplayInteraction.js +1 -1
- package/src/callback/activateClippingPolygonCallback.d.ts +29 -0
- package/src/callback/activateClippingPolygonCallback.js +54 -0
- package/src/callback/closeSplashScreenCallback.d.ts +8 -0
- package/src/callback/closeSplashScreenCallback.js +33 -0
- package/src/callback/deactivateClippingPolygonCallback.d.ts +29 -0
- package/src/callback/deactivateClippingPolygonCallback.js +54 -0
- package/src/callback/openSplashScreenCallback.d.ts +8 -0
- package/src/callback/openSplashScreenCallback.js +35 -0
- package/src/callback/toggleNavbarButtonCallback.d.ts +36 -0
- package/src/callback/toggleNavbarButtonCallback.js +62 -0
- package/src/components/form-inputs-controls/VcsSelect.vue +1 -1
- package/src/components/form-inputs-controls/VcsTextArea.vue +12 -7
- package/src/components/form-output/markdownHelper.d.ts +0 -25
- package/src/components/form-output/markdownHelper.js +1 -386
- package/src/components/lists/VcsGroupedList.vue +178 -0
- package/src/components/lists/VcsGroupedList.vue.d.ts +17 -0
- package/src/components/lists/VcsList.vue +142 -396
- package/src/components/lists/VcsList.vue.d.ts +38 -168
- package/src/components/lists/VcsTreeview.vue +11 -12
- package/src/components/lists/listHelper.d.ts +87 -0
- package/src/components/lists/listHelper.js +348 -0
- package/src/components/section/VcsFormSection.vue +7 -2
- package/src/components/section/VcsFormSection.vue.d.ts +9 -0
- package/src/components/vector-properties/VcsVectorPropertiesComponent.vue.d.ts +1 -1
- package/src/contentTree/LayerTree.vue +2 -1
- package/src/contentTree/LayerTree.vue.d.ts +2 -0
- package/src/contentTree/contentTreeCollection.d.ts +1 -0
- package/src/contentTree/contentTreeCollection.js +7 -3
- package/src/contentTree/contentTreeItem.js +4 -2
- package/src/contentTree/groupContentTreeItem.js +5 -3
- package/src/featureInfo/ClusterFeatureComponent.vue +58 -0
- package/src/featureInfo/ClusterFeatureComponent.vue.d.ts +6 -0
- package/src/featureInfo/abstractFeatureInfoView.js +1 -2
- package/src/featureInfo/featureInfo.d.ts +87 -1
- package/src/featureInfo/featureInfo.js +350 -34
- package/src/featureInfo/featureInfoInteraction.js +18 -3
- package/src/featureInfo/iframeFeatureInfoView.js +1 -1
- package/src/featureInfo/markdownBalloonFeatureInfoView.js +2 -4
- package/src/featureInfo/markdownFeatureInfoView.js +1 -1
- package/src/i18n/de.d.ts +17 -4
- package/src/i18n/de.js +7 -0
- package/src/i18n/en.d.ts +17 -4
- package/src/i18n/en.js +7 -0
- package/src/legend/legendHelper.d.ts +1 -1
- package/src/legend/legendHelper.js +52 -9
- package/src/localStorage.d.ts +21 -0
- package/src/localStorage.js +51 -0
- package/src/manager/collectionManager/CollectionComponent.vue +1 -1
- package/src/manager/collectionManager/CollectionComponentContent.vue +2 -3
- package/src/manager/collectionManager/CollectionComponentList.vue +2 -3
- package/src/manager/collectionManager/CollectionComponentStandalone.vue +1 -1
- package/src/manager/navbarManager.js +9 -4
- package/src/manager/toolbox/ToolboxManagerComponent.vue +10 -8
- package/src/manager/toolbox/ToolboxManagerComponent.vue.d.ts +11 -0
- package/src/manager/window/windowHelper.d.ts +7 -3
- package/src/manager/window/windowHelper.js +30 -10
- package/src/navigation/overviewMap.d.ts +1 -0
- package/src/navigation/overviewMap.js +4 -3
- package/src/pluginHelper.d.ts +7 -0
- package/src/pluginHelper.js +18 -4
- package/src/search/ResultItem.vue.d.ts +1 -1
- package/src/search/search.js +1 -1
- package/src/state.d.ts +4 -2
- package/src/state.js +54 -31
- package/src/uiConfig.d.ts +27 -0
- package/src/uiConfig.js +16 -1
- package/src/vcsUiApp.js +7 -11
- package/dist/assets/ui-5135917c.css +0 -1
- /package/dist/assets/{vue-c3c55d88.js → vue-b5c1e81a.js} +0 -0
@@ -8,12 +8,12 @@ import {
|
|
8
8
|
Viewpoint,
|
9
9
|
} from '@vcmap/core';
|
10
10
|
import { Feature } from 'ol';
|
11
|
-
import { reactive, ref } from 'vue';
|
11
|
+
import { nextTick, reactive, ref } from 'vue';
|
12
12
|
import { parseBoolean } from '@vcsuite/parsers';
|
13
13
|
import { vcsAppSymbol } from '../pluginHelper.js';
|
14
14
|
import { WindowSlot } from '../manager/window/windowManager.js';
|
15
15
|
import {
|
16
|
-
|
16
|
+
getFittedWindowPositionOptions,
|
17
17
|
getTargetSize,
|
18
18
|
} from '../manager/window/windowHelper.js';
|
19
19
|
import SearchComponent from '../search/SearchComponent.vue';
|
@@ -142,6 +142,8 @@ export function createToggleAction(
|
|
142
142
|
return { action, destroy };
|
143
143
|
}
|
144
144
|
|
145
|
+
export const searchComponentId = 'searchId';
|
146
|
+
|
145
147
|
/**
|
146
148
|
* Creates a toggle button for the search tool, which is only available, if at least one search implementation is registered.
|
147
149
|
* @param {import("../vcsUiApp.js").default} app
|
@@ -153,8 +155,8 @@ export function createSearchButtonAction(app) {
|
|
153
155
|
const uiConfig = app.uiConfig.config;
|
154
156
|
|
155
157
|
const determineAction = () => {
|
156
|
-
if (app.windowManager.has(
|
157
|
-
app.windowManager.remove(
|
158
|
+
if (app.windowManager.has(searchComponentId)) {
|
159
|
+
app.windowManager.remove(searchComponentId);
|
158
160
|
}
|
159
161
|
if (
|
160
162
|
!uiConfig.hideSearch &&
|
@@ -168,7 +170,7 @@ export function createSearchButtonAction(app) {
|
|
168
170
|
title: 'search.tooltip',
|
169
171
|
},
|
170
172
|
{
|
171
|
-
id:
|
173
|
+
id: searchComponentId,
|
172
174
|
component: SearchComponent,
|
173
175
|
state: { hideHeader: true },
|
174
176
|
slot: WindowSlot.DYNAMIC_RIGHT,
|
@@ -272,6 +274,7 @@ export function createModalAction(actionOptions, modalComponent, app, owner) {
|
|
272
274
|
const id = uuid();
|
273
275
|
const { position: windowPositionOptions, ...component } = modalComponent;
|
274
276
|
let modalActivator = null;
|
277
|
+
let clickedWindowPosition = null;
|
275
278
|
|
276
279
|
/**
|
277
280
|
* Closes the modal at mousedown on an app element
|
@@ -285,28 +288,58 @@ export function createModalAction(actionOptions, modalComponent, app, owner) {
|
|
285
288
|
}
|
286
289
|
};
|
287
290
|
|
291
|
+
const getPositionOptions = (contentHeight = 0) => {
|
292
|
+
const { width, height } = modalActivator.getBoundingClientRect();
|
293
|
+
const fittedPosition = getFittedWindowPositionOptions(
|
294
|
+
clickedWindowPosition.x,
|
295
|
+
clickedWindowPosition.y,
|
296
|
+
windowPositionOptions?.width || 320,
|
297
|
+
windowPositionOptions?.height || contentHeight,
|
298
|
+
app.maps.target,
|
299
|
+
width,
|
300
|
+
height,
|
301
|
+
);
|
302
|
+
const position = {
|
303
|
+
...fittedPosition,
|
304
|
+
...windowPositionOptions,
|
305
|
+
};
|
306
|
+
const targetSize = getTargetSize(app.maps.target);
|
307
|
+
if (contentHeight) {
|
308
|
+
if (position.bottom) {
|
309
|
+
position.maxHeight = Math.min(
|
310
|
+
position.maxHeight ?? Infinity,
|
311
|
+
clickedWindowPosition.y - targetSize.top,
|
312
|
+
);
|
313
|
+
} else {
|
314
|
+
position.maxHeight = Math.min(
|
315
|
+
position.maxHeight ?? Infinity,
|
316
|
+
targetSize.height - (clickedWindowPosition.y - targetSize.top),
|
317
|
+
);
|
318
|
+
}
|
319
|
+
}
|
320
|
+
position.maxWidth = 320;
|
321
|
+
position.width = windowPositionOptions?.width || -1; // unset width magic. dont touch.
|
322
|
+
return position;
|
323
|
+
};
|
324
|
+
|
288
325
|
const action = reactive({
|
289
326
|
...actionOptions,
|
290
327
|
active: false,
|
291
328
|
callback(event) {
|
292
329
|
if (!this.active) {
|
293
330
|
this.active = true;
|
294
|
-
const { left, top, width } =
|
295
|
-
event.currentTarget.getBoundingClientRect();
|
296
331
|
modalActivator = event.currentTarget;
|
297
|
-
|
298
|
-
...getFittedWindowPositionOptionsFromMapEvent(
|
299
|
-
{ x: left + width, y: top - getTargetSize(app.maps.target).top },
|
300
|
-
windowPositionOptions?.width || 320,
|
301
|
-
windowPositionOptions?.height || 0,
|
302
|
-
app.maps.target,
|
303
|
-
),
|
304
|
-
...windowPositionOptions,
|
305
|
-
};
|
306
|
-
position.maxWidth = 320;
|
307
|
-
position.width = windowPositionOptions?.width || -1; // unset width magic. dont touch.
|
332
|
+
clickedWindowPosition = { x: event.x, y: event.y };
|
308
333
|
const state = { ...modalComponent?.state, hideHeader: true };
|
309
|
-
app.windowManager.add(
|
334
|
+
app.windowManager.add(
|
335
|
+
{
|
336
|
+
position: getPositionOptions(),
|
337
|
+
...component,
|
338
|
+
id,
|
339
|
+
state,
|
340
|
+
},
|
341
|
+
owner,
|
342
|
+
);
|
310
343
|
document.addEventListener('mousedown', handleMouseDown);
|
311
344
|
} else {
|
312
345
|
this.active = false;
|
@@ -325,6 +358,24 @@ export function createModalAction(actionOptions, modalComponent, app, owner) {
|
|
325
358
|
}),
|
326
359
|
];
|
327
360
|
|
361
|
+
// if no height is provided, update fitted window position after actual div size is available
|
362
|
+
if (!windowPositionOptions?.height) {
|
363
|
+
listeners.push(
|
364
|
+
app.windowManager.added.addEventListener(async (added) => {
|
365
|
+
if (added.id === id) {
|
366
|
+
await nextTick();
|
367
|
+
const div = document.getElementById(`window-component--${id}`);
|
368
|
+
if (div) {
|
369
|
+
app.windowManager.setWindowPositionOptions(
|
370
|
+
id,
|
371
|
+
getPositionOptions(div.offsetHeight),
|
372
|
+
);
|
373
|
+
}
|
374
|
+
}
|
375
|
+
}),
|
376
|
+
);
|
377
|
+
}
|
378
|
+
|
328
379
|
const destroy = () => {
|
329
380
|
listeners.forEach((cb) => {
|
330
381
|
cb();
|
@@ -3,7 +3,7 @@
|
|
3
3
|
<VcsSplashScreen
|
4
4
|
v-if="splashScreen"
|
5
5
|
:options="splashScreen"
|
6
|
-
v-model="
|
6
|
+
v-model="showSplashScreen"
|
7
7
|
></VcsSplashScreen>
|
8
8
|
<VcsNavbar v-if="!config.hideHeader" />
|
9
9
|
<VcsContainer :attribution-action="attributionAction" />
|
@@ -42,7 +42,14 @@
|
|
42
42
|
</style>
|
43
43
|
|
44
44
|
<script>
|
45
|
-
import {
|
45
|
+
import {
|
46
|
+
computed,
|
47
|
+
onMounted,
|
48
|
+
onUnmounted,
|
49
|
+
provide,
|
50
|
+
watch,
|
51
|
+
shallowRef,
|
52
|
+
} from 'vue';
|
46
53
|
import { useDisplay } from 'vuetify';
|
47
54
|
import { getVcsAppById, moduleIdSymbol } from '@vcmap/core';
|
48
55
|
import { VContainer, VFooter, VSpacer } from 'vuetify/components';
|
@@ -69,12 +76,14 @@
|
|
69
76
|
import VcsAttributionsFooter from './VcsAttributionsFooter.vue';
|
70
77
|
import VcsObliqueFooter from './VcsObliqueFooter.vue';
|
71
78
|
import VcsTextPageFooter from './VcsTextPageFooter.vue';
|
72
|
-
import VcsSplashScreen from './VcsSplashScreen.vue';
|
79
|
+
import VcsSplashScreen, { getSplashScreenHash } from './VcsSplashScreen.vue';
|
73
80
|
import VcsTextPage from './VcsTextPage.vue';
|
74
81
|
import VcsAttributions from './VcsAttributions.vue';
|
75
82
|
import { getAttributions } from './attributionsHelper.js';
|
76
83
|
import VcsDefaultLogoMobile from '../logo-mobile.svg';
|
77
84
|
import VcsPositionDisplay from './VcsPositionDisplay.vue';
|
85
|
+
import { getFromLocalStorage, hideSplashScreenKey } from '../localStorage.js';
|
86
|
+
import { name as packageName } from '../../package.json';
|
78
87
|
|
79
88
|
/**
|
80
89
|
* This helper checks the uiConfig and depending on the value will setup/teardown the providedSetupFunction
|
@@ -202,6 +211,8 @@
|
|
202
211
|
};
|
203
212
|
}
|
204
213
|
|
214
|
+
export const legendComponentId = 'legendId';
|
215
|
+
|
205
216
|
/**
|
206
217
|
* This helper function will add a legend action button to the apps NavbarManager TOOL location, if legend entries are available.
|
207
218
|
* Watches number of legend entries.
|
@@ -218,7 +229,7 @@
|
|
218
229
|
title: 'legend.tooltip',
|
219
230
|
},
|
220
231
|
{
|
221
|
-
id:
|
232
|
+
id: legendComponentId,
|
222
233
|
component: VcsLegend,
|
223
234
|
state: {
|
224
235
|
headerTitle: 'legend.title',
|
@@ -238,10 +249,10 @@
|
|
238
249
|
* Adds a legend button, if not existing
|
239
250
|
*/
|
240
251
|
const addLegend = () => {
|
241
|
-
if (!app.navbarManager.has(
|
252
|
+
if (!app.navbarManager.has(legendComponentId)) {
|
242
253
|
app.navbarManager.add(
|
243
254
|
{
|
244
|
-
id:
|
255
|
+
id: legendComponentId,
|
245
256
|
action: legendAction,
|
246
257
|
},
|
247
258
|
vcsAppSymbol,
|
@@ -255,11 +266,11 @@
|
|
255
266
|
if (
|
256
267
|
app.uiConfig.config.openLegendOnAdd &&
|
257
268
|
newValue.length > currentEntryLength &&
|
258
|
-
!app.windowManager.has(
|
269
|
+
!app.windowManager.has(legendComponentId)
|
259
270
|
) {
|
260
271
|
app.windowManager.add(
|
261
272
|
{
|
262
|
-
id:
|
273
|
+
id: legendComponentId,
|
263
274
|
component: VcsLegend,
|
264
275
|
state: {
|
265
276
|
headerTitle: 'legend.title',
|
@@ -289,8 +300,8 @@
|
|
289
300
|
(style) => style?.properties?.legend,
|
290
301
|
);
|
291
302
|
if (layersWithLegend < 1 && stylesWithLegend < 1) {
|
292
|
-
app.navbarManager.remove(
|
293
|
-
app.windowManager.remove(
|
303
|
+
app.navbarManager.remove(legendComponentId);
|
304
|
+
app.windowManager.remove(legendComponentId);
|
294
305
|
} else {
|
295
306
|
addLegend();
|
296
307
|
}
|
@@ -314,14 +325,16 @@
|
|
314
325
|
|
315
326
|
return () => {
|
316
327
|
watchEntries();
|
317
|
-
app.navbarManager.remove(
|
318
|
-
app.windowManager.remove(
|
328
|
+
app.navbarManager.remove(legendComponentId);
|
329
|
+
app.windowManager.remove(legendComponentId);
|
319
330
|
destroy();
|
320
331
|
legendDestroy();
|
321
332
|
listeners.forEach((cb) => cb());
|
322
333
|
};
|
323
334
|
}
|
324
335
|
|
336
|
+
export const customScreenComponentId = 'customScreenId';
|
337
|
+
|
325
338
|
/**
|
326
339
|
* This helper function will add a customScreen action button to the apps NavbarManager MENU location.
|
327
340
|
* @param {import("../vcsUiApp.js").default} app
|
@@ -338,7 +351,7 @@
|
|
338
351
|
title: customScreen.title,
|
339
352
|
},
|
340
353
|
{
|
341
|
-
id:
|
354
|
+
id: customScreenComponentId,
|
342
355
|
component: VcsTextPage,
|
343
356
|
state: {
|
344
357
|
headerIcon: customScreen.icon,
|
@@ -355,7 +368,7 @@
|
|
355
368
|
);
|
356
369
|
app.navbarManager.add(
|
357
370
|
{
|
358
|
-
id:
|
371
|
+
id: customScreenComponentId,
|
359
372
|
action: customScreenAction,
|
360
373
|
},
|
361
374
|
vcsAppSymbol,
|
@@ -369,8 +382,8 @@
|
|
369
382
|
const stopCustomScreenWatcher = watch(
|
370
383
|
() => app.uiConfig.config.customScreen,
|
371
384
|
(newCustomScreen) => {
|
372
|
-
if (app.navbarManager.has(
|
373
|
-
app.navbarManager.remove(
|
385
|
+
if (app.navbarManager.has(customScreenComponentId)) {
|
386
|
+
app.navbarManager.remove(customScreenComponentId);
|
374
387
|
}
|
375
388
|
if (newCustomScreen) {
|
376
389
|
customScreen = setupCustomScreenAction();
|
@@ -385,17 +398,19 @@
|
|
385
398
|
stopCustomScreenWatcher();
|
386
399
|
};
|
387
400
|
}
|
401
|
+
|
402
|
+
export const splashScreenComponentId = 'splashScreenToggle';
|
388
403
|
/**
|
389
404
|
* This helper function will add a Splash Screen action button to the apps NavbarManager MENU location.
|
390
405
|
* @param {import("../vcsUiApp.js").default} app
|
391
|
-
* @param {import("vue").Ref} splashScreenRef
|
392
406
|
* @returns {WatchStopHandle}
|
393
407
|
*/
|
394
|
-
function setupSplashScreen(app
|
408
|
+
function setupSplashScreen(app) {
|
395
409
|
function setupSplashScreenAction(moduleId) {
|
396
|
-
const {
|
410
|
+
const { config, showSplashScreen } = app.uiConfig;
|
411
|
+
const { splashScreen } = config;
|
397
412
|
if (splashScreen && moduleId !== app.dynamicModuleId) {
|
398
|
-
|
413
|
+
showSplashScreen.value = true;
|
399
414
|
}
|
400
415
|
if (splashScreen && splashScreen.menuEntry) {
|
401
416
|
const splashScreenAction = {
|
@@ -403,12 +418,12 @@
|
|
403
418
|
icon: splashScreen.icon || 'mdi-alert-box',
|
404
419
|
title: splashScreen.title,
|
405
420
|
callback() {
|
406
|
-
|
421
|
+
showSplashScreen.value = !showSplashScreen.value;
|
407
422
|
},
|
408
423
|
};
|
409
424
|
app.navbarManager.add(
|
410
425
|
{
|
411
|
-
id:
|
426
|
+
id: splashScreenComponentId,
|
412
427
|
action: splashScreenAction,
|
413
428
|
},
|
414
429
|
vcsAppSymbol,
|
@@ -419,8 +434,8 @@
|
|
419
434
|
setupSplashScreenAction();
|
420
435
|
const removeAddedListener = app.uiConfig.added.addEventListener((item) => {
|
421
436
|
if (item.name === 'splashScreen') {
|
422
|
-
if (app.navbarManager.has(
|
423
|
-
app.navbarManager.remove(
|
437
|
+
if (app.navbarManager.has(splashScreenComponentId)) {
|
438
|
+
app.navbarManager.remove(splashScreenComponentId);
|
424
439
|
}
|
425
440
|
setupSplashScreenAction(item[moduleIdSymbol]);
|
426
441
|
}
|
@@ -428,8 +443,8 @@
|
|
428
443
|
const removeRemovedListener = app.uiConfig.removed.addEventListener(
|
429
444
|
(item) => {
|
430
445
|
if (item.name === 'splashScreen') {
|
431
|
-
if (app.navbarManager.has(
|
432
|
-
app.navbarManager.remove(
|
446
|
+
if (app.navbarManager.has(splashScreenComponentId)) {
|
447
|
+
app.navbarManager.remove(splashScreenComponentId);
|
433
448
|
}
|
434
449
|
}
|
435
450
|
},
|
@@ -439,13 +454,14 @@
|
|
439
454
|
removeRemovedListener();
|
440
455
|
};
|
441
456
|
}
|
457
|
+
|
458
|
+
export const settingsComponentId = 'vcsSettings';
|
442
459
|
/**
|
443
460
|
* This helper function will add a settings action button to the apps NavbarManager MENU location.
|
444
461
|
* @param {import("../vcsUiApp.js").default} app
|
445
462
|
* @returns {function():void}
|
446
463
|
*/
|
447
464
|
export function setupSettingsWindow(app) {
|
448
|
-
const settingsWindowId = 'vcsSettings';
|
449
465
|
const { action: settingsAction, destroy: settingsDestroy } =
|
450
466
|
createToggleAction(
|
451
467
|
{
|
@@ -454,7 +470,7 @@
|
|
454
470
|
title: 'settings.tooltip',
|
455
471
|
},
|
456
472
|
{
|
457
|
-
id:
|
473
|
+
id: settingsComponentId,
|
458
474
|
component: VcsSettings,
|
459
475
|
state: { headerIcon: 'mdi-cog', headerTitle: 'settings.title' },
|
460
476
|
slot: WindowSlot.DYNAMIC_RIGHT,
|
@@ -464,19 +480,20 @@
|
|
464
480
|
);
|
465
481
|
app.navbarManager.add(
|
466
482
|
{
|
467
|
-
id:
|
483
|
+
id: settingsComponentId,
|
468
484
|
action: settingsAction,
|
469
485
|
},
|
470
486
|
vcsAppSymbol,
|
471
487
|
ButtonLocation.MENU,
|
472
488
|
);
|
473
489
|
return () => {
|
474
|
-
app.navbarManager.remove(
|
475
|
-
app.windowManager.remove(
|
490
|
+
app.navbarManager.remove(settingsComponentId);
|
491
|
+
app.windowManager.remove(settingsComponentId);
|
476
492
|
settingsDestroy();
|
477
493
|
};
|
478
494
|
}
|
479
495
|
|
496
|
+
export const helpComponentId = 'helpButton';
|
480
497
|
/**
|
481
498
|
* This helper function will add a help action button referencing VC Map help page to the apps NavbarManager MENU location.
|
482
499
|
* @param {import("../vcsUiApp.js").default} app
|
@@ -492,7 +509,7 @@
|
|
492
509
|
);
|
493
510
|
app.navbarManager.add(
|
494
511
|
{
|
495
|
-
id:
|
512
|
+
id: helpComponentId,
|
496
513
|
action: helpAction,
|
497
514
|
},
|
498
515
|
vcsAppSymbol,
|
@@ -674,6 +691,8 @@
|
|
674
691
|
};
|
675
692
|
}
|
676
693
|
|
694
|
+
export const attributionsComponentId = 'attributionId';
|
695
|
+
|
677
696
|
/**
|
678
697
|
* This helper gets attributions of all active maps, layers and oblique collections and returns an array of entries.
|
679
698
|
* It also returns a attributionAction to toggle the attributions window and a destroy function.
|
@@ -691,7 +710,7 @@
|
|
691
710
|
title: 'footer.attributions.tooltip',
|
692
711
|
},
|
693
712
|
{
|
694
|
-
id:
|
713
|
+
id: attributionsComponentId,
|
695
714
|
component: VcsAttributions,
|
696
715
|
state: {
|
697
716
|
headerTitle: 'footer.attributions.title',
|
@@ -758,8 +777,8 @@
|
|
758
777
|
'hideSettings',
|
759
778
|
);
|
760
779
|
const stopCustomScreen = setupCustomScreen(app);
|
761
|
-
const
|
762
|
-
const stopSplashScreen = setupSplashScreen(app
|
780
|
+
const { showSplashScreen } = app.uiConfig;
|
781
|
+
const stopSplashScreen = setupSplashScreen(app);
|
763
782
|
setupHelpButton(app);
|
764
783
|
const destroyMyWorkspace = setupUIConfigDependency(
|
765
784
|
app,
|
@@ -776,6 +795,33 @@
|
|
776
795
|
pluginMountedListener = setupPluginMountedListeners(app);
|
777
796
|
});
|
778
797
|
|
798
|
+
function getSplashScreenConfig() {
|
799
|
+
if (app.uiConfig.config.splashScreen) {
|
800
|
+
const config = app.uiConfig.getByKey('splashScreen');
|
801
|
+
const hash = getSplashScreenHash(app);
|
802
|
+
const moduleId = config[moduleIdSymbol];
|
803
|
+
const storedHash = getFromLocalStorage(
|
804
|
+
`${packageName}_${moduleId}`,
|
805
|
+
hideSplashScreenKey,
|
806
|
+
);
|
807
|
+
if (hash !== storedHash) {
|
808
|
+
return {
|
809
|
+
title: 'components.splashScreen.name',
|
810
|
+
tooltip: 'components.splashScreen.tooltip',
|
811
|
+
position: { width: '800px', height: '400px' },
|
812
|
+
...app.uiConfig.config.splashScreen,
|
813
|
+
};
|
814
|
+
}
|
815
|
+
}
|
816
|
+
return undefined;
|
817
|
+
}
|
818
|
+
const splashScreen = shallowRef(getSplashScreenConfig());
|
819
|
+
app.uiConfig.added.addEventListener(({ name }) => {
|
820
|
+
if (name === 'splashScreen') {
|
821
|
+
splashScreen.value = getSplashScreenConfig();
|
822
|
+
}
|
823
|
+
});
|
824
|
+
|
779
825
|
onUnmounted(() => {
|
780
826
|
if (pluginMountedListener) {
|
781
827
|
pluginMountedListener();
|
@@ -829,21 +875,8 @@
|
|
829
875
|
}
|
830
876
|
return undefined;
|
831
877
|
}),
|
832
|
-
|
833
|
-
splashScreen
|
834
|
-
if (app.uiConfig.config.splashScreen) {
|
835
|
-
return {
|
836
|
-
title: 'components.splashScreen.name',
|
837
|
-
tooltip: 'components.splashScreen.tooltip',
|
838
|
-
position: {
|
839
|
-
width: '800px',
|
840
|
-
height: '400px',
|
841
|
-
},
|
842
|
-
...app.uiConfig.config.splashScreen,
|
843
|
-
};
|
844
|
-
}
|
845
|
-
return undefined;
|
846
|
-
}),
|
878
|
+
showSplashScreen,
|
879
|
+
splashScreen,
|
847
880
|
attributionEntries,
|
848
881
|
attributionAction,
|
849
882
|
};
|
@@ -74,10 +74,16 @@ export function setupAttributions(app: import("../vcsUiApp.js").default): {
|
|
74
74
|
attributionAction: import("../actions/actionHelper.js").VcsAction;
|
75
75
|
destroyAttributions: () => void;
|
76
76
|
};
|
77
|
+
export const legendComponentId: "legendId";
|
78
|
+
export const customScreenComponentId: "customScreenId";
|
79
|
+
export const splashScreenComponentId: "splashScreenToggle";
|
80
|
+
export const settingsComponentId: "vcsSettings";
|
81
|
+
export const helpComponentId: "helpButton";
|
77
82
|
/**
|
78
83
|
* @type {string}
|
79
84
|
*/
|
80
85
|
export const categoryManagerWindowId: string;
|
86
|
+
export const attributionsComponentId: "attributionId";
|
81
87
|
declare const _default: import("vue").DefineComponent<{
|
82
88
|
appId: {
|
83
89
|
type: StringConstructor;
|
@@ -183,6 +189,14 @@ declare const _default: import("vue").DefineComponent<{
|
|
183
189
|
}[] | undefined;
|
184
190
|
readonly menuEntry?: boolean | undefined;
|
185
191
|
readonly acceptInput?: boolean | undefined;
|
192
|
+
/**
|
193
|
+
* Whether the Secondary Button is disabled as well as long as the checkbox is not checked.
|
194
|
+
*/
|
195
|
+
readonly requireInputForSecondary?: boolean | undefined;
|
196
|
+
/**
|
197
|
+
* Whether to display a checkbox allowing the user not to see the SplashScreen again. This parameter is relative to moduleId and configuration; the SplashScreen will be shown again in case of any change.
|
198
|
+
*/
|
199
|
+
readonly enableDontShowAgain?: boolean | undefined;
|
186
200
|
readonly position?: {
|
187
201
|
readonly width?: string | undefined;
|
188
202
|
readonly height?: string | undefined;
|
@@ -408,8 +422,8 @@ declare const _default: import("vue").DefineComponent<{
|
|
408
422
|
content?: string | undefined;
|
409
423
|
tooltip: string;
|
410
424
|
} | undefined>;
|
411
|
-
|
412
|
-
splashScreen: import("vue").
|
425
|
+
showSplashScreen: import("vue").Ref<boolean>;
|
426
|
+
splashScreen: import("vue").ShallowRef<{
|
413
427
|
title: string;
|
414
428
|
icon?: string | undefined;
|
415
429
|
content?: string | undefined;
|
@@ -425,6 +439,14 @@ declare const _default: import("vue").DefineComponent<{
|
|
425
439
|
}[] | undefined;
|
426
440
|
menuEntry?: boolean | undefined;
|
427
441
|
acceptInput?: boolean | undefined;
|
442
|
+
/**
|
443
|
+
* Whether the Secondary Button is disabled as well as long as the checkbox is not checked.
|
444
|
+
*/
|
445
|
+
requireInputForSecondary?: boolean | undefined;
|
446
|
+
/**
|
447
|
+
* Whether to display a checkbox allowing the user not to see the SplashScreen again. This parameter is relative to moduleId and configuration; the SplashScreen will be shown again in case of any change.
|
448
|
+
*/
|
449
|
+
enableDontShowAgain?: boolean | undefined;
|
428
450
|
position: {
|
429
451
|
readonly width?: string | undefined;
|
430
452
|
readonly height?: string | undefined;
|
@@ -103,6 +103,14 @@ declare const _default: import("vue").DefineComponent<{
|
|
103
103
|
}[] | undefined;
|
104
104
|
readonly menuEntry?: boolean | undefined;
|
105
105
|
readonly acceptInput?: boolean | undefined;
|
106
|
+
/**
|
107
|
+
* Whether the Secondary Button is disabled as well as long as the checkbox is not checked.
|
108
|
+
*/
|
109
|
+
readonly requireInputForSecondary?: boolean | undefined;
|
110
|
+
/**
|
111
|
+
* Whether to display a checkbox allowing the user not to see the SplashScreen again. This parameter is relative to moduleId and configuration; the SplashScreen will be shown again in case of any change.
|
112
|
+
*/
|
113
|
+
readonly enableDontShowAgain?: boolean | undefined;
|
106
114
|
readonly position?: {
|
107
115
|
readonly width?: string | undefined;
|
108
116
|
readonly height?: string | undefined;
|
@@ -17,8 +17,12 @@
|
|
17
17
|
|
18
18
|
<script>
|
19
19
|
import { computed, inject, onUnmounted, shallowRef } from 'vue';
|
20
|
-
import {
|
21
|
-
|
20
|
+
import {
|
21
|
+
ObliqueMap,
|
22
|
+
ObliqueViewDirection,
|
23
|
+
renderTemplate,
|
24
|
+
} from '@vcmap/core';
|
25
|
+
import { parseAndSanitizeMarkdown } from '../components/form-output/markdownHelper.js';
|
22
26
|
|
23
27
|
const i18nViewDirection = {
|
24
28
|
[ObliqueViewDirection.NORTH]: 'footer.oblique.north',
|
@@ -95,7 +99,9 @@
|
|
95
99
|
app.uiConfig.config.obliqueFooterTemplate ??
|
96
100
|
'footer.oblique.template';
|
97
101
|
return renderTemplate(
|
98
|
-
|
102
|
+
parseAndSanitizeMarkdown(
|
103
|
+
app.vueI18n.te(template) ? app.vueI18n.tm(template) : template,
|
104
|
+
),
|
99
105
|
getTranslatedImageInfo(currentImage.value),
|
100
106
|
);
|
101
107
|
}
|
@@ -25,6 +25,13 @@
|
|
25
25
|
/>
|
26
26
|
</template>
|
27
27
|
</VcsCheckbox>
|
28
|
+
<VcsCheckbox v-if="options.enableDontShowAgain" v-model="dontShowAgain">
|
29
|
+
<template #label>
|
30
|
+
<div class="pl-2">
|
31
|
+
{{ $t('components.splashScreen.dontShowAgain') }}
|
32
|
+
</div>
|
33
|
+
</template>
|
34
|
+
</VcsCheckbox>
|
28
35
|
</v-card-text>
|
29
36
|
|
30
37
|
<v-card-actions>
|
@@ -33,6 +40,11 @@
|
|
33
40
|
v-if="
|
34
41
|
options.secondaryButtonTitle && options.secondaryCallbackOptions
|
35
42
|
"
|
43
|
+
:disabled="
|
44
|
+
option.requireInputForSecondary &&
|
45
|
+
options.acceptInput &&
|
46
|
+
!checkBox
|
47
|
+
"
|
36
48
|
@click="secondaryButtonClicked"
|
37
49
|
>
|
38
50
|
{{ $st(options.secondaryButtonTitle) }}
|
@@ -55,11 +67,27 @@
|
|
55
67
|
<script>
|
56
68
|
import { VDialog, VCard, VCardText, VCardActions } from 'vuetify/components';
|
57
69
|
import { computed, ref, inject } from 'vue';
|
70
|
+
import { moduleIdSymbol } from '@vcmap/core';
|
71
|
+
import { v5 as uuidv5 } from 'uuid';
|
72
|
+
import { hideSplashScreenKey, setToLocalStorage } from '../localStorage.js';
|
58
73
|
import { executeCallbacks } from '../callback/vcsCallback.js';
|
59
74
|
import VcsFormButton from '../components/buttons/VcsFormButton.vue';
|
60
75
|
import VcsCheckbox from '../components/form-inputs-controls/VcsCheckbox.vue';
|
61
76
|
import VcsMarkdown from '../components/form-output/VcsMarkdown.vue';
|
62
77
|
import { useProxiedAtomicModel } from '../components/modelHelper.js';
|
78
|
+
import { name } from '../../package.json';
|
79
|
+
|
80
|
+
/**
|
81
|
+
* @param {import("@vcmap/ui").VcsUiApp} app
|
82
|
+
* @returns {Promise<string>} The hash of the SplashScreen config.
|
83
|
+
*/
|
84
|
+
export function getSplashScreenHash(app) {
|
85
|
+
const config = app.uiConfig.getByKey('splashScreen');
|
86
|
+
const string = JSON.stringify(
|
87
|
+
Object.entries(config.value).sort((a, b) => a[0].localeCompare(b[0])),
|
88
|
+
);
|
89
|
+
return uuidv5(string, uuidv5.URL);
|
90
|
+
}
|
63
91
|
|
64
92
|
export default {
|
65
93
|
name: 'VcsSplashScreen',
|
@@ -87,9 +115,17 @@
|
|
87
115
|
const localValue = useProxiedAtomicModel(props, 'modelValue', emit);
|
88
116
|
|
89
117
|
const checkBox = ref(false);
|
118
|
+
const dontShowAgain = ref(false);
|
119
|
+
|
90
120
|
function exitScreen() {
|
91
121
|
localValue.value = false;
|
92
122
|
checkBox.value = false;
|
123
|
+
if (dontShowAgain.value) {
|
124
|
+
const config = app.uiConfig.getByKey('splashScreen');
|
125
|
+
const hash = getSplashScreenHash(app);
|
126
|
+
const moduleId = config[moduleIdSymbol];
|
127
|
+
setToLocalStorage(`${name}_${moduleId}`, hideSplashScreenKey, hash);
|
128
|
+
}
|
93
129
|
if (Array.isArray(props.options.exitCallbackOptions)) {
|
94
130
|
executeCallbacks(app, props.options.exitCallbackOptions);
|
95
131
|
}
|
@@ -113,6 +149,7 @@
|
|
113
149
|
exitScreen,
|
114
150
|
secondaryButtonClicked,
|
115
151
|
checkBox,
|
152
|
+
dontShowAgain,
|
116
153
|
position,
|
117
154
|
};
|
118
155
|
},
|
@@ -1,3 +1,8 @@
|
|
1
|
+
/**
|
2
|
+
* @param {import("@vcmap/ui").VcsUiApp} app
|
3
|
+
* @returns {Promise<string>} The hash of the SplashScreen config.
|
4
|
+
*/
|
5
|
+
export function getSplashScreenHash(app: import("@vcmap/ui").VcsUiApp): Promise<string>;
|
1
6
|
declare const _default: import("vue").DefineComponent<{
|
2
7
|
modelValue: {
|
3
8
|
type: BooleanConstructor;
|
@@ -12,6 +17,7 @@ declare const _default: import("vue").DefineComponent<{
|
|
12
17
|
exitScreen: () => void;
|
13
18
|
secondaryButtonClicked: () => void;
|
14
19
|
checkBox: import("vue").Ref<boolean>;
|
20
|
+
dontShowAgain: import("vue").Ref<boolean>;
|
15
21
|
position: import("vue").ComputedRef<{
|
16
22
|
width: any;
|
17
23
|
height: any;
|