@vcmap/ui 5.0.0-rc.10 → 5.0.0-rc.11

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 (116) hide show
  1. package/README.md +11 -4
  2. package/build/build.js +0 -3
  3. package/build/buildHelpers.js +0 -1
  4. package/build/buildPreview.js +7 -0
  5. package/config/aerowest.config.json +13 -3
  6. package/config/base.config.json +89 -64
  7. package/config/codes.config.json +397 -0
  8. package/config/dev.config.json +169 -0
  9. package/config/graphFeatureInfo.config.json +100 -0
  10. package/config/www.config.json +1232 -0
  11. package/dist/assets/{cesium.eb5667.js → cesium.e67536.js} +0 -0
  12. package/dist/assets/cesium.js +1 -1
  13. package/dist/assets/core.ebf665.js +4 -0
  14. package/dist/assets/core.js +1 -1
  15. package/dist/assets/{index.4ccd4433.js → index.9b213929.js} +1 -1
  16. package/dist/assets/{ol.ef03b1.js → ol.8bbd50.js} +0 -0
  17. package/dist/assets/ol.js +1 -1
  18. package/dist/assets/ui.fdfe0d.css +1 -0
  19. package/dist/assets/ui.fdfe0d.js +68 -0
  20. package/dist/assets/ui.js +1 -1
  21. package/dist/assets/vue.0bb7c6.js +9 -0
  22. package/dist/assets/vue.js +2 -1
  23. package/dist/assets/{vuetify.401a29.css → vuetify.53300f.css} +1 -1
  24. package/dist/assets/{vuetify.401a29.js → vuetify.53300f.js} +71 -71
  25. package/dist/assets/vuetify.js +2 -2
  26. package/dist/index.html +1 -1
  27. package/index.js +36 -5
  28. package/lib/vue.js +1 -0
  29. package/map.config.json +15 -6
  30. package/package.json +6 -7
  31. package/plugins/@vcmap/create-link/fallbackCreateLink.vue +71 -0
  32. package/plugins/@vcmap/create-link/index.js +83 -0
  33. package/plugins/@vcmap/create-link/package.json +6 -0
  34. package/plugins/@vcmap/pluginExample/index.js +1 -1
  35. package/plugins/@vcmap/pluginExample/pluginExampleComponent.vue +20 -3
  36. package/plugins/@vcmap/project-selector/ProjectSelectorComponent.vue +1 -1
  37. package/plugins/@vcmap/project-selector/index.js +1 -1
  38. package/plugins/@vcmap/project-selector/package.json +1 -2
  39. package/plugins/@vcmap/theme-changer/ThemeChangerComponent.vue +1 -1
  40. package/plugins/@vcmap/theme-changer/index.js +1 -1
  41. package/plugins/@vcmap/theme-changer/package.json +1 -2
  42. package/plugins/categoryTest/Categories.vue +89 -1
  43. package/plugins/categoryTest/Category.vue +1 -1
  44. package/plugins/simple-graph/README.md +51 -0
  45. package/plugins/simple-graph/SimpleGraphComponent.vue +70 -0
  46. package/plugins/simple-graph/index.js +17 -0
  47. package/plugins/simple-graph/package.json +11 -0
  48. package/plugins/simple-graph/simpleGraphView.js +76 -0
  49. package/plugins/test/editor.vue +1 -1
  50. package/plugins/test/index.js +63 -2
  51. package/plugins/test/windowManagerExample.vue +1 -1
  52. package/src/actions/stateRefAction.js +2 -2
  53. package/src/actions/styleSelector.vue +1 -1
  54. package/src/application/Navbar.vue +13 -2
  55. package/src/application/VcsApp.vue +201 -92
  56. package/src/application/VcsMap.vue +1 -1
  57. package/src/application/VcsSettings.vue +1 -1
  58. package/src/application/vcsAppWrapper.vue +1 -0
  59. package/src/components/form-inputs-controls/VcsCheckbox.vue +13 -0
  60. package/src/components/form-inputs-controls/VcsColorPicker.vue +1 -1
  61. package/src/components/form-inputs-controls/VcsRadio.vue +123 -0
  62. package/src/components/form-output/VcsFormattedNumber.vue +1 -1
  63. package/src/components/lists/VcsActionList.vue +13 -4
  64. package/src/components/lists/VcsTreeview.vue +4 -4
  65. package/src/components/lists/VcsTreeviewLeaf.vue +9 -2
  66. package/src/components/lists/VcsTreeviewSearchbar.vue +1 -2
  67. package/src/components/tables/VcsTable.vue +245 -0
  68. package/src/contentTree/LayerTree.vue +1 -1
  69. package/src/contentTree/contentTreeCollection.js +4 -4
  70. package/src/contentTree/contentTreeItem.js +9 -9
  71. package/src/contentTree/groupContentTreeItem.js +1 -1
  72. package/src/contentTree/layerContentTreeItem.js +15 -1
  73. package/src/contentTree/layerGroupContentTreeItem.js +21 -1
  74. package/src/contentTree/nodeContentTreeItem.js +1 -1
  75. package/src/featureInfo/AddressBalloonComponent.vue +47 -0
  76. package/src/featureInfo/BalloonComponent.vue +138 -0
  77. package/src/featureInfo/abstractFeatureInfoView.js +313 -0
  78. package/src/featureInfo/addressBalloonFeatureInfoView.js +118 -0
  79. package/src/featureInfo/balloonFeatureInfoView.js +151 -0
  80. package/src/featureInfo/balloonHelper.js +132 -0
  81. package/src/featureInfo/featureInfo.js +455 -0
  82. package/src/featureInfo/featureInfoInteraction.js +42 -0
  83. package/src/featureInfo/iframeFeatureInfoView.js +95 -0
  84. package/src/featureInfo/tableFeatureInfoView.js +106 -0
  85. package/src/i18n/de.js +16 -0
  86. package/src/i18n/en.js +16 -0
  87. package/src/i18n/i18nCollection.js +17 -0
  88. package/src/manager/buttonManager.js +5 -5
  89. package/src/manager/categoryManager/ComponentsManager.vue +30 -0
  90. package/src/manager/categoryManager/categoryManager.js +500 -0
  91. package/src/manager/contextMenu/contextMenuComponent.vue +43 -0
  92. package/src/manager/contextMenu/contextMenuInteraction.js +42 -0
  93. package/src/manager/contextMenu/contextMenuManager.js +197 -0
  94. package/src/manager/navbarManager.js +8 -8
  95. package/src/manager/toolbox/ToolboxManager.vue +2 -2
  96. package/src/manager/toolbox/toolboxManager.js +7 -3
  97. package/src/manager/window/WindowComponent.vue +1 -1
  98. package/src/manager/window/WindowManager.vue +5 -3
  99. package/src/manager/window/windowManager.js +118 -14
  100. package/src/navigation/mapNavigation.vue +3 -5
  101. package/src/navigation/overviewMap.js +28 -5
  102. package/src/navigation/vcsCompass.vue +1 -1
  103. package/src/setup.js +0 -2
  104. package/src/state.js +256 -0
  105. package/src/styles/_theming.scss +0 -5
  106. package/src/uiConfig.js +79 -0
  107. package/src/vcsUiApp.js +210 -20
  108. package/src/vuePlugins/vuetify.js +14 -4
  109. package/config/berlin.config.json +0 -510
  110. package/dist/assets/core.216494.js +0 -4
  111. package/dist/assets/ui.99a1a7.css +0 -1
  112. package/dist/assets/ui.99a1a7.js +0 -70
  113. package/dist/assets/vue-composition-api.c5aca1.js +0 -14
  114. package/dist/assets/vue-composition-api.js +0 -2
  115. package/dist/assets/vue.762edd.js +0 -9
  116. package/lib/vue-composition-api.js +0 -2
@@ -2,7 +2,10 @@
2
2
  <v-container class="fill-height pa-0" absolute fluid>
3
3
  <Navbar />
4
4
  <v-container class="vcs-main pa-0" :class="{ 'vcs-main-xs': $vuetify.breakpoint.xs }" fluid absolute>
5
- <div v-if="$vuetify.breakpoint.smAndDown" class="company-logo-mobile" />
5
+ <template v-if="$vuetify.breakpoint.smAndDown">
6
+ <img v-if="mobileLogo" :src="mobileLogo" alt="Logo" class="mobile-logo">
7
+ <div v-else class="company-logo-mobile mobile-logo" />
8
+ </template>
6
9
  <VcsMap :map-id="mapId" />
7
10
  <MapNavigation />
8
11
  <ToolboxManagerComponent />
@@ -31,15 +34,27 @@
31
34
  bottom: 56px;
32
35
  }
33
36
 
37
+ .mobile-logo {
38
+ max-height: 40px;
39
+ max-width: 70px;
40
+ position: absolute;
41
+ top: 1rem;
42
+ left: 1rem;
43
+ z-index: 1;
44
+ }
45
+
34
46
  </style>
35
47
 
36
48
  <script>
37
49
  import { v4 as uuid } from 'uuid';
38
50
  import {
51
+ computed,
52
+ getCurrentInstance,
39
53
  onMounted,
40
54
  onUnmounted,
41
55
  provide,
42
- } from '@vue/composition-api';
56
+ watch,
57
+ } from 'vue';
43
58
  import { getVcsAppById } from '@vcmap/core';
44
59
  import WindowManagerComponent from '../manager/window/WindowManager.vue';
45
60
  import ToolboxManagerComponent from '../manager/toolbox/ToolboxManager.vue';
@@ -50,8 +65,178 @@
50
65
  import { createMapButtonAction, createToggleAction } from '../actions/actionHelper.js';
51
66
  import MapNavigation from '../navigation/mapNavigation.vue';
52
67
  import VcsSettings from './VcsSettings.vue';
53
- import { WindowSlot } from '../manager/window/windowManager';
68
+ import { WindowSlot } from '../manager/window/windowManager.js';
69
+ import ComponentsManager from '../manager/categoryManager/ComponentsManager.vue';
70
+ import { defaultPrimaryColor } from '../vuePlugins/vuetify.js';
71
+
72
+ /**
73
+ * You should call this function in the component providing the vcsUiApp to your
74
+ * application in the components mounted hook. This will call VcsAppMounted on all plugins in the app
75
+ * and add a listener to call. Returns a destroy hook to stop listening to the added event. If you use the VcsApp
76
+ * component, do not call this function, since the component will do this for you.
77
+ * @param {VcsUiApp} app
78
+ * @returns {function():void}
79
+ */
80
+ export function setupPluginMountedListeners(app) {
81
+ [...app.plugins].forEach((plugin) => {
82
+ if (plugin.onVcsAppMounted) {
83
+ plugin.onVcsAppMounted(app);
84
+ }
85
+ });
86
+
87
+ return app.plugins.added.addEventListener((plugin) => {
88
+ if (plugin.onVcsAppMounted) {
89
+ plugin.onVcsAppMounted(app);
90
+ }
91
+ });
92
+ }
93
+
94
+ /**
95
+ * This helper function will add a map action button based on the default icons
96
+ * to the apps NavbarManager. Furthermore, all maps on the app are synced for adding and removing.
97
+ * @param {VcsUiApp} app
98
+ * @returns {function():void}
99
+ */
100
+ export function setupMapNavbar(app) {
101
+ const iconMap = {
102
+ OpenlayersMap: '$vcs2d',
103
+ CesiumMap: '$vcs3d',
104
+ ObliqueMap: '$vcsObliqueView',
105
+ };
106
+
107
+ const mapButtonActionDestroy = {};
108
+ const setupMap = ({ className, name }) => {
109
+ if (mapButtonActionDestroy[name]) {
110
+ mapButtonActionDestroy[name]();
111
+ }
112
+ const { action, destroy } = createMapButtonAction(
113
+ {
114
+ name,
115
+ icon: iconMap[className],
116
+ title: `navbar.maps.${className}`,
117
+ },
118
+ name,
119
+ app.maps,
120
+ );
121
+ app.navbarManager.add(
122
+ {
123
+ id: `mapButton-${name}`,
124
+ action,
125
+ },
126
+ vcsAppSymbol,
127
+ ButtonLocation.MAP,
128
+ );
129
+ mapButtonActionDestroy[name] = () => {
130
+ app.navbarManager.remove(`mapButton-${name}`);
131
+ destroy();
132
+ };
133
+ };
134
+ [...app.maps].forEach(setupMap);
135
+ const mapAddedListener = app.maps.added.addEventListener(setupMap);
136
+
137
+ const mapRemovedListener = app.maps.removed.addEventListener(({ name }) => {
138
+ if (mapButtonActionDestroy[name]) {
139
+ mapButtonActionDestroy[name]();
140
+ delete mapButtonActionDestroy[name];
141
+ }
142
+ });
143
+
144
+ return () => {
145
+ mapAddedListener();
146
+ mapRemovedListener();
147
+ Object.values(mapButtonActionDestroy).forEach(cb => cb());
148
+ };
149
+ }
150
+
151
+ /**
152
+ * This helper function will add a Components manager button to the navbar. The Components Manager
153
+ * will only be shown if there is at least one category under management in the categoryManager.
154
+ * @param {VcsUiApp} app
155
+ * @returns {function():void}
156
+ */
157
+ export function setupComponentsWindow(app) {
158
+ const { action: componentsManagerAction, destroy: destroyComponentsManagerAction } = createToggleAction(
159
+ {
160
+ name: 'components-manager',
161
+ icon: '$vcsComponents',
162
+ title: 'components.tooltip',
163
+ },
164
+ {
165
+ id: 'component-manager',
166
+ state: {
167
+ headerTitle: 'components.title',
168
+ headerIcon: '$vcsComponents',
169
+ },
170
+ component: ComponentsManager,
171
+ slot: WindowSlot.STATIC,
172
+ },
173
+ app.windowManager,
174
+ vcsAppSymbol,
175
+ );
176
+
177
+ // only show Components Window if we have at least one managed Category
178
+ if (app.categoryManager.items.value.length > 0) {
179
+ app.navbarManager.add(
180
+ { id: 'component-manager', action: componentsManagerAction },
181
+ vcsAppSymbol,
182
+ ButtonLocation.CONTENT,
183
+ );
184
+ }
185
+ watch(app.categoryManager.items, () => {
186
+ if (app.categoryManager.items.value.length > 0) {
187
+ if (!app.navbarManager.has('component-manager')) {
188
+ app.navbarManager.add(
189
+ { id: 'component-manager', action: componentsManagerAction },
190
+ vcsAppSymbol,
191
+ ButtonLocation.CONTENT,
192
+ );
193
+ }
194
+ } else {
195
+ app.windowManager.remove('component-manager');
196
+ app.navbarManager.remove('component-manager');
197
+ }
198
+ });
199
+
200
+ return () => {
201
+ destroyComponentsManagerAction();
202
+ };
203
+ }
54
204
 
205
+ /**
206
+ * This helper sets up a listener to sync the theming relevant keys from the {@see UiConfigObject}
207
+ * with a given vuetify instance. Use this helper, if you do not use the VcsApp component and wish to evaluate
208
+ * the theming keys. Returns a function to stop syncing.
209
+ * @param {VcsUiApp} app
210
+ * @param {import("vuetify").Framework} vuetify
211
+ * @returns {function():void} - call to stop syncing
212
+ */
213
+ export function setupUiConfigTheming(app, vuetify) {
214
+ const listeners = [
215
+ app.uiConfig.added.addEventListener((item) => {
216
+ if (item.name === 'primaryColor') {
217
+ vuetify.theme.themes.dark.primary = item.value;
218
+ vuetify.theme.themes.light.primary = item.value;
219
+ }
220
+ }),
221
+ app.uiConfig.removed.addEventListener((item) => {
222
+ if (item.name === 'primaryColor') {
223
+ vuetify.theme.themes.dark.primary = defaultPrimaryColor;
224
+ vuetify.theme.themes.light.primary = defaultPrimaryColor;
225
+ }
226
+ }),
227
+ ];
228
+
229
+ return () => {
230
+ listeners.forEach((cb) => { cb(); });
231
+ listeners.splice(0);
232
+ };
233
+ }
234
+
235
+ /**
236
+ * The base component to setup the entire application. To embed the VcsApp, use this component.
237
+ * @vue-prop {string} appId - the id of the app to inject. this will setup listeners on the app to call vcsAppMounted on plugins
238
+ * @vue-provide
239
+ */
55
240
  export default {
56
241
  components: {
57
242
  MapNavigation,
@@ -65,62 +250,15 @@
65
250
  type: String,
66
251
  required: true,
67
252
  },
68
- app: {
69
- type: Boolean,
70
- default: true,
71
- },
72
253
  },
73
254
  setup(props) {
74
255
  const id = uuid();
75
256
  const mapId = `mapCollection-${id}`;
257
+ /** @type {VcsUiApp} */
76
258
  const app = getVcsAppById(props.appId);
77
259
  provide('vcsApp', app);
78
260
 
79
- const iconMap = {
80
- OpenlayersMap: '$vcs2d',
81
- CesiumMap: '$vcs3d',
82
- ObliqueMap: '$vcsObliqueView',
83
- };
84
-
85
- const mapButtonActionDestroy = {};
86
-
87
- const setupMap = ({ className, name }) => {
88
- if (mapButtonActionDestroy[name]) {
89
- mapButtonActionDestroy[name]();
90
- }
91
- const { action, destroy } = createMapButtonAction(
92
- {
93
- name,
94
- icon: iconMap[className],
95
- title: `navbar.maps.${className}`,
96
- },
97
- name,
98
- app.maps,
99
- );
100
- app.navbarManager.add(
101
- {
102
- id: `mapButton-${name}`,
103
- action,
104
- },
105
- vcsAppSymbol,
106
- ButtonLocation.MAP,
107
- );
108
- mapButtonActionDestroy[name] = () => {
109
- app.navbarManager.remove(`mapButton-${name}`);
110
- destroy();
111
- };
112
- };
113
-
114
- [...app.maps].forEach(setupMap);
115
- const mapAddedDestroy = app.maps.added.addEventListener(setupMap);
116
-
117
- const mapRemovedDestroy = app.maps.removed.addEventListener(({ name }) => {
118
- if (mapButtonActionDestroy[name]) {
119
- mapButtonActionDestroy[name]();
120
- delete mapButtonActionDestroy[name];
121
- }
122
- });
123
-
261
+ const mapNavbarListener = setupMapNavbar(app);
124
262
  const { action: settingsAction, destroy: settingsDestroy } = createToggleAction(
125
263
  {
126
264
  name: 'settings.title',
@@ -145,57 +283,28 @@
145
283
  ButtonLocation.MENU,
146
284
  );
147
285
 
148
- let pluginAdded;
149
- const pluginRemoved = app.plugins.removed.addEventListener(async (plugin) => {
150
- app.windowManager.removeOwner(plugin.name);
151
- app.navbarManager.removeOwner(plugin.name);
152
- app.toolboxManager.removeOwner(plugin.name);
153
- });
286
+ const destroyComponentsWindow = setupComponentsWindow(app);
287
+ const destroyThemingListener = setupUiConfigTheming(app, getCurrentInstance().proxy.$vuetify);
154
288
 
289
+ let pluginMountedListener;
155
290
  onMounted(() => {
156
- pluginAdded = app.plugins.added.addEventListener((plugin) => {
157
- app.windowManager.removeOwner(plugin.name);
158
- app.navbarManager.removeOwner(plugin.name);
159
- app.toolboxManager.removeOwner(plugin.name);
160
- if (plugin.onVcsAppMounted) {
161
- plugin.onVcsAppMounted(app);
162
- }
163
- });
164
- [...app.plugins].forEach((plugin) => {
165
- if (plugin.onVcsAppMounted) {
166
- plugin.onVcsAppMounted(app);
167
- }
168
- });
291
+ pluginMountedListener = setupPluginMountedListeners(app);
169
292
  app.maps.setTarget(mapId);
170
293
  });
171
294
 
172
295
  onUnmounted(() => {
173
- if (mapAddedDestroy) {
174
- mapAddedDestroy();
175
- }
176
- if (mapRemovedDestroy) {
177
- mapRemovedDestroy();
178
- }
179
- if (pluginAdded) {
180
- pluginAdded();
181
- }
182
- if (pluginRemoved) {
183
- pluginRemoved();
184
- }
185
- Object.values(mapButtonActionDestroy).forEach(cb => cb());
186
-
187
- if (settingsDestroy) {
188
- settingsDestroy();
296
+ if (pluginMountedListener) {
297
+ pluginMountedListener();
189
298
  }
299
+ mapNavbarListener();
300
+ settingsDestroy();
301
+ destroyComponentsWindow();
302
+ destroyThemingListener();
190
303
  });
191
304
 
192
305
  return {
193
306
  mapId,
194
- };
195
- },
196
- provide() {
197
- return {
198
- language: window.navigator.language.split('-')[0],
307
+ mobileLogo: computed(() => app.uiConfig.config.value.mobileLogo ?? app.uiConfig.config.value.logo),
199
308
  };
200
309
  },
201
310
  };
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div :id="mapId" />
2
+ <div :id="mapId" @click.right.stop="(e) => { e.preventDefault(); }" />
3
3
  </template>
4
4
 
5
5
  <style lang="scss" scoped>
@@ -33,7 +33,7 @@
33
33
  <script>
34
34
  import {
35
35
  ref, inject, onUnmounted, getCurrentInstance, computed,
36
- } from '@vue/composition-api';
36
+ } from 'vue';
37
37
  import VcsLabel from '../components/form-inputs-controls/VcsLabel.vue';
38
38
  import VcsSelect from '../components/form-inputs-controls/VcsSelect.vue';
39
39
 
@@ -11,6 +11,7 @@
11
11
  * This component wraps the {@see VcsApp} component in a
12
12
  * v-app tag to ensure vuetify functionality. If you provide your own vuetify app,
13
13
  * do NOT use this wrapper, but use {@see VcsApp} directly, since you may only use v-app once.
14
+ * @vue-prop {string} appId - the app to wrap. will be passed to the VcsApp component
14
15
  */
15
16
  export default {
16
17
  name: 'VcsAppWrapper',
@@ -9,6 +9,7 @@
9
9
  <v-checkbox
10
10
  on-icon="$vcsCheckboxChecked"
11
11
  off-icon="$vcsCheckbox"
12
+ class="vcs-checkbox"
12
13
  hide-details
13
14
  indeterminate-icon="$vcsCheckboxIndeterminate"
14
15
  :dense="$attrs.dense!==false"
@@ -28,6 +29,18 @@
28
29
  </VcsTooltip>
29
30
  </template>
30
31
  <style lang="scss" scoped>
32
+ .vcs-checkbox {
33
+ ::v-deep {
34
+ label.v-label,
35
+ .v-icon.v-icon{
36
+ color: inherit;
37
+ }
38
+ .v-input--selection-controls__input {
39
+ margin: 0;
40
+ padding: 0;
41
+ }
42
+ }
43
+ }
31
44
  .v-input--selection-controls {
32
45
  margin: 0;
33
46
  padding: 0;
@@ -28,7 +28,7 @@
28
28
  import {
29
29
  onMounted,
30
30
  onUnmounted,
31
- } from '@vue/composition-api';
31
+ } from 'vue';
32
32
  import { Subject } from 'rxjs';
33
33
  import { debounceTime, takeUntil } from 'rxjs/operators';
34
34
 
@@ -0,0 +1,123 @@
1
+ <template>
2
+ <VcsTooltip
3
+ :tooltip-position="tooltipPosition"
4
+ :tooltip="errorMessage"
5
+ color="error"
6
+ >
7
+ <template #activator="{ on, attrs }">
8
+ <span v-on="on">
9
+ <v-radio-group
10
+ hide-details
11
+ class="w-full vcs-radio-group"
12
+ :dense="$attrs.dense!==false"
13
+ :ripple="false"
14
+ v-bind="{...$attrs, ...attrs}"
15
+ v-on="{...$listeners, ...on}"
16
+ @update:error="setError"
17
+ >
18
+ <v-radio
19
+ v-for="(item, idx) in items"
20
+ :id="`radio-${idx}`"
21
+ :key="`radio-${idx}`"
22
+ :ripple="false"
23
+ :color="item.color ?? 'secondary'"
24
+ :value="item.value ?? item"
25
+ :disabled="item.disabled ?? false"
26
+ :class="$attrs.dense!==false ? 'vcs-radio-dense' : 'vcs-radio'"
27
+ >
28
+ <template #label>
29
+ <VcsLabel :html-for="`radio-${idx}`" :dense="!!$attrs.dense">
30
+ {{ $t(item.label ?? item) }}
31
+ </VcsLabel>
32
+ </template>
33
+ </v-radio>
34
+ </v-radio-group>
35
+ </span>
36
+ </template>
37
+ </VcsTooltip>
38
+ </template>
39
+ <style lang="scss" scoped>
40
+ @import "../../styles/vcsFont";
41
+ .v-input--radio-group--column .v-radio:not(:last-child):not(:only-child) {
42
+ margin-bottom: 0;
43
+ }
44
+ .v-input{
45
+ &.vcs-radio-group{
46
+ ::v-deep {
47
+ margin-top: 0;
48
+ padding-top: 0;
49
+ label.v-label,
50
+ .v-icon.v-icon{
51
+ font-size: $base-font-size;
52
+ color: inherit;
53
+ }
54
+ .v-radio:not(:last-child):not(:only-child){
55
+ margin-bottom: 0;
56
+ }
57
+ .v-input--selection-controls__input{
58
+ margin: 0;
59
+ }
60
+ }
61
+ }
62
+ }
63
+ .vcs-radio {
64
+ height: 40px;
65
+ align-items: center;
66
+ }
67
+ .vcs-radio-dense {
68
+ height: 32px;
69
+ align-items: center;
70
+ }
71
+ </style>
72
+ <script>
73
+ import VcsTooltip from '../notification/VcsTooltip.vue';
74
+ import VcsLabel from './VcsLabel.vue';
75
+ import validate from '../notification/validation.js';
76
+
77
+ /**
78
+ * @typedef {Object} VcsRadioItem
79
+ * @property {string} label
80
+ * @property {string} [color='secondary']
81
+ * @property {any} value
82
+ * @property {boolean} [disabled=false]
83
+ */
84
+
85
+ /**
86
+ * @description Stylized wrapper around {@link https://vuetifyjs.com/en/api/v-radio-group/ |vuetify v-radio-group} using
87
+ * {@link https://vuetifyjs.com/en/api/v-radio/ |vuetify v-radio}.
88
+ * Provides two height options depending on "dense" property:
89
+ * - if dense is set true (default), height is 24 px
90
+ * - if dense is set false, height is 32 px
91
+ * Provides VcsTooltip to show error messages
92
+ * @vue-prop {('bottom' | 'left' | 'top' | 'right')} [tooltipPosition='right'] - Position of the error tooltip.
93
+ * @vue-prop {Array<string|VcsRadioItem>} items - A list of options. If strings are provided, the string is used as label and value.
94
+ */
95
+ export default {
96
+ name: 'VcsRadio',
97
+ components: { VcsTooltip, VcsLabel },
98
+ props: {
99
+ tooltipPosition: {
100
+ type: String,
101
+ default: 'right',
102
+ },
103
+ items: {
104
+ type: Array,
105
+ required: true,
106
+ },
107
+ },
108
+ data() {
109
+ return {
110
+ errorMessage: '',
111
+ };
112
+ },
113
+ methods: {
114
+ setError() {
115
+ const rules = [...this.$attrs.rules].concat(this.$attrs.errorMessages);
116
+ this.errorMessage = validate(rules, this.$attrs.value).join('\n');
117
+ },
118
+ },
119
+ model: {
120
+ event: 'change',
121
+ },
122
+ };
123
+ </script>
@@ -27,7 +27,7 @@
27
27
  }
28
28
  </style>
29
29
  <script>
30
- import { computed } from '@vue/composition-api';
30
+ import { computed } from 'vue';
31
31
 
32
32
  /**
33
33
  * Converts a number (e.g. 12345678,9) to a locale-aware and
@@ -52,19 +52,28 @@
52
52
  */
53
53
 
54
54
  /**
55
- * @param {Array<VcsAction>} actions
55
+ * @param {VcsAction} action
56
56
  * @returns {boolean}
57
57
  */
58
- export function validateActions(actions) {
59
- return actions.every(item => is(item, {
58
+ export function validateAction(action) {
59
+ return is(action, {
60
60
  name: String,
61
61
  title: [undefined, String],
62
62
  icon: [undefined, String],
63
63
  callback: Function,
64
64
  active: [undefined, Boolean],
65
- }));
65
+ });
66
+ }
67
+
68
+ /**
69
+ * @param {Array<VcsAction>} actions
70
+ * @returns {boolean}
71
+ */
72
+ export function validateActions(actions) {
73
+ return actions.every(validateAction);
66
74
  }
67
75
 
76
+
68
77
  /**
69
78
  * @description
70
79
  * A component rendering a list of actions with overflow mechanic using
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div class="d-contents">
3
3
  <VcsTreeviewSearchbar
4
- v-if="hasSearchbar"
4
+ v-if="showSearchbar"
5
5
  :placeholder="searchbarPlaceholder"
6
6
  v-model="search"
7
7
  />
@@ -55,7 +55,7 @@
55
55
  </style>
56
56
 
57
57
  <script>
58
- import { getCurrentInstance, ref } from '@vue/composition-api';
58
+ import { getCurrentInstance, ref } from 'vue';
59
59
  import VcsTreeviewLeaf from './VcsTreeviewLeaf.vue';
60
60
  import VcsTreeviewSearchbar from './VcsTreeviewSearchbar.vue';
61
61
 
@@ -63,14 +63,14 @@
63
63
  * @description extends API of https://vuetifyjs.com/en/api/v-treeview/
64
64
  * Can render dynamic components as leaf items.
65
65
  * In order to display an item needs to be registered and added to `availableComponents`.
66
- * @vue-prop {boolean} [hasSearchbar=false] - Whether there is a searchbar for this treeview
66
+ * @vue-prop {boolean} [showSearchbar=false] - Whether there is a searchbar for this treeview
67
67
  * @vue-prop {string} [searchbarPlaceholder] - Placeholder text for the searchbar, will be translated
68
68
  */
69
69
  export default {
70
70
  name: 'VcsTreeview',
71
71
  components: { VcsTreeviewSearchbar, VcsTreeviewLeaf },
72
72
  props: {
73
- hasSearchbar: {
73
+ showSearchbar: {
74
74
  type: Boolean,
75
75
  default: false,
76
76
  },
@@ -13,7 +13,7 @@
13
13
  <span ref="imgContainer" />
14
14
  </span>
15
15
 
16
- <div class="position-relative col-8 pa-0 d-flex align-center">
16
+ <div class="position-relative col-8 pa-0 d-flex align-center treeview-label" :title="$t(item.title)">
17
17
  <span>{{ $t(item.title) }}</span>
18
18
  </div>
19
19
  <VcsActionButtonList
@@ -27,6 +27,13 @@
27
27
  />
28
28
  </div>
29
29
  </template>
30
+ <style lang="css" scoped>
31
+ .treeview-label span{
32
+ white-space: nowrap;
33
+ overflow: hidden;
34
+ text-overflow: ellipsis;
35
+ }
36
+ </style>
30
37
 
31
38
  <script>
32
39
  import
@@ -34,7 +41,7 @@
34
41
  computed,
35
42
  onMounted,
36
43
  ref,
37
- } from '@vue/composition-api';
44
+ } from 'vue';
38
45
 
39
46
  import VcsActionButtonList from '../buttons/VcsActionButtonList.vue';
40
47
 
@@ -104,7 +104,7 @@
104
104
 
105
105
 
106
106
  <script>
107
- import { onMounted, onUnmounted } from '@vue/composition-api';
107
+ import { onMounted, onUnmounted } from 'vue';
108
108
 
109
109
  import { Subject } from 'rxjs';
110
110
  import { debounceTime } from 'rxjs/operators';
@@ -147,7 +147,6 @@
147
147
  onUnmounted(() => sub.unsubscribe());
148
148
 
149
149
  return {
150
- sub,
151
150
  handleInput: (val) => {
152
151
  sub.next(val);
153
152
  },