@vcmap/ui 5.0.0-rc.16 → 5.0.0-rc.17

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 (57) hide show
  1. package/build/buildHelpers.js +7 -1
  2. package/config/base.config.json +3 -45
  3. package/config/www.config.json +9 -10
  4. package/dist/assets/{cesium.430460.js → cesium.41de56.js} +0 -0
  5. package/dist/assets/cesium.js +1 -1
  6. package/dist/assets/{core.5089ba.js → core.af84e3.js} +1700 -1718
  7. package/dist/assets/core.js +1 -1
  8. package/dist/assets/{index.854f8e2b.js → index.5b773cad.js} +1 -1
  9. package/dist/assets/{ol.9be53a.js → ol.5c7490.js} +0 -0
  10. package/dist/assets/ol.js +1 -1
  11. package/dist/assets/{ui.49010a.css → ui.dffe32.css} +1 -1
  12. package/dist/assets/{ui.49010a.js → ui.dffe32.js} +6345 -6011
  13. package/dist/assets/ui.js +1 -1
  14. package/dist/assets/{vue.247c1c.js → vue.25da17.js} +0 -0
  15. package/dist/assets/vue.js +2 -2
  16. package/dist/assets/{vuetify.735e58.css → vuetify.e4ece7.css} +0 -0
  17. package/dist/assets/{vuetify.735e58.js → vuetify.e4ece7.js} +5 -2
  18. package/dist/assets/vuetify.js +2 -2
  19. package/dist/index.html +1 -1
  20. package/index.js +14 -3
  21. package/package.json +2 -2
  22. package/plugins/@vcmap/pluginExample/index.js +2 -1
  23. package/plugins/@vcmap/pluginExample/pluginExampleComponent.vue +7 -0
  24. package/plugins/categoryTest/Categories.vue +27 -13
  25. package/plugins/categoryTest/Category.vue +7 -1
  26. package/plugins/categoryTest/index.js +1 -1
  27. package/plugins/test/allIconsComponent.vue +3 -3
  28. package/plugins/test/index.js +6 -4
  29. package/plugins/test/testList.vue +4 -1
  30. package/plugins/test/vcsContent.vue +1 -1
  31. package/plugins/test/windowManagerExample.vue +9 -7
  32. package/src/actions/actionHelper.js +10 -9
  33. package/src/application/VcsApp.vue +25 -26
  34. package/src/components/form-inputs-controls/VcsCheckbox.vue +1 -0
  35. package/src/components/form-inputs-controls/VcsFormSection.vue +14 -6
  36. package/src/components/lists/VcsList.vue +4 -2
  37. package/src/contentTree/contentTreeCollection.js +9 -0
  38. package/src/contentTree/layerContentTreeItem.js +1 -1
  39. package/src/featureInfo/BalloonComponent.vue +3 -0
  40. package/src/featureInfo/balloonFeatureInfoView.js +2 -8
  41. package/src/featureInfo/balloonHelper.js +22 -5
  42. package/src/featureInfo/featureInfo.js +1 -2
  43. package/src/i18n/de.js +6 -1
  44. package/src/i18n/en.js +6 -1
  45. package/src/manager/categoryManager/CategoryComponent.vue +115 -0
  46. package/src/manager/categoryManager/CategoryComponentList.vue +57 -0
  47. package/src/manager/categoryManager/CategoryManager.vue +35 -0
  48. package/src/manager/categoryManager/categoryManager.js +251 -165
  49. package/src/manager/contextMenu/contextMenuManager.js +8 -2
  50. package/src/manager/window/WindowComponent.vue +49 -75
  51. package/src/manager/window/WindowComponentHeader.vue +49 -7
  52. package/src/manager/window/WindowManager.vue +53 -30
  53. package/src/manager/window/windowHelper.js +341 -0
  54. package/src/manager/window/windowManager.js +162 -150
  55. package/src/notifier/notifier.js +4 -5
  56. package/src/vcsUiApp.js +7 -1
  57. package/src/manager/categoryManager/ComponentsManager.vue +0 -30
package/dist/assets/ui.js CHANGED
@@ -1 +1 @@
1
- export * from "./ui.49010a.js";
1
+ export * from "./ui.dffe32.js";
File without changes
@@ -1,5 +1,5 @@
1
- export * from "./vue.247c1c.js";
2
- import { default as f } from "./vue.247c1c.js";
1
+ export * from "./vue.25da17.js";
2
+ import { default as f } from "./vue.25da17.js";
3
3
  export {
4
4
  f as default
5
5
  };
@@ -1,16 +1,19 @@
1
1
 
2
2
  function loadCss(href) {
3
+ const base64url = href
4
+ .replace(/-/g, '+')
5
+ .replace(/_/g, '/');
3
6
  return new Promise((resolve, reject) => {
4
7
  const elem = document.createElement('link');
5
8
  elem.rel = 'stylesheet';
6
- elem.href = href;
9
+ elem.href = base64url;
7
10
  elem.defer = false;
8
11
  elem.async = false;
9
12
  elem.onload = resolve;
10
13
  elem.onerror = reject;
11
14
  document.head.appendChild(elem);
12
15
  });
13
- } await loadCss('./assets/vuetify.735e58.css');import v from "./vue.247c1c.js";
16
+ } await loadCss('./assets/vuetify.e4ece7.css');import v from "./vue.25da17.js";
14
17
  const Ne = v.extend().extend({
15
18
  name: "themeable",
16
19
  provide() {
@@ -1,5 +1,5 @@
1
- export * from "./vuetify.735e58.js";
2
- import { default as f } from "./vuetify.735e58.js";
1
+ export * from "./vuetify.e4ece7.js";
2
+ import { default as f } from "./vuetify.e4ece7.js";
3
3
  export {
4
4
  f as default
5
5
  };
package/dist/index.html CHANGED
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="utf-8" />
5
5
  <meta name="viewport" content="width=device-width,initial-scale=1.0" />
6
- <script type="module" crossorigin src="./assets/index.854f8e2b.js"></script>
6
+ <script type="module" crossorigin src="./assets/index.5b773cad.js"></script>
7
7
  </head>
8
8
  <body style="height: 100vH;">
9
9
  <noscript>
package/index.js CHANGED
@@ -21,7 +21,7 @@ export {
21
21
  default as VcsApp,
22
22
  setupMapNavbar,
23
23
  setupPluginMountedListeners,
24
- setupComponentsWindow,
24
+ setupCategoryManagerWindow,
25
25
  } from './src/application/VcsApp.vue';
26
26
  export { default as VcsAppWrapper } from './src/application/vcsAppWrapper.vue';
27
27
  export { default as VcsMap } from './src/application/VcsMap.vue';
@@ -52,18 +52,29 @@ export {
52
52
  default as WindowManager,
53
53
  WindowSlot,
54
54
  WindowPositions,
55
+ posToPixel,
56
+ windowPositionFromOptions,
57
+ } from './src/manager/window/windowManager.js';
58
+ export {
55
59
  WindowAlignment,
56
60
  getFittedWindowPositionOptions,
57
61
  getFittedWindowPositionOptionsFromMapEvent,
58
62
  getWindowPositionOptions,
59
63
  getWindowPositionOptionsFromMapEvent,
60
- } from './src/manager/window/windowManager.js';
64
+ posToNumber,
65
+ posToPercent,
66
+ optionsFromWindowPosition,
67
+ updateWindowPosition,
68
+ clipToTargetSize,
69
+ moveWindow,
70
+ applyPositionOnTarget,
71
+ } from './src/manager/window/windowHelper.js';
61
72
 
62
73
  export { default as ButtonManager } from './src/manager/buttonManager.js';
63
74
  export { default as NavbarManager, ButtonLocation, getActionsByLocation } from './src/manager/navbarManager.js';
64
75
  export { default as ToolboxManager, ToolboxType } from './src/manager/toolbox/toolboxManager.js';
65
76
  export { default as CategoryManager } from './src/manager/categoryManager/categoryManager.js';
66
- export { default as ComponentsManager } from './src/manager/categoryManager/ComponentsManager.vue';
77
+ export { default as CategoryManagerComponent } from './src/manager/categoryManager/CategoryManager.vue';
67
78
  export { default as ContextMenuManager } from './src/manager/contextMenu/contextMenuManager.js';
68
79
  export { default as ContextMenuComponent } from './src/manager/contextMenu/contextMenuComponent.vue';
69
80
  export { default as ContextMenuInteraction } from './src/manager/contextMenu/contextMenuInteraction.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vcmap/ui",
3
- "version": "5.0.0-rc.16",
3
+ "version": "5.0.0-rc.17",
4
4
  "author": "Virtual City Systems",
5
5
  "license": "MIT",
6
6
  "scripts": {
@@ -43,7 +43,7 @@
43
43
  },
44
44
  "peerDependencies": {
45
45
  "@vcmap/cesium": "~1.97.1",
46
- "@vcmap/core": "~5.0.0-rc.24",
46
+ "@vcmap/core": "~5.0.0-rc.25",
47
47
  "ol": "~7.1.0",
48
48
  "vue": "~2.7.3",
49
49
  "vuetify": "~2.6.7"
@@ -80,7 +80,7 @@ export default function (config) {
80
80
  conditionalInput: '',
81
81
  initialTextInput: pluginConfig.initialTextInput.value,
82
82
  numberInput: 100.156,
83
- checkboxInput: false,
83
+ checkboxInput: true,
84
84
  email: '',
85
85
  prependedInput: '',
86
86
  files: [],
@@ -169,6 +169,7 @@ export default function (config) {
169
169
  headerTitle: 'pluginExample.title',
170
170
  headerIcon: '$vcsCircle',
171
171
  headerActions: actions,
172
+ infoUrl: 'https://vc.systems',
172
173
  },
173
174
  props: {
174
175
  actions,
@@ -3,6 +3,7 @@
3
3
  <VcsFormSection
4
4
  heading="VcsFormSection Select & Text Inputs"
5
5
  :header-actions="actions"
6
+ :action-button-list-overflow-count="4"
6
7
  >
7
8
  <template #help>
8
9
  <ol>
@@ -305,6 +306,12 @@
305
306
  <VcsFormSection
306
307
  heading="VcsFormSection Mixed Inputs"
307
308
  >
309
+ <template #header="{ heading }">
310
+ <article class="pa-2 secondary text--primary">
311
+ {{ heading }}
312
+ <h3>This is a custom header using header slot</h3>
313
+ </article>
314
+ </template>
308
315
  <template #default>
309
316
  <v-container>
310
317
  <v-row
@@ -13,9 +13,9 @@
13
13
  <span>
14
14
  <VcsButton icon="$vcsPlus" @click="newDialog = true" />
15
15
  <VcsButton icon="$vcsExport" @click="uploadDialog = true" />
16
- <VcsButton @click="addManagedCategories"> Add Categories To Manager </VcsButton>
16
+ <VcsButton @click="addManagedCategories">Add Categories To Manager</VcsButton>
17
+ <VcsButton @click="addFoobar">Add Foobar</VcsButton>
17
18
  </span>
18
-
19
19
  <v-dialog
20
20
  v-model="newDialog"
21
21
  >
@@ -121,17 +121,36 @@
121
121
  'viewpoints',
122
122
  'styles',
123
123
  ],
124
+ async addFoobar() {
125
+ if (!app.categories.hasKey('foobar')) {
126
+ const category = await app.categories.requestCategory({
127
+ name: 'foobar',
128
+ type: 'Category',
129
+ title: 'Foobar',
130
+ });
131
+ app.categoryManager.add({ categoryName: category.name }, '@vcmap/categoryTest');
132
+ app.categoryManager.addMappingFunction(() => true, (item, c, listItem) => {
133
+ listItem.title = item.name;
134
+ }, [category.name], '@vcmap/categoryTest');
135
+ for (let i = 0; i <= 12; i++) {
136
+ category.collection.add({
137
+ name: `foobar-${i}`,
138
+ });
139
+ }
140
+ }
141
+ },
124
142
  async add() {
125
143
  const { value: newCategoryValue } = newCategory;
126
144
  if (newCategoryValue.type === 'AppBackedCategory') {
127
145
  newCategoryValue.name = newCategoryValue.collectionName;
128
146
  }
129
- await app.categories.requestCategory(newCategoryValue);
147
+ const category = await app.categories.requestCategory(newCategoryValue);
130
148
  newCategory.value = {
131
149
  name: 'new',
132
- type: 'category.Category',
150
+ type: 'Category',
133
151
  collectionName: null,
134
152
  };
153
+ app.categoryManager.add({ categoryName: category.name }, '@vcmap/categoryTest');
135
154
  newDialog.value = false;
136
155
  },
137
156
  async upload() {
@@ -141,10 +160,11 @@
141
160
  console.error('must provide name');
142
161
  return;
143
162
  }
144
- await app.categories.requestCategory({ name: jsonUpload.name, type: 'Category' });
163
+ const category = await app.categories.requestCategory({ name: jsonUpload.name, type: 'Category' });
145
164
  if (jsonUpload?.items?.length > 0) {
146
165
  await app.categories.parseCategoryItems(jsonUpload.name, jsonUpload.items, app.dynamicContextId);
147
166
  }
167
+ app.categoryManager.add({ categoryName: category.name }, '@vcmap/categoryTest');
148
168
  uploadString.value = '';
149
169
  uploadDialog.value = false;
150
170
  } catch (e) {
@@ -209,10 +229,8 @@
209
229
  }));
210
230
  },
211
231
  }];
212
- app.categoryManager.addCategory(layersCat.name, '@vcmap/categoryTest', actions);
213
- app.categoryManager.addMappingFunction((item, category) => {
214
- return category.name === 'layers';
215
- }, (item, category, treeViewItem) => {
232
+ app.categoryManager.add({ categoryName: layersCat.name, actions }, '@vcmap/categoryTest');
233
+ app.categoryManager.addMappingFunction(() => true, (item, category, treeViewItem) => {
216
234
  // eslint-disable-next-line no-console
217
235
  const action = {
218
236
  name: 'mySuperAction',
@@ -222,10 +240,6 @@
222
240
  },
223
241
  };
224
242
  treeViewItem.actions.push(action);
225
- treeViewItem.clickable = true;
226
- treeViewItem.clicked = () => {
227
- if (!item.active) item.activate(); else item.deactivate();
228
- };
229
243
  const action2 = {
230
244
  name: 'mySuperAction3',
231
245
  icon: 'mdi-minus',
@@ -65,6 +65,8 @@
65
65
  VCard,
66
66
  VForm,
67
67
  VTextarea,
68
+ VSheet,
69
+ VBtn,
68
70
  } from 'vuetify/lib';
69
71
 
70
72
  export default {
@@ -80,6 +82,8 @@
80
82
  VCard,
81
83
  VForm,
82
84
  VTextarea,
85
+ VSheet,
86
+ VBtn,
83
87
  },
84
88
  props: {
85
89
  categoryName: {
@@ -95,6 +99,7 @@
95
99
  const category = ref([]);
96
100
  const downloadLink = ref('');
97
101
  const open = ref(true);
102
+ const link = ref(null);
98
103
  if (categoryObject) {
99
104
  category.value = [...categoryObject.collection].map(c => ({ name: c.name, type: c.className || 'Object' }));
100
105
  }
@@ -105,6 +110,7 @@
105
110
  jsonString,
106
111
  downloadLink,
107
112
  open,
113
+ link,
108
114
  async addItem() {
109
115
  try {
110
116
  const config = JSON.parse(jsonString.value);
@@ -126,7 +132,7 @@
126
132
  downloadLink.value = `data:text/json;charset=utf-8,${encodeURIComponent(stringObject)}`;
127
133
  if (downloadLink.value) {
128
134
  nextTick(() => {
129
- this.$refs.link.click();
135
+ link.value.click();
130
136
  });
131
137
  }
132
138
  },
@@ -7,7 +7,7 @@ import Categories from './Categories.vue';
7
7
  export default async function categoryTest() {
8
8
  return {
9
9
  name: '@vcmap/categoryTest',
10
- onVcsAppMounted(app) {
10
+ initialize(app) {
11
11
  const { action, destroy } = createToggleAction(
12
12
  {
13
13
  name: 'Category Editor',
@@ -44,7 +44,7 @@
44
44
  </script>
45
45
 
46
46
  <style scoped>
47
- .icons-window {
48
- max-height: 600px;
49
- }
47
+ /*.icons-window {*/
48
+ /* max-height: 600px;*/
49
+ /*}*/
50
50
  </style>
@@ -73,7 +73,7 @@ export default async function () {
73
73
  app.windowManager,
74
74
  '@vcmap/test',
75
75
  );
76
- const { action: clipboardDialogAction, destroy: destroryClipboardDialogAction } = createModalAction(
76
+ const { action: clipboardDialogAction, destroy: destroyClipboardDialogAction } = createModalAction(
77
77
  {
78
78
  name: 'Create Link',
79
79
  },
@@ -86,7 +86,9 @@ export default async function () {
86
86
  };
87
87
  },
88
88
  async created() {
89
- this.url = setStateToUrl(await app.getState(true)).toString();
89
+ const url = new URL(window.location.href);
90
+ setStateToUrl(await app.getState(true), url);
91
+ this.url = url.toString();
90
92
  },
91
93
  },
92
94
  position: {
@@ -95,7 +97,7 @@ export default async function () {
95
97
  right: '8%',
96
98
  },
97
99
  },
98
- app.windowManager,
100
+ app,
99
101
  '@vcmap/test',
100
102
  );
101
103
  const { action: listAction, destroy: destroyList } = createToggleAction(
@@ -117,7 +119,7 @@ export default async function () {
117
119
  destroyConfigEditorAction,
118
120
  destroyWindowAction,
119
121
  destroyIconAction,
120
- destroryClipboardDialogAction,
122
+ destroyClipboardDialogAction,
121
123
  destroyList,
122
124
  ];
123
125
  const alertAction = {
@@ -123,6 +123,7 @@
123
123
  title: 'Foo',
124
124
  tooltip: 'this is the foo',
125
125
  icon: 'mdi-pen',
126
+ selectionChanged: value => console.log('changed cb foo', value),
126
127
  },
127
128
  {
128
129
  name: 'bar',
@@ -136,11 +137,13 @@
136
137
  },
137
138
  },
138
139
  ],
140
+ selectionChanged: value => console.log('changed cb bar', value),
139
141
  },
140
142
  {
141
- name: 'bar',
143
+ name: 'baz',
142
144
  title: 'Baz',
143
145
  tooltip: 'special baz',
146
+ selectionChanged: value => console.log('bchanged cb baz', value),
144
147
  },
145
148
  ];
146
149
 
@@ -18,7 +18,7 @@
18
18
 
19
19
  export default {
20
20
  name: 'VcsContent',
21
- components: [VSheet],
21
+ components: { VSheet },
22
22
  setup() {
23
23
  return { };
24
24
  },
@@ -88,7 +88,7 @@
88
88
  {
89
89
  id: 'position1',
90
90
  state: {
91
- headerTitle: 'Example position1',
91
+ headerTitle: 'Example position1 relative',
92
92
  },
93
93
  component: VcsContent,
94
94
  position: {
@@ -101,15 +101,17 @@
101
101
  {
102
102
  id: 'position2',
103
103
  state: {
104
- hideHeader: true,
105
- headerTitle: 'Example position2',
104
+ hideHeader: false,
105
+ headerTitle: 'Example position2 absolute',
106
106
  },
107
107
  component: EmptyComponent,
108
108
  position: {
109
- left: '35%',
110
- right: '35%',
111
- top: '40%',
112
- bottom: '20%',
109
+ left: '200px',
110
+ top: '300px',
111
+ minHeight: '250px',
112
+ maxHeight: '500px',
113
+ minWidth: '400px',
114
+ maxWidth: '1000px',
113
115
  },
114
116
  },
115
117
  ];
@@ -4,7 +4,8 @@ import { Collection, Extent, MapCollection, mercatorProjection, Viewpoint } from
4
4
  import { Feature } from 'ol';
5
5
  import { reactive, ref } from 'vue';
6
6
  import { vcsAppSymbol } from '../pluginHelper.js';
7
- import { getWindowPositionOptions, WindowSlot } from '../manager/window/windowManager.js';
7
+ import { WindowSlot } from '../manager/window/windowManager.js';
8
+ import { getWindowPositionOptions } from '../manager/window/windowHelper.js';
8
9
  import SearchComponent from '../search/searchComponent.vue';
9
10
 
10
11
  /**
@@ -189,11 +190,11 @@ export function createOverviewMapAction(overviewMap, windowComponent, windowMana
189
190
  * at the clicked position (the actions position) by default, unless the window component already has a position set.
190
191
  * @param {ActionOptions} actionOptions
191
192
  * @param {WindowComponentOptions} modalComponent
192
- * @param {WindowManager} windowManager
193
+ * @param {VcsUiApp} app
193
194
  * @param {string|symbol} owner
194
195
  * @returns {{action: VcsAction, destroy: Function}}
195
196
  */
196
- export function createModalAction(actionOptions, modalComponent, windowManager, owner) {
197
+ export function createModalAction(actionOptions, modalComponent, app, owner) {
197
198
  check(actionOptions, {
198
199
  name: String,
199
200
  icon: [undefined, String],
@@ -216,7 +217,7 @@ export function createModalAction(actionOptions, modalComponent, windowManager,
216
217
  left: 0,
217
218
  right: 0,
218
219
  });
219
- elem.onclick = () => { windowManager.remove(id); };
220
+ elem.onclick = () => { app.windowManager.remove(id); };
220
221
  document.body.appendChild(elem);
221
222
  }
222
223
  };
@@ -235,20 +236,20 @@ export function createModalAction(actionOptions, modalComponent, windowManager,
235
236
  if (!this.active) {
236
237
  this.active = true;
237
238
  const { left, top, width } = event.currentTarget.getBoundingClientRect();
238
- const position = getWindowPositionOptions(left + width, top);
239
+ const position = getWindowPositionOptions(left + width, top, app.maps.target);
239
240
  const state = { ...modalComponent?.state, hideHeader: true };
240
- windowManager.add({ position, ...modalComponent, id, state }, owner);
241
- addModal(windowManager.componentIds.length - 2);
241
+ app.windowManager.add({ position, ...modalComponent, id, state }, owner);
242
+ addModal(app.windowManager.componentIds.length - 2);
242
243
  } else {
243
244
  this.active = false;
244
- windowManager.remove(id);
245
+ app.windowManager.remove(id);
245
246
  }
246
247
  return null;
247
248
  },
248
249
  };
249
250
 
250
251
  const listeners = [
251
- windowManager.removed.addEventListener(({ id: windowId }) => {
252
+ app.windowManager.removed.addEventListener(({ id: windowId }) => {
252
253
  if (windowId === id) {
253
254
  action.active = false;
254
255
  removeModal();
@@ -85,7 +85,7 @@
85
85
  import MapNavigation from '../navigation/mapNavigation.vue';
86
86
  import VcsSettings from './VcsSettings.vue';
87
87
  import { WindowSlot } from '../manager/window/windowManager.js';
88
- import ComponentsManager from '../manager/categoryManager/ComponentsManager.vue';
88
+ import CategoryManager from '../manager/categoryManager/CategoryManager.vue';
89
89
  import { defaultPrimaryColor } from '../vuePlugins/vuetify.js';
90
90
  import VcsLegend from '../legend/vcsLegend.vue';
91
91
  import { getLegendEntries } from '../legend/legendHelper.js';
@@ -276,56 +276,54 @@
276
276
  }
277
277
 
278
278
  /**
279
- * This helper function will add a Components manager button to the navbar. The Components Manager
279
+ * This helper function will add a category manager button to the navbar. The category Manager
280
280
  * will only be shown if there is at least one category under management in the categoryManager.
281
281
  * @param {VcsUiApp} app
282
282
  * @returns {function():void}
283
283
  */
284
- export function setupComponentsWindow(app) {
285
- const { action: componentsManagerAction, destroy: destroyComponentsManagerAction } = createToggleAction(
284
+ export function setupCategoryManagerWindow(app) {
285
+ const id = 'category-manager';
286
+ const { action: categoryManagerAction, destroy } = createToggleAction(
286
287
  {
287
- name: 'components-manager',
288
+ name: id,
288
289
  icon: '$vcsComponents',
289
- title: 'components.tooltip',
290
+ title: 'categoryManager.tooltip',
290
291
  },
291
292
  {
292
- id: 'component-manager',
293
+ id,
293
294
  state: {
294
- headerTitle: 'components.title',
295
+ headerTitle: 'categoryManager.title',
295
296
  headerIcon: '$vcsComponents',
296
297
  },
297
- component: ComponentsManager,
298
+ component: CategoryManager,
298
299
  slot: WindowSlot.STATIC,
299
300
  },
300
301
  app.windowManager,
301
302
  vcsAppSymbol,
302
303
  );
303
304
 
304
- // only show Components Window if we have at least one managed Category
305
- if (app.categoryManager.items.value.length > 0) {
306
- app.navbarManager.add(
307
- { id: 'component-manager', action: componentsManagerAction },
308
- vcsAppSymbol,
309
- ButtonLocation.CONTENT,
310
- );
311
- }
312
- watch(app.categoryManager.items.value, () => {
313
- if (app.categoryManager.items.value.length > 0) {
314
- if (!app.navbarManager.has('component-manager')) {
305
+ const setupCategories = () => {
306
+ if (app.categoryManager.componentIds.length > 0) {
307
+ if (!app.navbarManager.has(id)) {
315
308
  app.navbarManager.add(
316
- { id: 'component-manager', action: componentsManagerAction },
309
+ { id, action: categoryManagerAction },
317
310
  vcsAppSymbol,
318
311
  ButtonLocation.CONTENT,
319
312
  );
320
313
  }
321
314
  } else {
322
- app.windowManager.remove('component-manager');
323
- app.navbarManager.remove('component-manager');
315
+ app.windowManager.remove(id);
316
+ app.navbarManager.remove(id);
324
317
  }
325
- });
318
+ };
319
+ const addedListener = app.categoryManager.added.addEventListener(setupCategories);
320
+ const removedListener = app.categoryManager.removed.addEventListener(setupCategories);
321
+ setupCategories();
326
322
 
327
323
  return () => {
328
- destroyComponentsManagerAction();
324
+ destroy();
325
+ addedListener();
326
+ removedListener();
329
327
  };
330
328
  }
331
329
 
@@ -432,7 +430,7 @@
432
430
  const mapNavbarListener = setupMapNavbar(app);
433
431
  const legendDestroy = setupLegendWindow(app);
434
432
  const settingsDestroy = setupSettingsWindow(app);
435
- const destroyComponentsWindow = setupComponentsWindow(app);
433
+ const destroyComponentsWindow = setupCategoryManagerWindow(app);
436
434
  const destroyThemingListener = setupUiConfigTheming(app, getCurrentInstance().proxy.$vuetify);
437
435
  const { attributionEntries, attributionAction, destroyAttributions } = setupAttributions(app);
438
436
 
@@ -440,6 +438,7 @@
440
438
  onMounted(() => {
441
439
  pluginMountedListener = setupPluginMountedListeners(app);
442
440
  app.maps.setTarget(mapId);
441
+ app.mounted.raiseEvent(mapId);
443
442
  });
444
443
 
445
444
  onUnmounted(() => {
@@ -7,6 +7,7 @@
7
7
  <template #activator="{ on, attrs }">
8
8
  <span v-on="on">
9
9
  <v-checkbox
10
+ :input-value="$attrs.value"
10
11
  on-icon="$vcsCheckboxChecked"
11
12
  off-icon="$vcsCheckbox"
12
13
  class="vcs-checkbox"
@@ -1,11 +1,12 @@
1
1
  <template>
2
2
  <section class="vcs-form-section">
3
- <slot name="header">
3
+ <slot name="header" :heading="heading" :actions="actions">
4
4
  <article class="pa-2 accent">
5
5
  <div class="form-section-header d-flex justify-space-between align-center">
6
6
  <strong class="caption">{{ $t(heading) }}</strong>
7
7
  <VcsActionButtonList
8
8
  :actions="actions"
9
+ :overflow-count="actionButtonListOverflowCount"
9
10
  small
10
11
  />
11
12
  </div>
@@ -30,7 +31,7 @@
30
31
 
31
32
 
32
33
  <script>
33
- import { computed, ref } from 'vue';
34
+ import { computed, reactive } from 'vue';
34
35
  import { VAlert } from 'vuetify/lib';
35
36
  import VcsActionButtonList from '../buttons/VcsActionButtonList.vue';
36
37
 
@@ -42,6 +43,7 @@
42
43
  * @vue-data {slot} [#help] - Slot to specify html based help. Gets precedence over helpText prop.
43
44
  * @vue-prop {string} heading - Title of the section to be displayed, will be translated.
44
45
  * @vue-prop {Array<VcsAction>} headerActions - Icons to be displayed on the right side
46
+ * @vue-prop {number} [actionButtonListOverflowCount] - overflow count to use for action lists in the title and items
45
47
  * @vue-prop {string} [helpText] - Optional help text. Must be plain string. Use 'help' slot for html based help texts. Help slot has precedence over helpText prop.
46
48
  * @vue-computed {Array<VcsAction>} actions - Returns header actions extended by a help action, if help prop is passed or help slot is used.
47
49
  */
@@ -60,19 +62,25 @@
60
62
  type: Array,
61
63
  default: () => ([]),
62
64
  },
65
+ actionButtonListOverflowCount: {
66
+ type: Number,
67
+ required: false,
68
+ default: undefined,
69
+ },
63
70
  helpText: {
64
71
  type: String,
65
72
  default: undefined,
66
73
  },
67
74
  },
68
75
  setup(props, { slots }) {
69
- const showHelp = ref(false);
70
- const helpAction = {
76
+ const helpAction = reactive({
71
77
  name: 'help',
72
78
  title: 'components.vcsFormSection.help',
79
+ active: false,
73
80
  icon: 'mdi-help-circle',
74
- callback: () => { showHelp.value = !showHelp.value; },
75
- };
81
+ callback() { this.active = !this.active; },
82
+ });
83
+ const showHelp = computed(() => helpAction.active);
76
84
  /**
77
85
  * @type {ComputedRef<VcsAction>}
78
86
  */