@vcmap/ui 5.0.0-rc.14 → 5.0.0-rc.15

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 (105) hide show
  1. package/README.md +33 -31
  2. package/build/build.js +9 -0
  3. package/build/buildHelpers.js +12 -10
  4. package/build/commonViteConfig.js +3 -10
  5. package/config/base.config.json +26 -24
  6. package/config/dev.config.json +8 -0
  7. package/config/www.config.json +102 -17
  8. package/dist/assets/cesium.2e288a.js +137226 -0
  9. package/dist/assets/cesium.js +1 -1
  10. package/dist/assets/core.8014d3.js +14473 -0
  11. package/dist/assets/core.js +1 -1
  12. package/dist/assets/index.3f74fa92.js +1 -0
  13. package/dist/assets/ol.31c3a5.js +44279 -0
  14. package/dist/assets/ol.js +1 -1
  15. package/dist/assets/ui.36f84f.css +1 -0
  16. package/dist/assets/ui.36f84f.js +16101 -0
  17. package/dist/assets/ui.js +1 -1
  18. package/dist/assets/vue.a39c10.js +4675 -0
  19. package/dist/assets/vue.js +5 -2
  20. package/dist/assets/{vuetify.202322.css → vuetify.378637.css} +1 -1
  21. package/dist/assets/vuetify.378637.js +21019 -0
  22. package/dist/assets/vuetify.js +5 -2
  23. package/dist/index.html +1 -1
  24. package/index.js +4 -1
  25. package/package.json +10 -10
  26. package/plugins/@vcmap/pluginExample/index.js +14 -0
  27. package/plugins/@vcmap/pluginExample/pluginExampleComponent.vue +93 -67
  28. package/plugins/@vcmap/project-selector/ContextsListComponent.vue +8 -1
  29. package/plugins/@vcmap/project-selector/ProjectSelectorComponent.vue +27 -1
  30. package/plugins/@vcmap/search-nominatim/LICENSE.md +14 -0
  31. package/plugins/@vcmap/search-nominatim/README.md +2 -0
  32. package/plugins/@vcmap/search-nominatim/config.json +4 -0
  33. package/plugins/@vcmap/search-nominatim/index.js +26 -0
  34. package/plugins/@vcmap/search-nominatim/nominatim.js +170 -0
  35. package/plugins/@vcmap/search-nominatim/package.json +43 -0
  36. package/plugins/@vcmap/theme-changer/ThemeChangerComponent.vue +24 -0
  37. package/plugins/buttonExamples/ButtonExamples.vue +28 -1
  38. package/plugins/categoryTest/Categories.vue +16 -0
  39. package/plugins/categoryTest/Category.vue +30 -4
  40. package/plugins/example/mySuperComponent.vue +12 -1
  41. package/plugins/package.json +2 -1
  42. package/plugins/simple-graph/SimpleGraphComponent.vue +5 -11
  43. package/plugins/test/allIconsComponent.vue +16 -0
  44. package/plugins/test/editor.vue +3 -0
  45. package/plugins/test/emptyComponent.vue +3 -0
  46. package/plugins/test/vcsContent.vue +3 -0
  47. package/src/actions/actionHelper.js +103 -2
  48. package/src/actions/styleSelector.vue +9 -0
  49. package/src/application/VcsApp.vue +77 -9
  50. package/src/application/VcsAttributions.vue +63 -0
  51. package/src/application/VcsAttributionsFooter.vue +87 -0
  52. package/src/application/{Navbar.vue → VcsNavbar.vue} +35 -2
  53. package/src/application/VcsSettings.vue +4 -0
  54. package/src/application/attributionsHelper.js +150 -0
  55. package/src/application/vcsAppWrapper.vue +5 -1
  56. package/src/components/buttons/VcsActionButtonList.vue +8 -1
  57. package/src/components/buttons/VcsButton.vue +7 -1
  58. package/src/components/form-inputs-controls/VcsCheckbox.vue +7 -2
  59. package/src/components/form-inputs-controls/VcsColorPicker.vue +4 -0
  60. package/src/components/form-inputs-controls/VcsFormSection.vue +48 -2
  61. package/src/components/form-inputs-controls/VcsRadio.vue +7 -1
  62. package/src/components/form-inputs-controls/VcsSelect.vue +5 -1
  63. package/src/components/form-inputs-controls/VcsTextArea.vue +2 -0
  64. package/src/components/form-inputs-controls/VcsTextField.vue +6 -2
  65. package/src/components/lists/VcsActionList.vue +12 -1
  66. package/src/components/lists/VcsTreeview.vue +6 -1
  67. package/src/components/lists/VcsTreeviewLeaf.vue +5 -1
  68. package/src/components/lists/VcsTreeviewSearchbar.vue +5 -0
  69. package/src/components/notification/VcsTooltip.vue +14 -9
  70. package/src/components/tables/VcsTable.vue +117 -38
  71. package/src/featureInfo/AddressBalloonComponent.vue +17 -1
  72. package/src/featureInfo/BalloonComponent.vue +57 -23
  73. package/src/featureInfo/balloonFeatureInfoView.js +2 -2
  74. package/src/featureInfo/featureInfo.js +10 -2
  75. package/src/i18n/de.js +15 -0
  76. package/src/i18n/en.js +15 -0
  77. package/src/legend/legendHelper.js +18 -12
  78. package/src/legend/styleLegendItem.vue +20 -1
  79. package/src/legend/vcsLegend.vue +29 -3
  80. package/src/manager/toolbox/GroupToolboxComponent.vue +13 -1
  81. package/src/manager/toolbox/SelectToolboxComponent.vue +13 -1
  82. package/src/manager/toolbox/ToolboxManager.vue +3 -0
  83. package/src/manager/window/WindowComponent.vue +6 -0
  84. package/src/manager/window/WindowComponentHeader.vue +6 -1
  85. package/src/navigation/mapNavigation.vue +15 -36
  86. package/src/navigation/orientationToolsButton.vue +6 -1
  87. package/src/navigation/overviewMap.js +10 -39
  88. package/src/navigation/tiltSlider.vue +3 -0
  89. package/src/navigation/vcsCompass.vue +2 -0
  90. package/src/search/resultItem.vue +89 -0
  91. package/src/search/resultsComponent.vue +98 -0
  92. package/src/search/search.js +326 -0
  93. package/src/search/searchComponent.vue +90 -0
  94. package/src/styles/_typography.scss +3 -0
  95. package/src/styles/utils/_cursor.scss +4 -0
  96. package/src/styles/variables.scss +4 -1
  97. package/src/vcsUiApp.js +16 -0
  98. package/dist/assets/cesium.9489f8.js +0 -8699
  99. package/dist/assets/core.aa346a.js +0 -4
  100. package/dist/assets/index.3cd4fffa.js +0 -1
  101. package/dist/assets/ol.39651b.js +0 -439
  102. package/dist/assets/ui.15ef6a.css +0 -1
  103. package/dist/assets/ui.15ef6a.js +0 -71
  104. package/dist/assets/vue.cbe9d8.js +0 -9
  105. package/dist/assets/vuetify.202322.js +0 -148
@@ -0,0 +1,87 @@
1
+ <template>
2
+ <span class="attribution-wrap">
3
+ <span v-for="attribution in mergedAttributions" class="attribution-span" :key="attribution.provider">
4
+ <a
5
+ :href="attribution.url"
6
+ target="_blank"
7
+ class="text--secondary"
8
+ >{{ $t(attribution.provider) }} <span>{{ attribution.years }}</span></a>
9
+ </span>
10
+ <VcsButton
11
+ class="d-flex text--secondary"
12
+ small
13
+ :key="attributionAction.name"
14
+ :tooltip="attributionAction.title"
15
+ :icon="attributionAction.icon"
16
+ :active="attributionAction.active"
17
+ @click.stop="attributionAction.callback($event)"
18
+ />
19
+ </span>
20
+ </template>
21
+
22
+ <style lang="scss" scoped>
23
+ .attribution-wrap{
24
+ white-space: nowrap;
25
+ margin-right: 40px;
26
+ overflow: hidden;
27
+ text-overflow: ellipsis;
28
+
29
+ .vcs-button-wrap{
30
+ position: absolute;
31
+ right: 4px;
32
+ bottom: 3px;
33
+ }
34
+ }
35
+ a:before {
36
+ content: '\00a9\00a0';
37
+ }
38
+ .attribution-span {
39
+ font-size: smaller;
40
+ &:before {
41
+ content: '\00a0\007c\00a0';
42
+ }
43
+ &:first-child::before{
44
+ content: '';
45
+ }
46
+ span{
47
+ font-size: inherit;
48
+ }
49
+ }
50
+
51
+ </style>
52
+
53
+ <script >
54
+
55
+ import { computed } from 'vue';
56
+ import { mergeAttributions } from './attributionsHelper.js';
57
+ import VcsButton from '../components/buttons/VcsButton.vue';
58
+
59
+ /**
60
+ * Lists attributions of maps, layers and oblique collections within the footer
61
+ * @vue-prop {import("vue").Ref<Array<AttributionEntry>} entries - array with one entry per active VcsObject
62
+ * @vue-prop {VcsAction} attributionAction - action to open attribution window
63
+ * @vue-computed {Array<{provider: string, years: string, url: URL}>} mergedAttributions - array with one entry per provider
64
+ */
65
+ export default {
66
+ name: 'VcsAttributionsFooter',
67
+ components: {
68
+ VcsButton,
69
+ },
70
+ props: {
71
+ entries: {
72
+ type: Array,
73
+ required: true,
74
+ },
75
+ attributionAction: {
76
+ type: Object,
77
+ required: true,
78
+ },
79
+ },
80
+ setup(props) {
81
+ const mergedAttributions = computed(() => mergeAttributions(props.entries));
82
+ return {
83
+ mergedAttributions,
84
+ };
85
+ },
86
+ };
87
+ </script>
@@ -86,6 +86,17 @@
86
86
  :show-icon="true"
87
87
  />
88
88
  </v-menu>
89
+ <VcsButton
90
+ class="d-flex"
91
+ v-if="searchAction"
92
+ large
93
+ :key="searchAction.name"
94
+ :tooltip="searchAction.title"
95
+ :icon="searchAction.icon"
96
+ :active="searchAction.active"
97
+ @click.stop="searchAction.callback($event)"
98
+ v-bind="{...$attrs}"
99
+ />
89
100
  <v-menu
90
101
  offset-y
91
102
  v-if="menuActions.length > 0"
@@ -124,15 +135,30 @@
124
135
  </style>
125
136
 
126
137
  <script>
127
- import { inject, ref, computed } from 'vue';
138
+ import { inject, ref, computed, onUnmounted } from 'vue';
139
+ import {
140
+ VCol, VContainer, VDivider, VMenu, VRow, VToolbar, VToolbarItems,
141
+ } from 'vuetify/lib';
128
142
  import { ButtonLocation, getActionsByLocation } from '../manager/navbarManager.js';
129
143
  import VcsActionButtonList from '../components/buttons/VcsActionButtonList.vue';
130
144
  import VcsActionList from '../components/lists/VcsActionList.vue';
131
145
  import VcsButton from '../components/buttons/VcsButton.vue';
146
+ import { createSearchButtonAction } from '../actions/actionHelper.js';
132
147
 
133
148
  export default {
134
149
  name: 'VcsNavbar',
135
- components: { VcsActionButtonList, VcsActionList, VcsButton },
150
+ components: {
151
+ VcsActionButtonList,
152
+ VcsActionList,
153
+ VcsButton,
154
+ VToolbar,
155
+ VContainer,
156
+ VRow,
157
+ VCol,
158
+ VToolbarItems,
159
+ VDivider,
160
+ VMenu,
161
+ },
136
162
  setup() {
137
163
  const app = inject('vcsApp');
138
164
 
@@ -142,12 +168,19 @@
142
168
  () => getActionsByLocation(buttonComponents.value, location, [...app.plugins].map(p => p.name)),
143
169
  );
144
170
 
171
+ const { searchAction, destroy: destroySearchAction } = createSearchButtonAction(app);
172
+
173
+ onUnmounted(() => {
174
+ destroySearchAction();
175
+ });
176
+
145
177
  return {
146
178
  mapActions: getActions(ButtonLocation.MAP),
147
179
  contentActions: getActions(ButtonLocation.CONTENT),
148
180
  toolActions: getActions(ButtonLocation.TOOL),
149
181
  projectActions: getActions(ButtonLocation.PROJECT),
150
182
  shareActions: getActions(ButtonLocation.SHARE),
183
+ searchAction,
151
184
  menuActions: getActions(ButtonLocation.MENU),
152
185
  config: app.uiConfig.config,
153
186
  };
@@ -34,6 +34,7 @@
34
34
  import {
35
35
  ref, inject, onUnmounted, getCurrentInstance, computed,
36
36
  } from 'vue';
37
+ import { VCol, VContainer, VRow } from 'vuetify/lib';
37
38
  import VcsLabel from '../components/form-inputs-controls/VcsLabel.vue';
38
39
  import VcsSelect from '../components/form-inputs-controls/VcsSelect.vue';
39
40
 
@@ -42,6 +43,9 @@
42
43
  components: {
43
44
  VcsSelect,
44
45
  VcsLabel,
46
+ VContainer,
47
+ VRow,
48
+ VCol,
45
49
  },
46
50
  setup() {
47
51
  const app = inject('vcsApp');
@@ -0,0 +1,150 @@
1
+ import { ref } from 'vue';
2
+ import { ObliqueMap } from '@vcmap/core';
3
+
4
+ /**
5
+ * @typedef {Object} Attribution.Options
6
+ * @property {string} provider - name of the data provider
7
+ * @property {number} [year] - year of dataset
8
+ * @property {URL} url - link to data provider
9
+ */
10
+
11
+ /**
12
+ * @typedef {Object} AttributionEntry
13
+ * @property {string} key - name of the VcsObject the attribution applies to
14
+ * @property {string} title - title of the VcsObject the attribution applies to
15
+ * @property {Attribution.Options|Array<Attribution.Options>} attributions - attributions of a map, layer or oblique collection
16
+ */
17
+
18
+ /**
19
+ * merges attribution entries of same providers
20
+ * @param {Array<AttributionEntry>} entries
21
+ * @returns {Array<{provider: string, years: string, url: URL}>}
22
+ */
23
+ export function mergeAttributions(entries) {
24
+ const providers = {};
25
+ entries.forEach(({ attributions }) => {
26
+ attributions.forEach(({ provider, year, url }) => {
27
+ const providerObject = providers[provider];
28
+ if (providerObject) {
29
+ if (year) {
30
+ const index = providerObject.years.indexOf(year);
31
+ if (url && index === -1) {
32
+ if (providerObject.years.every(y => Number(y) < Number(year))) {
33
+ providerObject.url = url;
34
+ }
35
+ if (year) {
36
+ const set = new Set([...providerObject.years, Number(year)]);
37
+ providerObject.years = [...set].sort((a, b) => a - b);
38
+ }
39
+ }
40
+ }
41
+ } else {
42
+ providers[provider] = {
43
+ years: year ? [Number(year)] : [],
44
+ url,
45
+ };
46
+ }
47
+ });
48
+ });
49
+ return Object.keys(providers).map(provider => ({
50
+ provider,
51
+ years: providers[provider].years.join(', '),
52
+ url: providers[provider].url,
53
+ }));
54
+ }
55
+
56
+ /**
57
+ * Gets attributions of all active maps, layers and oblique collections and returns an array of entries.
58
+ * Each entry is defined by a key derived from the object's className and name, and it's associated attributions.
59
+ * Listens to state changes of maps, layers and oblique collections and synchronizes the entries array correspondingly.
60
+ * Returns a destroy function to clear listeners.
61
+ * @param {import("ui").VcsUiApp} app
62
+ * @returns {{entries: import("vue").Ref<Array<AttributionEntry>>, destroy: function():void}}
63
+ */
64
+ export function getAttributions(app) {
65
+ /**
66
+ * @type {import("vue").Ref<Array<AttributionEntry>>}
67
+ */
68
+ const entries = ref([]);
69
+ /**
70
+ * @type {function():void}
71
+ */
72
+ let obliqueListener = () => {};
73
+
74
+ /**
75
+ * Adds an entry for an object using a combination of the object's className and name as key.
76
+ * @param {import("@vcmap/core").VcsMap|import("@vcmap/core").Layer|import("@vcmap/core").ObliqueCollection} object
77
+ */
78
+ function addAttributions(object) {
79
+ const { attributions } = object.properties;
80
+ if (!attributions) { return; }
81
+ const key = `${object.className}_${object.name}`;
82
+ const idx = entries.value.findIndex(e => e.key === key);
83
+ if (idx < 0) {
84
+ entries.value.push({
85
+ key,
86
+ title: object.properties?.title ?? `${object.className}: ${object.name}`,
87
+ attributions: Array.isArray(attributions) ? attributions : [attributions],
88
+ });
89
+ }
90
+ }
91
+
92
+ /**
93
+ * @param {import("@vcmap/core").VcsMap|import("@vcmap/core").Layer|import("@vcmap/core").ObliqueCollection} object
94
+ */
95
+ function removeAttributions(object) {
96
+ const idx = entries.value.findIndex(e => e.key === `${object.className}_${object.name}`);
97
+ if (idx >= 0) {
98
+ entries.value.splice(idx, 1);
99
+ }
100
+ }
101
+
102
+ /**
103
+ * adds or removes a AttributionEntry on layer state changes
104
+ * @param {import("@vcmap/core").VcsMap|import("@vcmap/core").Layer|import("@vcmap/core").ObliqueCollection} object
105
+ */
106
+ function syncAttributions(object) {
107
+ if (object?.properties?.attributions === undefined) { return; }
108
+ if (object.active || object.loaded) {
109
+ addAttributions(object);
110
+ } else {
111
+ removeAttributions(object);
112
+ }
113
+ }
114
+
115
+ /**
116
+ *
117
+ * @param {import("@vcmap/core").VcsMap} map
118
+ */
119
+ function initAttributions(map) {
120
+ if (!map) { return; }
121
+ obliqueListener();
122
+ entries.value.splice(0);
123
+ syncAttributions(map);
124
+ [...map.layerCollection].forEach((layer) => {
125
+ if (layer.isSupported(map)) {
126
+ syncAttributions(layer);
127
+ }
128
+ });
129
+ if (map instanceof ObliqueMap) {
130
+ syncAttributions(map.collection);
131
+ obliqueListener = map.collectionChanged.addEventListener(syncAttributions);
132
+ }
133
+ }
134
+
135
+ const listeners = [
136
+ app.maps.mapActivated.addEventListener(initAttributions),
137
+ app.layers.stateChanged.addEventListener(syncAttributions),
138
+ app.layers.removed.addEventListener(removeAttributions),
139
+ app.maps.removed.addEventListener(removeAttributions),
140
+ ];
141
+
142
+ initAttributions(app.maps.activeMap);
143
+
144
+ const destroy = () => {
145
+ listeners.forEach(cb => cb());
146
+ obliqueListener();
147
+ };
148
+
149
+ return { entries, destroy };
150
+ }
@@ -5,6 +5,7 @@
5
5
  </template>
6
6
 
7
7
  <script>
8
+ import { VApp } from 'vuetify/lib';
8
9
  import VcsApp from './VcsApp.vue';
9
10
 
10
11
  /**
@@ -21,7 +22,10 @@
21
22
  required: true,
22
23
  },
23
24
  },
24
- components: { VcsApp },
25
+ components: {
26
+ VcsApp,
27
+ VApp,
28
+ },
25
29
  };
26
30
  </script>
27
31
 
@@ -38,6 +38,7 @@
38
38
  </style>
39
39
  <script>
40
40
 
41
+ import { VIcon, VMenu, VSpacer } from 'vuetify/lib';
41
42
  import VcsButton from './VcsButton.vue';
42
43
  import VcsActionList, { validateActions } from '../lists/VcsActionList.vue';
43
44
 
@@ -54,7 +55,13 @@
54
55
  */
55
56
  export default {
56
57
  name: 'VcsActionButtonList',
57
- components: { VcsActionList, VcsButton },
58
+ components: {
59
+ VcsActionList,
60
+ VcsButton,
61
+ VMenu,
62
+ VIcon,
63
+ VSpacer,
64
+ },
58
65
  props: {
59
66
  actions: {
60
67
  type: Array,
@@ -94,6 +94,7 @@
94
94
  </style>
95
95
 
96
96
  <script>
97
+ import { VBtn, VIcon } from 'vuetify/lib';
97
98
  import VcsBadge from '../notification/VcsBadge.vue';
98
99
  import VcsTooltip from '../notification/VcsTooltip.vue';
99
100
 
@@ -118,7 +119,12 @@
118
119
  */
119
120
  export default {
120
121
  name: 'VcsButton',
121
- components: { VcsTooltip, VcsBadge },
122
+ components: {
123
+ VcsTooltip,
124
+ VcsBadge,
125
+ VBtn,
126
+ VIcon,
127
+ },
122
128
  inheritAttrs: false,
123
129
  props: {
124
130
  active: {
@@ -47,6 +47,7 @@
47
47
  }
48
48
  </style>
49
49
  <script>
50
+ import { VCheckbox } from 'vuetify/lib';
50
51
  import VcsLabel from './VcsLabel.vue';
51
52
  import VcsTooltip from '../notification/VcsTooltip.vue';
52
53
  import validate from '../notification/validation.js';
@@ -58,11 +59,15 @@
58
59
  * - if dense is set false, height is 32 px
59
60
  * Provides VcsTooltip to show error messages
60
61
  * @vue-prop {('bottom' | 'left' | 'top' | 'right')} [tooltipPosition='right'] - Position of the error tooltip.
61
- * @vue-prop {string} label Label to be displayed, will be translated.
62
+ * @vue-prop {string} label - Label to be displayed, will be translated.
62
63
  */
63
64
  export default {
64
65
  name: 'VcsCheckbox',
65
- components: { VcsTooltip, VcsLabel },
66
+ components: {
67
+ VcsTooltip,
68
+ VcsLabel,
69
+ VCheckbox,
70
+ },
66
71
  props: {
67
72
  tooltipPosition: {
68
73
  type: String,
@@ -31,6 +31,7 @@
31
31
  } from 'vue';
32
32
  import { Subject } from 'rxjs';
33
33
  import { debounceTime, takeUntil } from 'rxjs/operators';
34
+ import { VColorPicker } from 'vuetify/lib';
34
35
 
35
36
  /**
36
37
  * @description
@@ -38,6 +39,9 @@
38
39
  */
39
40
  export default {
40
41
  name: 'VcsColorPicker',
42
+ components: {
43
+ VColorPicker,
44
+ },
41
45
  props: {
42
46
  width: {
43
47
  type: Number,
@@ -5,12 +5,23 @@
5
5
  <div class="form-section-header d-flex justify-space-between align-center">
6
6
  <strong class="caption">{{ $t(title) }}</strong>
7
7
  <VcsActionButtonList
8
- :actions="titleActions"
8
+ :actions="actions"
9
9
  small
10
10
  />
11
11
  </div>
12
12
  </article>
13
13
  </slot>
14
+ <v-alert
15
+ :value="showHelp"
16
+ dense
17
+ text
18
+ color="secondary"
19
+ class="ma-0"
20
+ >
21
+ <slot name="help">
22
+ <span>{{ $t(helpText) }}</span>
23
+ </slot>
24
+ </v-alert>
14
25
  <article class="section-content">
15
26
  <slot />
16
27
  </article>
@@ -19,6 +30,8 @@
19
30
 
20
31
 
21
32
  <script>
33
+ import { computed, ref } from 'vue';
34
+ import { VAlert } from 'vuetify/lib';
22
35
  import VcsActionButtonList from '../buttons/VcsActionButtonList.vue';
23
36
 
24
37
  /**
@@ -26,12 +39,18 @@
26
39
  * Stylized form section with action buttons
27
40
  * @vue-data {slot} [#title] - slot to override form section header
28
41
  * @vue-data {slot} [#default] - slot with the section content
42
+ * @vue-data {slot} [#help] - Slot to specify html based help. Gets precedence over helpText prop.
29
43
  * @vue-prop {string} title - Title to be displayed, will be translated.
30
44
  * @vue-prop {Array<VcsAction>} titleActions - Icons to be displayed on the right side
45
+ * @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
+ * @vue-computed {Array<VcsAction>} actions - Returns title actions extended by a help action, if help prop is passed or help slot is used.
31
47
  */
32
48
  export default {
33
49
  name: 'VcsFormSection',
34
- components: { VcsActionButtonList },
50
+ components: {
51
+ VcsActionButtonList,
52
+ VAlert,
53
+ },
35
54
  props: {
36
55
  title: {
37
56
  type: String,
@@ -41,6 +60,33 @@
41
60
  type: Array,
42
61
  default: () => ([]),
43
62
  },
63
+ helpText: {
64
+ type: String,
65
+ default: undefined,
66
+ },
67
+ },
68
+ setup(props, { slots }) {
69
+ const showHelp = ref(false);
70
+ const helpAction = {
71
+ name: 'help',
72
+ title: 'components.vcsFormSection.help',
73
+ icon: 'mdi-help-circle',
74
+ callback: () => { showHelp.value = !showHelp.value; },
75
+ };
76
+ /**
77
+ * @type {ComputedRef<VcsAction>}
78
+ */
79
+ const actions = computed(() => {
80
+ if (props.helpText || (slots.help && slots.help().length > 0)) {
81
+ return [helpAction, ...props.titleActions];
82
+ }
83
+ return props.titleActions;
84
+ });
85
+
86
+ return {
87
+ showHelp,
88
+ actions,
89
+ };
44
90
  },
45
91
  };
46
92
  </script>
@@ -70,6 +70,7 @@
70
70
  }
71
71
  </style>
72
72
  <script>
73
+ import { VRadio, VRadioGroup } from 'vuetify/lib';
73
74
  import VcsTooltip from '../notification/VcsTooltip.vue';
74
75
  import VcsLabel from './VcsLabel.vue';
75
76
  import validate from '../notification/validation.js';
@@ -94,7 +95,12 @@
94
95
  */
95
96
  export default {
96
97
  name: 'VcsRadio',
97
- components: { VcsTooltip, VcsLabel },
98
+ components: {
99
+ VcsTooltip,
100
+ VcsLabel,
101
+ VRadioGroup,
102
+ VRadio,
103
+ },
98
104
  props: {
99
105
  tooltipPosition: {
100
106
  type: String,
@@ -49,6 +49,7 @@
49
49
  </style>
50
50
  <script>
51
51
 
52
+ import { VSelect } from 'vuetify/lib';
52
53
  import VcsTooltip from '../notification/VcsTooltip.vue';
53
54
  import validate from '../notification/validation.js';
54
55
 
@@ -64,7 +65,10 @@
64
65
  */
65
66
  export default {
66
67
  name: 'VcsSelect',
67
- components: { VcsTooltip },
68
+ components: {
69
+ VcsTooltip,
70
+ VSelect,
71
+ },
68
72
  props: {
69
73
  tooltipPosition: {
70
74
  type: String,
@@ -51,6 +51,7 @@
51
51
  </style>
52
52
 
53
53
  <script>
54
+ import { VTextarea } from 'vuetify/lib';
54
55
  import VcsTooltip from '../notification/VcsTooltip.vue';
55
56
 
56
57
  /**
@@ -73,6 +74,7 @@
73
74
  name: 'VcsTextArea',
74
75
  components: {
75
76
  VcsTooltip,
77
+ VTextarea,
76
78
  },
77
79
  props: {
78
80
  tooltipPosition: {
@@ -51,10 +51,11 @@
51
51
  </style>
52
52
 
53
53
  <script>
54
+ import { VTextField } from 'vuetify/lib';
54
55
  import VcsTooltip from '../notification/VcsTooltip.vue';
55
56
 
56
57
  /**
57
- * @description extends API of {@link https://vuetifyjs.com/en/api/v-text-field/|vuetify v-text-field}.
58
+ * @description extends API of {@link https://vuetifyjs.com/en/api/v-text-field v-text-field}.
58
59
  * Provides two height options depending on "dense" property:
59
60
  * - if dense is set true (default), height is 24 px
60
61
  * - if dense is set false, height is 32 px
@@ -72,6 +73,7 @@
72
73
  name: 'VcsTextField',
73
74
  components: {
74
75
  VcsTooltip,
76
+ VTextField,
75
77
  },
76
78
  props: {
77
79
  tooltipPosition: {
@@ -101,7 +103,7 @@
101
103
  return this.joinedErrorBucket.length > 0 && (this.firstInput || !this.neverBlurred);
102
104
  },
103
105
  isOutlined() {
104
- return (this.hover || this.focus || this.isError) && !(this.$attrs.disabled || this.$attrs.disabled === '');
106
+ return (this.$attrs.outlined || this.hover || this.focus || this.isError) && !(this.$attrs.disabled || this.$attrs.disabled === '');
105
107
  },
106
108
  joinedErrorBucket() {
107
109
  if (!this.isMounted) {
@@ -124,6 +126,8 @@
124
126
  },
125
127
  mounted() {
126
128
  this.isMounted = true;
129
+ // fix for autofocus
130
+ this.focus = this.$attrs.autofocus != null;
127
131
  },
128
132
  };
129
133
  </script>
@@ -40,6 +40,9 @@
40
40
  </style>
41
41
  <script>
42
42
  import { is } from '@vcsuite/check';
43
+ import {
44
+ VIcon, VList, VListItem, VListItemContent, VListItemIcon, VListItemTitle,
45
+ } from 'vuetify/lib';
43
46
  import VcsTooltip from '../notification/VcsTooltip.vue';
44
47
 
45
48
  /**
@@ -91,7 +94,15 @@
91
94
  */
92
95
  export default {
93
96
  name: 'VcsActionList',
94
- components: { VcsTooltip },
97
+ components: {
98
+ VcsTooltip,
99
+ VList,
100
+ VListItem,
101
+ VListItemIcon,
102
+ VIcon,
103
+ VListItemTitle,
104
+ VListItemContent,
105
+ },
95
106
  props: {
96
107
  actions: {
97
108
  type: Array,
@@ -56,6 +56,7 @@
56
56
 
57
57
  <script>
58
58
  import { getCurrentInstance, ref } from 'vue';
59
+ import { VTreeview } from 'vuetify/lib';
59
60
  import VcsTreeviewLeaf from './VcsTreeviewLeaf.vue';
60
61
  import VcsTreeviewSearchbar from './VcsTreeviewSearchbar.vue';
61
62
 
@@ -68,7 +69,11 @@
68
69
  */
69
70
  export default {
70
71
  name: 'VcsTreeview',
71
- components: { VcsTreeviewSearchbar, VcsTreeviewLeaf },
72
+ components: {
73
+ VcsTreeviewSearchbar,
74
+ VcsTreeviewLeaf,
75
+ VTreeview,
76
+ },
72
77
  props: {
73
78
  showSearchbar: {
74
79
  type: Boolean,
@@ -46,6 +46,7 @@
46
46
  ref,
47
47
  } from 'vue';
48
48
 
49
+ import { VIcon } from 'vuetify/lib';
49
50
  import VcsActionButtonList from '../buttons/VcsActionButtonList.vue';
50
51
 
51
52
 
@@ -62,7 +63,10 @@
62
63
  * @vue-computed {boolean} leaf - Whether the item is a leaf item or not
63
64
  */
64
65
  export default {
65
- components: { VcsActionButtonList },
66
+ components: {
67
+ VcsActionButtonList,
68
+ VIcon,
69
+ },
66
70
  props: {
67
71
  item: {
68
72
  type: Object,