@aziontech/webkit 0.0.1

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/package.json +46 -0
  2. package/src/core/field-auto-complete/field-auto-complete.vue +121 -0
  3. package/src/core/field-auto-complete/field-auto-complete.vue.d.ts +107 -0
  4. package/src/core/field-auto-complete/field-auto-complete.vue.d.ts.map +1 -0
  5. package/src/core/field-auto-complete/package.json +11 -0
  6. package/src/core/field-checkbox-block/field-checkbox-block.vue +106 -0
  7. package/src/core/field-checkbox-block/field-checkbox-block.vue.d.ts +111 -0
  8. package/src/core/field-checkbox-block/field-checkbox-block.vue.d.ts.map +1 -0
  9. package/src/core/field-checkbox-block/package.json +11 -0
  10. package/src/core/field-dropdown/field-dropdown.vue +240 -0
  11. package/src/core/field-dropdown/field-dropdown.vue.d.ts +203 -0
  12. package/src/core/field-dropdown/field-dropdown.vue.d.ts.map +1 -0
  13. package/src/core/field-dropdown/package.json +11 -0
  14. package/src/core/field-dropdown-icon/field-dropdown-icon.vue +129 -0
  15. package/src/core/field-dropdown-icon/field-dropdown-icon.vue.d.ts +111 -0
  16. package/src/core/field-dropdown-icon/field-dropdown-icon.vue.d.ts.map +1 -0
  17. package/src/core/field-dropdown-icon/package.json +11 -0
  18. package/src/core/field-dropdown-lazy-loader/field-dropdown-lazy-loader.vue +631 -0
  19. package/src/core/field-dropdown-lazy-loader/field-dropdown-lazy-loader.vue.d.ts +196 -0
  20. package/src/core/field-dropdown-lazy-loader/field-dropdown-lazy-loader.vue.d.ts.map +1 -0
  21. package/src/core/field-dropdown-lazy-loader/package.json +11 -0
  22. package/src/core/field-dropdown-lazy-loader-dynamic/field-dropdown-lazy-loader-dynamic.vue +426 -0
  23. package/src/core/field-dropdown-lazy-loader-dynamic/field-dropdown-lazy-loader-dynamic.vue.d.ts +158 -0
  24. package/src/core/field-dropdown-lazy-loader-dynamic/field-dropdown-lazy-loader-dynamic.vue.d.ts.map +1 -0
  25. package/src/core/field-dropdown-lazy-loader-dynamic/package.json +11 -0
  26. package/src/core/field-dropdown-lazy-loader-with-filter/field-dropdown-lazy-loader-with-filter.vue +527 -0
  27. package/src/core/field-dropdown-lazy-loader-with-filter/field-dropdown-lazy-loader-with-filter.vue.d.ts +203 -0
  28. package/src/core/field-dropdown-lazy-loader-with-filter/field-dropdown-lazy-loader-with-filter.vue.d.ts.map +1 -0
  29. package/src/core/field-dropdown-lazy-loader-with-filter/package.json +11 -0
  30. package/src/core/field-dropdown-multi-select-lazy-loader/field-dropdown-multi-select-lazy-loader.vue +439 -0
  31. package/src/core/field-dropdown-multi-select-lazy-loader/field-dropdown-multi-select-lazy-loader.vue.d.ts +162 -0
  32. package/src/core/field-dropdown-multi-select-lazy-loader/field-dropdown-multi-select-lazy-loader.vue.d.ts.map +1 -0
  33. package/src/core/field-dropdown-multi-select-lazy-loader/package.json +11 -0
  34. package/src/core/field-group-checkbox/field-group-checkbox.vue +102 -0
  35. package/src/core/field-group-checkbox/field-group-checkbox.vue.d.ts +87 -0
  36. package/src/core/field-group-checkbox/field-group-checkbox.vue.d.ts.map +1 -0
  37. package/src/core/field-group-checkbox/package.json +11 -0
  38. package/src/core/field-group-radio/field-group-radio.vue +149 -0
  39. package/src/core/field-group-radio/field-group-radio.vue.d.ts +99 -0
  40. package/src/core/field-group-radio/field-group-radio.vue.d.ts.map +1 -0
  41. package/src/core/field-group-radio/package.json +11 -0
  42. package/src/core/field-group-switch/field-group-switch.vue +121 -0
  43. package/src/core/field-group-switch/field-group-switch.vue.d.ts +87 -0
  44. package/src/core/field-group-switch/field-group-switch.vue.d.ts.map +1 -0
  45. package/src/core/field-group-switch/package.json +11 -0
  46. package/src/core/field-input-group/field-input-group.vue +111 -0
  47. package/src/core/field-input-group/field-input-group.vue.d.ts +87 -0
  48. package/src/core/field-input-group/field-input-group.vue.d.ts.map +1 -0
  49. package/src/core/field-input-group/package.json +11 -0
  50. package/src/core/field-multi-select/field-multi-select.vue +167 -0
  51. package/src/core/field-multi-select/field-multi-select.vue.d.ts +136 -0
  52. package/src/core/field-multi-select/field-multi-select.vue.d.ts.map +1 -0
  53. package/src/core/field-multi-select/package.json +11 -0
  54. package/src/core/field-number/field-number.vue +144 -0
  55. package/src/core/field-number/field-number.vue.d.ts +132 -0
  56. package/src/core/field-number/field-number.vue.d.ts.map +1 -0
  57. package/src/core/field-number/package.json +11 -0
  58. package/src/core/field-phone-number/field-phone-number.vue +151 -0
  59. package/src/core/field-phone-number/field-phone-number.vue.d.ts +76 -0
  60. package/src/core/field-phone-number/field-phone-number.vue.d.ts.map +1 -0
  61. package/src/core/field-phone-number/package.json +11 -0
  62. package/src/core/field-phone-number-country/field-phone-number-country.vue +60 -0
  63. package/src/core/field-phone-number-country/field-phone-number-country.vue.d.ts +18 -0
  64. package/src/core/field-phone-number-country/field-phone-number-country.vue.d.ts.map +1 -0
  65. package/src/core/field-phone-number-country/package.json +11 -0
  66. package/src/core/field-pick-list/field-pick-list.vue +285 -0
  67. package/src/core/field-pick-list/field-pick-list.vue.d.ts +43 -0
  68. package/src/core/field-pick-list/field-pick-list.vue.d.ts.map +1 -0
  69. package/src/core/field-pick-list/package.json +11 -0
  70. package/src/core/field-radio-block/field-radio-block.vue +108 -0
  71. package/src/core/field-radio-block/field-radio-block.vue.d.ts +115 -0
  72. package/src/core/field-radio-block/field-radio-block.vue.d.ts.map +1 -0
  73. package/src/core/field-radio-block/package.json +11 -0
  74. package/src/core/field-switch/field-switch.vue +41 -0
  75. package/src/core/field-switch/field-switch.vue.d.ts +33 -0
  76. package/src/core/field-switch/field-switch.vue.d.ts.map +1 -0
  77. package/src/core/field-switch/package.json +11 -0
  78. package/src/core/field-switch-block/field-switch-block.vue +123 -0
  79. package/src/core/field-switch-block/field-switch-block.vue.d.ts +123 -0
  80. package/src/core/field-switch-block/field-switch-block.vue.d.ts.map +1 -0
  81. package/src/core/field-switch-block/package.json +11 -0
  82. package/src/core/field-text/field-text.vue +128 -0
  83. package/src/core/field-text/field-text.vue.d.ts +108 -0
  84. package/src/core/field-text/field-text.vue.d.ts.map +1 -0
  85. package/src/core/field-text/package.json +11 -0
  86. package/src/core/field-text-area/field-text-area.vue +178 -0
  87. package/src/core/field-text-area/field-text-area.vue.d.ts +142 -0
  88. package/src/core/field-text-area/field-text-area.vue.d.ts.map +1 -0
  89. package/src/core/field-text-area/package.json +11 -0
  90. package/src/core/field-text-icon/field-text-icon.vue +127 -0
  91. package/src/core/field-text-icon/field-text-icon.vue.d.ts +100 -0
  92. package/src/core/field-text-icon/field-text-icon.vue.d.ts.map +1 -0
  93. package/src/core/field-text-icon/package.json +11 -0
  94. package/src/core/field-text-password/field-text-password.vue +127 -0
  95. package/src/core/field-text-password/field-text-password.vue.d.ts +108 -0
  96. package/src/core/field-text-password/field-text-password.vue.d.ts.map +1 -0
  97. package/src/core/field-text-password/package.json +11 -0
  98. package/src/core/label/label.vue +35 -0
  99. package/src/core/label/label.vue.d.ts +24 -0
  100. package/src/core/label/label.vue.d.ts.map +1 -0
  101. package/src/core/label/package.json +11 -0
  102. package/src/core/selector-block/package.json +11 -0
  103. package/src/core/selector-block/selector-block.vue +128 -0
  104. package/src/core/selector-block/selector-block.vue.d.ts +99 -0
  105. package/src/core/selector-block/selector-block.vue.d.ts.map +1 -0
@@ -0,0 +1,203 @@
1
+ declare const _default: typeof __VLS_export;
2
+ export default _default;
3
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
4
+ type __VLS_WithSlots<T, S> = T & (new () => {
5
+ $slots: S;
6
+ });
7
+ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
8
+ value: {
9
+ type: (StringConstructor | NumberConstructor)[];
10
+ default: string;
11
+ };
12
+ name: {
13
+ type: StringConstructor;
14
+ required: true;
15
+ };
16
+ label: {
17
+ type: StringConstructor;
18
+ default: string;
19
+ };
20
+ placeholder: {
21
+ type: StringConstructor;
22
+ default: string;
23
+ };
24
+ description: {
25
+ type: StringConstructor;
26
+ default: string;
27
+ };
28
+ optionLabel: {
29
+ type: StringConstructor;
30
+ default: string;
31
+ };
32
+ optionValue: {
33
+ type: StringConstructor;
34
+ default: string;
35
+ };
36
+ moreOptions: {
37
+ type: ArrayConstructor;
38
+ default: null;
39
+ };
40
+ optionDisabled: {
41
+ type: (StringConstructor | FunctionConstructor)[];
42
+ default: string;
43
+ };
44
+ service: {
45
+ type: FunctionConstructor;
46
+ required: true;
47
+ };
48
+ loadService: {
49
+ type: FunctionConstructor;
50
+ required: true;
51
+ };
52
+ enableWorkaroundLabelToDisabledOptions: {
53
+ type: BooleanConstructor;
54
+ default: boolean;
55
+ };
56
+ enableClearOption: {
57
+ type: BooleanConstructor;
58
+ default: boolean;
59
+ };
60
+ disableEmitFirstRender: {
61
+ type: BooleanConstructor;
62
+ default: boolean;
63
+ };
64
+ keyToFilter: {
65
+ type: StringConstructor;
66
+ default: string;
67
+ };
68
+ valuesToFilter: {
69
+ type: ArrayConstructor;
70
+ default: () => never[];
71
+ };
72
+ showGroup: {
73
+ type: BooleanConstructor;
74
+ default: boolean;
75
+ };
76
+ optionGroupLabel: {
77
+ type: StringConstructor;
78
+ default: string;
79
+ };
80
+ optionGroupChildren: {
81
+ type: StringConstructor;
82
+ default: string;
83
+ };
84
+ defaultGroup: {
85
+ type: StringConstructor;
86
+ default: string;
87
+ };
88
+ }>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
89
+ onBlur: (...args: any[]) => void;
90
+ onChange: (...args: any[]) => void;
91
+ onSelectOption: (...args: any[]) => void;
92
+ onAccessDenied: (...args: any[]) => void;
93
+ }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
94
+ value: {
95
+ type: (StringConstructor | NumberConstructor)[];
96
+ default: string;
97
+ };
98
+ name: {
99
+ type: StringConstructor;
100
+ required: true;
101
+ };
102
+ label: {
103
+ type: StringConstructor;
104
+ default: string;
105
+ };
106
+ placeholder: {
107
+ type: StringConstructor;
108
+ default: string;
109
+ };
110
+ description: {
111
+ type: StringConstructor;
112
+ default: string;
113
+ };
114
+ optionLabel: {
115
+ type: StringConstructor;
116
+ default: string;
117
+ };
118
+ optionValue: {
119
+ type: StringConstructor;
120
+ default: string;
121
+ };
122
+ moreOptions: {
123
+ type: ArrayConstructor;
124
+ default: null;
125
+ };
126
+ optionDisabled: {
127
+ type: (StringConstructor | FunctionConstructor)[];
128
+ default: string;
129
+ };
130
+ service: {
131
+ type: FunctionConstructor;
132
+ required: true;
133
+ };
134
+ loadService: {
135
+ type: FunctionConstructor;
136
+ required: true;
137
+ };
138
+ enableWorkaroundLabelToDisabledOptions: {
139
+ type: BooleanConstructor;
140
+ default: boolean;
141
+ };
142
+ enableClearOption: {
143
+ type: BooleanConstructor;
144
+ default: boolean;
145
+ };
146
+ disableEmitFirstRender: {
147
+ type: BooleanConstructor;
148
+ default: boolean;
149
+ };
150
+ keyToFilter: {
151
+ type: StringConstructor;
152
+ default: string;
153
+ };
154
+ valuesToFilter: {
155
+ type: ArrayConstructor;
156
+ default: () => never[];
157
+ };
158
+ showGroup: {
159
+ type: BooleanConstructor;
160
+ default: boolean;
161
+ };
162
+ optionGroupLabel: {
163
+ type: StringConstructor;
164
+ default: string;
165
+ };
166
+ optionGroupChildren: {
167
+ type: StringConstructor;
168
+ default: string;
169
+ };
170
+ defaultGroup: {
171
+ type: StringConstructor;
172
+ default: string;
173
+ };
174
+ }>> & Readonly<{
175
+ onOnBlur?: ((...args: any[]) => any) | undefined;
176
+ onOnChange?: ((...args: any[]) => any) | undefined;
177
+ onOnSelectOption?: ((...args: any[]) => any) | undefined;
178
+ onOnAccessDenied?: ((...args: any[]) => any) | undefined;
179
+ }>, {
180
+ value: string | number;
181
+ label: string;
182
+ placeholder: string;
183
+ description: string;
184
+ optionLabel: string;
185
+ optionDisabled: string | Function;
186
+ optionGroupLabel: string;
187
+ optionGroupChildren: string;
188
+ optionValue: string;
189
+ enableWorkaroundLabelToDisabledOptions: boolean;
190
+ moreOptions: unknown[];
191
+ enableClearOption: boolean;
192
+ disableEmitFirstRender: boolean;
193
+ keyToFilter: string;
194
+ valuesToFilter: unknown[];
195
+ showGroup: boolean;
196
+ defaultGroup: string;
197
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
198
+ type __VLS_Slots = {
199
+ footer?: ((props: {}) => any) | undefined;
200
+ } & {
201
+ description?: ((props: {}) => any) | undefined;
202
+ };
203
+ //# sourceMappingURL=field-dropdown-lazy-loader-with-filter.vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-dropdown-lazy-loader-with-filter.vue.d.ts","sourceRoot":"","sources":["field-dropdown-lazy-loader-with-filter.vue"],"names":[],"mappings":"wBAixCqB,OAAO,YAAY;;AADxC,4BAA2B,eAAe,CAAC,OAAO,UAAU,EAAE,WAAW,CAAC,CAAC;qBAEtD,CAAC,EAAE,CAAC;;;AAvFzB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6EAoFG"}
@@ -0,0 +1,11 @@
1
+ {
2
+ "main": "./field-dropdown-lazy-loader-with-filter.vue",
3
+ "module": "./field-dropdown-lazy-loader-with-filter.vue",
4
+ "types": "./field-dropdown-lazy-loader-with-filter.vue.d.ts",
5
+ "browser": {
6
+ "./sfc": "./field-dropdown-lazy-loader-with-filter.vue"
7
+ },
8
+ "sideEffects": [
9
+ "*.vue"
10
+ ]
11
+ }
@@ -0,0 +1,439 @@
1
+ <template>
2
+ <LabelBlock
3
+ v-if="props.label"
4
+ :for="props.name"
5
+ :label="props.label"
6
+ :isRequired="$attrs.required"
7
+ :data-testid="customTestId.label"
8
+ />
9
+ <MultiSelect
10
+ :id="name"
11
+ :name="props.name"
12
+ :loading="loading"
13
+ v-model="inputValue"
14
+ :options="data"
15
+ :optionLabel="props.optionLabel"
16
+ :optionDisabled="props.optionDisabled"
17
+ :optionValue="props.optionValue"
18
+ :placeholder="props.placeholder"
19
+ :showClear="props.enableClearOption"
20
+ @change="emitChange"
21
+ @blur="emitBlur"
22
+ :class="errorMessage ? 'p-invalid' : ''"
23
+ v-bind="$attrs"
24
+ class="w-full md:w-80"
25
+ display="chip"
26
+ :pt="{
27
+ clearIcon: {
28
+ 'data-testid': customTestId.clearIcon
29
+ },
30
+ filterInput: {
31
+ class: 'w-full',
32
+ 'data-testid': customTestId.filterInput
33
+ },
34
+ trigger: {
35
+ 'data-testid': customTestId.trigger
36
+ },
37
+ loadingIcon: {
38
+ 'data-testid': customTestId.loadingIcon
39
+ }
40
+ }"
41
+ :data-testid="customTestId.multiselect"
42
+ :virtualScrollerOptions="VIRTUAL_SCROLLER_CONFIG"
43
+ >
44
+ <template
45
+ v-if="enableCustomLabel"
46
+ #value="slotProps"
47
+ >
48
+ <span :data-testid="customTestId.value">
49
+ {{ getLabelsForSelectedValues(slotProps.value) }}
50
+ </span>
51
+ </template>
52
+ <template #header>
53
+ <div class="p-2 flex">
54
+ <div class="p-inputgroup">
55
+ <InputText
56
+ type="text"
57
+ v-model="search"
58
+ placeholder="Search"
59
+ class="w-full rounded-r-none"
60
+ ref="focusSearch"
61
+ :data-testid="customTestId.search"
62
+ />
63
+ <span
64
+ class="p-inputgroup-addon"
65
+ @click="searchFilter"
66
+ >
67
+ <i class="pi pi-search"></i>
68
+ </span>
69
+ </div>
70
+ </div>
71
+ </template>
72
+ <template #footer>
73
+ <slot name="footer" />
74
+ </template>
75
+ </MultiSelect>
76
+ <small
77
+ v-if="errorMessage"
78
+ :data-testid="customTestId.error"
79
+ class="p-error text-xs font-normal leading-tight"
80
+ >
81
+ {{ errorMessage }}
82
+ </small>
83
+ <small
84
+ class="text-xs text-color-secondary font-normal leading-5"
85
+ :data-testid="customTestId.description"
86
+ v-if="props.description || hasDescriptionSlot"
87
+ >
88
+ <slot name="description">
89
+ {{ props.description }}
90
+ </slot>
91
+ </small>
92
+ </template>
93
+ <script setup>
94
+ import MultiSelect from 'primevue/multiselect'
95
+ import InputText from 'primevue/inputtext'
96
+ import { useField } from 'vee-validate'
97
+ import { computed, toRef, useSlots, useAttrs, ref, onMounted, watchEffect, watch } from 'vue'
98
+ import { watchDebounced } from '@vueuse/core'
99
+ import LabelBlock from '../label'
100
+
101
+ const props = defineProps({
102
+ value: {
103
+ type: Array,
104
+ default: () => []
105
+ },
106
+ name: {
107
+ type: String,
108
+ required: true
109
+ },
110
+ label: {
111
+ type: String,
112
+ default: ''
113
+ },
114
+ placeholder: {
115
+ type: String,
116
+ default: ''
117
+ },
118
+ description: {
119
+ type: String,
120
+ default: ''
121
+ },
122
+ optionLabel: {
123
+ type: String,
124
+ default: ''
125
+ },
126
+ optionValue: {
127
+ type: String,
128
+ default: ''
129
+ },
130
+ moreOptions: {
131
+ type: Array,
132
+ default: null
133
+ },
134
+ optionDisabled: {
135
+ type: [String, Function],
136
+ default: ''
137
+ },
138
+ service: {
139
+ type: [Function, String],
140
+ required: true
141
+ },
142
+ loadService: {
143
+ type: [Function, String],
144
+ required: true
145
+ },
146
+ enableWorkaroundLabelToDisabledOptions: {
147
+ type: Boolean,
148
+ default: false
149
+ },
150
+ enableClearOption: {
151
+ type: Boolean,
152
+ default: false
153
+ },
154
+ disableEmitFirstRender: {
155
+ type: Boolean,
156
+ default: false
157
+ },
158
+ validationRules: {
159
+ type: Object,
160
+ default: () => ({})
161
+ }
162
+ })
163
+
164
+ const emit = defineEmits(['onBlur', 'onChange', 'onSelectOption', 'onAccessDenied', 'onClear'])
165
+ const PAGE_INCREMENT = 1
166
+ const PAGE_SIZE = 100
167
+ const INITIAL_PAGE = 1
168
+ const SEARCH_DEBOUNCE = 500
169
+ const SEARCH_MAX_WAIT = 1000
170
+ const NUMBER_OF_CHARACTERS_MIN_FOR_SEARCH = 3
171
+ const NUMBER_OF_CHARACTERS_TO_RESET_SEARCH = 0
172
+ const PERMISSION_DENIED = 'You do not have permission'
173
+
174
+ const hasNoPermission = ref(false)
175
+ const name = toRef(props, 'name')
176
+ const slots = useSlots()
177
+ const data = ref([])
178
+ const loading = ref(false)
179
+ const totalCount = ref(0)
180
+ const page = ref(INITIAL_PAGE)
181
+ const search = ref('')
182
+ const focusSearch = ref(null)
183
+ const disableEmitInit = ref(props.disableEmitFirstRender)
184
+
185
+ onMounted(async () => {
186
+ await fetchData()
187
+ })
188
+
189
+ const hasDescriptionSlot = !!slots.description
190
+
191
+ const { value: inputValue, errorMessage } = useField(name, props.validationRules, {
192
+ initialValue: props.value
193
+ })
194
+
195
+ const handleLazyLoad = async (event) => {
196
+ const { last } = event
197
+ const numberOfPage = Math.ceil(totalCount.value / PAGE_SIZE)
198
+ const goRequest = last >= data.value?.length
199
+ if (page.value < numberOfPage && goRequest && !loading.value) {
200
+ page.value += PAGE_INCREMENT
201
+ await fetchData(page.value)
202
+ }
203
+ }
204
+
205
+ const emitBlur = () => {
206
+ emit('onBlur')
207
+ }
208
+
209
+ const emitChange = () => {
210
+ const selectedOptions =
211
+ inputValue.value
212
+ ?.map((value) => data.value.find((option) => option[props.optionValue] === value))
213
+ .filter(Boolean) || []
214
+
215
+ emit('onChange', inputValue.value)
216
+
217
+ if (!inputValue.value || inputValue.value.length === 0) {
218
+ emit('onClear')
219
+ }
220
+
221
+ selectedOptions.forEach((option) => {
222
+ emit('onSelectOption', option)
223
+ })
224
+ }
225
+
226
+ const preventValueSetWithoutPermission = () => {
227
+ if (!Array.isArray(props.value)) return
228
+
229
+ const valueItems = props.value.map((val) => ({
230
+ [props.optionValue]: val,
231
+ [props.optionLabel]: val
232
+ }))
233
+
234
+ data.value = valueItems
235
+ }
236
+
237
+ const getLabelsForSelectedValues = (selectedValues) => {
238
+ if (!Array.isArray(selectedValues)) return ''
239
+
240
+ return selectedValues
241
+ .map((value) => {
242
+ const result = props.options.find((option) => option.value === value)
243
+ return result?.label || value
244
+ })
245
+ .join(', ')
246
+ }
247
+
248
+ const fetchData = async (currentPage = 1) => {
249
+ try {
250
+ loading.value = true
251
+
252
+ if (currentPage === INITIAL_PAGE) {
253
+ data.value = []
254
+ }
255
+
256
+ const response = await props.service({
257
+ pageSize: PAGE_SIZE,
258
+ page: currentPage,
259
+ search: search.value,
260
+ ordering: 'name'
261
+ })
262
+
263
+ totalCount.value = response.count
264
+
265
+ let results = response.body?.map((item) => {
266
+ return {
267
+ [props.optionLabel]: item.name,
268
+ [props.optionValue]: item.id,
269
+ ...props?.moreOptions?.reduce(
270
+ (additionalFields, option) => ({
271
+ ...additionalFields,
272
+ [option]: item[option]
273
+ }),
274
+ {}
275
+ )
276
+ }
277
+ })
278
+
279
+ if (currentPage === INITIAL_PAGE) {
280
+ data.value = results ? results : []
281
+ } else {
282
+ const uniqueResults = results.filter(
283
+ (newItem) =>
284
+ !data.value.some(
285
+ (existingItem) => existingItem[props.optionValue] === newItem[props.optionValue]
286
+ )
287
+ )
288
+ data.value = [...data.value, ...uniqueResults]
289
+ }
290
+
291
+ if (
292
+ currentPage === INITIAL_PAGE &&
293
+ props.value &&
294
+ props.value.length > 0 &&
295
+ search.value === ''
296
+ ) {
297
+ await checkValuesInList(props.value)
298
+ }
299
+ } catch (error) {
300
+ if (error.includes && error.includes(PERMISSION_DENIED)) {
301
+ hasNoPermission.value = true
302
+ preventValueSetWithoutPermission()
303
+ }
304
+ emit('onAccessDenied')
305
+ } finally {
306
+ loading.value = false
307
+ }
308
+ }
309
+
310
+ const loadSelectedValue = async (id) => {
311
+ if (!id) return
312
+
313
+ try {
314
+ loading.value = true
315
+ const results = await props.loadService({ id })
316
+
317
+ if (!results) return
318
+
319
+ const newOption = {
320
+ [props.optionLabel]: results.name,
321
+ [props.optionValue]: results.id,
322
+ ...props?.moreOptions?.reduce(
323
+ (additionalFields, option) => ({
324
+ ...additionalFields,
325
+ [option]: results[option]
326
+ }),
327
+ {}
328
+ )
329
+ }
330
+
331
+ const optionExists = data.value.some(
332
+ (item) => item[props.optionValue] === newOption[props.optionValue]
333
+ )
334
+
335
+ if (!optionExists) {
336
+ data.value = [newOption, ...data.value]
337
+ }
338
+
339
+ if (disableEmitInit.value) {
340
+ disableEmitInit.value = false
341
+ return
342
+ }
343
+ } finally {
344
+ loading.value = false
345
+ }
346
+ }
347
+
348
+ const checkValuesInList = async (values) => {
349
+ if (!Array.isArray(values)) return
350
+
351
+ for (const value of values) {
352
+ const existItemInList = data.value?.some((item) => item[props.optionValue] === value)
353
+ if (!existItemInList) {
354
+ await loadSelectedValue(value)
355
+ }
356
+ }
357
+
358
+ if (!disableEmitInit.value) {
359
+ emitChange()
360
+ }
361
+ }
362
+
363
+ const searchFilter = () => {
364
+ page.value = INITIAL_PAGE
365
+ fetchData()
366
+ }
367
+
368
+ const enableCustomLabel = computed(() => {
369
+ return (
370
+ props.enableWorkaroundLabelToDisabledOptions &&
371
+ !!inputValue.value &&
372
+ inputValue.value.length > 0
373
+ )
374
+ })
375
+
376
+ const attrs = useAttrs()
377
+ const customTestId = computed(() => {
378
+ const id = attrs['data-testid'] || 'field-multiselect'
379
+ return {
380
+ label: `${id}__label`,
381
+ multiselect: `${id}__multiselect`,
382
+ value: `${id}__value`,
383
+ clearIcon: `${id}__clear-icon`,
384
+ description: `${id}__description`,
385
+ error: `${id}__error-message`,
386
+ filterInput: `${id}__dropdown-filter-input`,
387
+ trigger: `${id}__dropdown-trigger`,
388
+ loadingIcon: `${id}__loading-icon`,
389
+ search: `${id}__dropdown-search`
390
+ }
391
+ })
392
+
393
+ watch(
394
+ () => props.value,
395
+ (newValue) => {
396
+ if (hasNoPermission.value) {
397
+ preventValueSetWithoutPermission()
398
+ }
399
+ checkValuesInList(newValue)
400
+ }
401
+ )
402
+
403
+ watchDebounced(
404
+ search,
405
+ () => {
406
+ if (
407
+ search.value.length >= NUMBER_OF_CHARACTERS_MIN_FOR_SEARCH ||
408
+ search.value.length === NUMBER_OF_CHARACTERS_TO_RESET_SEARCH
409
+ ) {
410
+ searchFilter()
411
+ }
412
+ },
413
+ { debounce: SEARCH_DEBOUNCE, maxWait: SEARCH_MAX_WAIT }
414
+ )
415
+
416
+ watchEffect(() => {
417
+ if (focusSearch.value) {
418
+ focusSearch.value.$el.focus()
419
+ }
420
+ })
421
+
422
+ const VIRTUAL_SCROLLER_CONFIG = {
423
+ lazy: true,
424
+ onLazyLoad: handleLazyLoad,
425
+ itemSize: 38,
426
+ showLoader: true,
427
+ loading
428
+ }
429
+
430
+ const refreshData = async () => {
431
+ page.value = INITIAL_PAGE
432
+ search.value = ''
433
+ await fetchData()
434
+ }
435
+
436
+ defineExpose({
437
+ refreshData
438
+ })
439
+ </script>