@vc-shell/framework 1.0.197 → 1.0.199

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/CHANGELOG.md +26 -0
  2. package/core/composables/useBreadcrumbs/index.ts +15 -9
  3. package/core/plugins/modularity/index.ts +1 -1
  4. package/dist/core/composables/useBreadcrumbs/index.d.ts +1 -6
  5. package/dist/core/composables/useBreadcrumbs/index.d.ts.map +1 -1
  6. package/dist/framework.js +27636 -27362
  7. package/dist/index.css +1 -1
  8. package/dist/locales/en.json +2 -1
  9. package/dist/shared/components/blade-navigation/components/vc-blade-navigation/vc-blade-navigation.vue.d.ts.map +1 -1
  10. package/dist/shared/components/blade-navigation/components/vc-blade-view/vc-blade-view.d.ts.map +1 -1
  11. package/dist/shared/components/blade-navigation/composables/useBladeNavigation/index.d.ts +1 -2
  12. package/dist/shared/components/blade-navigation/composables/useBladeNavigation/index.d.ts.map +1 -1
  13. package/dist/shared/components/blade-navigation/types/index.d.ts +1 -1
  14. package/dist/shared/components/blade-navigation/types/index.d.ts.map +1 -1
  15. package/dist/shared/modules/dynamic/components/SchemaRender.d.ts +3 -3
  16. package/dist/shared/modules/dynamic/components/fields/Button.d.ts +1 -1
  17. package/dist/shared/modules/dynamic/components/fields/Card.d.ts +1 -1
  18. package/dist/shared/modules/dynamic/components/fields/Checkbox.d.ts +1 -1
  19. package/dist/shared/modules/dynamic/components/fields/ContentField.d.ts +1 -1
  20. package/dist/shared/modules/dynamic/components/fields/CustomComponent.d.ts +1 -1
  21. package/dist/shared/modules/dynamic/components/fields/DynamicProperty.d.ts +1 -1
  22. package/dist/shared/modules/dynamic/components/fields/DynamicProperty.d.ts.map +1 -1
  23. package/dist/shared/modules/dynamic/components/fields/EditorField.d.ts +1 -1
  24. package/dist/shared/modules/dynamic/components/fields/Fieldset.d.ts +1 -1
  25. package/dist/shared/modules/dynamic/components/fields/GalleryField.d.ts +1 -1
  26. package/dist/shared/modules/dynamic/components/fields/ImageField.d.ts +1 -1
  27. package/dist/shared/modules/dynamic/components/fields/InputCurrency.d.ts +1 -1
  28. package/dist/shared/modules/dynamic/components/fields/InputField.d.ts +1 -1
  29. package/dist/shared/modules/dynamic/components/fields/MultivalueField.d.ts +1 -1
  30. package/dist/shared/modules/dynamic/components/fields/RatingField.d.ts +1 -1
  31. package/dist/shared/modules/dynamic/components/fields/SelectField.d.ts +1 -1
  32. package/dist/shared/modules/dynamic/components/fields/StatusField.d.ts +1 -1
  33. package/dist/shared/modules/dynamic/components/fields/SwitchField.d.ts +1 -1
  34. package/dist/shared/modules/dynamic/components/fields/Table.d.ts +1 -1
  35. package/dist/shared/modules/dynamic/components/fields/TextareaField.d.ts +1 -1
  36. package/dist/shared/modules/dynamic/components/fields/VideoField.d.ts +1 -1
  37. package/dist/shared/modules/dynamic/components/fields/props.d.ts +1 -1
  38. package/dist/shared/modules/dynamic/components/fields/storybook/Button.stories.d.ts +3 -3
  39. package/dist/shared/modules/dynamic/components/fields/storybook/Card.stories.d.ts +3 -3
  40. package/dist/shared/modules/dynamic/components/fields/storybook/Checkbox.stories.d.ts +3 -3
  41. package/dist/shared/modules/dynamic/components/fields/storybook/ContentField.stories.d.ts +3 -3
  42. package/dist/shared/modules/dynamic/components/fields/storybook/EditorField.stories.d.ts +3 -3
  43. package/dist/shared/modules/dynamic/components/fields/storybook/Fieldset.stories.d.ts +3 -3
  44. package/dist/shared/modules/dynamic/components/fields/storybook/GalleryField.stories.d.ts +3 -3
  45. package/dist/shared/modules/dynamic/components/fields/storybook/ImageField.stories.d.ts +3 -3
  46. package/dist/shared/modules/dynamic/components/fields/storybook/InputCurrency.stories.d.ts +3 -3
  47. package/dist/shared/modules/dynamic/components/fields/storybook/InputField.stories.d.ts +3 -3
  48. package/dist/shared/modules/dynamic/components/fields/storybook/MultivalueField.stories.d.ts +3 -3
  49. package/dist/shared/modules/dynamic/components/fields/storybook/RatingField.stories.d.ts +3 -3
  50. package/dist/shared/modules/dynamic/components/fields/storybook/SelectField.stories.d.ts +3 -3
  51. package/dist/shared/modules/dynamic/components/fields/storybook/StatusField.stories.d.ts +3 -3
  52. package/dist/shared/modules/dynamic/components/fields/storybook/TextareaField.stories.d.ts +3 -3
  53. package/dist/shared/modules/dynamic/components/fields/storybook/VideoField.stories.d.ts +3 -3
  54. package/dist/shared/modules/dynamic/components/fields/storybook/pages/DynamicRender.d.ts +3 -3
  55. package/dist/shared/modules/dynamic/composables/index.d.ts +1 -0
  56. package/dist/shared/modules/dynamic/composables/index.d.ts.map +1 -1
  57. package/dist/shared/modules/dynamic/composables/useDynamicViewsUtils/index.d.ts +10 -0
  58. package/dist/shared/modules/dynamic/composables/useDynamicViewsUtils/index.d.ts.map +1 -0
  59. package/dist/shared/modules/dynamic/factories/types/index.d.ts +14 -2
  60. package/dist/shared/modules/dynamic/factories/types/index.d.ts.map +1 -1
  61. package/dist/shared/modules/dynamic/index.d.ts +2 -3
  62. package/dist/shared/modules/dynamic/index.d.ts.map +1 -1
  63. package/dist/shared/modules/dynamic/pages/dynamic-blade-form.vue.d.ts +2 -1
  64. package/dist/shared/modules/dynamic/pages/dynamic-blade-form.vue.d.ts.map +1 -1
  65. package/dist/shared/modules/dynamic/pages/dynamic-blade-list.vue.d.ts +2 -0
  66. package/dist/shared/modules/dynamic/pages/dynamic-blade-list.vue.d.ts.map +1 -1
  67. package/dist/tsconfig.tsbuildinfo +1 -1
  68. package/dist/ui/components/atoms/vc-card/vc-card.stories.d.ts +26 -7
  69. package/dist/ui/components/atoms/vc-card/vc-card.stories.d.ts.map +1 -1
  70. package/dist/ui/components/molecules/vc-breadcrumbs/_internal/vc-breadcrumbs-item/vc-breadcrumbs-item.vue.d.ts +1 -0
  71. package/dist/ui/components/molecules/vc-breadcrumbs/_internal/vc-breadcrumbs-item/vc-breadcrumbs-item.vue.d.ts.map +1 -1
  72. package/dist/ui/components/molecules/vc-breadcrumbs/index.d.ts +1 -13
  73. package/dist/ui/components/molecules/vc-breadcrumbs/index.d.ts.map +1 -1
  74. package/dist/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.stories.d.ts +33 -0
  75. package/dist/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.stories.d.ts.map +1 -1
  76. package/dist/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.vue.d.ts +14 -0
  77. package/dist/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.vue.d.ts.map +1 -1
  78. package/dist/ui/components/molecules/vc-input/vc-input.stories.d.ts +26 -7
  79. package/dist/ui/components/molecules/vc-input/vc-input.stories.d.ts.map +1 -1
  80. package/dist/ui/components/molecules/vc-input/vc-input.vue.d.ts +9 -2
  81. package/dist/ui/components/molecules/vc-input/vc-input.vue.d.ts.map +1 -1
  82. package/dist/ui/components/molecules/vc-multivalue/vc-multivalue.stories.d.ts +84 -63
  83. package/dist/ui/components/molecules/vc-multivalue/vc-multivalue.stories.d.ts.map +1 -1
  84. package/dist/ui/components/molecules/vc-multivalue/vc-multivalue.vue.d.ts +14 -10
  85. package/dist/ui/components/molecules/vc-multivalue/vc-multivalue.vue.d.ts.map +1 -1
  86. package/dist/ui/components/molecules/vc-select/vc-select.vue.d.ts.map +1 -1
  87. package/dist/ui/components/organisms/vc-app/_internal/vc-app-bar/vc-app-bar.vue.d.ts.map +1 -1
  88. package/dist/ui/components/organisms/vc-blade/_internal/vc-blade-header/vc-blade-header.vue.d.ts +1 -1
  89. package/dist/ui/components/organisms/vc-dynamic-property/vc-dynamic-property.vue.d.ts +3 -9
  90. package/dist/ui/components/organisms/vc-dynamic-property/vc-dynamic-property.vue.d.ts.map +1 -1
  91. package/dist/ui/types/index.d.ts +3 -2
  92. package/dist/ui/types/index.d.ts.map +1 -1
  93. package/package.json +4 -4
  94. package/shared/components/blade-navigation/components/vc-blade-navigation/vc-blade-navigation.vue +84 -38
  95. package/shared/components/blade-navigation/components/vc-blade-view/vc-blade-view.ts +11 -4
  96. package/shared/components/blade-navigation/composables/useBladeNavigation/index.ts +37 -54
  97. package/shared/components/blade-navigation/types/index.ts +1 -1
  98. package/shared/modules/assets-manager/components/assets-manager/assets-manager.vue +2 -2
  99. package/shared/modules/dynamic/components/fields/DynamicProperty.ts +7 -3
  100. package/shared/modules/dynamic/components/fields/GalleryField.ts +1 -1
  101. package/shared/modules/dynamic/composables/index.ts +1 -0
  102. package/shared/modules/dynamic/composables/useDynamicViewsUtils/index.ts +46 -0
  103. package/shared/modules/dynamic/factories/types/index.ts +17 -2
  104. package/shared/modules/dynamic/index.ts +2 -3
  105. package/shared/modules/dynamic/pages/dynamic-blade-form.vue +1 -0
  106. package/shared/modules/dynamic/pages/dynamic-blade-list.vue +7 -1
  107. package/ui/components/molecules/vc-breadcrumbs/_internal/vc-breadcrumbs-item/vc-breadcrumbs-item.vue +3 -0
  108. package/ui/components/molecules/vc-breadcrumbs/index.ts +1 -3
  109. package/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.vue +124 -5
  110. package/ui/components/molecules/vc-input/vc-input.vue +58 -18
  111. package/ui/components/molecules/vc-multivalue/vc-multivalue.vue +124 -83
  112. package/ui/components/molecules/vc-select/vc-select.vue +42 -17
  113. package/ui/components/organisms/vc-app/_internal/vc-app-bar/vc-app-bar.vue +10 -14
  114. package/ui/components/organisms/vc-dynamic-property/vc-dynamic-property.vue +49 -16
  115. package/ui/components/organisms/vc-table/_internal/vc-table-cell/vc-table-cell.vue +1 -1
  116. package/ui/types/index.ts +3 -2
@@ -31,94 +31,99 @@
31
31
  ref="dropdownToggleRef"
32
32
  class="vc-multivalue__field-wrapper"
33
33
  >
34
- <div
35
- v-for="(item, i) in modelValue"
36
- :key="`${item?.id}_${generateId()}`"
37
- class="vc-multivalue__field-value-wrapper"
38
- >
34
+ <div class="tw-items-center tw-flex tw-flex-wrap">
39
35
  <div
40
- v-if="item"
41
- class="vc-multivalue__field-value"
36
+ v-for="(item, i) in modelValue"
37
+ :key="`${item?.id}_${generateId()}`"
38
+ class="vc-multivalue__field-value-wrapper"
42
39
  >
43
- <slot
44
- name="selected-item"
45
- :value="
46
- type === 'number'
47
- ? Number(item[props.optionLabel as keyof T]).toFixed(3)
48
- : item[props.optionLabel as keyof T]
49
- "
50
- :item="item"
51
- :remove="() => onDelete(i)"
40
+ <div
41
+ v-if="item"
42
+ class="vc-multivalue__field-value"
52
43
  >
53
- <span class="tw-truncate">{{
54
- type === "number"
55
- ? Number(item[props.optionLabel as keyof T]).toFixed(3)
56
- : item[props.optionLabel as keyof T]
57
- }}</span>
58
- </slot>
59
- <VcIcon
60
- v-if="!disabled"
61
- class="vc-multivalue__field-value-clear"
62
- icon="fas fa-times"
63
- size="s"
64
- @click="onDelete(i)"
65
- ></VcIcon>
44
+ <slot
45
+ name="selected-item"
46
+ :value="formatValue(item)"
47
+ :item="item"
48
+ :remove="() => onDelete(i)"
49
+ >
50
+ <span class="tw-truncate">{{ formatValue(item) }}</span>
51
+ </slot>
52
+ <VcIcon
53
+ v-if="!disabled"
54
+ class="vc-multivalue__field-value-clear"
55
+ icon="fas fa-times"
56
+ size="s"
57
+ @click="onDelete(i)"
58
+ ></VcIcon>
59
+ </div>
66
60
  </div>
67
- </div>
68
61
 
69
- <template v-if="multivalue">
70
- <div class="vc-multivalue__field vc-multivalue__field_dictionary tw-grow tw-basis-0 tw-p-2">
71
- <VcButton
72
- small
73
- :disabled="disabled"
74
- @click.stop="toggleDropdown"
75
- >Add +</VcButton
76
- >
77
- <teleport to="body">
78
- <div
79
- v-if="isOpened"
80
- ref="dropdownRef"
81
- v-on-click-outside="[toggleDropdown, { ignore: [dropdownToggleRef] }]"
82
- class="vc-multivalue__dropdown"
83
- :style="dropdownStyle"
62
+ <template v-if="multivalue">
63
+ <div class="vc-multivalue__field vc-multivalue__field_dictionary tw-grow tw-basis-0 tw-p-2">
64
+ <VcButton
65
+ small
66
+ :disabled="disabled"
67
+ @click.stop="toggleDropdown"
68
+ >Add +</VcButton
84
69
  >
85
- <input
86
- ref="searchRef"
87
- class="vc-multivalue__search"
88
- @input="onSearch"
89
- />
90
-
91
- <VcContainer
92
- ref="root"
93
- :no-padding="true"
70
+ <teleport to="body">
71
+ <div
72
+ v-if="isOpened"
73
+ ref="dropdownRef"
74
+ v-on-click-outside="[toggleDropdown, { ignore: [dropdownToggleRef] }]"
75
+ class="vc-multivalue__dropdown"
76
+ :style="dropdownStyle"
94
77
  >
95
- <div
96
- v-for="(item, i) in slicedDictionary"
97
- :key="i"
98
- class="vc-multivalue__item"
99
- @click="onItemSelect(item)"
78
+ <input
79
+ ref="searchRef"
80
+ class="vc-multivalue__search"
81
+ @input="onSearch"
82
+ />
83
+
84
+ <VcContainer
85
+ ref="root"
86
+ :no-padding="true"
100
87
  >
101
- <slot
102
- name="option"
103
- :item="item"
104
- >{{ item[optionLabel as keyof T] }}</slot
88
+ <div
89
+ v-for="(item, i) in slicedDictionary"
90
+ :key="i"
91
+ class="vc-multivalue__item"
92
+ @click="onItemSelect(item)"
105
93
  >
106
- </div>
107
- </VcContainer>
108
- </div>
109
- </teleport>
110
- </div>
111
- </template>
112
- <template v-else>
113
- <input
114
- v-model="value"
115
- class="vc-multivalue__field tw-grow tw-basis-0 tw-pl-3"
116
- :placeholder="placeholder"
117
- :type="type"
118
- :disabled="disabled"
119
- @keypress.enter.stop.prevent="onInput"
120
- />
121
- </template>
94
+ <slot
95
+ name="option"
96
+ :item="item"
97
+ >{{ item[optionLabel as keyof T] }}</slot
98
+ >
99
+ </div>
100
+ </VcContainer>
101
+ </div>
102
+ </teleport>
103
+ </div>
104
+ </template>
105
+ <template v-else>
106
+ <input
107
+ v-model="value"
108
+ class="vc-multivalue__field tw-grow tw-basis-0 tw-pl-3"
109
+ :placeholder="placeholder"
110
+ :type="internalTypeComputed"
111
+ :disabled="disabled"
112
+ @keypress.enter.stop.prevent="onInput"
113
+ @keydown="onKeyDown"
114
+ />
115
+ </template>
116
+ </div>
117
+ <!-- Loading-->
118
+ <div
119
+ v-if="loading"
120
+ class="tw-flex tw-items-center tw-flex-nowrap tw-px-3 tw-text-[color:var(--select-clear-color)]"
121
+ >
122
+ <VcIcon
123
+ icon="fas fa-circle-notch tw-animate-spin"
124
+ size="m"
125
+ ></VcIcon>
126
+ </div>
122
127
  </div>
123
128
 
124
129
  <Transition
@@ -160,7 +165,7 @@ export interface Props<T> {
160
165
  modelValue?: T[];
161
166
  required?: boolean;
162
167
  disabled?: boolean;
163
- type?: "text" | "number";
168
+ type?: "text" | "number" | "integer";
164
169
  label?: string;
165
170
  tooltip?: string;
166
171
  name?: string;
@@ -173,6 +178,7 @@ export interface Props<T> {
173
178
  errorMessage?: string;
174
179
  multilanguage?: boolean;
175
180
  currentLanguage?: string;
181
+ loading?: boolean;
176
182
  }
177
183
 
178
184
  export interface Emits<T> {
@@ -204,7 +210,7 @@ const props = withDefaults(defineProps<Props<T>>(), {
204
210
  const emit = defineEmits<Emits<T>>();
205
211
  defineSlots<{
206
212
  option: (args: { item: T }) => any;
207
- "selected-item": (args: { value: string | T[keyof T]; item: T; remove: () => void }) => any;
213
+ "selected-item": (args: { value: string | number | T[keyof T]; item: T; remove: () => void }) => any;
208
214
  hint: void;
209
215
  error: void;
210
216
  }>();
@@ -215,6 +221,7 @@ const root = ref();
215
221
  const searchRef = ref();
216
222
  const isOpened = ref(false);
217
223
  const value = ref();
224
+ const internalType = ref(unref(props.type));
218
225
 
219
226
  const popper = useFloating(dropdownToggleRef, dropdownRef, {
220
227
  placement: "bottom",
@@ -243,6 +250,41 @@ const slicedDictionary = computed(() => {
243
250
  });
244
251
  });
245
252
 
253
+ const formatValue = computed(() => {
254
+ return (item: T) => {
255
+ if (props.type === "number") {
256
+ return Number(item[props.optionLabel as keyof T]).toFixed(3);
257
+ } else if (props.type === "integer") {
258
+ return Math.trunc(+item[props.optionLabel as keyof T]);
259
+ } else {
260
+ return item[props.optionLabel as keyof T];
261
+ }
262
+ };
263
+ });
264
+
265
+ const internalTypeComputed = computed({
266
+ get() {
267
+ if (internalType.value === "integer") {
268
+ return "number";
269
+ }
270
+ return internalType.value;
271
+ },
272
+ set(value) {
273
+ internalType.value = value;
274
+ },
275
+ });
276
+
277
+ function onKeyDown(e: KeyboardEvent) {
278
+ const allowedKeys = ["Backspace", "Delete", "ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "Enter"];
279
+ const keypressed = e.key;
280
+ if (props.type === "integer") {
281
+ if (!/^\d$/.test(keypressed) && !allowedKeys.includes(keypressed)) {
282
+ e.preventDefault();
283
+ return;
284
+ }
285
+ }
286
+ }
287
+
246
288
  function onInput(e: KeyboardEvent) {
247
289
  const newValue = (e.target as HTMLInputElement).value;
248
290
  emit("update:model-value", [...props.modelValue, { [props.optionLabel]: newValue } as T]);
@@ -356,8 +398,7 @@ function onSearch(event: Event) {
356
398
  tw-rounded-[var(--multivalue-border-radius)]
357
399
  tw-bg-[color:var(--multivalue-background-color)]
358
400
  tw-items-center
359
- tw-flex
360
- tw-flex-wrap;
401
+ tw-flex tw-justify-between;
361
402
  }
362
403
 
363
404
  &__dropdown {
@@ -76,7 +76,6 @@
76
76
  <div class="tw-flex tw-flex-wrap tw-gap-1 tw-py-1">
77
77
  <div
78
78
  v-for="(item, i) in selectedScope"
79
- v-bind="item"
80
79
  :key="i"
81
80
  class="tw-flex tw-items-center"
82
81
  >
@@ -84,12 +83,19 @@
84
83
  <div
85
84
  class="tw-bg-[#fbfdfe] tw-border tw-border-solid tw-border-[color:#bdd1df] tw-rounded-[2px] tw-flex tw-items-center tw-h-[28px] tw-box-border tw-px-2"
86
85
  >
87
- <slot
88
- name="selected-item"
89
- v-bind="item"
90
- >
91
- <span>{{ getOptionLabel(item.opt) }}</span>
92
- </slot>
86
+ <template v-if="loading">
87
+ <span class="tw-text-[#a5a5a5]">{{
88
+ t("COMPONENTS.MOLECULES.VC_SELECT.LOADING")
89
+ }}</span>
90
+ </template>
91
+ <template v-else>
92
+ <slot
93
+ name="selected-item"
94
+ v-bind="item"
95
+ >
96
+ <span>{{ getOptionLabel(item.opt) }}</span>
97
+ </slot>
98
+ </template>
93
99
  <VcIcon
94
100
  v-if="!disabled"
95
101
  class="tw-text-[#a9bfd2] tw-ml-2 tw-cursor-pointer hover:tw-text-[color:var(--select-clear-color-hover)]"
@@ -100,12 +106,23 @@
100
106
  </div>
101
107
  </template>
102
108
  <template v-else-if="!multiple">
103
- <slot
104
- name="selected-item"
105
- v-bind="item"
106
- >
107
- {{ getEmittingOptionValue(item.opt) }}
108
- </slot>
109
+ <template v-if="loading">
110
+ <span class="tw-text-[#a5a5a5]">{{
111
+ t("COMPONENTS.MOLECULES.VC_SELECT.LOADING")
112
+ }}</span>
113
+ </template>
114
+ <template v-else>
115
+ <slot
116
+ name="selected-item"
117
+ v-bind="item"
118
+ >
119
+ {{
120
+ loading
121
+ ? t("COMPONENTS.MOLECULES.VC_SELECT.LOADING")
122
+ : getEmittingOptionValue(item.opt)
123
+ }}
124
+ </slot>
125
+ </template>
109
126
  </template>
110
127
  </div>
111
128
  </div>
@@ -140,7 +157,7 @@
140
157
  class="tw-flex tw-items-center tw-flex-nowrap tw-pl-3 tw-text-[color:var(--select-clear-color)]"
141
158
  >
142
159
  <VcIcon
143
- icon="fas fa-spinner tw-animate-spin"
160
+ icon="fas fa-circle-notch tw-animate-spin"
144
161
  size="m"
145
162
  ></VcIcon>
146
163
  </div>
@@ -715,9 +732,17 @@ const dropdownStyle = computed(() => {
715
732
  function getPropValueFn(propValue: OptionProp<Option>, defaultVal: OptionProp<Option>) {
716
733
  const val = propValue !== undefined ? propValue : defaultVal;
717
734
 
718
- return typeof val === "function"
719
- ? val
720
- : (opt: Option) => (opt !== null && typeof opt === "object" && val && val in opt ? opt[val as keyof Option] : opt);
735
+ if (typeof val === "function") {
736
+ return val;
737
+ } else {
738
+ return (opt: Option) => {
739
+ if (opt !== null && typeof opt === "object" && val && val in opt) {
740
+ return opt[val as keyof Option];
741
+ } else {
742
+ return opt;
743
+ }
744
+ };
745
+ }
721
746
  }
722
747
 
723
748
  function getOption(value: Option, valueCache: Option[]) {
@@ -70,7 +70,8 @@ import { useI18n } from "vue-i18n";
70
70
  import { VcIcon, VcLink } from "./../../../../";
71
71
  import { IBladeToolbar } from "./../../../../../../core/types";
72
72
  import { useBladeNavigation } from "./../../../../../../shared";
73
- import { Ref, nextTick, ref, toRef, unref, watch } from "vue";
73
+ import { Ref, ref } from "vue";
74
+ import { watchDebounced } from "@vueuse/core";
74
75
 
75
76
  export interface Props {
76
77
  logo?: string;
@@ -93,22 +94,17 @@ const { t } = useI18n({ useScope: "global" });
93
94
 
94
95
  const { blades } = useBladeNavigation();
95
96
 
96
- let viewTitle: Ref<string>;
97
+ const viewTitle: Ref<string> = ref("");
97
98
  const quantity = ref();
98
99
 
99
- watch(
100
- () => blades,
101
- async (newVal) => {
102
- await nextTick().then(() => {
103
- viewTitle = toRef(
104
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
105
- unref(newVal.value[newVal.value.length - 1]?.props?.navigation?.instance) as Record<string, any>,
106
- "title",
107
- );
108
- quantity.value = newVal.value.length;
109
- });
100
+ watchDebounced(
101
+ blades,
102
+ (newVal) => {
103
+ viewTitle.value = newVal[newVal.length - 1]?.props?.navigation?.instance?.title ?? "";
104
+
105
+ quantity.value = newVal.length;
110
106
  },
111
- { deep: true, immediate: true, flush: "post" },
107
+ { deep: true, immediate: true, flush: "post", debounce: 1 },
112
108
  );
113
109
  </script>
114
110
 
@@ -65,8 +65,9 @@
65
65
  :current-language="currentLanguage"
66
66
  :options="items"
67
67
  :option-label="multilanguage ? 'value' : 'alias'"
68
- option-value="id"
68
+ :option-value="multilanguage ? 'value' : 'alias'"
69
69
  :multivalue="computedProperty.multivalue"
70
+ :loading="loading"
70
71
  @search="onSearch"
71
72
  @close="onClose"
72
73
  ></VcMultivalue>
@@ -82,7 +83,6 @@
82
83
  :required="computedProperty.required"
83
84
  :placeholder="computedProperty.displayName || 'Add value'"
84
85
  :disabled="disabled"
85
- :multilanguage="multilanguage"
86
86
  :current-language="currentLanguage"
87
87
  :loading="loading"
88
88
  ></VcInput>
@@ -98,6 +98,8 @@
98
98
  type="number"
99
99
  :error="!!errors.length"
100
100
  :error-message="errorMessage"
101
+ option-label="value"
102
+ option-value="value"
101
103
  :options="items"
102
104
  ></VcMultivalue>
103
105
  </template>
@@ -109,9 +111,11 @@
109
111
  :required="computedProperty.required"
110
112
  placeholder="Add value"
111
113
  :disabled="disabled"
112
- type="number"
114
+ type="integer"
113
115
  :error="!!errors.length"
114
116
  :error-message="errorMessage"
117
+ option-label="value"
118
+ option-value="value"
115
119
  :options="items"
116
120
  ></VcMultivalue>
117
121
  </template>
@@ -138,7 +142,7 @@
138
142
  :error-message="errorMessage"
139
143
  :label="computedProperty.displayName"
140
144
  clearable
141
- type="number"
145
+ type="integer"
142
146
  step="1"
143
147
  :required="computedProperty.required"
144
148
  :placeholder="computedProperty.placeholder"
@@ -169,7 +173,6 @@
169
173
  :required="computedProperty.required"
170
174
  :placeholder="computedProperty.placeholder"
171
175
  :disabled="disabled"
172
- :multilanguage="multilanguage"
173
176
  :current-language="currentLanguage"
174
177
  ></VcTextarea
175
178
  ></template>
@@ -190,10 +193,11 @@
190
193
 
191
194
  <!-- eslint-disable @typescript-eslint/no-explicit-any -->
192
195
  <script lang="ts" setup generic="T extends { [x: string]: any; id?: string }">
193
- import { ref, onMounted, computed, Ref } from "vue";
196
+ import { ref, onMounted, computed, Ref, watch } from "vue";
194
197
  import { Field } from "vee-validate";
195
198
  import { useI18n } from "vue-i18n";
196
199
  import { VcSelect, VcInput, VcTextarea, VcCheckbox } from "./../../";
200
+ import * as _ from "lodash-es";
197
201
 
198
202
  type IValidationRules = {
199
203
  required?: boolean;
@@ -206,7 +210,11 @@ const props = withDefaults(
206
210
  defineProps<{
207
211
  property: T;
208
212
  modelValue: any;
209
- optionsGetter: (property: T, keyword?: string, locale?: string) => Promise<any[]> | any[] | undefined;
213
+ optionsGetter: (
214
+ propertyId: string,
215
+ keyword?: string,
216
+ locale?: string,
217
+ ) => Promise<any[] | undefined> | any[] | undefined;
210
218
  required: boolean;
211
219
  multivalue?: boolean;
212
220
  multilanguage?: boolean;
@@ -236,15 +244,38 @@ const props = withDefaults(
236
244
  );
237
245
 
238
246
  const emit = defineEmits<{
239
- "update:model-value": [
240
- data: { readonly property: T; readonly value: any; readonly dictionary?: any[]; readonly locale?: string },
241
- ];
247
+ "update:model-value": [data: { readonly value: any; readonly dictionary?: any[]; readonly locale?: string }];
242
248
  }>();
243
249
 
244
250
  const { locale, te, t } = useI18n({ useScope: "global" });
245
251
 
246
252
  const items: Ref<any[]> = ref([]);
247
253
  const loading = ref(false);
254
+ const initialOptions = ref<any[]>([]);
255
+ const internalProperty = ref(props.property) as Ref<typeof props.property>;
256
+ const internalModel = ref(props.modelValue) as Ref<typeof props.modelValue>;
257
+
258
+ watch(
259
+ () => props.property,
260
+ (newVal) => {
261
+ internalProperty.value = _.cloneDeep(newVal);
262
+ },
263
+ {
264
+ deep: true,
265
+ immediate: true,
266
+ },
267
+ );
268
+
269
+ watch(
270
+ () => props.modelValue,
271
+ (newVal) => {
272
+ internalModel.value = _.cloneDeep(newVal);
273
+ },
274
+ {
275
+ deep: true,
276
+ immediate: true,
277
+ },
278
+ );
248
279
 
249
280
  const computedProperty = computed(() => {
250
281
  const rules: IValidationRules = {};
@@ -277,7 +308,7 @@ const computedProperty = computed(() => {
277
308
  dictionary: props.dictionary || false,
278
309
  multivalue: props.multivalue || false,
279
310
  name: props.multilanguage ? props.name + "_" + props.currentLanguage : props.name,
280
- key: props.multilanguage ? props.property.id + "_" + props.currentLanguage : props.property.id,
311
+ key: props.multilanguage ? internalProperty.value.id + "_" + props.currentLanguage : internalProperty.value.id,
281
312
  displayName: propertyDisplayNameLocalized,
282
313
  optionValue: props.optionsValue,
283
314
  optionLabel: optionLabelField,
@@ -288,11 +319,10 @@ const computedProperty = computed(() => {
288
319
 
289
320
  const value = computed({
290
321
  get() {
291
- return props.modelValue;
322
+ return internalModel.value;
292
323
  },
293
324
  set(newValue) {
294
325
  emit("update:model-value", {
295
- property: props.property,
296
326
  value: newValue,
297
327
  dictionary: items.value,
298
328
  locale: props.currentLanguage,
@@ -302,13 +332,14 @@ const value = computed({
302
332
 
303
333
  onMounted(async () => {
304
334
  await getOptions();
335
+ initialOptions.value = items.value;
305
336
  });
306
337
 
307
338
  async function getOptions(keyword: string | undefined = undefined) {
308
- if (props.optionsGetter) {
339
+ if (props.optionsGetter && internalProperty.value.dictionary && internalProperty.value.id) {
309
340
  try {
310
341
  loading.value = true;
311
- const res = await props.optionsGetter(props.property, keyword, props.currentLanguage);
342
+ const res = await props.optionsGetter(internalProperty.value.id, keyword, props.currentLanguage);
312
343
 
313
344
  if (res) {
314
345
  items.value = res;
@@ -324,6 +355,8 @@ async function onSearch(keyword: string) {
324
355
  }
325
356
 
326
357
  async function onClose() {
327
- getOptions();
358
+ if (initialOptions.value.length) {
359
+ items.value = initialOptions.value;
360
+ }
328
361
  }
329
362
  </script>
@@ -116,7 +116,7 @@
116
116
  class="tw-text-right tw-truncate"
117
117
  :class="cell.class"
118
118
  >
119
- {{ Number(value).toFixed(0) }}
119
+ {{ typeof Number(value) === "number" && Number(value) >= 0 ? Number(value).toFixed(0) : "N/A" }}
120
120
  </div>
121
121
 
122
122
  <!-- Link cell -->
package/ui/types/index.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { MaybeRef } from "vue";
1
2
  import * as components from "./../components";
2
3
 
3
4
  // Declare all components globally
@@ -12,7 +13,7 @@ declare module "vue" {
12
13
 
13
14
  export interface Breadcrumbs {
14
15
  icon?: string;
15
- title: string;
16
- clickHandler?: (id: string) => void | Promise<void>;
16
+ title: MaybeRef<string | undefined>;
17
+ clickHandler?: (id: string) => void | boolean | Promise<void | boolean>;
17
18
  id: string;
18
19
  }