@vc-shell/framework 1.0.93 → 1.0.94
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/CHANGELOG.md +14 -1
- package/core/utilities/camelize.ts +5 -0
- package/core/utilities/generateId.ts +3 -0
- package/core/utilities/index.ts +2 -0
- package/core/utilities/kebabToCamel.ts +1 -1
- package/dist/core/utilities/camelize.d.ts +2 -0
- package/dist/core/utilities/camelize.d.ts.map +1 -0
- package/dist/core/utilities/generateId.d.ts +2 -0
- package/dist/core/utilities/generateId.d.ts.map +1 -0
- package/dist/core/utilities/index.d.ts +2 -0
- package/dist/core/utilities/index.d.ts.map +1 -1
- package/dist/core/utilities/kebabToCamel.d.ts +1 -0
- package/dist/core/utilities/kebabToCamel.d.ts.map +1 -1
- package/dist/framework.mjs +6293 -6076
- package/dist/index.css +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/ui/components/molecules/index.d.ts +1 -0
- package/dist/ui/components/molecules/index.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-multivalue/index.d.ts +42 -0
- package/dist/ui/components/molecules/vc-multivalue/index.d.ts.map +1 -0
- package/dist/ui/components/molecules/vc-multivalue/vc-multivalue.vue.d.ts +66 -0
- package/dist/ui/components/molecules/vc-multivalue/vc-multivalue.vue.d.ts.map +1 -0
- package/dist/ui/components/organisms/vc-dynamic-property/index.d.ts +16 -12
- package/dist/ui/components/organisms/vc-dynamic-property/index.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-dynamic-property/vc-dynamic-property.vue.d.ts +16 -12
- package/dist/ui/components/organisms/vc-dynamic-property/vc-dynamic-property.vue.d.ts.map +1 -1
- package/dist/ui/types/index.d.ts +1 -0
- package/dist/ui/types/index.d.ts.map +1 -1
- package/package.json +3 -3
- package/ui/components/molecules/index.ts +1 -0
- package/ui/components/molecules/vc-multivalue/index.ts +3 -0
- package/ui/components/molecules/vc-multivalue/vc-multivalue.vue +396 -0
- package/ui/components/organisms/vc-dynamic-property/vc-dynamic-property.vue +17 -15
- package/ui/types/index.ts +1 -0
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
class="vc-multivalue"
|
|
4
|
+
:class="[
|
|
5
|
+
`vc-multivalue_${type}`,
|
|
6
|
+
{
|
|
7
|
+
'vc-multivalue_opened': isOpened,
|
|
8
|
+
'vc-multivalue_error tw-pb-[20px]': error,
|
|
9
|
+
'vc-multivalue_disabled': disabled,
|
|
10
|
+
},
|
|
11
|
+
]"
|
|
12
|
+
>
|
|
13
|
+
<!-- Input label -->
|
|
14
|
+
<VcLabel
|
|
15
|
+
v-if="label"
|
|
16
|
+
class="tw-mb-2"
|
|
17
|
+
:required="required"
|
|
18
|
+
>
|
|
19
|
+
<span>{{ label }}</span>
|
|
20
|
+
<template
|
|
21
|
+
v-if="tooltip"
|
|
22
|
+
#tooltip
|
|
23
|
+
>{{ tooltip }}</template
|
|
24
|
+
>
|
|
25
|
+
</VcLabel>
|
|
26
|
+
|
|
27
|
+
<!-- Input field -->
|
|
28
|
+
<div
|
|
29
|
+
ref="dropdownToggleRef"
|
|
30
|
+
class="vc-multivalue__field-wrapper"
|
|
31
|
+
>
|
|
32
|
+
<div
|
|
33
|
+
v-for="(item, i) in modelValue"
|
|
34
|
+
:key="`${item.id}_${generateId()}`"
|
|
35
|
+
class="vc-multivalue__field-value-wrapper"
|
|
36
|
+
>
|
|
37
|
+
<div class="vc-multivalue__field-value">
|
|
38
|
+
<span class="tw-truncate">{{
|
|
39
|
+
type === "number" ? Number(item[props.emitLabel]).toFixed(3) : item[props.emitLabel]
|
|
40
|
+
}}</span>
|
|
41
|
+
<VcIcon
|
|
42
|
+
v-if="!disabled"
|
|
43
|
+
class="vc-multivalue__field-value-clear"
|
|
44
|
+
icon="fas fa-times"
|
|
45
|
+
size="s"
|
|
46
|
+
@click="onDelete(i)"
|
|
47
|
+
></VcIcon>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
|
|
51
|
+
<template v-if="multivalue">
|
|
52
|
+
<div class="vc-multivalue__field vc-multivalue__field_dictionary tw-grow tw-basis-0 tw-p-2">
|
|
53
|
+
<VcButton
|
|
54
|
+
small
|
|
55
|
+
@click.stop="toggleDropdown"
|
|
56
|
+
>Add +</VcButton
|
|
57
|
+
>
|
|
58
|
+
<teleport to="#app">
|
|
59
|
+
<div
|
|
60
|
+
v-if="isOpened"
|
|
61
|
+
ref="dropdownRef"
|
|
62
|
+
v-on-click-outside="[toggleDropdown, { ignore: [dropdownToggleRef] }]"
|
|
63
|
+
class="vc-multivalue__dropdown"
|
|
64
|
+
:style="dropdownStyle"
|
|
65
|
+
>
|
|
66
|
+
<input
|
|
67
|
+
ref="searchRef"
|
|
68
|
+
class="vc-multivalue__search"
|
|
69
|
+
@input="onSearch"
|
|
70
|
+
/>
|
|
71
|
+
|
|
72
|
+
<VcContainer
|
|
73
|
+
ref="root"
|
|
74
|
+
:no-padding="true"
|
|
75
|
+
>
|
|
76
|
+
<div
|
|
77
|
+
v-for="(item, i) in slicedDictionary"
|
|
78
|
+
:key="i"
|
|
79
|
+
class="vc-multivalue__item"
|
|
80
|
+
@click="onItemSelect(item)"
|
|
81
|
+
>
|
|
82
|
+
<slot
|
|
83
|
+
name="item"
|
|
84
|
+
:item="item"
|
|
85
|
+
>{{ item[optionLabel] }}</slot
|
|
86
|
+
>
|
|
87
|
+
</div>
|
|
88
|
+
</VcContainer>
|
|
89
|
+
</div>
|
|
90
|
+
</teleport>
|
|
91
|
+
</div>
|
|
92
|
+
</template>
|
|
93
|
+
<template v-else>
|
|
94
|
+
<input
|
|
95
|
+
v-model="value"
|
|
96
|
+
class="vc-multivalue__field tw-grow tw-basis-0 tw-pl-3"
|
|
97
|
+
:placeholder="placeholder"
|
|
98
|
+
:type="type"
|
|
99
|
+
:disabled="disabled"
|
|
100
|
+
@keypress.enter.stop.prevent="onInput"
|
|
101
|
+
/>
|
|
102
|
+
</template>
|
|
103
|
+
</div>
|
|
104
|
+
|
|
105
|
+
<slot
|
|
106
|
+
v-if="errorMessage"
|
|
107
|
+
name="error"
|
|
108
|
+
>
|
|
109
|
+
<VcHint class="vc-multivalue__error tw-mt-1">
|
|
110
|
+
{{ errorMessage }}
|
|
111
|
+
</VcHint>
|
|
112
|
+
</slot>
|
|
113
|
+
</div>
|
|
114
|
+
</template>
|
|
115
|
+
|
|
116
|
+
<script lang="ts" setup generic="T extends {id?: string; alias?: string}">
|
|
117
|
+
import { unref, nextTick, ref, computed } from "vue";
|
|
118
|
+
import { vOnClickOutside } from "@vueuse/components";
|
|
119
|
+
import { useFloating, UseFloatingReturn, offset, flip, shift, autoUpdate } from "@floating-ui/vue";
|
|
120
|
+
import { generateId } from "../../../../core/utilities";
|
|
121
|
+
|
|
122
|
+
export interface Props<T> {
|
|
123
|
+
placeholder?: string;
|
|
124
|
+
modelValue?: T[];
|
|
125
|
+
required?: boolean;
|
|
126
|
+
disabled?: boolean;
|
|
127
|
+
type?: "text" | "number";
|
|
128
|
+
label?: string;
|
|
129
|
+
tooltip?: string;
|
|
130
|
+
name?: string;
|
|
131
|
+
options?: T[];
|
|
132
|
+
optionValue?: string;
|
|
133
|
+
optionLabel?: string;
|
|
134
|
+
emitValue?: string;
|
|
135
|
+
emitLabel?: string;
|
|
136
|
+
multivalue?: boolean;
|
|
137
|
+
error?: boolean;
|
|
138
|
+
errorMessage?: string;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export interface Emits<T> {
|
|
142
|
+
(event: "update:model-value", value: T[]): void;
|
|
143
|
+
(event: "close"): void;
|
|
144
|
+
(event: "search", value: string): void;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
type FloatingInstanceType = UseFloatingReturn & {
|
|
148
|
+
middlewareData: {
|
|
149
|
+
sameWidthChangeBorders: {
|
|
150
|
+
borderTop?: string;
|
|
151
|
+
borderBottom?: string;
|
|
152
|
+
borderRadius?: string;
|
|
153
|
+
width?: string;
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
const props = withDefaults(defineProps<Props<T>>(), {
|
|
159
|
+
modelValue: () => [],
|
|
160
|
+
type: "text",
|
|
161
|
+
name: "Field",
|
|
162
|
+
options: () => [],
|
|
163
|
+
optionValue: "id",
|
|
164
|
+
optionLabel: "title",
|
|
165
|
+
emitValue: "valueId",
|
|
166
|
+
emitLabel: "value",
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
const emit = defineEmits<Emits<T>>();
|
|
170
|
+
|
|
171
|
+
const dropdownToggleRef = ref();
|
|
172
|
+
const dropdownRef = ref();
|
|
173
|
+
const root = ref();
|
|
174
|
+
const searchRef = ref();
|
|
175
|
+
const isOpened = ref(false);
|
|
176
|
+
const value = ref();
|
|
177
|
+
|
|
178
|
+
const popper = useFloating(dropdownToggleRef, dropdownRef, {
|
|
179
|
+
placement: "bottom",
|
|
180
|
+
whileElementsMounted: autoUpdate,
|
|
181
|
+
middleware: [
|
|
182
|
+
flip({ fallbackPlacements: ["top", "bottom"] }),
|
|
183
|
+
shift({ mainAxis: false }),
|
|
184
|
+
sameWidthChangeBorders(),
|
|
185
|
+
offset(-2),
|
|
186
|
+
],
|
|
187
|
+
}) as FloatingInstanceType;
|
|
188
|
+
|
|
189
|
+
const dropdownStyle = computed(() => {
|
|
190
|
+
return {
|
|
191
|
+
top: `${popper.y.value ?? 0}px`,
|
|
192
|
+
left: `${popper.x.value ?? 0}px`,
|
|
193
|
+
...popper.middlewareData.value.sameWidthChangeBorders,
|
|
194
|
+
};
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
const slicedDictionary = computed(() => {
|
|
198
|
+
return props.options?.filter((x) => {
|
|
199
|
+
return !props.modelValue?.find((item) => item[props.emitValue] === x[props.optionValue]);
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
// Handle input event to propertly validate value and emit changes
|
|
204
|
+
function onInput(e: KeyboardEvent) {
|
|
205
|
+
const newValue = (e.target as HTMLInputElement).value;
|
|
206
|
+
emit("update:model-value", [...props.modelValue, { [props.emitLabel]: newValue } as T]);
|
|
207
|
+
value.value = undefined;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function onItemSelect(item: T) {
|
|
211
|
+
emit("update:model-value", [
|
|
212
|
+
...props.modelValue,
|
|
213
|
+
{ [props.emitValue]: item[props.optionValue], [props.emitLabel]: item[props.optionLabel] } as T,
|
|
214
|
+
]);
|
|
215
|
+
emit("close");
|
|
216
|
+
closeDropdown();
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Handle event to propertly remove particular value and emit changes
|
|
220
|
+
function onDelete(i: number) {
|
|
221
|
+
const result = unref(props.modelValue);
|
|
222
|
+
result.splice(i, 1);
|
|
223
|
+
emit("update:model-value", [...result]);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
function sameWidthChangeBorders() {
|
|
227
|
+
return {
|
|
228
|
+
name: "sameWidthChangeBorders",
|
|
229
|
+
fn: ({ rects, placement, x, y }) => {
|
|
230
|
+
let borderTop;
|
|
231
|
+
let borderBottom;
|
|
232
|
+
let borderRadius;
|
|
233
|
+
if (placement === "top") {
|
|
234
|
+
borderTop = "1px solid var(--select-border-color)";
|
|
235
|
+
borderBottom = "1px solid var(--select-background-color)";
|
|
236
|
+
borderRadius = "var(--select-border-radius) var(--select-border-radius) 0 0";
|
|
237
|
+
} else {
|
|
238
|
+
borderBottom = "1px solid var(--select-border-color)";
|
|
239
|
+
borderTop = "1px solid var(--select-background-color)";
|
|
240
|
+
borderRadius = "0 0 var(--select-border-radius) var(--select-border-radius)";
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const width = `${rects.reference.width}px`;
|
|
244
|
+
|
|
245
|
+
return {
|
|
246
|
+
x,
|
|
247
|
+
y,
|
|
248
|
+
data: {
|
|
249
|
+
borderTop,
|
|
250
|
+
borderBottom,
|
|
251
|
+
borderRadius,
|
|
252
|
+
width,
|
|
253
|
+
},
|
|
254
|
+
};
|
|
255
|
+
},
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
async function toggleDropdown() {
|
|
260
|
+
if (!props.disabled) {
|
|
261
|
+
if (isOpened.value) {
|
|
262
|
+
closeDropdown();
|
|
263
|
+
} else {
|
|
264
|
+
isOpened.value = true;
|
|
265
|
+
|
|
266
|
+
nextTick(() => {
|
|
267
|
+
searchRef?.value?.focus();
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
function closeDropdown() {
|
|
274
|
+
isOpened.value = false;
|
|
275
|
+
emit("close");
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
function onSearch(event: InputEvent) {
|
|
279
|
+
emit("search", (event.target as HTMLInputElement).value);
|
|
280
|
+
}
|
|
281
|
+
</script>
|
|
282
|
+
|
|
283
|
+
<style lang="scss">
|
|
284
|
+
:root {
|
|
285
|
+
--multivalue-height: 38px;
|
|
286
|
+
--multivalue-border-radius: 3px;
|
|
287
|
+
--multivalue-border-color: #d3dbe9;
|
|
288
|
+
--multivalue-border-color-error: #f14e4e;
|
|
289
|
+
--multivalue-background-color: #ffffff;
|
|
290
|
+
--multivalue-placeholder-color: #a5a5a5;
|
|
291
|
+
|
|
292
|
+
--select-height: 38px;
|
|
293
|
+
--select-border-radius: 3px;
|
|
294
|
+
--select-border-color: #d3dbe9;
|
|
295
|
+
--select-border-color-error: #f14e4e;
|
|
296
|
+
--select-background-color: #ffffff;
|
|
297
|
+
--select-background-color-disabled: #fafafa;
|
|
298
|
+
--select-placeholder-color: #a5a5a5;
|
|
299
|
+
--select-chevron-color: #43b0e6;
|
|
300
|
+
--select-chevron-color-hover: #319ed4;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
.vc-multivalue {
|
|
304
|
+
@apply tw-overflow-hidden;
|
|
305
|
+
|
|
306
|
+
&_date,
|
|
307
|
+
&_datetime-local {
|
|
308
|
+
@apply tw-max-w-[220px];
|
|
309
|
+
|
|
310
|
+
.vc-app_mobile & {
|
|
311
|
+
@apply tw-max-w-full;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
&__field-wrapper {
|
|
316
|
+
@apply tw-border tw-border-solid
|
|
317
|
+
tw-border-[color:var(--multivalue-border-color)]
|
|
318
|
+
tw-rounded-[var(--multivalue-border-radius)]
|
|
319
|
+
tw-bg-[color:var(--multivalue-background-color)]
|
|
320
|
+
tw-items-center
|
|
321
|
+
tw-flex
|
|
322
|
+
tw-flex-wrap;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
&__dropdown {
|
|
326
|
+
@apply tw-flex tw-flex-col tw-box-border
|
|
327
|
+
tw-max-h-[300px] tw-z-10 tw-overflow-hidden
|
|
328
|
+
tw-absolute tw-bg-[color:var(--select-background-color)]
|
|
329
|
+
tw-border tw-border-solid tw-border-[color:var(--select-border-color)]
|
|
330
|
+
tw-border-t-[color:var(--select-background-color)]
|
|
331
|
+
tw-rounded-b-[var(--select-border-radius)]
|
|
332
|
+
tw-p-2;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
&__search {
|
|
336
|
+
@apply tw-w-full tw-box-border tw-border tw-border-solid tw-border-[#eaecf2]
|
|
337
|
+
tw-rounded-[4px] tw-h-8 tw-leading-[32px]
|
|
338
|
+
tw-outline-none tw-mb-3 tw-px-2;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
&__item {
|
|
342
|
+
@apply tw-flex tw-items-center tw-min-h-[36px] tw-px-2 tw-rounded-[3px] tw-cursor-pointer hover:tw-bg-[#eff7fc];
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
&_opened &__field-wrapper {
|
|
346
|
+
@apply tw-rounded-t-[var(--select-border-radius)];
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
&_error &__field-wrapper {
|
|
350
|
+
@apply tw-border tw-border-solid tw-border-[color:var(--multivalue-border-color-error)];
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
&__error {
|
|
354
|
+
@apply tw-text-[color:var(--multivalue-border-color-error)];
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
&__field {
|
|
358
|
+
@apply tw-border-none tw-outline-none tw-h-[var(--multivalue-height)]
|
|
359
|
+
tw-min-w-[120px] tw-box-border placeholder:tw-text-[color:var(--multivalue-placeholder-color)];
|
|
360
|
+
|
|
361
|
+
&::-webkit-input-placeholder {
|
|
362
|
+
@apply tw-text-[color:var(--multivalue-placeholder-color)];
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
&::-moz-placeholder {
|
|
366
|
+
@apply tw-text-[color:var(--multivalue-placeholder-color)];
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
&::-ms-placeholder {
|
|
370
|
+
@apply tw-text-[color:var(--multivalue-placeholder-color)];
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
&-value-wrapper {
|
|
374
|
+
@apply tw-h-[var(--multivalue-height)] tw-ml-2 tw-flex tw-items-center;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
&-value {
|
|
378
|
+
@apply tw-bg-[#fbfdfe] tw-border tw-border-solid tw-border-[color:#bdd1df] tw-rounded-[2px]
|
|
379
|
+
tw-flex tw-items-center tw-h-[28px] tw-box-border tw-px-2 tw-max-w-[150px];
|
|
380
|
+
|
|
381
|
+
&-clear {
|
|
382
|
+
@apply tw-text-[#a9bfd2] tw-ml-2 tw-cursor-pointer;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
&_dictionary {
|
|
387
|
+
@apply tw-h-auto tw-min-w-[auto];
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
&_disabled &__field-wrapper,
|
|
392
|
+
&_disabled &__field {
|
|
393
|
+
@apply tw-bg-[#fafafa] tw-text-[#424242];
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
</style>
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
:error-message="errorMessage"
|
|
15
15
|
:label="computedProperty.displayName"
|
|
16
16
|
:required="computedProperty.required"
|
|
17
|
-
:placeholder="computedProperty.
|
|
17
|
+
:placeholder="computedProperty.placeholder"
|
|
18
18
|
:options="items"
|
|
19
19
|
:option-value="computedProperty.optionValue"
|
|
20
20
|
:option-label="computedProperty.optionLabel"
|
|
@@ -155,7 +155,7 @@
|
|
|
155
155
|
clearable
|
|
156
156
|
type="number"
|
|
157
157
|
:required="computedProperty.required"
|
|
158
|
-
:placeholder="computedProperty.
|
|
158
|
+
:placeholder="computedProperty.placeholder"
|
|
159
159
|
:disabled="disabled"
|
|
160
160
|
></VcInput>
|
|
161
161
|
</Field>
|
|
@@ -178,7 +178,7 @@
|
|
|
178
178
|
type="number"
|
|
179
179
|
step="1"
|
|
180
180
|
:required="computedProperty.required"
|
|
181
|
-
:placeholder="computedProperty.
|
|
181
|
+
:placeholder="computedProperty.placeholder"
|
|
182
182
|
:disabled="disabled"
|
|
183
183
|
></VcInput>
|
|
184
184
|
</Field>
|
|
@@ -199,7 +199,7 @@
|
|
|
199
199
|
:label="computedProperty.displayName"
|
|
200
200
|
type="datetime-local"
|
|
201
201
|
:required="computedProperty.required"
|
|
202
|
-
:placeholder="computedProperty.
|
|
202
|
+
:placeholder="computedProperty.placeholder"
|
|
203
203
|
:disabled="disabled"
|
|
204
204
|
></VcInput>
|
|
205
205
|
</Field>
|
|
@@ -218,7 +218,7 @@
|
|
|
218
218
|
:error-message="errorMessage"
|
|
219
219
|
:label="computedProperty.displayName"
|
|
220
220
|
:required="computedProperty.required"
|
|
221
|
-
:placeholder="computedProperty.
|
|
221
|
+
:placeholder="computedProperty.placeholder"
|
|
222
222
|
:disabled="disabled"
|
|
223
223
|
></VcTextarea>
|
|
224
224
|
</Field>
|
|
@@ -261,11 +261,11 @@ const props = withDefaults(
|
|
|
261
261
|
defineProps<{
|
|
262
262
|
property: T;
|
|
263
263
|
modelValue: any;
|
|
264
|
-
optionsGetter: (property: T, keyword?: string) => Promise<unknown[]
|
|
264
|
+
optionsGetter: (property: T, keyword?: string) => Promise<unknown[]> | unknown[];
|
|
265
265
|
required: boolean;
|
|
266
|
-
multivalue
|
|
266
|
+
multivalue?: boolean;
|
|
267
267
|
valueType: string;
|
|
268
|
-
dictionary
|
|
268
|
+
dictionary?: boolean;
|
|
269
269
|
name: string;
|
|
270
270
|
optionsValue?: string;
|
|
271
271
|
optionsLabel?: string;
|
|
@@ -279,6 +279,7 @@ const props = withDefaults(
|
|
|
279
279
|
regex: string;
|
|
280
280
|
};
|
|
281
281
|
disabled?: boolean;
|
|
282
|
+
placeholder?: string;
|
|
282
283
|
}>(),
|
|
283
284
|
{
|
|
284
285
|
optionsValue: "id",
|
|
@@ -300,19 +301,19 @@ const computedProperty = computed(() => {
|
|
|
300
301
|
if (props.required) {
|
|
301
302
|
rules["required"] = true;
|
|
302
303
|
}
|
|
303
|
-
if (props.rules
|
|
304
|
+
if (props.rules?.min) {
|
|
304
305
|
rules["min"] = Number(props.rules.min);
|
|
305
306
|
}
|
|
306
|
-
if (props.rules
|
|
307
|
+
if (props.rules?.max) {
|
|
307
308
|
rules["max"] = Number(props.rules.max);
|
|
308
309
|
}
|
|
309
|
-
if (props.rules
|
|
310
|
+
if (props.rules?.regex) {
|
|
310
311
|
rules["regex"] = new RegExp(props.rules.regex);
|
|
311
312
|
}
|
|
312
313
|
|
|
313
|
-
const propertyDisplayName =
|
|
314
|
-
displayName.languageCode?.startsWith(locale.value as string)
|
|
315
|
-
|
|
314
|
+
const propertyDisplayName =
|
|
315
|
+
props.displayNames?.find((displayName) => displayName.languageCode?.startsWith(locale.value as string))?.name ||
|
|
316
|
+
props.name;
|
|
316
317
|
const propertyDisplayNameLocalized =
|
|
317
318
|
propertyDisplayName && te(propertyDisplayName.toUpperCase())
|
|
318
319
|
? t(propertyDisplayName.toUpperCase())
|
|
@@ -324,10 +325,11 @@ const computedProperty = computed(() => {
|
|
|
324
325
|
dictionary: props.dictionary || false,
|
|
325
326
|
multivalue: props.multivalue || false,
|
|
326
327
|
name: props.name,
|
|
327
|
-
displayName: propertyDisplayNameLocalized
|
|
328
|
+
displayName: propertyDisplayNameLocalized, //|| setting?.displayName || setting?.defaultValue,
|
|
328
329
|
optionValue: props.optionsValue,
|
|
329
330
|
optionLabel: props.optionsLabel,
|
|
330
331
|
required: props.required,
|
|
332
|
+
placeholder: props.placeholder || propertyDisplayNameLocalized,
|
|
331
333
|
};
|
|
332
334
|
});
|
|
333
335
|
|
package/ui/types/index.ts
CHANGED
|
@@ -38,6 +38,7 @@ declare module "@vue/runtime-core" {
|
|
|
38
38
|
VcSelect: (typeof VcShellComponents)["VcSelect"];
|
|
39
39
|
VcSlider: (typeof VcShellComponents)["VcSlider"];
|
|
40
40
|
VcTextarea: (typeof VcShellComponents)["VcTextarea"];
|
|
41
|
+
VcMultivalue: (typeof VcShellComponents)["VcMultivalue"];
|
|
41
42
|
|
|
42
43
|
// organisms
|
|
43
44
|
VcApp: (typeof VcShellComponents)["VcApp"];
|