@vcmap/ui 5.0.0-rc.12 → 5.0.0-rc.13

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 (37) hide show
  1. package/README.md +1 -1
  2. package/dist/assets/{cesium.4057e6.js → cesium.21663e.js} +0 -0
  3. package/dist/assets/cesium.js +1 -1
  4. package/dist/assets/{core.deb2b7.js → core.63242d.js} +1 -1
  5. package/dist/assets/core.js +1 -1
  6. package/dist/assets/{index.7aa11f5a.js → index.44b91cfe.js} +1 -1
  7. package/dist/assets/{ol.70b137.js → ol.88ba9d.js} +0 -0
  8. package/dist/assets/ol.js +1 -1
  9. package/dist/assets/ui.3c2933.css +1 -0
  10. package/dist/assets/{ui.9eb282.js → ui.3c2933.js} +43 -42
  11. package/dist/assets/ui.js +1 -1
  12. package/dist/assets/{vue.65d93f.js → vue.c897fc.js} +0 -0
  13. package/dist/assets/vue.js +2 -2
  14. package/dist/assets/{vuetify.149dde.css → vuetify.147c3a.css} +0 -0
  15. package/dist/assets/{vuetify.149dde.js → vuetify.147c3a.js} +1 -1
  16. package/dist/assets/vuetify.js +2 -2
  17. package/dist/index.html +1 -1
  18. package/index.js +1 -0
  19. package/package.json +12 -2
  20. package/plugins/example/index.js +10 -23
  21. package/plugins/test/index.js +13 -4
  22. package/plugins/test/toolbox-data.js +82 -57
  23. package/src/application/VcsApp.vue +1 -1
  24. package/src/components/lists/VcsActionList.vue +13 -7
  25. package/src/featureInfo/BalloonComponent.vue +2 -0
  26. package/src/featureInfo/featureInfo.js +5 -3
  27. package/src/i18n/de.js +4 -0
  28. package/src/i18n/en.js +4 -0
  29. package/src/manager/buttonManager.js +2 -7
  30. package/src/manager/navbarManager.js +1 -1
  31. package/src/manager/toolbox/GroupToolboxComponent.vue +118 -0
  32. package/src/manager/toolbox/SelectToolboxComponent.vue +128 -0
  33. package/src/manager/toolbox/ToolboxManager.vue +116 -99
  34. package/src/manager/toolbox/toolboxManager.js +233 -88
  35. package/src/vcsUiApp.js +1 -1
  36. package/dist/assets/ui.9eb282.css +0 -1
  37. package/src/manager/toolbox/ToolboxGroupComponent.vue +0 -132
@@ -0,0 +1,128 @@
1
+ <template>
2
+ <div
3
+ v-if="group.action"
4
+ :class="{ 'vcs-toolbox-action-select-button--active': open }"
5
+ style="width:fit-content"
6
+ >
7
+ <VcsButton
8
+ :key="group.action.tools[group.action.currentIndex].name"
9
+ :tooltip="group.action.tools[group.action.currentIndex].title"
10
+ :icon="group.action.tools[group.action.currentIndex].icon"
11
+ :active="group.action.active"
12
+ @click.stop="group.action.callback($event)"
13
+ v-bind="{...$attrs}"
14
+ class="vcs-toolbox-action-selected"
15
+ :min-width="32"
16
+ :width="32"
17
+ large
18
+ />
19
+ <v-menu
20
+ v-model="open"
21
+ @input="$emit('toggle', open)"
22
+ offset-y
23
+ :nudge-left="nudgeLeft"
24
+ z-index="0"
25
+ >
26
+ <template #activator="{ on, attrs }">
27
+ <VcsButton
28
+ :tooltip="group.action.title"
29
+ v-bind="attrs"
30
+ v-on="on"
31
+ class="vcs-toolbox-action-select"
32
+ :min-width="16"
33
+ :width="16"
34
+ large
35
+ >
36
+ <v-icon v-text="open ? 'mdi-chevron-up' : 'mdi-chevron-down'" color="accent" class="text--darken-3" />
37
+ </VcsButton>
38
+ </template>
39
+
40
+ <v-toolbar
41
+ class="vcs-toolbox-2 toolbar__secondary mx-auto v-sheet marginToTop justify-center"
42
+ :height="40"
43
+ width="fit-content"
44
+ color="basic"
45
+ dense
46
+ >
47
+ <v-toolbar-items class="w-full">
48
+ <div class="d-flex align-center justify-space-between w-full mx-1">
49
+ <VcsButton
50
+ v-for="(item, index) in group.action.tools"
51
+ :key="`${item.name}-${index}`"
52
+ :tooltip="item.title"
53
+ :icon="item.icon"
54
+ @click="group.action.selected(index)"
55
+ v-bind="{...$attrs}"
56
+ large
57
+ />
58
+ </div>
59
+ </v-toolbar-items>
60
+ </v-toolbar>
61
+ </v-menu>
62
+ </div>
63
+ </template>
64
+ <style lang="scss">
65
+ .vcs-toolbox-action-selected > .v-btn.vcs-button--large {
66
+ max-width: 40px;
67
+ }
68
+
69
+ .vcs-toolbox-action-select > .v-btn.vcs-button--large {
70
+ max-width: 8px;
71
+ }
72
+
73
+ .vcs-toolbox-action-select-button--active {
74
+ //border: 2px solid var(--v-basic-base);
75
+ border-radius: 5px;
76
+ background: var(--v-basic-base);
77
+ }
78
+
79
+ .vcs-toolbox-2 {
80
+ .v-toolbar__content {
81
+ padding: 0;
82
+ }
83
+ }
84
+
85
+ .marginToTop {
86
+ margin-top: 3px;
87
+ }
88
+ </style>
89
+ <script>
90
+ import { ref, computed } from 'vue';
91
+ import VcsButton from '../../components/buttons/VcsButton.vue';
92
+
93
+ /**
94
+ * @description
95
+ * A dynamic Toolbox Button rendering a selected item and a dropdown to select an item using {@link https://vuetifyjs.com/en/api/v-menu/|vuetify v-menu} and {@link VcsButton}.
96
+ * @vue-prop {SelectToolboxComponent} group - A toolbox group of type 'select'.
97
+ * @vue-computed {number} nudgeLeft - offset of the dropdown toolbar to the left
98
+ */
99
+ export default {
100
+ name: 'ToolboxActionSelect',
101
+ components: { VcsButton },
102
+ props: {
103
+ group: {
104
+ type: Object,
105
+ required: true,
106
+ },
107
+ },
108
+ setup(props) {
109
+ const open = ref(false);
110
+
111
+ /**
112
+ * v-menu auto prop is not working as expected.
113
+ * Workaround using hardcoded button sizes and paddings
114
+ * @type {ComputedRef<number>}
115
+ */
116
+ const nudgeLeft = computed(() => {
117
+ const toolboxBtnWidth = 42 + 8; // with padding
118
+ const menuBtnWidth = 16;
119
+ return (props.group.action.tools.length * (toolboxBtnWidth / 2)) + (menuBtnWidth / 2);
120
+ });
121
+
122
+ return {
123
+ open,
124
+ nudgeLeft,
125
+ };
126
+ },
127
+ };
128
+ </script>
@@ -1,24 +1,36 @@
1
- <script src="../../vcsUiApp.js"></script>
2
1
  <template>
3
2
  <v-toolbar
4
- v-if="toolboxOpen && actionGroups.length > 0 && $vuetify.breakpoint.mdAndUp"
5
- dense
3
+ v-if="toolboxOpen && orderedGroups.length > 0 && $vuetify.breakpoint.mdAndUp"
6
4
  class="vcs-toolbox toolbar__secondary mx-auto v-sheet marginToTop"
7
- :class="{ 'rounded-b': groupId === null }"
8
- :width="width"
5
+ :class="{ 'rounded-b': !open }"
6
+ :height="40"
7
+ width="fit-content"
8
+ dense
9
9
  >
10
10
  <v-toolbar-items class="w-full">
11
- <div class="d-flex align-center justify-space-between w-full">
12
- <ToolboxGroupComponent
13
- v-for="(group, idx) in actionGroups"
14
- :key="group.id"
15
- :group-icon="group.icon"
16
- :group-title="group.title"
17
- :actions="group.actions"
18
- class="px-2"
19
- :active="groupId === group.id"
20
- :position="getPosition(idx)"
21
- @click="toggleGroup(group.id)"
11
+ <div
12
+ class="d-flex align-center justify-space-between w-full mx-1"
13
+ v-for="group in orderedGroups"
14
+ :key="group.id"
15
+ >
16
+ <ToolboxActionGroup
17
+ v-if="group.type === ToolboxType.GROUP"
18
+ :group="group"
19
+ @toggle="(groupOpen) => open = groupOpen"
20
+ />
21
+ <ToolboxActionSelect
22
+ v-else-if="group.type === ToolboxType.SELECT"
23
+ :group="group"
24
+ @toggle="(selectOpen) => open = selectOpen"
25
+ />
26
+ <VcsButton
27
+ v-else
28
+ :tooltip="group.action.title"
29
+ :icon="group.action.icon"
30
+ :active="group.action.active"
31
+ @click.stop="group.action.callback($event)"
32
+ v-bind="{...$attrs}"
33
+ large
22
34
  />
23
35
  </div>
24
36
  </v-toolbar-items>
@@ -41,71 +53,95 @@
41
53
  &.theme--light.v-toolbar.v-sheet {
42
54
  background-color: #ffffffda;
43
55
  }
56
+ &.theme--dark.v-toolbar.v-sheet {
57
+ background-color: #000000da;
58
+ }
44
59
  }
45
60
 
46
61
  .marginToTop {
47
62
  margin-top: 2px;
48
63
  }
64
+
65
+ .v-toolbar__items > div{
66
+ gap: 8px;
67
+ width: fit-content;
68
+ display: inline-block;
69
+ }
49
70
  </style>
50
71
 
51
72
  <script>
73
+ import { inject, ref, computed, watch, onUnmounted } from 'vue';
74
+ import { ButtonLocation, vcsAppSymbol } from '@vcmap/ui';
75
+ import { getComponentsByOrder, ToolboxType } from './toolboxManager.js';
76
+ import ToolboxActionSelect from './SelectToolboxComponent.vue';
77
+ import ToolboxActionGroup from './GroupToolboxComponent.vue';
78
+ import VcsButton from '../../components/buttons/VcsButton.vue';
52
79
 
53
- import { inject, ref, computed, watch, onUnmounted } from 'vue';
54
- import ToolboxGroupComponent from './ToolboxGroupComponent.vue';
55
- import {ButtonLocation, vcsAppSymbol} from '@vcmap/ui';
80
+ /**
81
+ * @typedef {Object} ToolboxButtonGroup
82
+ * @property {string} id
83
+ * @property {string} type
84
+ * @property {string} icon
85
+ * @property {string} title
86
+ * @property {Array<ButtonComponent>} buttons
87
+ * @property {string} [selected]
88
+ * @property {function(index:number):void} [selectCb]
89
+ */
56
90
 
57
- /**
58
- * @typedef {Object} ActionGroup
59
- * @property {string} id
60
- * @property {string} icon
61
- * @property {string} title
62
- * @property {Array<VcsAction>} actions
63
- */
91
+ /**
92
+ * @description ToolboxManager component rendering toolbox different kind of Toolbox buttons:
93
+ * - Single toggle button
94
+ * - Select drop down button to select an item, selected button is rendered besides
95
+ * - Group drop down button showing a group of toggle buttons
96
+ * Watches for changes in toolbox components.
97
+ * Adds Toolbox button in Navbar, if components are available or removes it otherwise.
98
+ * @vue-computed {Array<ToolboxButtonGroup>} groups - Array of group components
99
+ * @vue-computed {Array<ToolboxButtonGroup>} orderedGroups - Array of group components sorted by owner
100
+ */
101
+ export default {
102
+ name: 'VcsToolboxManager',
103
+ components: {
104
+ ToolboxActionSelect,
105
+ ToolboxActionGroup,
106
+ VcsButton,
107
+ },
108
+ setup() {
109
+ const app = inject('vcsApp');
64
110
 
65
- /**
66
- * @description ToolboxManager component rendering toolbox using {@link ToolboxGroupComponent}.
67
- * @vue-computed {Array<ActionGroup>} actionGroups - Array of group components
68
- * @vue-computed {number} width - width of toolbox depending on number of groups
69
- */
70
- export default {
71
- name: 'VcsToolboxManager',
72
- components: {
73
- ToolboxGroupComponent,
74
- },
75
- setup() {
76
- const app = inject('vcsApp');
111
+ const toolboxComponentIds = ref(app.toolboxManager.componentIds);
112
+ const groups = computed(() => {
113
+ return toolboxComponentIds.value.map(id => app.toolboxManager.get(id));
114
+ });
77
115
 
78
- const toolboxComponentIds = ref(app.toolboxManager.componentIds);
79
- const actionGroups = computed(() => {
80
- const groups = toolboxComponentIds.value.map(id => app.toolboxManager.get(id));
81
- return groups
82
- .map((g) => {
83
- const buttonIds = ref(g.buttonManager.componentIds);
84
- return {
85
- id: g.id,
86
- icon: g.icon,
87
- title: g.title,
88
- actions: buttonIds.value.map(id => g.buttonManager.get(id).action),
89
- };
90
- })
91
- .filter(g => g.actions.length > 0);
92
- });
116
+ /**
117
+ * To be rendered in Toolbox components must meet certain conditions:
118
+ * - SingleToolboxComponent: no further conditions
119
+ * - SelectToolboxComponent: must have at least two tools
120
+ * - GroupToolboxComponent: must have at least one member (button)
121
+ * @param {SingleToolboxComponent|SelectToolboxComponent|GroupToolboxComponent} c
122
+ * @returns {boolean}
123
+ */
124
+ function filterFunc(c) {
125
+ return c.type === ToolboxType.SINGLE ||
126
+ c?.action?.tools?.length > 1 ||
127
+ c.buttonManager?.componentIds?.length > 0;
128
+ }
129
+ const orderedGroups = computed(() => getComponentsByOrder(groups.value).filter(filterFunc));
93
130
 
94
- const toolboxOpen = ref(true);
95
- const toolboxToggleAction = {
96
- name: 'toolboxToggleAction',
97
- icon: '$vcsTools',
98
- title: 'Toolbox',
99
- active: true,
100
- callback() {
101
- this.active = !this.active;
102
- toolboxOpen.value = this.active;
103
- },
104
- };
131
+ const toolboxOpen = ref(true);
132
+ const toolboxToggleAction = {
133
+ name: 'toolboxToggleAction',
134
+ icon: '$vcsTools',
135
+ title: 'Toolbox',
136
+ active: true,
137
+ callback() {
138
+ this.active = !this.active;
139
+ toolboxOpen.value = this.active;
140
+ },
141
+ };
105
142
 
106
- const stopWatching = watch([actionGroups],
107
- ([actionGroups]) => {
108
- if (actionGroups.length > 0) {
143
+ function handleToolboxButton() {
144
+ if (groups.value.length > 0) {
109
145
  if (!app.navbarManager.has('toolbox')) {
110
146
  app.navbarManager.add(
111
147
  {
@@ -120,39 +156,20 @@ export default {
120
156
  app.navbarManager.remove('toolbox');
121
157
  }
122
158
  }
123
- );
124
-
125
- onUnmounted(() => {
126
- stopWatching();
127
- });
159
+ handleToolboxButton();
128
160
 
129
- // XXX can this solved by CSS to get rid of the hardcoded size and padding?
130
- const buttonSize = 54;
131
- const buttonPadding = 8;
132
- const size = buttonSize + (2 * buttonPadding);
133
- const width = computed(() => actionGroups.value.length * size);
161
+ const stopWatching = watch(groups, () => handleToolboxButton());
134
162
 
135
- /**
136
- * calculates relative x-position of a button from the left edge of toolbar
137
- * @param {number} idx
138
- * @returns {number}
139
- */
140
- const getPosition = (idx) => (size * (idx + 1)) - (size / 2);
163
+ onUnmounted(() => {
164
+ stopWatching();
165
+ });
141
166
 
142
- return {
143
- toolboxOpen,
144
- actionGroups,
145
- width,
146
- getPosition,
147
- groupId: ref(null),
148
- toggleGroup(groupId) {
149
- if (this.groupId === groupId) {
150
- this.groupId = null;
151
- } else {
152
- this.groupId = groupId;
153
- }
154
- },
155
- };
156
- },
157
- };
167
+ return {
168
+ toolboxOpen,
169
+ orderedGroups,
170
+ ToolboxType,
171
+ open: ref(false),
172
+ };
173
+ },
174
+ };
158
175
  </script>