@vcmap/ui 5.0.0-rc.8 → 5.0.0-rc.9

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 (178) hide show
  1. package/README.md +69 -22
  2. package/build/build.js +0 -3
  3. package/build/buildHelpers.js +0 -1
  4. package/build/commonViteConfig.js +1 -1
  5. package/config/dev.config.json +4 -4
  6. package/dist/assets/{cesium.6b5bb6.js → cesium.4e40f4.js} +0 -0
  7. package/dist/assets/cesium.js +1 -1
  8. package/dist/assets/core.edcf5e.js +4 -0
  9. package/dist/assets/core.js +1 -1
  10. package/dist/assets/{index.0be2842f.js → index.889d0f3a.js} +1 -1
  11. package/dist/assets/{ol.0561aa.js → ol.246fd4.js} +0 -0
  12. package/dist/assets/ol.js +1 -1
  13. package/dist/assets/ui.df4f6d.css +1 -0
  14. package/dist/assets/ui.df4f6d.js +43 -0
  15. package/dist/assets/ui.js +1 -1
  16. package/dist/assets/{vue-composition-api.f926fa.js → vue-composition-api.a520f3.js} +1 -1
  17. package/dist/assets/vue-composition-api.js +2 -2
  18. package/dist/assets/{vue.ddcb6b.js → vue.2cee44.js} +0 -0
  19. package/dist/assets/vue.js +1 -1
  20. package/dist/assets/{vuetify.d21163.css → vuetify.cc817b.css} +0 -0
  21. package/dist/assets/{vuetify.d21163.js → vuetify.cc817b.js} +1 -1
  22. package/dist/assets/vuetify.js +2 -2
  23. package/dist/index.html +1 -1
  24. package/index.js +39 -1
  25. package/package.json +2 -3
  26. package/plugins/@vcmap/pluginExample/index.js +5 -5
  27. package/plugins/@vcmap/pluginExample/pluginExampleComponent.vue +1 -1
  28. package/plugins/@vcmap/project-selector/ContextsListComponent.vue +1 -1
  29. package/plugins/@vcmap/project-selector/index.js +5 -5
  30. package/plugins/@vcmap/project-selector/package.json +1 -2
  31. package/plugins/@vcmap/theme-changer/index.js +6 -6
  32. package/plugins/buttonExamples/ButtonExamples.vue +1 -1
  33. package/plugins/buttonExamples/index.js +5 -4
  34. package/plugins/categoryTest/Categories.vue +1 -1
  35. package/plugins/categoryTest/Category.vue +1 -1
  36. package/plugins/categoryTest/index.js +5 -5
  37. package/plugins/example/index.js +33 -14
  38. package/plugins/test/allIconsComponent.vue +34 -0
  39. package/plugins/test/editor.vue +1 -1
  40. package/plugins/test/index.js +40 -17
  41. package/plugins/test/toolbox-data.js +106 -26
  42. package/plugins/test/windowManagerExample.vue +1 -2
  43. package/src/actions/actionHelper.js +2 -1
  44. package/src/actions/styleSelector.vue +1 -1
  45. package/src/application/Navbar.vue +18 -6
  46. package/src/application/VcsApp.vue +34 -28
  47. package/src/assets/logo-mobile.svg +9 -0
  48. package/src/assets/logo.svg +23 -23
  49. package/src/components/buttons/VcsActionButtonList.vue +99 -0
  50. package/src/components/buttons/VcsButton.vue +201 -0
  51. package/src/components/form-inputs-controls/VcsCheckbox.vue +73 -0
  52. package/src/components/form-inputs-controls/VcsColorPicker.vue +81 -0
  53. package/src/components/form-inputs-controls/VcsFormSection.vue +46 -0
  54. package/src/components/form-inputs-controls/VcsLabel.vue +38 -0
  55. package/src/components/form-inputs-controls/VcsSelect.vue +97 -0
  56. package/src/components/form-inputs-controls/VcsTextArea.vue +130 -0
  57. package/src/components/form-inputs-controls/VcsTextField.vue +129 -0
  58. package/src/components/form-output/VcsFormattedNumber.vue +103 -0
  59. package/src/components/lists/VcsActionList.vue +100 -0
  60. package/src/components/lists/VcsTreeview.vue +109 -0
  61. package/src/components/lists/VcsTreeviewLeaf.vue +105 -0
  62. package/src/components/lists/VcsTreeviewSearchbar.vue +156 -0
  63. package/src/components/notification/VcsBadge.vue +27 -0
  64. package/src/components/notification/VcsTooltip.vue +154 -0
  65. package/src/components/notification/validation.js +19 -0
  66. package/src/contentTree/LayerTree.vue +1 -1
  67. package/src/contentTree/contentTreeCollection.js +6 -2
  68. package/src/icons/+all.js +359 -0
  69. package/src/icons/2DAreaIcon.vue +21 -0
  70. package/src/icons/2DDistanceIcon.vue +18 -0
  71. package/src/icons/3DAreaIcon.vue +21 -0
  72. package/src/icons/3DDistanceIcon.vue +18 -0
  73. package/src/icons/3DHeightIcon.vue +18 -0
  74. package/src/icons/AngleIcon.vue +8 -0
  75. package/src/icons/AssociationsIcon.vue +34 -0
  76. package/src/icons/AxisIcon.vue +10 -0
  77. package/src/icons/BoundingBoxIcon.vue +15 -0
  78. package/src/icons/CheckboxCheckedIcon.vue +16 -0
  79. package/src/icons/CheckboxIcon.vue +23 -0
  80. package/src/icons/CheckboxIndeterminateIcon.vue +24 -0
  81. package/src/icons/CircleIcon.vue +10 -0
  82. package/src/icons/ColorSwatchIcon.vue +17 -0
  83. package/src/icons/CommentIcon.vue +19 -0
  84. package/src/icons/CompassIcon.vue +8 -0
  85. package/src/icons/ComponentsIcon.vue +7 -0
  86. package/src/icons/ConeIcon.vue +11 -0
  87. package/src/icons/DimensionsHouseIcon.vue +14 -0
  88. package/src/icons/ElevationProfileIcon.vue +111 -0
  89. package/src/icons/ExportAreaIcon.vue +7 -0
  90. package/src/icons/ExportFlightIcon.vue +7 -0
  91. package/src/icons/ExportIcon.vue +8 -0
  92. package/src/icons/ExternalLinkIcon.vue +10 -0
  93. package/src/icons/EyeIcon.vue +7 -0
  94. package/src/icons/FastForwardIcon.vue +7 -0
  95. package/src/icons/FilterIcon.vue +8 -0
  96. package/src/icons/GlobeNatureIcon.vue +14 -0
  97. package/src/icons/HealthCareIndustriesIcon.vue +118 -0
  98. package/src/icons/HelpIcon.vue +7 -0
  99. package/src/icons/HomePointIcon.vue +8 -0
  100. package/src/icons/HospitalsIcon.vue +237 -0
  101. package/src/icons/HouseIcon.vue +25 -0
  102. package/src/icons/ImportIcon.vue +8 -0
  103. package/src/icons/InfoIcon.vue +10 -0
  104. package/src/icons/KebabIcon.vue +36 -0
  105. package/src/icons/LabelIcon.vue +7 -0
  106. package/src/icons/LayersIcon.vue +26 -0
  107. package/src/icons/LegendIcon.vue +65 -0
  108. package/src/icons/LineIcon.vue +7 -0
  109. package/src/icons/LinkIcon.vue +7 -0
  110. package/src/icons/MapIcon.vue +8 -0
  111. package/src/icons/MenuIcon.vue +34 -0
  112. package/src/icons/MinusIcon.vue +8 -0
  113. package/src/icons/ObjectAttributeIcon.vue +18 -0
  114. package/src/icons/ObjectSelectIcon.vue +8 -0
  115. package/src/icons/ObliqueViewIcon.vue +13 -0
  116. package/src/icons/PdfIcon.vue +10 -0
  117. package/src/icons/PedestrianIcon.vue +8 -0
  118. package/src/icons/PenIcon.vue +14 -0
  119. package/src/icons/PlayCircleIcon.vue +10 -0
  120. package/src/icons/PlusIcon.vue +9 -0
  121. package/src/icons/PoiIcon.vue +7 -0
  122. package/src/icons/PointSelectIcon.vue +7 -0
  123. package/src/icons/PolygonIcon.vue +38 -0
  124. package/src/icons/PresentationModeIcon.vue +7 -0
  125. package/src/icons/ProgressIcon.vue +24 -0
  126. package/src/icons/QueryIcon.vue +15 -0
  127. package/src/icons/RectangleIcon.vue +9 -0
  128. package/src/icons/ReturnIcon.vue +7 -0
  129. package/src/icons/RewindIcon.vue +6 -0
  130. package/src/icons/SearchIcon.vue +8 -0
  131. package/src/icons/ShadowIcon.vue +9 -0
  132. package/src/icons/ShapesIcon.vue +28 -0
  133. package/src/icons/ShareIcon.vue +22 -0
  134. package/src/icons/SimpleCircleFilledIcon.vue +15 -0
  135. package/src/icons/SimpleCircleHalfFilledIcon.vue +12 -0
  136. package/src/icons/SimpleCircleOutlinedIcon.vue +15 -0
  137. package/src/icons/SkipNextIcon.vue +7 -0
  138. package/src/icons/SkipPreviousIcon.vue +9 -0
  139. package/src/icons/SplitViewIcon.vue +19 -0
  140. package/src/icons/TextStyleIcon.vue +14 -0
  141. package/src/icons/ThreeDimensionsIcon.vue +7 -0
  142. package/src/icons/ToolsIcon.vue +35 -0
  143. package/src/icons/TouchIcon.vue +8 -0
  144. package/src/icons/TrashCanIcon.vue +7 -0
  145. package/src/icons/TriangleIcon.vue +15 -0
  146. package/src/icons/TwoDimensionsIcon.vue +8 -0
  147. package/src/icons/UploadIcon.vue +14 -0
  148. package/src/icons/VideoRecorderIcon.vue +14 -0
  149. package/src/icons/WalkingIcon.vue +7 -0
  150. package/src/icons/WallIcon.vue +14 -0
  151. package/src/manager/buttonManager.js +5 -53
  152. package/src/manager/navbarManager.js +81 -0
  153. package/src/manager/toolbox/ToolboxGroupComponent.vue +128 -0
  154. package/src/manager/toolbox/ToolboxManager.vue +119 -76
  155. package/src/manager/toolbox/toolboxManager.js +204 -0
  156. package/src/manager/window/WindowComponentHeader.vue +1 -1
  157. package/src/manager/window/WindowManager.vue +18 -1
  158. package/src/manager/window/windowManager.js +3 -5
  159. package/src/navigation/mapNavigation.vue +9 -5
  160. package/src/navigation/orientationToolsButton.vue +1 -1
  161. package/src/navigation/tiltSlider.vue +1 -1
  162. package/src/styles/_theming.scss +10 -0
  163. package/src/styles/main.scss +3 -0
  164. package/src/styles/variables.scss +70 -0
  165. package/src/styles/vcsFont.scss +5 -0
  166. package/src/styles/vcsGrid.scss +4 -0
  167. package/src/vcsUiApp.js +4 -3
  168. package/src/vuePlugins/vuetify.js +1 -1
  169. package/dist/assets/core.98f9bb.js +0 -4
  170. package/dist/assets/ui.b7c1e3.css +0 -1
  171. package/dist/assets/ui.b7c1e3.js +0 -39
  172. package/dist/assets/uicomponents.682c5f.css +0 -1
  173. package/dist/assets/uicomponents.682c5f.js +0 -32
  174. package/dist/assets/uicomponents.js +0 -1
  175. package/lib/uicomponents.js +0 -1
  176. package/src/manager/toolbox/ToolboxMultiSelectButton.vue +0 -96
  177. package/src/manager/toolbox/ToolboxSingleSelectButton.vue +0 -98
  178. package/src/manager/toolbox/toolbox-manager.js +0 -203
@@ -0,0 +1,128 @@
1
+ <template>
2
+ <div v-if="actions.length > 0">
3
+ <VcsButton
4
+ v-if="singleActionButton"
5
+ :key="singleActionButton.name"
6
+ :tooltip="singleActionButton.title"
7
+ :icon="singleActionButton.icon"
8
+ :active="singleActionButton.active"
9
+ @click.stop="singleActionButton.callback($event)"
10
+ v-bind="{...$attrs}"
11
+ />
12
+ <VcsButton
13
+ v-else-if="groupButtons.length > 0"
14
+ v-bind="{...$attrs}"
15
+ width="48"
16
+ :icon="groupIcon"
17
+ :tooltip="groupTitle"
18
+ :active="active"
19
+ @click="$emit('click')"
20
+ >
21
+ <v-icon v-text="active ? 'mdi-chevron-up' : 'mdi-chevron-down'" color="accent" class="text--darken-3" />
22
+ </VcsButton>
23
+ <v-toolbar
24
+ v-if="active"
25
+ dense
26
+ absolute
27
+ :width="width"
28
+ class="toolbar__secondary rounded-b mx-auto v-sheet mt-12 px-4"
29
+ :style="{left: `${nudgeLeft}px` }"
30
+ >
31
+ <v-toolbar-items class="w-full">
32
+ <div class="d-flex align-center justify-space-between w-full action-btn-wrap">
33
+ <VcsButton
34
+ v-for="(button, index) in groupButtons"
35
+ :key="`${button.name}-${index}`"
36
+ :tooltip="button.title"
37
+ :icon="button.icon"
38
+ :active="button.active"
39
+ @click.stop="button.callback($event)"
40
+ small
41
+ :width="buttonSize"
42
+ v-bind="{...$attrs}"
43
+ />
44
+ </div>
45
+ </v-toolbar-items>
46
+ </v-toolbar>
47
+ </div>
48
+ </template>
49
+ <style lang="scss" scoped>
50
+ .action-btn-wrap{
51
+ gap: 8px;
52
+ }
53
+ .v-toolbar.v-sheet {
54
+ background-color: #ffffffda;
55
+ }
56
+ </style>
57
+ <script>
58
+
59
+ import VcsButton from '../../components/buttons/VcsButton.vue';
60
+ import { validateActions } from '../../components/lists/VcsActionList.vue';
61
+
62
+ /**
63
+ * @description
64
+ * A component rendering a single action or a group of actions in a dropdown toolbox using {@link VcsButton} and {@link ToolboxButton}.
65
+ * @vue-prop {Array<VcsAction>} actions - Array of actions
66
+ * @vue-prop {string} [groupIcon=''] - optional icon for group dropdown button
67
+ * @vue-prop {string} [groupTitle=''] - optional title for group dropdown button
68
+ * @vue-prop {boolean} active - boolean flag, whether group is active
69
+ * @vue-prop {boolean} position - relative x-position of the button within the toolbar
70
+ * @vue-computed {Array<VcsAction>} singleActionButton - single button without dropdown
71
+ * @vue-computed {Array<VcsAction>} groupButtons - buttons rendered below group dropdown button
72
+ * @vue-computed {number} nudgeLeft - offset depending on buttonSize and buttonPadding to render toolbox centered below dropdown button
73
+ */
74
+ export default {
75
+ name: 'ToolboxGroupComponent',
76
+ components: { VcsButton },
77
+ props: {
78
+ actions: {
79
+ type: Array,
80
+ required: true,
81
+ validator: validateActions,
82
+ },
83
+ groupIcon: {
84
+ type: String,
85
+ required: true,
86
+ },
87
+ groupTitle: {
88
+ type: String,
89
+ default: '',
90
+ },
91
+ active: {
92
+ type: Boolean,
93
+ required: true,
94
+ },
95
+ position: {
96
+ type: Number,
97
+ required: true,
98
+ },
99
+ },
100
+ data() {
101
+ return {
102
+ buttonSize: 34,
103
+ buttonPadding: 8,
104
+ };
105
+ },
106
+ computed: {
107
+ singleActionButton() {
108
+ if (this.actions.length === 1) {
109
+ return this.actions[0];
110
+ }
111
+ return undefined;
112
+ },
113
+ groupButtons() {
114
+ if (this.singleActionButton) {
115
+ return [];
116
+ }
117
+ return this.actions;
118
+ },
119
+ width() {
120
+ // XXX can this be solved by CSS to get rid of hardcoded size and padding?
121
+ return this.groupButtons.length * (this.buttonSize + 2 * this.buttonPadding);
122
+ },
123
+ nudgeLeft() {
124
+ return this.position - this.width / 2;
125
+ },
126
+ },
127
+ };
128
+ </script>
@@ -1,43 +1,24 @@
1
+ <script src="../../vcsUiApp.js"></script>
1
2
  <template>
2
3
  <v-toolbar
4
+ v-if="toolboxOpen && actionGroups.length > 0 && $vuetify.breakpoint.mdAndUp"
3
5
  dense
4
- class="vcs-toolbox toolbar__secondary rounded-b mx-auto v-sheet"
5
- :style="{ maxWidth: `${getWidth()}px` }"
6
+ class="vcs-toolbox toolbar__secondary rounded-b mx-auto v-sheet marginToTop"
7
+ :width="width"
6
8
  >
7
9
  <v-toolbar-items class="w-full">
8
10
  <div class="d-flex align-center justify-space-between w-full">
9
- <span
10
- v-for="group of groups"
11
+ <ToolboxGroupComponent
12
+ v-for="(group, idx) in actionGroups"
11
13
  :key="group.id"
12
- >
13
- <component
14
- v-if="group.type === 'customComponent'"
15
- :is="group.component"
16
- :icon="'$vcsObjectAttribute'"
17
- :value="group.active"
18
- @click.native="group.active = !group.active"
19
- :group="group"
20
- />
21
- <Button
22
- v-if="group.type === 'toggleButton'"
23
- :group="group"
24
- :icon="'$vcsObjectAttribute'"
25
- :value="group.active"
26
- @click.native="group.active = !group.active"
27
- />
28
- <ToolboxSingleSelectButton
29
- v-if="toolboxGroupVisible(group) && group.type === 'singleSelectButton'"
30
- :group="group"
31
- @selected="id => selectSingleSelectOption(id)"
32
- @set-open="({ id, open }) => setGroupOpen({ id, open })"
33
- />
34
- <ToolboxMultiSelectButton
35
- v-if="toolboxGroupVisible(group) && group.type === 'multiSelectButton'"
36
- :group="group"
37
- @selected="id => selectMultiSlectOption(id)"
38
- @set-open="({ id, open }) => setGroupOpen({ id, open })"
39
- />
40
- </span>
14
+ :group-icon="group.icon"
15
+ :group-title="group.title"
16
+ :actions="group.actions"
17
+ class="px-2"
18
+ :active="groupId === group.id"
19
+ :position="getPosition(idx)"
20
+ @click="toggleGroup(group.id)"
21
+ />
41
22
  </div>
42
23
  </v-toolbar-items>
43
24
  </v-toolbar>
@@ -60,55 +41,117 @@
60
41
  background-color: #ffffffda;
61
42
  }
62
43
  }
44
+
45
+ .marginToTop {
46
+ margin-top: 2px;
47
+ }
63
48
  </style>
64
49
 
65
50
  <script>
66
51
 
67
- import { inject } from '@vue/composition-api';
68
- import { VcsButton } from '@vcsuite/ui-components';
52
+ import { inject, ref, computed, watch, onUnmounted } from '@vue/composition-api';
53
+ import ToolboxGroupComponent from './ToolboxGroupComponent.vue';
54
+ import {ButtonLocation, vcsAppSymbol} from '@vcmap/ui';
55
+
56
+ /**
57
+ * @typedef {Object} ActionGroup
58
+ * @property {string} id
59
+ * @property {string} icon
60
+ * @property {string} title
61
+ * @property {Array<VcsAction>} actions
62
+ */
69
63
 
70
- import ToolboxSingleSelectButton from './ToolboxSingleSelectButton.vue';
71
- import ToolboxMultiSelectButton from './ToolboxMultiSelectButton.vue';
64
+ /**
65
+ * @description ToolboxManager component rendering toolbox using {@link ToolboxGroupComponent}.
66
+ * @vue-computed {Array<ActionGroup>} actionGroups - Array of group components
67
+ * @vue-computed {number} width - width of toolbox depending on number of groups
68
+ */
69
+ export default {
70
+ name: 'VcsToolboxManager',
71
+ components: {
72
+ ToolboxGroupComponent,
73
+ },
74
+ setup() {
75
+ const app = inject('vcsApp');
72
76
 
73
- export default {
74
- name: 'VcsToolbox',
75
- props: {
76
- width: {
77
- type: Number,
78
- default: 600,
77
+ const toolboxComponentIds = ref(app.toolboxManager.componentIds);
78
+ const actionGroups = computed(() => {
79
+ const groups = toolboxComponentIds.value.map(id => app.toolboxManager.get(id));
80
+ return groups
81
+ .map((g) => {
82
+ const buttonIds = ref(g.buttonManager.componentIds);
83
+ return {
84
+ id: g.id,
85
+ icon: g.icon,
86
+ title: g.title,
87
+ actions: buttonIds.value.map(id => g.buttonManager.get(id).action),
88
+ };
89
+ })
90
+ .filter(g => g.actions.length > 0);
91
+ });
92
+
93
+ const toolboxOpen = ref(true);
94
+ const toolboxToggleAction = {
95
+ name: 'toolboxToggleAction',
96
+ icon: '$vcsTools',
97
+ title: 'Toolbox',
98
+ active: true,
99
+ callback() {
100
+ this.active = !this.active;
101
+ toolboxOpen.value = this.active;
79
102
  },
80
- },
81
- setup() {
82
- const app = inject('vcsApp');
83
- const { toolboxManager } = app;
84
- const { state: { groups } } = toolboxManager;
85
- const getWidth = () => toolboxManager.getNumberOfUsedSlots() * 75;
86
- const toolboxGroupVisible = value => value &&
87
- value.options &&
88
- value.options.length;
89
- const selectSingleSelectOption = (id) => {
90
- toolboxManager.bringToTop(id);
91
- };
92
- const selectMultiSlectOption = (id) => {
93
- toolboxManager.selectOption(id);
94
- };
95
- const setGroupOpen = ({ id, open }) => {
96
- toolboxManager.setGroupOpen(id, open);
97
- };
103
+ };
104
+
105
+ const stopWatching = watch([actionGroups],
106
+ ([actionGroups]) => {
107
+ if (actionGroups.length > 0) {
108
+ if (!app.navbarManager.has('toolbox')) {
109
+ app.navbarManager.add(
110
+ {
111
+ id: 'toolbox',
112
+ action: toolboxToggleAction,
113
+ },
114
+ vcsAppSymbol,
115
+ ButtonLocation.TOOL,
116
+ );
117
+ }
118
+ } else {
119
+ app.navbarManager.remove('toolbox');
120
+ }
121
+ }
122
+ );
123
+
124
+ onUnmounted(() => {
125
+ stopWatching();
126
+ });
127
+
128
+ // XXX can this solved by CSS to get rid of the hardcoded size and padding?
129
+ const buttonSize = 54;
130
+ const buttonPadding = 8;
131
+ const size = buttonSize + (2 * buttonPadding);
132
+ const width = computed(() => actionGroups.value.length * size);
98
133
 
99
- return {
100
- groups,
101
- getWidth,
102
- selectSingleSelectOption,
103
- selectMultiSlectOption,
104
- setGroupOpen,
105
- toolboxGroupVisible,
106
- };
107
- },
108
- components: {
109
- ToolboxSingleSelectButton,
110
- ToolboxMultiSelectButton,
111
- VcsButton,
112
- },
113
- };
134
+ /**
135
+ * calculates relative x-position of a button from the left edge of toolbar
136
+ * @param {number} idx
137
+ * @returns {number}
138
+ */
139
+ const getPosition = (idx) => (size * (idx + 1)) - (size / 2);
140
+
141
+ return {
142
+ toolboxOpen,
143
+ actionGroups,
144
+ width,
145
+ getPosition,
146
+ groupId: null,
147
+ toggleGroup(groupId) {
148
+ if (this.groupId === groupId) {
149
+ this.groupId = null;
150
+ } else {
151
+ this.groupId = groupId;
152
+ }
153
+ },
154
+ };
155
+ },
156
+ };
114
157
  </script>
@@ -0,0 +1,204 @@
1
+ /* eslint-disable import/prefer-default-export */
2
+ import { VcsEvent } from '@vcmap/core';
3
+ import { reactive } from '@vue/composition-api';
4
+ import { check, checkMaybe } from '@vcsuite/check';
5
+ import { v4 as uuidv4 } from 'uuid';
6
+ import { ButtonManager } from '../buttonManager.js';
7
+
8
+ /**
9
+ * @typedef ToolboxGroupComponentOptions
10
+ * @property {string} [id] Optional ID, If not provided an uuid will be generated.
11
+ * @property {string} [icon] Optional group icon, for dropdowns
12
+ * @property {string} [title] Optional group title, for dropdowns
13
+ */
14
+
15
+ /**
16
+ * @typedef ToolboxGroupComponent
17
+ * @property {string} id
18
+ * @property {string} title
19
+ * @property {ButtonManager} buttonManager
20
+ */
21
+
22
+ /**
23
+ * Default groups predefining icon and title of the group
24
+ * @type {Array<ToolboxGroupComponentOptions>}
25
+ */
26
+ const defaultGroups = [
27
+ {
28
+ id: 'select',
29
+ icon: '$vcsPen',
30
+ title: 'select',
31
+ },
32
+ {
33
+ id: 'measurement',
34
+ icon: '$vcsDimensionsHouse',
35
+ title: 'measurement',
36
+ },
37
+ {
38
+ id: 'flight',
39
+ icon: '$vcsVideoRecorder',
40
+ title: 'flight',
41
+ },
42
+ ];
43
+
44
+ /**
45
+ * Requests default groups for a toolboxManager.
46
+ * Once requested, group id, icon and title are defined and cannot be changed or overwritten.
47
+ * @param {ToolboxManager} toolboxManager
48
+ * @param {Array<ToolboxGroupComponentOptions>} groups
49
+ */
50
+ export function setupDefaultGroups(toolboxManager, groups = defaultGroups) {
51
+ groups.forEach(({ id, icon, title }) => toolboxManager.requestGroup(id, icon, title));
52
+ }
53
+
54
+ /**
55
+ * @class ToolboxManager
56
+ * @description Manages a set of Toolbox Groups
57
+ * @implements VcsComponentManager<ToolboxGroupComponent,ToolboxGroupComponentOptions>
58
+ */
59
+ export class ToolboxManager {
60
+ constructor() {
61
+ /**
62
+ * @type {import("@vcmap/core").VcsEvent<ToolboxGroupComponent>}
63
+ */
64
+ this.added = new VcsEvent();
65
+ /**
66
+ * @type {import("@vcmap/core").VcsEvent<ToolboxGroupComponent>}
67
+ */
68
+ this.removed = new VcsEvent();
69
+ /**
70
+ * reactive ordered array of ids,
71
+ * @type {Array<string>}
72
+ */
73
+ this.componentIds = reactive([]);
74
+
75
+ /**
76
+ * @type {Map<string, ToolboxGroupComponent>}
77
+ * @private
78
+ */
79
+ this._toolboxGroups = new Map();
80
+ }
81
+
82
+ /**
83
+ * @param {string} id
84
+ * @returns {ToolboxGroupComponent}
85
+ */
86
+ get(id) {
87
+ return this._toolboxGroups.get(id);
88
+ }
89
+
90
+ /**
91
+ * @param {string} id
92
+ * @returns {boolean}
93
+ */
94
+ has(id) {
95
+ return this._toolboxGroups.has(id);
96
+ }
97
+
98
+ /**
99
+ * Toolbox groups should be static. Removing them can lead to undefined behavior.
100
+ * @param {string} id
101
+ */
102
+ remove(id) {
103
+ check(id, String);
104
+ const toolboxGroupComponent = this._toolboxGroups.get(id);
105
+ if (toolboxGroupComponent) {
106
+ const index = this.componentIds.indexOf(id);
107
+ this.componentIds.splice(index, 1);
108
+ this._toolboxGroups.delete(id);
109
+ this.removed.raiseEvent(toolboxGroupComponent);
110
+ toolboxGroupComponent.buttonManager.destroy();
111
+ }
112
+ }
113
+
114
+ /**
115
+ * Do not call add directly. Use requestGroup for adding toolbox groups.
116
+ * @param {ToolboxGroupComponentOptions} toolboxGroupComponentOptions
117
+ * @throws {Error} if a buttonComponent with the same ID has already been added
118
+ * @returns {ToolboxGroupComponent}
119
+ */
120
+ add(toolboxGroupComponentOptions) {
121
+ checkMaybe(toolboxGroupComponentOptions.id, String);
122
+ checkMaybe(toolboxGroupComponentOptions.icon, String);
123
+ checkMaybe(toolboxGroupComponentOptions.title, String);
124
+
125
+ if (toolboxGroupComponentOptions.id && this.has(toolboxGroupComponentOptions.id)) {
126
+ throw new Error(`A toolGroup with id ${toolboxGroupComponentOptions.id} has already been registered.`);
127
+ }
128
+ const id = toolboxGroupComponentOptions.id || uuidv4();
129
+ const icon = toolboxGroupComponentOptions.icon || undefined;
130
+ const title = toolboxGroupComponentOptions.title || undefined;
131
+ const buttonManager = new ButtonManager();
132
+
133
+ /**
134
+ * @type {ToolboxGroupComponent}
135
+ */
136
+ const toolboxGroupComponent = {
137
+ get id() {
138
+ return id;
139
+ },
140
+ get icon() {
141
+ return icon;
142
+ },
143
+ get title() {
144
+ return title;
145
+ },
146
+ get buttonManager() {
147
+ return buttonManager;
148
+ },
149
+ };
150
+
151
+ this._toolboxGroups.set(id, toolboxGroupComponent);
152
+ this.componentIds.push(id);
153
+ this.added.raiseEvent(toolboxGroupComponent);
154
+ return toolboxGroupComponent;
155
+ }
156
+
157
+ /**
158
+ * Returns an existing group or creates a new group. Add toolbox groups with this API.
159
+ * @param {string} id
160
+ * @param {string} [icon='mdi-select-group']
161
+ * @param {string} [title='defaultGroup']
162
+ * @returns {ToolboxGroupComponent}
163
+ */
164
+ requestGroup(id, icon = 'mdi-select-group', title = 'defaultGroup') {
165
+ check(id, String);
166
+ checkMaybe(icon, String);
167
+ checkMaybe(title, String);
168
+
169
+ if (this.has(id)) {
170
+ return this.get(id);
171
+ } else {
172
+ return this.add({ id, icon, title });
173
+ }
174
+ }
175
+
176
+ /**
177
+ * removes all {@link ButtonComponent}s of a specific owner and fires removed Events
178
+ * @param {string|vcsAppSymbol} owner
179
+ */
180
+ removeOwner(owner) {
181
+ this.componentIds.forEach((id) => {
182
+ this.get(id).buttonManager.removeOwner(owner);
183
+ });
184
+ }
185
+
186
+ /**
187
+ * removes all buttonComponents and fires removed Events
188
+ */
189
+ clear() {
190
+ const componentIds = [...this.componentIds];
191
+ componentIds.forEach((id) => { this.remove(id); });
192
+ }
193
+
194
+ /**
195
+ * destroys the ButtonManager;
196
+ */
197
+ destroy() {
198
+ this.added.destroy();
199
+ this.removed.destroy();
200
+ this.clear();
201
+ this.componentIds.splice(0);
202
+ this._toolboxGroups.clear();
203
+ }
204
+ }
@@ -25,7 +25,7 @@
25
25
  </style>
26
26
 
27
27
  <script>
28
- import { VcsButton } from '@vcsuite/ui-components';
28
+ import VcsButton from '../../components/buttons/VcsButton.vue';
29
29
 
30
30
  export default {
31
31
  components: { VcsButton },
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div>
2
+ <div :class="$vuetify.breakpoint.xs ? 'win-container-mobile' : 'unset'">
3
3
  <WindowComponent
4
4
  v-for="(id, zIndex) in componentIds"
5
5
  :key="id"
@@ -28,6 +28,23 @@
28
28
  </div>
29
29
  </template>
30
30
 
31
+ <style scoped lang="scss">
32
+ .win-container-mobile {
33
+ position: absolute;
34
+ z-index: 2;
35
+ width: 100%;
36
+ height: 100%;
37
+ }
38
+ .win-container-mobile > {
39
+ div{
40
+ width: 100% !important;
41
+ inset: unset !important;
42
+ border-radius: 0 !important;
43
+ }
44
+ }
45
+
46
+ </style>
47
+
31
48
  <script>
32
49
  import { inject } from '@vue/composition-api';
33
50
 
@@ -71,7 +71,7 @@ export const WindowPositions = {
71
71
 
72
72
  /**
73
73
  * @typedef WindowComponentOptions
74
- * @property {string} [id] Optional ID, If not provided a uuid will be generated.
74
+ * @property {string} [id] Optional ID, If not provided an uuid will be generated.
75
75
  * @property {VueComponent} component Main Component which is shown below the header.
76
76
  * @property {VueComponent} [headerComponent] Replaces the Header Component.
77
77
  * @property {WindowPositionOptions} [position] Will be ignored if WindowSlot !== DETACHED, can be given otherwise or default will be used
@@ -199,10 +199,7 @@ export class WindowManager {
199
199
  * @returns {WindowComponent}
200
200
  */
201
201
  get(id) {
202
- if (this.has(id)) {
203
- return this._windowComponents.get(id);
204
- }
205
- return undefined;
202
+ return this._windowComponents.get(id);
206
203
  }
207
204
 
208
205
  /**
@@ -219,6 +216,7 @@ export class WindowManager {
219
216
  * @param {string} id
220
217
  */
221
218
  remove(id) {
219
+ check(id, String);
222
220
  const windowComponent = this._windowComponents.get(id);
223
221
  if (windowComponent) {
224
222
  const index = this.componentIds.indexOf(id);
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <v-container class="nav-container">
2
+ <v-container :class="$vuetify.breakpoint.xs ? 'nav-container mobile' : 'nav-container'">
3
3
  <v-row>
4
4
  <VcsCompass
5
5
  :view-mode="viewMode"
@@ -13,16 +13,16 @@
13
13
  v-model="heading"
14
14
  />
15
15
  </v-row>
16
- <v-row justify="center">
16
+ <v-row justify="center" v-if="$vuetify.breakpoint.mdAndUp">
17
17
  <VcsZoomButton
18
18
  @zoom-out="zoomOut()"
19
19
  @zoom-in="zoomIn()"
20
20
  />
21
21
  </v-row>
22
- <v-row v-if="is3D" justify="center">
22
+ <v-row justify="center" v-if="is3D && $vuetify.breakpoint.mdAndUp">
23
23
  <TiltSlider v-model="tilt" />
24
24
  </v-row>
25
- <v-row justify="center">
25
+ <v-row justify="center" v-if="$vuetify.breakpoint.mdAndUp">
26
26
  <OrientationToolsButton
27
27
  :icon="overviewAction.icon"
28
28
  :tooltip="overviewAction.title"
@@ -191,8 +191,12 @@
191
191
  right: 2rem;
192
192
  bottom: 2rem;
193
193
  width: unset;
194
+ &.mobile{
195
+ top: 1rem;
196
+ right: 1rem;
197
+ bottom: auto;
198
+ }
194
199
  }
195
-
196
200
  .nav-container > {
197
201
  .row {
198
202
  margin-bottom: 15px;
@@ -23,7 +23,7 @@
23
23
  }
24
24
  </style>
25
25
  <script>
26
- import { VcsTooltip } from '@vcsuite/ui-components';
26
+ import VcsTooltip from '../components/notification/VcsTooltip.vue';
27
27
 
28
28
  /**
29
29
  * A v-card with h & w 8. Requires an icon and binds all attributes & listeners to the v-card
@@ -47,7 +47,7 @@
47
47
  </style>
48
48
  <script>
49
49
  import { clamp } from 'ol/math.js';
50
- import { VcsTooltip } from '@vcsuite/ui-components';
50
+ import VcsTooltip from '../components/notification/VcsTooltip.vue';
51
51
 
52
52
  /**
53
53
  * A vertical slider from 0 to -90. pass value with v-model