@vcmap/ui 6.0.0-rc.3 → 6.0.0-rc.6
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.
- package/build/buildHelpers.js +60 -11
- package/build/buildTypes.js +9 -5
- package/build/bundle.js +1 -1
- package/build/info/publish.js +25 -31
- package/build/lintTypes.js +5 -0
- package/config/base.config.json +2 -7
- package/config/dev.config.json +11 -1
- package/config/projects.config.json +2 -1
- package/config/theming.config.json +68 -0
- package/config/www.config.json +27 -23
- package/dist/assets/@mdi/font/css/{materialdesignicons.min-7a4f6be0.css → materialdesignicons.min-680621ca.css} +1 -1
- package/dist/assets/{cesium-cb4dbfba.js → cesium-ccb4cc30.js} +272 -385
- package/dist/assets/cesium.js +1 -1
- package/dist/assets/{core-72f21835.js → core-e06aa7a6.js} +2313 -2321
- package/dist/assets/core.js +1 -1
- package/dist/assets/{ol-2d33bc8b.js → ol-e7981d5c.js} +233 -329
- package/dist/assets/ol.js +1 -1
- package/dist/assets/ui-5dda32d2.css +1 -0
- package/dist/assets/{ui-2ab43a16.js → ui-5dda32d2.js} +11344 -11078
- package/dist/assets/ui.js +1 -1
- package/dist/assets/vue-87bc6efe.js +6083 -0
- package/dist/assets/vue.js +1 -1
- package/dist/assets/{vuetify-760ced3b.css → vuetify-4c4e4217.css} +2 -2
- package/dist/assets/{vuetify-760ced3b.js → vuetify-4c4e4217.js} +8063 -8262
- package/dist/assets/vuetify.js +1 -1
- package/index.d.ts +27 -17
- package/index.js +16 -8
- package/package.json +17 -17
- package/plugins/@vcmap-show-case/custom-icons-example/README.md +3 -0
- package/plugins/@vcmap-show-case/custom-icons-example/assets/imageExample.png +0 -0
- package/plugins/@vcmap-show-case/custom-icons-example/assets/svgExample.svg +1 -0
- package/plugins/@vcmap-show-case/custom-icons-example/package.json +5 -0
- package/plugins/@vcmap-show-case/custom-icons-example/src/CustomIconsExample.vue +90 -0
- package/plugins/@vcmap-show-case/custom-icons-example/src/index.js +45 -0
- package/plugins/@vcmap-show-case/form-inputs-example/src/FormInputsExample.vue +2 -3
- package/plugins/@vcmap-show-case/plugin-editors/src/PluginEditors.vue +11 -7
- package/plugins/@vcmap-show-case/project-selector/src/ModulesListComponent.vue +18 -11
- package/plugins/@vcmap-show-case/search-example/src/index.js +1 -0
- package/plugins/@vcmap-show-case/search-example/src/searchImpl.js +35 -5
- package/plugins/@vcmap-show-case/theming-example/README.md +3 -0
- package/plugins/@vcmap-show-case/theming-example/package.json +5 -0
- package/plugins/@vcmap-show-case/theming-example/src/ThemingExample.vue +116 -0
- package/plugins/@vcmap-show-case/theming-example/src/index.js +53 -0
- package/plugins/@vcmap-show-case/toolbox-example/src/index.js +2 -1
- package/plugins/package.json +7 -23
- package/public/assets/@mdi/font/css/materialdesignicons.min.css +1 -1
- package/src/actions/StyleSelector.vue +1 -1
- package/src/actions/actionHelper.d.ts +4 -11
- package/src/actions/actionHelper.js +15 -7
- package/src/actions/listActions.d.ts +5 -5
- package/src/actions/listActions.js +2 -2
- package/src/application/VcsApp.vue +113 -50
- package/src/application/VcsApp.vue.d.ts +301 -4
- package/src/application/VcsAttributionsFooter.vue.d.ts +1 -1
- package/src/application/VcsContainer.vue +27 -10
- package/src/application/VcsContainer.vue.d.ts +241 -0
- package/src/application/VcsMainMap.vue +7 -7
- package/src/application/VcsMainMap.vue.d.ts +2 -2
- package/src/application/VcsNavbar.vue +14 -2
- package/src/application/VcsNavbar.vue.d.ts +1 -0
- package/src/application/VcsSplashScreen.vue +33 -26
- package/src/application/VcsTextPageFooter.vue +2 -1
- package/src/application/attributionsHelper.d.ts +20 -22
- package/src/application/attributionsHelper.js +4 -4
- package/src/callback/vcsCallback.d.ts +2 -2
- package/src/callback/vcsCallback.js +1 -1
- package/src/components/buttons/VcsActionButtonList.vue +61 -6
- package/src/components/buttons/VcsActionButtonList.vue.d.ts +28 -0
- package/src/components/buttons/VcsButton.vue +2 -4
- package/src/components/buttons/VcsButton.vue.d.ts +1 -1
- package/src/components/buttons/VcsFormButton.vue +4 -4
- package/src/components/buttons/VcsToolButton.vue +4 -2
- package/src/components/buttons/VcsToolButton.vue.d.ts +2 -2
- package/src/components/composables.d.ts +5 -0
- package/src/components/composables.js +79 -9
- package/src/components/extent/VcsExtent.vue +10 -6
- package/src/components/extent/VcsExtent.vue.d.ts +1 -0
- package/src/components/flight/VcsFlightComponent.vue +13 -13
- package/src/components/flight/VcsFlightComponent.vue.d.ts +1 -0
- package/src/components/form-inputs-controls/VcsCheckbox.vue +8 -3
- package/src/components/form-inputs-controls/VcsChipArrayInput.vue +13 -16
- package/src/components/form-inputs-controls/VcsChipArrayInput.vue.d.ts +2 -4
- package/src/components/form-inputs-controls/VcsCoordinate.vue +4 -4
- package/src/components/form-inputs-controls/VcsFileInput.vue +1 -1
- package/src/components/form-inputs-controls/VcsLabel.vue +1 -1
- package/src/components/form-inputs-controls/VcsRadio.vue +8 -6
- package/src/components/form-inputs-controls/VcsRadio.vue.d.ts +1 -0
- package/src/components/form-inputs-controls/VcsSelect.vue +2 -5
- package/src/components/form-inputs-controls/VcsSlider.vue +5 -6
- package/src/components/form-inputs-controls/VcsSlider.vue.d.ts +2 -4
- package/src/components/form-inputs-controls/VcsTextArea.vue +2 -5
- package/src/components/form-inputs-controls/VcsTextField.vue +24 -1
- package/src/components/form-inputs-controls/VcsTextField.vue.d.ts +11 -1
- package/src/components/form-inputs-controls/VcsWizard.vue +3 -3
- package/src/components/form-inputs-controls/VcsWizardStep.vue +6 -5
- package/src/components/form-inputs-controls/vcsTextField.scss +8 -5
- package/src/components/form-output/VcsFormattedNumber.vue +7 -5
- package/src/components/form-output/VcsMarkdown.vue +15 -12
- package/src/components/form-output/VcsMarkdown.vue.d.ts +1 -0
- package/src/components/form-output/markdownHelper.d.ts +30 -0
- package/src/components/form-output/markdownHelper.js +398 -0
- package/src/components/import/VcsFileDrop.vue +8 -5
- package/src/components/import/VcsImportComponent.vue +8 -4
- package/src/components/import/VcsImportComponent.vue.d.ts +1 -2
- package/src/components/lists/VcsActionList.vue +6 -6
- package/src/components/lists/VcsList.vue +22 -37
- package/src/components/lists/VcsList.vue.d.ts +14 -55
- package/src/components/lists/{VcsListItem.vue → VcsListItemComponent.vue} +37 -11
- package/src/components/lists/VcsListItemComponent.vue.d.ts +79 -0
- package/src/components/lists/VcsTreeview.vue +95 -26
- package/src/components/lists/VcsTreeview.vue.d.ts +16 -3
- package/src/components/lists/VcsTreeviewSearchbar.vue +16 -5
- package/src/components/lists/VcsTreeviewSearchbar.vue.d.ts +3 -1
- package/src/components/lists/VcsTreeviewTitle.vue +36 -0
- package/src/components/modelHelper.d.ts +10 -8
- package/src/components/modelHelper.js +8 -6
- package/src/components/notification/VcsHelp.vue +6 -7
- package/src/components/notification/VcsHelp.vue.d.ts +0 -8
- package/src/components/plugins/AbstractConfigEditor.vue +1 -22
- package/src/components/plugins/AbstractConfigEditor.vue.d.ts +6 -29
- package/src/components/section/VcsExpansionPanel.vue +9 -3
- package/src/components/section/VcsExpansionPanel.vue.d.ts +2 -2
- package/src/components/section/VcsFormSection.vue +13 -7
- package/src/components/section/VcsFormSection.vue.d.ts +2 -3
- package/src/components/style/VcsImageSelector.vue +14 -6
- package/src/components/style/VcsImageSelector.vue.d.ts +1 -0
- package/src/components/style/VcsStrokeSelector.vue +5 -2
- package/src/components/style/VcsStrokeSelector.vue.d.ts +1 -0
- package/src/components/style/VcsTextMenu.vue +3 -3
- package/src/components/style/VcsVectorStyleComponent.vue +1 -1
- package/src/components/tables/VcsDataTable.vue +42 -32
- package/src/components/tables/VcsDataTable.vue.d.ts +1 -0
- package/src/components/tables/VcsTable.vue +45 -62
- package/src/components/tables/VcsTable.vue.d.ts +30 -17
- package/src/components/tables/VcsTableCell.vue +72 -0
- package/src/components/tables/VcsTableCell.vue.d.ts +13 -0
- package/src/components/vector-properties/VcsFeatureEditingWindow.vue +6 -5
- package/src/components/vector-properties/VcsFeatureTransforms.vue +5 -0
- package/src/components/vector-properties/VcsVectorPropertiesComponent.vue +42 -31
- package/src/components/vector-properties/VcsVectorPropertiesComponent.vue.d.ts +1 -0
- package/src/components/viewpoint/VcsViewpointComponent.vue +14 -11
- package/src/components/viewpoint/VcsViewpointComponent.vue.d.ts +1 -0
- package/src/components/viewpoint/VcsViewpointEditor.vue +2 -2
- package/src/contentTree/LayerTree.vue +9 -27
- package/src/contentTree/LayerTree.vue.d.ts +1 -1
- package/src/contentTree/contentTreeCollection.d.ts +1 -0
- package/src/contentTree/contentTreeCollection.js +45 -11
- package/src/contentTree/contentTreeItem.d.ts +2 -2
- package/src/contentTree/contentTreeItem.js +1 -1
- package/src/featureInfo/BalloonComponent.vue +32 -25
- package/src/featureInfo/BalloonComponent.vue.d.ts +1 -0
- package/src/featureInfo/MarkdownBalloonComponent.vue +4 -2
- package/src/featureInfo/MarkdownBalloonComponent.vue.d.ts +2 -2
- package/src/featureInfo/abstractFeatureInfoView.d.ts +10 -4
- package/src/featureInfo/abstractFeatureInfoView.js +19 -11
- package/src/featureInfo/featureInfo.d.ts +7 -7
- package/src/featureInfo/featureInfo.js +51 -31
- package/src/featureInfo/iframeFeatureInfoView.d.ts +8 -2
- package/src/featureInfo/iframeFeatureInfoView.js +15 -5
- package/src/featureInfo/markdownBalloonFeatureInfoView.d.ts +1 -1
- package/src/featureInfo/markdownBalloonFeatureInfoView.js +5 -5
- package/src/featureInfo/markdownFeatureInfoView.d.ts +1 -1
- package/src/featureInfo/markdownFeatureInfoView.js +9 -11
- package/src/featureInfo/tableFeatureInfoView.js +13 -4
- package/src/i18n/i18nCollection.d.ts +9 -15
- package/src/i18n/i18nCollection.js +3 -3
- package/src/legend/VcsLegend.vue +6 -2
- package/src/legend/VcsLegend.vue.d.ts +1 -0
- package/src/manager/collectionManager/CollectionComponentList.vue +2 -2
- package/src/manager/collectionManager/CollectionComponentList.vue.d.ts +2 -2
- package/src/manager/collectionManager/categoryManager.d.ts +1 -1
- package/src/manager/collectionManager/collectionComponentClass.d.ts +3 -3
- package/src/manager/collectionManager/collectionComponentClass.js +6 -6
- package/src/manager/collectionManager/collectionManager.d.ts +1 -1
- package/src/manager/collectionManager/editorCollectionComponentClass.js +2 -1
- package/src/manager/panel/PanelComponent.vue +2 -9
- package/src/manager/panel/PanelManagerComponent.vue +7 -3
- package/src/manager/panel/panelHelper.js +3 -3
- package/src/manager/panel/panelManager.d.ts +9 -1
- package/src/manager/panel/panelManager.js +15 -3
- package/src/manager/toolbox/GroupToolboxComponent.vue +11 -5
- package/src/manager/toolbox/GroupToolboxComponent.vue.d.ts +1 -0
- package/src/manager/toolbox/SelectToolboxComponent.vue +11 -6
- package/src/manager/toolbox/SelectToolboxComponent.vue.d.ts +1 -0
- package/src/manager/toolbox/{ToolboxManager.vue → ToolboxManagerComponent.vue} +13 -7
- package/src/manager/toolbox/{ToolboxManager.vue.d.ts → ToolboxManagerComponent.vue.d.ts} +1 -0
- package/src/manager/window/WindowComponent.vue +12 -8
- package/src/manager/window/WindowComponentHeader.vue +33 -9
- package/src/manager/window/WindowComponentHeader.vue.d.ts +3 -0
- package/src/manager/window/WindowManager.vue +2 -2
- package/src/manager/window/windowManager.d.ts +6 -6
- package/src/manager/window/windowManager.js +3 -3
- package/src/navigation/MapNavigation.vue +20 -0
- package/src/navigation/OrientationToolsButton.vue +2 -4
- package/src/navigation/TiltSlider.vue +3 -5
- package/src/navigation/locatorHelper.js +1 -1
- package/src/navigation/overviewMap.js +1 -1
- package/src/notifier/NotifierComponent.vue +18 -15
- package/src/search/ResultItem.vue +18 -6
- package/src/search/ResultsComponent.vue +31 -20
- package/src/search/ResultsComponent.vue.d.ts +2 -1
- package/src/search/SearchComponent.vue +11 -15
- package/src/search/SearchComponent.vue.d.ts +1 -0
- package/src/siteConfig.js +8 -8
- package/src/styles/_typography.scss +0 -2
- package/src/styles/main.scss +0 -4
- package/src/styles/vcsList.scss +1 -1
- package/src/uiConfig.d.ts +311 -7
- package/src/uiConfig.js +30 -17
- package/src/vcsUiApp.d.ts +48 -63
- package/src/vcsUiApp.js +44 -37
- package/src/vuePlugins/vuetify.d.ts +88 -62
- package/src/vuePlugins/vuetify.js +119 -20
- package/dist/assets/ui-2ab43a16.css +0 -1
- package/dist/assets/vue-03b265aa.js +0 -6096
- package/plugins/@vcmap-show-case/theme-changer/README.md +0 -23
- package/plugins/@vcmap-show-case/theme-changer/config.json +0 -69
- package/plugins/@vcmap-show-case/theme-changer/package.json +0 -11
- package/plugins/@vcmap-show-case/theme-changer/src/ThemeChangerComponent.vue +0 -120
- package/plugins/@vcmap-show-case/theme-changer/src/index.js +0 -108
- package/src/application/markdownHelper.d.ts +0 -12
- package/src/application/markdownHelper.js +0 -70
- package/src/components/lists/VcsListItem.vue.d.ts +0 -27
- package/src/components/lists/VcsTreeviewLeaf.vue +0 -83
- package/src/components/notification/VcsTooltip.vue +0 -156
- package/src/components/notification/VcsTooltip.vue.d.ts +0 -27
- package/src/featureInfo/MarkdownComponent.vue +0 -16
- package/src/featureInfo/MarkdownComponent.vue.d.ts +0 -7
- package/src/styles/_theming.scss +0 -73
- package/src/styles/settings.scss +0 -6
- package/src/styles/shades.scss +0 -4
- package/src/styles/variables.scss +0 -140
- package/src/styles/vcsFont.scss +0 -2
- package/src/styles/vcsGrid.scss +0 -3
- /package/src/components/lists/{VcsTreeviewLeaf.vue.d.ts → VcsTreeviewTitle.vue.d.ts} +0 -0
@@ -0,0 +1,398 @@
|
|
1
|
+
import { marked } from 'marked';
|
2
|
+
import DOMPurify from 'dompurify';
|
3
|
+
import {
|
4
|
+
BooleanType,
|
5
|
+
newParsingContext,
|
6
|
+
StringType,
|
7
|
+
NoneType,
|
8
|
+
} from 'ol/expr/expression';
|
9
|
+
import { buildExpression, newEvaluationContext } from 'ol/expr/cpu';
|
10
|
+
import { is } from '@vcsuite/check';
|
11
|
+
|
12
|
+
/**
|
13
|
+
* @typedef {Object} Block
|
14
|
+
* @property {RegExpExecArray} opening
|
15
|
+
* @property {RegExpExecArray} closing
|
16
|
+
*/
|
17
|
+
|
18
|
+
/**
|
19
|
+
* @typedef {Block} ConditionalBlock
|
20
|
+
* @property {RegExpExecArray|undefined} elseStatement
|
21
|
+
* @property {RegExpExecArray[]} elseIfs
|
22
|
+
*/
|
23
|
+
|
24
|
+
/**
|
25
|
+
* @param {string} content
|
26
|
+
* @returns {string}
|
27
|
+
*/
|
28
|
+
export function parseAndSanitizeMarkdown(content) {
|
29
|
+
const html = marked.parse(content, { breaks: true });
|
30
|
+
|
31
|
+
// Then sanitize the HTML using DOMPurify
|
32
|
+
return DOMPurify.sanitize(html, { ADD_ATTR: ['target'] });
|
33
|
+
}
|
34
|
+
|
35
|
+
/**
|
36
|
+
* @param {string} expressionString
|
37
|
+
* @param {Record<string, unknown>} data
|
38
|
+
* @param {number} evaluationType
|
39
|
+
* @returns {*}
|
40
|
+
*/
|
41
|
+
function evaluateExpression(expressionString, data, evaluationType) {
|
42
|
+
const parsed = expressionString.startsWith('[')
|
43
|
+
? JSON.parse(expressionString)
|
44
|
+
: [
|
45
|
+
'get',
|
46
|
+
...expressionString
|
47
|
+
.replace(/\[([^\]]+)]/g, '.$1')
|
48
|
+
.split('.')
|
49
|
+
.filter((f) => f),
|
50
|
+
];
|
51
|
+
|
52
|
+
const compiledExpression = buildExpression(
|
53
|
+
parsed,
|
54
|
+
evaluationType,
|
55
|
+
newParsingContext(),
|
56
|
+
);
|
57
|
+
const evaluationContext = newEvaluationContext();
|
58
|
+
evaluationContext.properties = data;
|
59
|
+
return compiledExpression(evaluationContext);
|
60
|
+
}
|
61
|
+
|
62
|
+
/**
|
63
|
+
* Replaces template strings by provided attributes, e.g. {{myAttribute}}
|
64
|
+
* @param {string} template
|
65
|
+
* @param {Record<string, unknown>} data
|
66
|
+
* @returns {string}
|
67
|
+
*/
|
68
|
+
function replaceAttributes(template, data) {
|
69
|
+
const pattern = /\{\{([^}]+)}}/g;
|
70
|
+
return template.replace(pattern, (p, value) => {
|
71
|
+
return evaluateExpression(value.trim(), data, StringType) ?? '';
|
72
|
+
});
|
73
|
+
}
|
74
|
+
|
75
|
+
/**
|
76
|
+
* @param {RegExp} regexp
|
77
|
+
* @param {string} string
|
78
|
+
* @returns {RegExpExecArray[]}
|
79
|
+
*/
|
80
|
+
function regexHits(regexp, string) {
|
81
|
+
const hits = [];
|
82
|
+
let hit;
|
83
|
+
// eslint-disable-next-line no-cond-assign
|
84
|
+
while ((hit = regexp.exec(string))) {
|
85
|
+
hits.push(hit);
|
86
|
+
}
|
87
|
+
|
88
|
+
return hits;
|
89
|
+
}
|
90
|
+
|
91
|
+
/**
|
92
|
+
* @param {RegExpExecArray[]} openings
|
93
|
+
* @param {RegExpExecArray[]} closings
|
94
|
+
* @param {(Block) => void} accepted
|
95
|
+
* @param {(Block) => void} rejected
|
96
|
+
* @returns {void}
|
97
|
+
*/
|
98
|
+
function findTopLevelBlock(openings, closings, accepted, rejected) {
|
99
|
+
const localOpenings = openings.slice();
|
100
|
+
const localClosings = closings.slice();
|
101
|
+
while (localOpenings.length > 0) {
|
102
|
+
let matchingClosing;
|
103
|
+
let matchingOpening;
|
104
|
+
while (!matchingClosing && localClosings.length > 0) {
|
105
|
+
const currentClosing = localClosings.shift();
|
106
|
+
const openingDistances = localOpenings.map(
|
107
|
+
(o) => currentClosing.index - o.index,
|
108
|
+
);
|
109
|
+
const minDistance = openingDistances.reduce((min, currentDistance) => {
|
110
|
+
if (currentDistance > 0 && currentDistance < min) {
|
111
|
+
return currentDistance;
|
112
|
+
}
|
113
|
+
return min;
|
114
|
+
}, Infinity);
|
115
|
+
const matchingOpeningIndex = openingDistances.indexOf(minDistance);
|
116
|
+
matchingOpening = localOpenings[matchingOpeningIndex];
|
117
|
+
|
118
|
+
if (matchingOpeningIndex === 0) {
|
119
|
+
matchingClosing = currentClosing;
|
120
|
+
} else {
|
121
|
+
rejected({ opening: matchingOpening, closing: currentClosing });
|
122
|
+
}
|
123
|
+
localOpenings.splice(matchingOpeningIndex, 1);
|
124
|
+
}
|
125
|
+
|
126
|
+
if (matchingClosing) {
|
127
|
+
accepted({ opening: matchingOpening, closing: matchingClosing });
|
128
|
+
}
|
129
|
+
}
|
130
|
+
}
|
131
|
+
|
132
|
+
/**
|
133
|
+
* @param {RegExpExecArray} tag
|
134
|
+
* @param {Block} block
|
135
|
+
* @returns {boolean}
|
136
|
+
*/
|
137
|
+
function tagWithinBlock(tag, block) {
|
138
|
+
return tag.index > block.opening.index && tag.index < block.closing.index;
|
139
|
+
}
|
140
|
+
|
141
|
+
/**
|
142
|
+
* @param {string} template
|
143
|
+
* @returns {Block[]}
|
144
|
+
*/
|
145
|
+
function getForEachBlocks(template) {
|
146
|
+
const forEachBlocks = [];
|
147
|
+
const forEachOpenings = regexHits(
|
148
|
+
/\s*{{#each\s\(([^.)]+)\)\sin\s([^}]+)}}\s*/g,
|
149
|
+
template,
|
150
|
+
);
|
151
|
+
const forEachClosings = regexHits(/\s*{{\/each}}\s*/g, template);
|
152
|
+
|
153
|
+
if (forEachClosings.length > forEachOpenings.length) {
|
154
|
+
throw new Error(
|
155
|
+
'Template failed to render, missing opening tag for each statements',
|
156
|
+
);
|
157
|
+
} else if (forEachClosings.length < forEachOpenings.length) {
|
158
|
+
throw new Error(
|
159
|
+
'Template failed to render, missing closing tag for each statements',
|
160
|
+
);
|
161
|
+
}
|
162
|
+
|
163
|
+
findTopLevelBlock(
|
164
|
+
forEachOpenings,
|
165
|
+
forEachClosings,
|
166
|
+
(block) => {
|
167
|
+
forEachBlocks.push(block);
|
168
|
+
},
|
169
|
+
() => {},
|
170
|
+
);
|
171
|
+
|
172
|
+
return forEachBlocks;
|
173
|
+
}
|
174
|
+
|
175
|
+
/**
|
176
|
+
* @param {string} template
|
177
|
+
* @param {Block[]} forEachBlocks
|
178
|
+
* @returns {ConditionalBlock[]}
|
179
|
+
*/
|
180
|
+
function getConditionalBlocks(template, forEachBlocks) {
|
181
|
+
const conditionalBlocks = [];
|
182
|
+
let conditionalOpenings = regexHits(/\s*{{#if\s([^}]*)}}\s*/g, template);
|
183
|
+
let conditionalClosings = regexHits(/\s*{{\/if}}\s*/g, template);
|
184
|
+
let elseIfs = regexHits(/\s*{{elseif\s([^}]*)}}\s*/g, template);
|
185
|
+
let elses = regexHits(/\s*{{else}}\s*/g, template);
|
186
|
+
|
187
|
+
const withinForEachBlock = (tag) =>
|
188
|
+
forEachBlocks.find((block) => tagWithinBlock(tag, block));
|
189
|
+
|
190
|
+
// conditionals within a for each blocks are rendered with the for each block, ignore
|
191
|
+
conditionalOpenings = conditionalOpenings.filter(
|
192
|
+
(t) => !withinForEachBlock(t),
|
193
|
+
);
|
194
|
+
conditionalClosings = conditionalClosings.filter(
|
195
|
+
(t) => !withinForEachBlock(t),
|
196
|
+
);
|
197
|
+
|
198
|
+
if (conditionalClosings.length > conditionalOpenings.length) {
|
199
|
+
throw new Error(
|
200
|
+
'Template failed to render, missing closing tag for if statements',
|
201
|
+
);
|
202
|
+
} else if (conditionalClosings.length < conditionalOpenings.length) {
|
203
|
+
throw new Error(
|
204
|
+
'Template failed to render, missing opening tag for if statements',
|
205
|
+
);
|
206
|
+
}
|
207
|
+
|
208
|
+
const filterElseIfElse = (block) => {
|
209
|
+
elseIfs = elseIfs.filter((tag) => !tagWithinBlock(tag, block));
|
210
|
+
elses = elses.filter((tag) => !tagWithinBlock(tag, block));
|
211
|
+
};
|
212
|
+
|
213
|
+
findTopLevelBlock(
|
214
|
+
conditionalOpenings,
|
215
|
+
conditionalClosings,
|
216
|
+
(block) => {
|
217
|
+
const elsIfs = elseIfs.filter((tag) => tagWithinBlock(tag, block));
|
218
|
+
const elseStatement = elses.find((tag) => tagWithinBlock(tag, block));
|
219
|
+
if (
|
220
|
+
elseStatement &&
|
221
|
+
elsIfs.length > 0 &&
|
222
|
+
elseStatement.index < elsIfs.at(-1).index
|
223
|
+
) {
|
224
|
+
throw new Error('{{else}} must be the last entry in a block');
|
225
|
+
}
|
226
|
+
conditionalBlocks.push({
|
227
|
+
...block,
|
228
|
+
elseStatement,
|
229
|
+
elseIfs,
|
230
|
+
});
|
231
|
+
},
|
232
|
+
(block) => {
|
233
|
+
filterElseIfElse(block);
|
234
|
+
},
|
235
|
+
);
|
236
|
+
|
237
|
+
return conditionalBlocks;
|
238
|
+
}
|
239
|
+
|
240
|
+
/**
|
241
|
+
* @param {string} openingTag
|
242
|
+
* @returns {boolean}
|
243
|
+
*/
|
244
|
+
function shouldRemoveWhiteSpace(openingTag) {
|
245
|
+
return /\n\s*\{/.test(openingTag) && /}\s*\n/.test(openingTag);
|
246
|
+
}
|
247
|
+
|
248
|
+
/**
|
249
|
+
* This will extract the block to render separately. This will depend on the white space handling. If the
|
250
|
+
* opening is placed on its own line, whitespace after the opening and before the closing blocks will be removed
|
251
|
+
* from the sub template, up to the first new line feed.
|
252
|
+
* @param {string} template
|
253
|
+
* @param {Block} block
|
254
|
+
* @returns {string}
|
255
|
+
*/
|
256
|
+
function getSubTemplateForBlock(template, block) {
|
257
|
+
const removeWhiteSpace = shouldRemoveWhiteSpace(block.opening[0]);
|
258
|
+
let startIndex = block.opening.index + block.opening[0].indexOf('}') + 2;
|
259
|
+
let endIndex = block.closing.index + block.closing[0].indexOf('{');
|
260
|
+
if (removeWhiteSpace) {
|
261
|
+
startIndex += (/}\s*\n/.exec(block.opening[0])?.[0].length ?? 1) - 1;
|
262
|
+
endIndex -= (/\n\s*\{/.exec(block.closing[0])?.[0].length ?? 2) - 2;
|
263
|
+
}
|
264
|
+
|
265
|
+
return template.substring(startIndex, endIndex);
|
266
|
+
}
|
267
|
+
|
268
|
+
/**
|
269
|
+
* This will replace a block with a previously extracted blocks rendered template.
|
270
|
+
* This will depend on the white space handling. If the opening is placed on its own line,
|
271
|
+
* whitespace before the opening and after the closing blocks will be removed up to the first new line feed,
|
272
|
+
* from the new template string all together.
|
273
|
+
* @param {string} template
|
274
|
+
* @param {Block} block
|
275
|
+
* @param {string} replacement
|
276
|
+
* @returns {string}
|
277
|
+
*/
|
278
|
+
function replaceBlock(template, block, replacement) {
|
279
|
+
const removeWhiteSpace = shouldRemoveWhiteSpace(block.opening[0]);
|
280
|
+
let startIndex = block.opening.index + block.opening[0].indexOf('{');
|
281
|
+
let endIndex = block.closing.index + block.closing[0].indexOf('}') + 2;
|
282
|
+
if (removeWhiteSpace) {
|
283
|
+
startIndex -= (/\n\s*\{/.exec(block.opening[0])?.[0].length ?? 2) - 2;
|
284
|
+
endIndex += (/}\s*\n/.exec(block.closing[0])?.[0].length ?? 1) - 1;
|
285
|
+
}
|
286
|
+
|
287
|
+
return `${template.substring(0, startIndex)}${replacement}${template.substring(endIndex)}`;
|
288
|
+
}
|
289
|
+
|
290
|
+
/**
|
291
|
+
* Replaces {{#if }} blocks
|
292
|
+
* @param {string} template
|
293
|
+
* @param {Record<string, unknown>} data
|
294
|
+
* @returns {string}
|
295
|
+
*/
|
296
|
+
function expandConditionalsAndLoops(template, data) {
|
297
|
+
let renderedTemplate = template;
|
298
|
+
const forEachBlocks = getForEachBlocks(template);
|
299
|
+
|
300
|
+
getConditionalBlocks(template, forEachBlocks)
|
301
|
+
.reverse()
|
302
|
+
.forEach(
|
303
|
+
/** @param {ConditionalBlock} block */ (block) => {
|
304
|
+
const partialBlocks = [block.opening];
|
305
|
+
if (block.elseIfs) {
|
306
|
+
partialBlocks.push(...block.elseIfs);
|
307
|
+
}
|
308
|
+
let trueStatementIndex = partialBlocks.findIndex((s) =>
|
309
|
+
evaluateExpression(s[1], data, BooleanType),
|
310
|
+
);
|
311
|
+
if (trueStatementIndex === -1 && block.elseStatement) {
|
312
|
+
trueStatementIndex = partialBlocks.length;
|
313
|
+
}
|
314
|
+
|
315
|
+
let renderedBlock = '';
|
316
|
+
if (trueStatementIndex > -1) {
|
317
|
+
if (block.elseStatement) {
|
318
|
+
partialBlocks.push(block.elseStatement);
|
319
|
+
}
|
320
|
+
partialBlocks.push(block.closing);
|
321
|
+
|
322
|
+
const blockTemplate = getSubTemplateForBlock(template, {
|
323
|
+
opening: partialBlocks[trueStatementIndex],
|
324
|
+
closing: partialBlocks[trueStatementIndex + 1],
|
325
|
+
});
|
326
|
+
|
327
|
+
renderedBlock = expandConditionalsAndLoops(blockTemplate, data);
|
328
|
+
}
|
329
|
+
|
330
|
+
renderedTemplate = replaceBlock(renderedTemplate, block, renderedBlock);
|
331
|
+
},
|
332
|
+
);
|
333
|
+
|
334
|
+
// only iterate over blocks not removed by conditionals
|
335
|
+
getForEachBlocks(renderedTemplate)
|
336
|
+
.reverse()
|
337
|
+
.forEach((block) => {
|
338
|
+
const obj = evaluateExpression(block.opening[2], data, NoneType);
|
339
|
+
let keyValuePairs;
|
340
|
+
if (is(obj, Object)) {
|
341
|
+
keyValuePairs = Object.entries(obj);
|
342
|
+
} else if (Array.isArray(obj)) {
|
343
|
+
keyValuePairs = obj.entries();
|
344
|
+
}
|
345
|
+
const renderedBlocks = [];
|
346
|
+
if (keyValuePairs) {
|
347
|
+
let index = 0;
|
348
|
+
const [valueName, keyName, indexName] = block.opening[1]
|
349
|
+
.split(',')
|
350
|
+
.map((e) => e.trim())
|
351
|
+
.slice(0, 3);
|
352
|
+
|
353
|
+
const blockTemplate = getSubTemplateForBlock(renderedTemplate, block);
|
354
|
+
// eslint-disable-next-line no-restricted-syntax
|
355
|
+
for (const args of keyValuePairs) {
|
356
|
+
const forEachData = structuredClone(data);
|
357
|
+
forEachData[valueName] = args[1];
|
358
|
+
if (keyName) {
|
359
|
+
forEachData[keyName] = args[0];
|
360
|
+
}
|
361
|
+
if (indexName) {
|
362
|
+
forEachData[indexName] = index;
|
363
|
+
}
|
364
|
+
const currentBlock = expandConditionalsAndLoops(
|
365
|
+
blockTemplate,
|
366
|
+
forEachData,
|
367
|
+
);
|
368
|
+
renderedBlocks.push(replaceAttributes(currentBlock, forEachData));
|
369
|
+
index += 1;
|
370
|
+
}
|
371
|
+
}
|
372
|
+
|
373
|
+
renderedTemplate = replaceBlock(
|
374
|
+
renderedTemplate,
|
375
|
+
block,
|
376
|
+
renderedBlocks.join(''),
|
377
|
+
);
|
378
|
+
});
|
379
|
+
|
380
|
+
return renderedTemplate;
|
381
|
+
}
|
382
|
+
|
383
|
+
/**
|
384
|
+
* Renders a template in these steps
|
385
|
+
* 1. expand conditional blocks. this will remove any blocks that do not match their expressions and choose from if / elseif / else block which of them to render
|
386
|
+
* 2. expand iterations. this will create new templates for each iteration and re-run the rendering for those blocks
|
387
|
+
* 3. render attributes. this will add the attributes to all the blocks not within each blocks
|
388
|
+
* @param {string|string[]} template
|
389
|
+
* @param {Record<string, unknown>} data
|
390
|
+
* @returns {string}
|
391
|
+
*/
|
392
|
+
export function renderTemplate(template, data) {
|
393
|
+
const templateString = Array.isArray(template)
|
394
|
+
? template.join('\n')
|
395
|
+
: template;
|
396
|
+
const conditionalTemplate = expandConditionalsAndLoops(templateString, data);
|
397
|
+
return replaceAttributes(conditionalTemplate, data);
|
398
|
+
}
|
@@ -7,10 +7,13 @@
|
|
7
7
|
class="d-flex justify-center drop-field"
|
8
8
|
:class="{ dragging: isDragging }"
|
9
9
|
:dragging="isDragging"
|
10
|
+
flat
|
10
11
|
v-bind="$attrs"
|
11
12
|
>
|
12
13
|
<slot>
|
13
|
-
<v-card-title class="d-flex align-center">{{
|
14
|
+
<v-card-title class="d-flex align-center text-primary">{{
|
15
|
+
$st(title)
|
16
|
+
}}</v-card-title>
|
14
17
|
</slot>
|
15
18
|
</v-card>
|
16
19
|
</template>
|
@@ -68,13 +71,13 @@
|
|
68
71
|
|
69
72
|
<style scoped lang="scss">
|
70
73
|
.drop-field {
|
71
|
-
|
72
|
-
outline
|
74
|
+
margin: 8px 8px;
|
75
|
+
outline: 2px dashed rgb(var(--v-theme-primary));
|
76
|
+
border-radius: 4px;
|
73
77
|
background-color: rgb(var(--v-theme-base-lighten-4));
|
74
78
|
}
|
75
79
|
|
76
80
|
.dragging {
|
77
|
-
|
78
|
-
background-color: rgb(var(--v-theme-base-lighten-1));
|
81
|
+
background-color: rgb(var(--v-theme-primary-lighten-3));
|
79
82
|
}
|
80
83
|
</style>
|
@@ -1,8 +1,7 @@
|
|
1
1
|
<template>
|
2
2
|
<v-card flat class="pa-2">
|
3
3
|
<vcs-file-drop
|
4
|
-
|
5
|
-
:height="2 * useItemHeight().value"
|
4
|
+
:height="dropElementHeight"
|
6
5
|
:multiple="multiple"
|
7
6
|
v-model="files"
|
8
7
|
/>
|
@@ -31,7 +30,7 @@
|
|
31
30
|
import { VCard } from 'vuetify/components';
|
32
31
|
import { computed, inject, ref } from 'vue';
|
33
32
|
import { removeListenersFromAttrs } from '../attrsHelpers.js';
|
34
|
-
import {
|
33
|
+
import { useFontSize } from '../../vuePlugins/vuetify.js';
|
35
34
|
import VcsFileDrop from './VcsFileDrop.vue';
|
36
35
|
import VcsFormButton from '../buttons/VcsFormButton.vue';
|
37
36
|
import VcsFileInput from '../form-inputs-controls/VcsFileInput.vue';
|
@@ -78,11 +77,16 @@
|
|
78
77
|
|
79
78
|
const noListenerAttrs = computed(() => removeListenersFromAttrs(attrs));
|
80
79
|
|
80
|
+
const fontSize = useFontSize();
|
81
|
+
const dropElementHeight = computed(() => {
|
82
|
+
return fontSize.value * 6 + 18;
|
83
|
+
});
|
84
|
+
|
81
85
|
return {
|
82
86
|
files,
|
83
87
|
loading,
|
84
88
|
noListenerAttrs,
|
85
|
-
|
89
|
+
dropElementHeight,
|
86
90
|
async doImport() {
|
87
91
|
loading.value = true;
|
88
92
|
try {
|
@@ -15,7 +15,7 @@ declare const _default: import("vue").DefineComponent<{
|
|
15
15
|
files: WritableComputedRef<File[]>;
|
16
16
|
loading: import("vue").Ref<boolean>;
|
17
17
|
noListenerAttrs: import("vue").ComputedRef<Record<string, unknown>>;
|
18
|
-
|
18
|
+
dropElementHeight: import("vue").ComputedRef<number>;
|
19
19
|
doImport(): Promise<void>;
|
20
20
|
}, any, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
21
21
|
importFiles: {
|
@@ -35,4 +35,3 @@ declare const _default: import("vue").DefineComponent<{
|
|
35
35
|
fileTypes: unknown[];
|
36
36
|
}, {}>;
|
37
37
|
export default _default;
|
38
|
-
import { useItemHeight } from '../../vuePlugins/vuetify.js';
|
@@ -27,13 +27,16 @@
|
|
27
27
|
.v-list-item-title {
|
28
28
|
color: rgb(var(--v-theme-primary));
|
29
29
|
}
|
30
|
+
.v-icon {
|
31
|
+
// the icon color slightly differs from the text color, darken-1 seems to fit better
|
32
|
+
color: rgb(var(--v-theme-primary-darken-1));
|
33
|
+
}
|
30
34
|
}
|
31
35
|
:deep(.v-list-item .v-list-item__prepend .v-list-item__spacer) {
|
32
36
|
width: 8px;
|
33
37
|
}
|
34
38
|
</style>
|
35
39
|
<script>
|
36
|
-
import { computed } from 'vue';
|
37
40
|
import { is, optional } from '@vcsuite/check';
|
38
41
|
import {
|
39
42
|
VIcon,
|
@@ -42,7 +45,7 @@
|
|
42
45
|
VListItemTitle,
|
43
46
|
VTooltip,
|
44
47
|
} from 'vuetify/components';
|
45
|
-
import {
|
48
|
+
import { useIconSize } from '../../vuePlugins/vuetify.js';
|
46
49
|
|
47
50
|
/**
|
48
51
|
* pattern to check actions
|
@@ -117,10 +120,7 @@
|
|
117
120
|
},
|
118
121
|
},
|
119
122
|
setup() {
|
120
|
-
const
|
121
|
-
const iconSize = computed(() => {
|
122
|
-
return fontSize.value * (1.2 + 0.1 / 3);
|
123
|
-
});
|
123
|
+
const iconSize = useIconSize();
|
124
124
|
return {
|
125
125
|
iconSize,
|
126
126
|
};
|
@@ -32,7 +32,7 @@
|
|
32
32
|
</template>
|
33
33
|
</v-list-item>
|
34
34
|
<template v-for="(item, index) in renderingItems">
|
35
|
-
<
|
35
|
+
<VcsListItemComponent
|
36
36
|
v-if="item"
|
37
37
|
:dragging="dragging === index"
|
38
38
|
:item="item"
|
@@ -66,7 +66,7 @@
|
|
66
66
|
<template #default="scope">
|
67
67
|
<slot name="item.default" v-bind="{ ...scope, index }" />
|
68
68
|
</template>
|
69
|
-
</
|
69
|
+
</VcsListItemComponent>
|
70
70
|
<slot name="item.intermediate" :item="item" :index="index" />
|
71
71
|
<div
|
72
72
|
v-if="hasIntermediateSlot"
|
@@ -94,14 +94,14 @@
|
|
94
94
|
VListItemTitle,
|
95
95
|
VTooltip,
|
96
96
|
} from 'vuetify/components';
|
97
|
+
import VcsListItemComponent from './VcsListItemComponent.vue';
|
97
98
|
import VcsActionButtonList from '../buttons/VcsActionButtonList.vue';
|
98
99
|
import VcsTreeviewSearchbar from './VcsTreeviewSearchbar.vue';
|
99
|
-
import VcsListItem from './VcsListItem.vue';
|
100
100
|
import { createEllipseTooltip } from '../composables.js';
|
101
101
|
|
102
102
|
/**
|
103
|
-
* @param {import("vue").Ref<VcsListItem[]>} items
|
104
|
-
* @param {import("vue").ShallowRef<VcsListItem[]>} selected
|
103
|
+
* @param {import("vue").Ref<import("./VcsListItemComponent.vue").VcsListItem[]>} items
|
104
|
+
* @param {import("vue").ShallowRef<import("./VcsListItemComponent.vue").VcsListItem[]>} selected
|
105
105
|
* @param {function(string, ...any[]):void} emit
|
106
106
|
* @returns {Array<import("../../actions/actionHelper.js").VcsAction>}
|
107
107
|
*/
|
@@ -138,25 +138,9 @@
|
|
138
138
|
];
|
139
139
|
}
|
140
140
|
|
141
|
-
/**
|
142
|
-
* @typedef {Object} VcsListItem
|
143
|
-
* @property {string} name
|
144
|
-
* @property {boolean} [visible] - Whether to display this item or not.
|
145
|
-
* @property {boolean} [disabled] - Whether this item should be displayed as disabled.
|
146
|
-
* @property {boolean|import("../../actions/actionHelper.js").ActionOptions} [renamable] - Whether the title of can be edited. will add a rename action to the end of the action list. This action will call titleChanged with the new title, you must provide the callback yourself, otherwise this does not work as expeted.
|
147
|
-
* @property {string} title - The title to be displayed
|
148
|
-
* @property {string} [tooltip]
|
149
|
-
* @property {string|HTMLCanvasElement|HTMLImageElement|undefined} [icon] - An optional icon to display with this item. Can be a URL or HTMLElement.
|
150
|
-
* @property {boolean} [hasUpdate] - Shows badge, if item has an update.
|
151
|
-
* @property {Array<import("../../actions/actionHelper.js").VcsAction>} [actions]
|
152
|
-
* @property {Array<function(PointerEvent):void>|undefined} [clickedCallbacks] - An array of callbacks called on item click. called before selection update
|
153
|
-
* @property {function(boolean):void} [selectionChanged] - A callback called if the selection changes with the current selection status. called before value update
|
154
|
-
* @property {function(string):void} [titleChanged] - A callback called if the title changes via rename action. only usable with renamble true.
|
155
|
-
*/
|
156
|
-
|
157
141
|
/**
|
158
142
|
* @typedef {Object} ItemMovedEvent
|
159
|
-
* @property {VcsListItem} item
|
143
|
+
* @property {import("./VcsListItemComponent.vue").VcsListItem} item
|
160
144
|
* @property {number} targetIndex
|
161
145
|
*/
|
162
146
|
|
@@ -172,12 +156,12 @@
|
|
172
156
|
* Clicking with CTRL adds or removes to a selection set.
|
173
157
|
* Clicking with SHIFT will create a selection range, starting or ending with the first item in the list
|
174
158
|
* or the last normally selected item (not the last item clicked with CTRL for instance).
|
175
|
-
* @vue-prop {Array<VcsListItem>} items
|
159
|
+
* @vue-prop {Array<import("./VcsListItemComponent.vue").VcsListItem>} items
|
176
160
|
* @vue-prop {boolean} [draggable=false]
|
177
161
|
* @vue-prop {boolean} [selectable=false]
|
178
162
|
* @vue-prop {boolean} [singleSelect=false]
|
179
|
-
* @vue-prop {Array<VcsListItem>} [value=[]] - the initial items to be selected.
|
180
|
-
* @vue-prop {boolean} [searchable=false] - if this list can have its items searched. you can provide your own predicate function by providing "filterPredicate" which is of type function(VcsListItem, string):boolean
|
163
|
+
* @vue-prop {Array<import("./VcsListItemComponent.vue").VcsListItem>} [value=[]] - the initial items to be selected.
|
164
|
+
* @vue-prop {boolean} [searchable=false] - if this list can have its items searched. you can provide your own predicate function by providing "filterPredicate" which is of type function(import("./VcsListItemComponent.vue").VcsListItem, string):boolean
|
181
165
|
* @vue-prop {string} [searchbarPlaceholder] - placeholder to render inside the search field
|
182
166
|
* @vue-prop {boolean} [showTitle=true] - show the title component
|
183
167
|
* @vue-prop {number} [actionButtonListOverflowCount] - overflow count to use for action lists in the title and items
|
@@ -194,7 +178,7 @@
|
|
194
178
|
export default {
|
195
179
|
name: 'VcsList',
|
196
180
|
components: {
|
197
|
-
|
181
|
+
VcsListItemComponent,
|
198
182
|
VcsTreeviewSearchbar,
|
199
183
|
VcsActionButtonList,
|
200
184
|
VTooltip,
|
@@ -263,7 +247,7 @@
|
|
263
247
|
},
|
264
248
|
},
|
265
249
|
setup(props, { emit, slots }) {
|
266
|
-
/** @type {import("vue").ShallowRef<Array<VcsListItem>>} */
|
250
|
+
/** @type {import("vue").ShallowRef<Array<import("./VcsListItemComponent.vue").VcsListItem>>} */
|
267
251
|
const selected = shallowRef([]);
|
268
252
|
/** @type {import("vue").Ref<string>} */
|
269
253
|
const query = ref('');
|
@@ -319,7 +303,7 @@
|
|
319
303
|
);
|
320
304
|
|
321
305
|
const vm = getCurrentInstance().proxy;
|
322
|
-
/** @type {function(VcsListItem, string):boolean} */
|
306
|
+
/** @type {function(import("./VcsListItemComponent.vue").VcsListItem, string):boolean} */
|
323
307
|
const filterPredicate = inject(
|
324
308
|
'filterPredicate',
|
325
309
|
(item, queryString = '') => {
|
@@ -331,7 +315,7 @@
|
|
331
315
|
);
|
332
316
|
|
333
317
|
/**
|
334
|
-
* @type {VcsListItem|null}
|
318
|
+
* @type {import("./VcsListItemComponent.vue").VcsListItem|null}
|
335
319
|
*/
|
336
320
|
let draggedItem = null;
|
337
321
|
|
@@ -356,7 +340,7 @@
|
|
356
340
|
|
357
341
|
/**
|
358
342
|
* @param {MouseEvent} e
|
359
|
-
* @param {VcsListItem} item
|
343
|
+
* @param {import("./VcsListItemComponent.vue").VcsListItem} item
|
360
344
|
* @param {number} index
|
361
345
|
*/
|
362
346
|
function drag(e, item, index) {
|
@@ -369,7 +353,7 @@
|
|
369
353
|
}
|
370
354
|
|
371
355
|
/**
|
372
|
-
* @type {import("vue").ComputedRef<Array<VcsListItem>>}
|
356
|
+
* @type {import("vue").ComputedRef<Array<import("./VcsListItemComponent.vue").VcsListItem>>}
|
373
357
|
*/
|
374
358
|
const renderingItems = computed(() => {
|
375
359
|
let items = props.items.filter((i) => i.visible !== false);
|
@@ -408,13 +392,13 @@
|
|
408
392
|
*/
|
409
393
|
renderingActions,
|
410
394
|
/**
|
411
|
-
* @type {import("vue").ComputedRef<Array<VcsListItem>>}
|
395
|
+
* @type {import("vue").ComputedRef<Array<import("./VcsListItemComponent.vue").VcsListItem>>}
|
412
396
|
*/
|
413
397
|
renderingItems,
|
414
|
-
/** @type {import("vue").ShallowRef<Array<VcsListItem>>} */
|
398
|
+
/** @type {import("vue").ShallowRef<Array<import("./VcsListItemComponent.vue").VcsListItem>>} */
|
415
399
|
selected,
|
416
400
|
/**
|
417
|
-
* @param {import("vue").UnwrapNestedRef<VcsListItem>} item
|
401
|
+
* @param {import("vue").UnwrapNestedRef<import("./VcsListItemComponent.vue").VcsListItem>} item
|
418
402
|
* @param {PointerEvent} event
|
419
403
|
*/
|
420
404
|
select(item, event) {
|
@@ -508,7 +492,7 @@
|
|
508
492
|
emit('update:modelValue', selected.value);
|
509
493
|
},
|
510
494
|
/**
|
511
|
-
* @param {import("vue").UnwrapNestedRefs<VcsListItem>} item
|
495
|
+
* @param {import("vue").UnwrapNestedRefs<import("./VcsListItemComponent.vue").VcsListItem>} item
|
512
496
|
*/
|
513
497
|
add(item) {
|
514
498
|
if (!isReactive(item)) {
|
@@ -521,7 +505,7 @@
|
|
521
505
|
}
|
522
506
|
},
|
523
507
|
/**
|
524
|
-
* @param {import("vue").UnwrapNestedRefs<VcsListItem>} item
|
508
|
+
* @param {import("vue").UnwrapNestedRefs<import("./VcsListItemComponent.vue").VcsListItem>} item
|
525
509
|
*/
|
526
510
|
remove(item) {
|
527
511
|
if (selected.value.includes(item) && !item.disabled) {
|
@@ -597,10 +581,11 @@
|
|
597
581
|
}
|
598
582
|
|
599
583
|
&:not(.vcs-list__selectable) {
|
584
|
+
cursor: auto;
|
585
|
+
|
600
586
|
.v-list-item--link {
|
601
587
|
cursor: auto;
|
602
588
|
}
|
603
|
-
cursor: auto;
|
604
589
|
|
605
590
|
&:hover {
|
606
591
|
.v-list-item__overlay {
|