@winchsa/ui 0.1.35 → 0.1.37
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/dist/components/forms/AutocompleteInput.d.vue.ts +5 -3
- package/dist/components/forms/AutocompleteInput.vue +161 -178
- package/dist/components/forms/AutocompleteInput.vue.d.ts +5 -3
- package/dist/components/forms/LicensePlateInput.vue +15 -2
- package/dist/components/table/DataTable.vue +1 -1
- package/dist/components/table/EditableDataTable.vue +13 -35
- package/dist/components/table/EditableDataTableRow.vue +17 -2
- package/dist/styles/core/template/_components.scss +12 -4
- package/dist/styles/core/template/index.css +11 -2
- package/dist/types.d.ts +1 -0
- package/dist/utils/formValidation.d.ts +2 -1
- package/dist/utils/formValidation.js +11 -1
- package/dist/utils/formValidation.mjs +10 -1
- package/dist/utils/utils.d.ts +2 -0
- package/dist/utils/utils.js +18 -2
- package/dist/utils/utils.mjs +14 -0
- package/package.json +1 -1
|
@@ -35,12 +35,14 @@ type __VLS_Props = {
|
|
|
35
35
|
isLoading?: boolean;
|
|
36
36
|
disableIfEmpty?: boolean;
|
|
37
37
|
clearable?: boolean;
|
|
38
|
+
showNoOptions?: boolean;
|
|
39
|
+
showNoResults?: boolean;
|
|
38
40
|
};
|
|
39
|
-
declare var
|
|
41
|
+
declare var __VLS_69: string | number, __VLS_70: any, __VLS_134: string | number, __VLS_135: any;
|
|
40
42
|
type __VLS_Slots = {} & {
|
|
41
|
-
[K in NonNullable<typeof
|
|
43
|
+
[K in NonNullable<typeof __VLS_69>]?: (props: typeof __VLS_70) => any;
|
|
42
44
|
} & {
|
|
43
|
-
[K in NonNullable<typeof
|
|
45
|
+
[K in NonNullable<typeof __VLS_134>]?: (props: typeof __VLS_135) => any;
|
|
44
46
|
};
|
|
45
47
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
46
48
|
records: Ref<{
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import MultiSelect from "vue-multiselect";
|
|
3
|
-
import { ref, computed, watch, useAttrs
|
|
3
|
+
import { ref, computed, watch, useAttrs } from "vue";
|
|
4
4
|
import { useI18n } from "vue-i18n";
|
|
5
5
|
import { VLabel, VValidation, VListItem, VMessages, VIcon } from "vuetify/components";
|
|
6
6
|
import { client } from "../../utils/client";
|
|
7
|
-
import { generateUniqueId } from "../../utils/utils";
|
|
7
|
+
import { generateUniqueId, searchArabicText } from "../../utils/utils";
|
|
8
8
|
import { buildQueryString } from "../../utils/queryParams";
|
|
9
9
|
import LoadingBar from "../LoadingBar.vue";
|
|
10
10
|
const { t } = useI18n();
|
|
@@ -43,8 +43,11 @@ const props = defineProps({
|
|
|
43
43
|
fetchEnabled: { type: Boolean, required: false, default: true },
|
|
44
44
|
isLoading: { type: Boolean, required: false, default: false },
|
|
45
45
|
disableIfEmpty: { type: Boolean, required: false, default: false },
|
|
46
|
-
clearable: { type: Boolean, required: false, default: true }
|
|
46
|
+
clearable: { type: Boolean, required: false, default: true },
|
|
47
|
+
showNoOptions: { type: Boolean, required: false, default: true },
|
|
48
|
+
showNoResults: { type: Boolean, required: false, default: true }
|
|
47
49
|
});
|
|
50
|
+
const emits = defineEmits(["update:model-value"]);
|
|
48
51
|
const defaultOptions = ref(props.options ?? []);
|
|
49
52
|
const displayedOptions = ref(props.options ?? []);
|
|
50
53
|
const loadedValuesHaveBeenSet = ref(false);
|
|
@@ -52,10 +55,8 @@ const loading = ref(false);
|
|
|
52
55
|
const showTeleport = ref(false);
|
|
53
56
|
const search = ref("");
|
|
54
57
|
const inputRef = ref({});
|
|
55
|
-
const teleportRef = ref(null);
|
|
56
58
|
const errorState = ref(false);
|
|
57
59
|
const isOpen = ref(false);
|
|
58
|
-
const emits = defineEmits(["update:model-value"]);
|
|
59
60
|
const value = computed({
|
|
60
61
|
get() {
|
|
61
62
|
return props.modelValue;
|
|
@@ -64,9 +65,7 @@ const value = computed({
|
|
|
64
65
|
emits("update:model-value", value2);
|
|
65
66
|
}
|
|
66
67
|
});
|
|
67
|
-
const isLoading = computed(() =>
|
|
68
|
-
return props.isLoading || loading.value;
|
|
69
|
-
});
|
|
68
|
+
const isLoading = computed(() => props.isLoading || loading.value);
|
|
70
69
|
const params = computed(() => buildQueryString(props.params));
|
|
71
70
|
const elementId = computed(() => {
|
|
72
71
|
const attrs = useAttrs();
|
|
@@ -74,10 +73,59 @@ const elementId = computed(() => {
|
|
|
74
73
|
return _elementIdToken ? `autocomplete-input-${_elementIdToken}-${guid}` : `autocomplete-input-${guid}`;
|
|
75
74
|
});
|
|
76
75
|
const internalPlaceholder = computed(() => {
|
|
77
|
-
return props.placeholder
|
|
78
|
-
|
|
79
|
-
|
|
76
|
+
return props.placeholder ?? t("inputs.placeholder_select", { name: props.label ? t(props.label) : "" });
|
|
77
|
+
});
|
|
78
|
+
const hasValue = computed(() => Array.isArray(value.value) ? value.value.length > 0 : !!value.value);
|
|
79
|
+
const hasError = computed(() => (validationIsValid) => {
|
|
80
|
+
return props.error || validationIsValid === false || errorState.value;
|
|
80
81
|
});
|
|
82
|
+
const filteredOptions = computed(() => {
|
|
83
|
+
if (!search.value) {
|
|
84
|
+
return displayedOptions.value;
|
|
85
|
+
}
|
|
86
|
+
return displayedOptions.value?.map((entry) => {
|
|
87
|
+
if (props.grouped) {
|
|
88
|
+
const matchingChildren = entry?.children?.filter((child) => {
|
|
89
|
+
const childValue = getOptionValue(child);
|
|
90
|
+
return searchArabicText(childValue, search.value);
|
|
91
|
+
});
|
|
92
|
+
return matchingChildren?.length ? { ...entry, children: matchingChildren } : null;
|
|
93
|
+
}
|
|
94
|
+
const entryValue = getOptionValue(entry);
|
|
95
|
+
return searchArabicText(entryValue, search.value) ? entry : null;
|
|
96
|
+
}).filter(Boolean);
|
|
97
|
+
});
|
|
98
|
+
const disableIfNoOptions = computed(() => filteredOptions.value.length === 0 && props.disableIfEmpty);
|
|
99
|
+
const sharedMultiSelectProps = computed(() => ({
|
|
100
|
+
options: filteredOptions.value,
|
|
101
|
+
multiple: props.multiple,
|
|
102
|
+
closeOnSelect: !props.multiple,
|
|
103
|
+
searchable: props.searchable,
|
|
104
|
+
internalSearch: false,
|
|
105
|
+
preselectFirst: props.preselectFirst,
|
|
106
|
+
disabled: props.disabled || disableIfNoOptions.value,
|
|
107
|
+
required: props.required,
|
|
108
|
+
groupSelect: props.grouped,
|
|
109
|
+
groupValues: props.groupValues,
|
|
110
|
+
groupLabel: props.groupLabel,
|
|
111
|
+
label: props.itemLabel,
|
|
112
|
+
trackBy: props.trackBy,
|
|
113
|
+
placeholder: hasValue.value ? "" : internalPlaceholder.value || t("inputs.placeholder_select"),
|
|
114
|
+
showLabels: false,
|
|
115
|
+
clearOnSelect: true,
|
|
116
|
+
showNoOptions: isLoading.value ? false : props.showNoOptions,
|
|
117
|
+
showNoResults: isLoading.value ? false : props.showNoResults,
|
|
118
|
+
deselectLabel: props.deselectLabel,
|
|
119
|
+
hideSelected: props.hideSelected,
|
|
120
|
+
selectLabel: props.selectLabel,
|
|
121
|
+
selectedLabel: props.selectedLabel
|
|
122
|
+
}));
|
|
123
|
+
const getOptionValue = (option) => {
|
|
124
|
+
if (typeof option === "object" && option !== null && "name" in option) {
|
|
125
|
+
return option.name?.toString() ?? "";
|
|
126
|
+
}
|
|
127
|
+
return option?.toString() || "";
|
|
128
|
+
};
|
|
81
129
|
const customPosition = () => {
|
|
82
130
|
const autocompleteInputElement = document.querySelector(`#${elementId.value}`);
|
|
83
131
|
const rect = autocompleteInputElement?.getBoundingClientRect();
|
|
@@ -88,26 +136,22 @@ const customPosition = () => {
|
|
|
88
136
|
height: rect?.height
|
|
89
137
|
};
|
|
90
138
|
};
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
return text.toString();
|
|
94
|
-
}
|
|
95
|
-
return text.trim().replace(/أ|ا|إ|آ/g, "\u0627").replace(/ي|ى|ئ/g, "\u064A").replace(/ة/g, "\u0647");
|
|
139
|
+
const customSearch = (query) => {
|
|
140
|
+
search.value = query?.toString().trim() || "";
|
|
96
141
|
};
|
|
97
|
-
const
|
|
98
|
-
if (
|
|
99
|
-
|
|
142
|
+
const handleOpen = () => {
|
|
143
|
+
if (props.teleported) {
|
|
144
|
+
showTeleport.value = true;
|
|
100
145
|
}
|
|
101
|
-
|
|
102
|
-
const normalizedQuery = normalizeArabic(query).toLowerCase();
|
|
103
|
-
return normalizedValue.includes(normalizedQuery);
|
|
146
|
+
isOpen.value = true;
|
|
104
147
|
};
|
|
105
|
-
const
|
|
106
|
-
|
|
148
|
+
const handleClose = () => {
|
|
149
|
+
showTeleport.value = false;
|
|
150
|
+
isOpen.value = false;
|
|
107
151
|
};
|
|
108
152
|
const resetTeleportState = () => {
|
|
109
153
|
if (!props.multiple && props.teleported) {
|
|
110
|
-
|
|
154
|
+
handleClose();
|
|
111
155
|
inputRef.value[`select-input-${elementId.value}`]?.deactivate();
|
|
112
156
|
}
|
|
113
157
|
};
|
|
@@ -132,98 +176,62 @@ const getRecords = async (searchQuery) => {
|
|
|
132
176
|
const fetchAndUpdateRecords = async (searchQuery) => {
|
|
133
177
|
displayedOptions.value = await getRecords(searchQuery);
|
|
134
178
|
};
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
179
|
+
const updateOptions = async (newOptions) => {
|
|
180
|
+
defaultOptions.value = newOptions;
|
|
181
|
+
displayedOptions.value = newOptions;
|
|
182
|
+
};
|
|
183
|
+
const handleSelect = () => {
|
|
184
|
+
errorState.value = false;
|
|
185
|
+
resetTeleportState();
|
|
186
|
+
};
|
|
187
|
+
const handleSearchChange = (query) => {
|
|
188
|
+
if (props.searchInternally) {
|
|
189
|
+
customSearch(query);
|
|
190
|
+
} else {
|
|
191
|
+
fetchAndUpdateRecords(query?.toString());
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
watch([() => props.trackByValue, defaultOptions], async ([trackByValue, _defaultOptions]) => {
|
|
195
|
+
if (!trackByValue || _defaultOptions.length === 0 || loadedValuesHaveBeenSet.value) {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
loadedValuesHaveBeenSet.value = true;
|
|
199
|
+
const loadedValues = Array.isArray(trackByValue) ? trackByValue : [trackByValue];
|
|
200
|
+
let items = _defaultOptions.flatMap((option) => props.grouped ? option.children : [option]);
|
|
201
|
+
const missingIds = loadedValues.filter(
|
|
202
|
+
(value2) => !items.some((item) => item?.[props.trackBy] == value2)
|
|
203
|
+
);
|
|
204
|
+
if (missingIds.length > 0 && props.url) {
|
|
205
|
+
const fetchedItems = await Promise.all(missingIds.map((id) => getRecords(id)));
|
|
206
|
+
if (fetchedItems.length > 0) {
|
|
207
|
+
items = items.concat(fetchedItems.flat());
|
|
154
208
|
}
|
|
155
|
-
},
|
|
156
|
-
{
|
|
157
|
-
immediate: true
|
|
158
209
|
}
|
|
159
|
-
);
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
errorState.value = true;
|
|
210
|
+
const optionsToSelect = loadedValues.map((value2) => items.find((item) => item?.[props.trackBy] == value2)).filter(Boolean);
|
|
211
|
+
if (optionsToSelect.length > 0) {
|
|
212
|
+
emits("update:model-value", optionsToSelect);
|
|
163
213
|
}
|
|
164
|
-
}, {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
});
|
|
214
|
+
}, { immediate: true });
|
|
215
|
+
watch(() => props.errorMessages, (newErrorMessages) => {
|
|
216
|
+
errorState.value = !!(newErrorMessages && newErrorMessages.length > 0);
|
|
217
|
+
}, { deep: true, immediate: true });
|
|
168
218
|
watch(() => params.value, (value2) => {
|
|
169
219
|
if (value2) {
|
|
170
220
|
fetchAndUpdateRecords();
|
|
171
221
|
}
|
|
172
222
|
});
|
|
173
|
-
|
|
174
|
-
if (!search.value) {
|
|
175
|
-
return displayedOptions.value;
|
|
176
|
-
}
|
|
177
|
-
return displayedOptions.value?.map((entry) => {
|
|
178
|
-
if (props.grouped) {
|
|
179
|
-
const matchingChildren = entry?.children?.filter((child) => {
|
|
180
|
-
const childValue = typeof child === "object" && child !== null && "name" in child ? child.name : child;
|
|
181
|
-
return searchArabic(childValue?.toString() ?? "", search.value);
|
|
182
|
-
});
|
|
183
|
-
if (matchingChildren && matchingChildren.length > 0) {
|
|
184
|
-
return {
|
|
185
|
-
...entry,
|
|
186
|
-
children: matchingChildren
|
|
187
|
-
};
|
|
188
|
-
}
|
|
189
|
-
return null;
|
|
190
|
-
}
|
|
191
|
-
const entryValue = typeof entry === "object" && entry !== null && "name" in entry ? entry.name : entry;
|
|
192
|
-
return searchArabic(entryValue?.toString() || "", search.value) ? entry : null;
|
|
193
|
-
}).filter(Boolean);
|
|
194
|
-
});
|
|
195
|
-
const disableIfNoOptions = computed(() => filteredOptions.value.length === 0 && props.disableIfEmpty);
|
|
196
|
-
watch(() => props.url, async () => {
|
|
197
|
-
if (props.fetchEnabled && props.url) {
|
|
198
|
-
const options = await getRecords();
|
|
199
|
-
defaultOptions.value = options;
|
|
200
|
-
displayedOptions.value = options;
|
|
201
|
-
}
|
|
202
|
-
}, {
|
|
203
|
-
immediate: true,
|
|
204
|
-
deep: true
|
|
205
|
-
});
|
|
206
|
-
watch(() => props.options, () => {
|
|
223
|
+
watch([() => props.url, () => props.options], async () => {
|
|
207
224
|
if (props.options && props.options.length > 0) {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
deep: true,
|
|
213
|
-
immediate: true
|
|
214
|
-
});
|
|
215
|
-
watch(showTeleport, (newValue) => {
|
|
216
|
-
if (newValue && props.teleported) {
|
|
217
|
-
nextTick(() => {
|
|
218
|
-
teleportRef.value?.activate();
|
|
219
|
-
});
|
|
225
|
+
updateOptions(props.options);
|
|
226
|
+
} else if (props.fetchEnabled && props.url) {
|
|
227
|
+
const options = await getRecords();
|
|
228
|
+
updateOptions(options);
|
|
220
229
|
}
|
|
221
|
-
});
|
|
230
|
+
}, { deep: true, immediate: true });
|
|
222
231
|
const refetch = async () => {
|
|
223
232
|
if (props.url) {
|
|
224
233
|
const options = await getRecords();
|
|
225
|
-
|
|
226
|
-
displayedOptions.value = options;
|
|
234
|
+
updateOptions(options);
|
|
227
235
|
return options;
|
|
228
236
|
}
|
|
229
237
|
return [];
|
|
@@ -252,22 +260,11 @@ defineExpose({
|
|
|
252
260
|
validate-on="input lazy"
|
|
253
261
|
>
|
|
254
262
|
<MultiSelect
|
|
255
|
-
ref="teleportRef"
|
|
256
263
|
v-model="value"
|
|
257
|
-
|
|
258
|
-
:multiple="multiple"
|
|
259
|
-
:close-on-select="multiple ? false : true"
|
|
260
|
-
:searchable="searchable"
|
|
261
|
-
:internal-search="false"
|
|
262
|
-
:preselect-first="preselectFirst"
|
|
263
|
-
:disabled="disabled || disableIfNoOptions"
|
|
264
|
-
:required="required"
|
|
265
|
-
:group-select="grouped"
|
|
266
|
-
:group-values="groupValues"
|
|
267
|
-
:group-label="groupLabel"
|
|
264
|
+
v-bind="sharedMultiSelectProps"
|
|
268
265
|
class="app-custom-input position-absolute app-z-7 app-custom-input-teleport"
|
|
269
266
|
:class="{
|
|
270
|
-
'app-custom-input-error':
|
|
267
|
+
'app-custom-input-error': hasError(isValid.value)
|
|
271
268
|
}"
|
|
272
269
|
:style="{
|
|
273
270
|
left: `${customPosition().left}px`,
|
|
@@ -275,25 +272,19 @@ defineExpose({
|
|
|
275
272
|
width: `${customPosition().width}px`,
|
|
276
273
|
height: `${customPosition().height}px`
|
|
277
274
|
}"
|
|
278
|
-
:label="itemLabel"
|
|
279
|
-
:track-by="trackBy"
|
|
280
|
-
:placeholder="value && value.length > 0 ? '' : internalPlaceholder || t('inputs.placeholder_select')"
|
|
281
|
-
:show-labels="false"
|
|
282
|
-
:clear-on-select="true"
|
|
283
|
-
:show-no-options="isLoading ? false : true"
|
|
284
|
-
:show-no-results="isLoading ? false : true"
|
|
285
|
-
:deselect-label="deselectLabel"
|
|
286
|
-
:hide-selected="hideSelected"
|
|
287
|
-
:select-label="selectLabel"
|
|
288
|
-
:selected-label="selectedLabel"
|
|
289
275
|
:value="value"
|
|
290
|
-
@search-change="
|
|
291
|
-
@select="
|
|
292
|
-
@close="
|
|
276
|
+
@search-change="handleSearchChange"
|
|
277
|
+
@select="handleSelect"
|
|
278
|
+
@close="handleClose"
|
|
293
279
|
>
|
|
294
280
|
<template #caret>
|
|
295
281
|
<span class="multiselect-arrow">
|
|
296
|
-
<VIcon
|
|
282
|
+
<VIcon
|
|
283
|
+
icon="tabler-chevron-down"
|
|
284
|
+
class="icon"
|
|
285
|
+
size="19"
|
|
286
|
+
:color="hasError(isValid.value) ? 'error' : ''"
|
|
287
|
+
/>
|
|
297
288
|
</span>
|
|
298
289
|
</template>
|
|
299
290
|
|
|
@@ -328,13 +319,16 @@ defineExpose({
|
|
|
328
319
|
|
|
329
320
|
<template #clear>
|
|
330
321
|
<div
|
|
331
|
-
v-if="
|
|
322
|
+
v-if="hasValue && !disabled && clearable"
|
|
332
323
|
class="multiselect-clear cursor-pointer"
|
|
333
324
|
@mousedown.prevent.stop="value = null"
|
|
334
325
|
>
|
|
335
|
-
<VIcon
|
|
336
|
-
tabler-x
|
|
337
|
-
|
|
326
|
+
<VIcon
|
|
327
|
+
icon="tabler-x"
|
|
328
|
+
class="icon"
|
|
329
|
+
size="19"
|
|
330
|
+
:color="hasError(isValid.value) ? 'error' : ''"
|
|
331
|
+
/>
|
|
338
332
|
</div>
|
|
339
333
|
</template>
|
|
340
334
|
|
|
@@ -348,9 +342,7 @@ defineExpose({
|
|
|
348
342
|
|
|
349
343
|
<template v-if="isLoading" #beforeList>
|
|
350
344
|
<div class="app-h-50px w-100">
|
|
351
|
-
<LoadingBar
|
|
352
|
-
:is-loading="isLoading"
|
|
353
|
-
/>
|
|
345
|
+
<LoadingBar :is-loading="isLoading" />
|
|
354
346
|
</div>
|
|
355
347
|
</template>
|
|
356
348
|
|
|
@@ -383,46 +375,30 @@ defineExpose({
|
|
|
383
375
|
validate-on="input lazy"
|
|
384
376
|
>
|
|
385
377
|
<div class="d-flex h-100 position-relative">
|
|
386
|
-
<div v-if="isOpen" class="w-100 h-100 position-absolute app-z-11" @click="closeMenu" />
|
|
378
|
+
<div v-if="isOpen && !teleported" class="w-100 h-100 position-absolute app-z-11" @click="closeMenu" />
|
|
387
379
|
<MultiSelect
|
|
388
380
|
:ref="el => inputRef[`select-input-${elementId}`] = el"
|
|
389
381
|
v-model="value"
|
|
390
|
-
|
|
391
|
-
:multiple="multiple"
|
|
392
|
-
:close-on-select="multiple ? false : true"
|
|
393
|
-
:searchable="searchable"
|
|
394
|
-
:internal-search="false"
|
|
395
|
-
:preselect-first="preselectFirst"
|
|
396
|
-
:disabled="disabled || disableIfNoOptions"
|
|
397
|
-
:required="required"
|
|
398
|
-
:group-select="grouped"
|
|
399
|
-
:group-values="groupValues"
|
|
400
|
-
:group-label="groupLabel"
|
|
382
|
+
v-bind="sharedMultiSelectProps"
|
|
401
383
|
class="app-custom-input"
|
|
402
384
|
:class="{
|
|
403
|
-
'app-custom-input-error':
|
|
385
|
+
'app-custom-input-error': hasError(isValid.value),
|
|
404
386
|
'app-teleport-clone': teleported
|
|
405
387
|
}"
|
|
406
388
|
style="margin-top: 2px;"
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
:clear-on-select="true"
|
|
412
|
-
:show-no-options="isLoading ? false : true"
|
|
413
|
-
:show-no-results="isLoading ? false : true"
|
|
414
|
-
:deselect-label="deselectLabel"
|
|
415
|
-
:hide-selected="hideSelected"
|
|
416
|
-
:select-label="selectLabel"
|
|
417
|
-
:selected-label="selectedLabel"
|
|
418
|
-
@open="showTeleport = true, isOpen = true"
|
|
419
|
-
@close="showTeleport = false, isOpen = false"
|
|
420
|
-
@search-change="searchInternally ? customSearch($event) : fetchAndUpdateRecords($event)"
|
|
421
|
-
@select="errorState = false, resetTeleportState()"
|
|
389
|
+
@open="handleOpen"
|
|
390
|
+
@close="handleClose"
|
|
391
|
+
@search-change="handleSearchChange"
|
|
392
|
+
@select="handleSelect"
|
|
422
393
|
>
|
|
423
394
|
<template #caret>
|
|
424
395
|
<span class="multiselect-arrow">
|
|
425
|
-
<VIcon
|
|
396
|
+
<VIcon
|
|
397
|
+
icon="tabler-chevron-down"
|
|
398
|
+
class="icon"
|
|
399
|
+
size="19"
|
|
400
|
+
:color="hasError(isValid.value) ? 'error' : ''"
|
|
401
|
+
/>
|
|
426
402
|
</span>
|
|
427
403
|
</template>
|
|
428
404
|
|
|
@@ -460,13 +436,16 @@ defineExpose({
|
|
|
460
436
|
|
|
461
437
|
<template #clear>
|
|
462
438
|
<div
|
|
463
|
-
v-if="
|
|
439
|
+
v-if="hasValue && !disabled && clearable"
|
|
464
440
|
class="multiselect-clear cursor-pointer"
|
|
465
441
|
@mousedown.prevent.stop="value = null"
|
|
466
442
|
>
|
|
467
|
-
<VIcon
|
|
468
|
-
tabler-x
|
|
469
|
-
|
|
443
|
+
<VIcon
|
|
444
|
+
icon="tabler-x"
|
|
445
|
+
class="icon"
|
|
446
|
+
size="19"
|
|
447
|
+
:color="hasError(isValid.value) ? 'error' : ''"
|
|
448
|
+
/>
|
|
470
449
|
</div>
|
|
471
450
|
</template>
|
|
472
451
|
|
|
@@ -480,9 +459,7 @@ defineExpose({
|
|
|
480
459
|
|
|
481
460
|
<template v-if="isLoading" #beforeList>
|
|
482
461
|
<div class="app-h-50px w-100">
|
|
483
|
-
<LoadingBar
|
|
484
|
-
:is-loading="isLoading"
|
|
485
|
-
/>
|
|
462
|
+
<LoadingBar :is-loading="isLoading" />
|
|
486
463
|
</div>
|
|
487
464
|
</template>
|
|
488
465
|
|
|
@@ -515,16 +492,22 @@ defineExpose({
|
|
|
515
492
|
<style>
|
|
516
493
|
.app-custom-input-teleport .multiselect__tags {
|
|
517
494
|
display: none !important;
|
|
495
|
+
height: 100%;
|
|
496
|
+
display: flex;
|
|
497
|
+
align-items: center;
|
|
498
|
+
cursor: pointer;
|
|
499
|
+
padding-top: 0;
|
|
518
500
|
}
|
|
519
501
|
.app-custom-input-teleport .multiselect-arrow {
|
|
520
502
|
display: none !important;
|
|
521
503
|
}
|
|
522
504
|
.app-custom-input-teleport .multiselect__placeholder {
|
|
523
|
-
|
|
505
|
+
margin: 0;
|
|
506
|
+
padding-top: 0;
|
|
524
507
|
}
|
|
525
508
|
.app-custom-input-teleport .multiselect__content-wrapper {
|
|
526
509
|
margin-top: 53px;
|
|
527
|
-
z-index:
|
|
510
|
+
z-index: 10;
|
|
528
511
|
display: block !important;
|
|
529
512
|
}
|
|
530
513
|
|
|
@@ -561,7 +544,7 @@ defineExpose({
|
|
|
561
544
|
font-size: 13px !important;
|
|
562
545
|
background-color: rgba(var(--v-theme-surface));
|
|
563
546
|
font-weight: 100 !important;
|
|
564
|
-
min-height:
|
|
547
|
+
min-height: 40px;
|
|
565
548
|
border-radius: 6px;
|
|
566
549
|
}
|
|
567
550
|
.app-custom-input .multiselect__tags:hover {
|
|
@@ -35,12 +35,14 @@ type __VLS_Props = {
|
|
|
35
35
|
isLoading?: boolean;
|
|
36
36
|
disableIfEmpty?: boolean;
|
|
37
37
|
clearable?: boolean;
|
|
38
|
+
showNoOptions?: boolean;
|
|
39
|
+
showNoResults?: boolean;
|
|
38
40
|
};
|
|
39
|
-
declare var
|
|
41
|
+
declare var __VLS_69: string | number, __VLS_70: any, __VLS_134: string | number, __VLS_135: any;
|
|
40
42
|
type __VLS_Slots = {} & {
|
|
41
|
-
[K in NonNullable<typeof
|
|
43
|
+
[K in NonNullable<typeof __VLS_69>]?: (props: typeof __VLS_70) => any;
|
|
42
44
|
} & {
|
|
43
|
-
[K in NonNullable<typeof
|
|
45
|
+
[K in NonNullable<typeof __VLS_134>]?: (props: typeof __VLS_135) => any;
|
|
44
46
|
};
|
|
45
47
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
46
48
|
records: Ref<{
|
|
@@ -63,6 +63,18 @@ const handleInput = (e, index) => {
|
|
|
63
63
|
updateModelAt(index, value);
|
|
64
64
|
}
|
|
65
65
|
};
|
|
66
|
+
const handleKeydown = (e, index) => {
|
|
67
|
+
if (e.key === "Delete" || e.key === "Del" || e.key === "Backspace") {
|
|
68
|
+
e.preventDefault();
|
|
69
|
+
const currentValue = model.value?.[index] ?? "";
|
|
70
|
+
if (!currentValue && index > 0) {
|
|
71
|
+
const prevInput = document.getElementById(`license-${props.customId || ""}-${index - 1}`);
|
|
72
|
+
prevInput?.focus();
|
|
73
|
+
} else if (currentValue) {
|
|
74
|
+
updateModelAt(index, "");
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
};
|
|
66
78
|
const clear = () => {
|
|
67
79
|
model.value = null;
|
|
68
80
|
};
|
|
@@ -108,6 +120,7 @@ watch(() => model.value, (newVal) => {
|
|
|
108
120
|
:maxlength="index === 3 ? 4 : 1"
|
|
109
121
|
:placeholder="index === 3 ? t('inputs.numbers') : t('inputs.character')"
|
|
110
122
|
@input="handleInput($event, index)"
|
|
123
|
+
@keydown="handleKeydown($event, index)"
|
|
111
124
|
>
|
|
112
125
|
<a
|
|
113
126
|
v-if="model?.some(Boolean)"
|
|
@@ -127,8 +140,8 @@ watch(() => model.value, (newVal) => {
|
|
|
127
140
|
v-if="!hideDetails"
|
|
128
141
|
class="mt-1"
|
|
129
142
|
color="error"
|
|
130
|
-
:messages="
|
|
131
|
-
:active="
|
|
143
|
+
:messages="[...validationErrors.value, errorMessages]"
|
|
144
|
+
:active="isValid.value === false || errorMessages?.length !== 0"
|
|
132
145
|
/>
|
|
133
146
|
</div>
|
|
134
147
|
</VValidation>
|
|
@@ -34,7 +34,8 @@ const moduleIdentifier = computed(() => props.module ?? "rows");
|
|
|
34
34
|
item-value="id"
|
|
35
35
|
class="secondary-table"
|
|
36
36
|
>
|
|
37
|
-
|
|
37
|
+
<!-- headers -->
|
|
38
|
+
<template v-for="header in headers" #[`header.${header.key}`] :key="`header.${header.key}`">
|
|
38
39
|
<div class="d-flex align-center gap-1">
|
|
39
40
|
{{ header.title }}
|
|
40
41
|
|
|
@@ -42,7 +43,7 @@ const moduleIdentifier = computed(() => props.module ?? "rows");
|
|
|
42
43
|
|
|
43
44
|
<VTooltip
|
|
44
45
|
v-if="header.tooltip"
|
|
45
|
-
content-class="
|
|
46
|
+
:content-class="`text-center text-pre-line ${header.tooltipClass}`"
|
|
46
47
|
>
|
|
47
48
|
<template #activator="{ props: tooltipProps }">
|
|
48
49
|
<div class="position-relative">
|
|
@@ -62,28 +63,12 @@ const moduleIdentifier = computed(() => props.module ?? "rows");
|
|
|
62
63
|
</div>
|
|
63
64
|
</template>
|
|
64
65
|
|
|
66
|
+
<!-- rows -->
|
|
65
67
|
<template
|
|
66
68
|
v-for="(header) in headers"
|
|
67
|
-
#[`item.${header.key}`]="{
|
|
68
|
-
:key="`row.${index}.${header.key}`"
|
|
69
|
+
#[`item.${header.key}`]="{ index }"
|
|
70
|
+
:key="`row.item.${index}.${header.key}`"
|
|
69
71
|
>
|
|
70
|
-
<span
|
|
71
|
-
v-if="header.key === 'index'"
|
|
72
|
-
:key="`row.${index}.${header.key}`"
|
|
73
|
-
class="px-2 d-flex align-center justify-center h-100 app-border-silver"
|
|
74
|
-
style="border-inline-start: 0px !important;"
|
|
75
|
-
>
|
|
76
|
-
{{ `${index + 1 < 10 ? "0" : ""}${index + 1}` }}
|
|
77
|
-
</span>
|
|
78
|
-
|
|
79
|
-
<span
|
|
80
|
-
v-if="header.type === 'display'"
|
|
81
|
-
:key="`row.${index}.${header.key}`"
|
|
82
|
-
class="px-2 d-flex align-center justify-center h-100 app-border-silver"
|
|
83
|
-
>
|
|
84
|
-
{{ item[header.key] }}
|
|
85
|
-
</span>
|
|
86
|
-
|
|
87
72
|
<!-- eslint-disable vue/no-mutating-props -->
|
|
88
73
|
<template v-if="header?.fields && header?.fields?.length > 0">
|
|
89
74
|
<div
|
|
@@ -120,6 +105,7 @@ const moduleIdentifier = computed(() => props.module ?? "rows");
|
|
|
120
105
|
<!-- eslint-enable vue/no-mutating-props -->
|
|
121
106
|
</template>
|
|
122
107
|
|
|
108
|
+
<!-- other slots -->
|
|
123
109
|
<template v-for="(_, name) in $slots" #[name]="slotProps">
|
|
124
110
|
<slot :name="name" v-bind="slotProps || {}" />
|
|
125
111
|
</template>
|
|
@@ -136,8 +122,8 @@ const moduleIdentifier = computed(() => props.module ?? "rows");
|
|
|
136
122
|
border-bottom: 0px solid rgba(var(--v-table-divider)) !important;
|
|
137
123
|
}
|
|
138
124
|
|
|
139
|
-
.v-table__wrapper {
|
|
140
|
-
overflow:
|
|
125
|
+
:deep(.v-table__wrapper) {
|
|
126
|
+
overflow: visible !important;
|
|
141
127
|
}
|
|
142
128
|
|
|
143
129
|
table tr th {
|
|
@@ -150,17 +136,15 @@ table tr th {
|
|
|
150
136
|
|
|
151
137
|
.secondary-table :deep(table) {
|
|
152
138
|
width: 100% !important;
|
|
153
|
-
border-collapse: collapse !important;
|
|
154
139
|
border-spacing: 0 !important;
|
|
155
140
|
border: 0px solid rgb(var(--v-theme-silver)) !important;
|
|
156
|
-
border-collapse: collapse !important;
|
|
157
141
|
font-size: 13px !important;
|
|
158
142
|
}
|
|
159
143
|
.secondary-table :deep(table) thead th {
|
|
160
144
|
border-top: 1px solid rgb(var(--v-theme-silver)) !important;
|
|
161
145
|
border-left: 1px solid rgb(var(--v-theme-silver)) !important;
|
|
162
146
|
border-right: 1px solid rgb(var(--v-theme-silver)) !important;
|
|
163
|
-
border-bottom: 0px !important;
|
|
147
|
+
border-bottom: 0px solid rgb(var(--v-theme-silver)) !important;
|
|
164
148
|
}
|
|
165
149
|
.secondary-table :deep(table) tbody tr:first-child {
|
|
166
150
|
display: none !important;
|
|
@@ -172,15 +156,15 @@ table tr th {
|
|
|
172
156
|
padding: 14px 16px !important;
|
|
173
157
|
height: fit-content !important;
|
|
174
158
|
top: 80px !important;
|
|
175
|
-
border:
|
|
159
|
+
border: 1px solid rgb(var(--v-theme-silver)) !important;
|
|
176
160
|
background-color: rgb(var(--v-theme-gray-200)) !important;
|
|
177
161
|
color: rgb(var(--v-theme-on-surface)) !important;
|
|
178
162
|
}
|
|
179
163
|
.secondary-table :deep(table) td:first-child {
|
|
180
|
-
border
|
|
164
|
+
border: 1px solid rgb(var(--v-theme-silver)) !important;
|
|
181
165
|
}
|
|
182
166
|
.secondary-table :deep(table) td:last-child {
|
|
183
|
-
border
|
|
167
|
+
border: 1px solid rgb(var(--v-theme-silver)) !important;
|
|
184
168
|
}
|
|
185
169
|
.secondary-table :deep(table) td {
|
|
186
170
|
padding: 0px !important;
|
|
@@ -264,7 +248,6 @@ table tr th {
|
|
|
264
248
|
height: 100%;
|
|
265
249
|
border-color: rgba(var(--v-theme-silver));
|
|
266
250
|
border-radius: 0;
|
|
267
|
-
padding-top: 0px !important;
|
|
268
251
|
}
|
|
269
252
|
:deep(.app-custom-input) .multiselect__tags .multiselect__single {
|
|
270
253
|
margin-bottom: 0px;
|
|
@@ -312,11 +295,6 @@ table tr th {
|
|
|
312
295
|
--v-field-border-opacity: 1 !important;
|
|
313
296
|
}
|
|
314
297
|
|
|
315
|
-
.app-input-table {
|
|
316
|
-
min-width: 250px !important;
|
|
317
|
-
max-width: 250px !important;
|
|
318
|
-
}
|
|
319
|
-
|
|
320
298
|
.app-custom-input-teleport .multiselect__tags {
|
|
321
299
|
border-color: rgba(var(--v-theme-silver)) !important;
|
|
322
300
|
border-radius: 0;
|
|
@@ -101,6 +101,7 @@ const placeholder = (header) => {
|
|
|
101
101
|
flat
|
|
102
102
|
hide-details
|
|
103
103
|
/>
|
|
104
|
+
|
|
104
105
|
<AppNumberField
|
|
105
106
|
v-if="header.type === 'number'"
|
|
106
107
|
v-model="item[header.key]"
|
|
@@ -158,7 +159,6 @@ const placeholder = (header) => {
|
|
|
158
159
|
:error-messages="errorMessages"
|
|
159
160
|
:error="error"
|
|
160
161
|
:disable-if-empty="header.disableIfEmpty"
|
|
161
|
-
teleported
|
|
162
162
|
hide-details
|
|
163
163
|
:clearable="header.clearable"
|
|
164
164
|
/>
|
|
@@ -185,7 +185,6 @@ const placeholder = (header) => {
|
|
|
185
185
|
:error="error"
|
|
186
186
|
:disable-if-empty="header.disableIfEmpty"
|
|
187
187
|
grouped
|
|
188
|
-
teleported
|
|
189
188
|
hide-details
|
|
190
189
|
:clearable="header.clearable"
|
|
191
190
|
/>
|
|
@@ -249,4 +248,20 @@ const placeholder = (header) => {
|
|
|
249
248
|
:error-messages="errorMessages"
|
|
250
249
|
hide-details
|
|
251
250
|
/>
|
|
251
|
+
|
|
252
|
+
<span
|
|
253
|
+
v-if="header.key === 'index'"
|
|
254
|
+
:key="`row.${index}.${header.key}`"
|
|
255
|
+
class="px-2 d-flex align-center justify-center h-100"
|
|
256
|
+
>
|
|
257
|
+
{{ `${index + 1 < 10 ? "0" : ""}${index + 1}` }}
|
|
258
|
+
</span>
|
|
259
|
+
|
|
260
|
+
<span
|
|
261
|
+
v-if="header.type === 'display'"
|
|
262
|
+
:key="`row.${index}.${header.key}`"
|
|
263
|
+
class="px-2 d-flex align-center justify-center h-100"
|
|
264
|
+
>
|
|
265
|
+
{{ item[header.key] }}
|
|
266
|
+
</span>
|
|
252
267
|
</template>
|
|
@@ -626,7 +626,7 @@ $btn-hover-overlay-opacity: (
|
|
|
626
626
|
|
|
627
627
|
&:not(.v-input--disabled) .v-switch__track {
|
|
628
628
|
border: 1px solid rgba(var(--v-border-color), var(--v-switch-opacity));
|
|
629
|
-
background-color:
|
|
629
|
+
background-color: rgba(var(--v-theme-on-surface),var(--v-focus-opacity));
|
|
630
630
|
opacity: 1;
|
|
631
631
|
}
|
|
632
632
|
|
|
@@ -636,9 +636,7 @@ $btn-hover-overlay-opacity: (
|
|
|
636
636
|
--v-selection-control-size: 1.5rem;
|
|
637
637
|
|
|
638
638
|
.v-switch__thumb {
|
|
639
|
-
background: rgb(var(--v-theme-on-success));
|
|
640
|
-
// block-size: 1rem;
|
|
641
|
-
// inline-size: 1rem;
|
|
639
|
+
background: rgb(var(--v-theme-on-success)) !important;
|
|
642
640
|
}
|
|
643
641
|
}
|
|
644
642
|
|
|
@@ -1042,3 +1040,13 @@ $btn-hover-overlay-opacity: (
|
|
|
1042
1040
|
::-webkit-resizer {
|
|
1043
1041
|
background: transparent;
|
|
1044
1042
|
}
|
|
1043
|
+
|
|
1044
|
+
|
|
1045
|
+
.v-tooltip > .v-overlay__content {
|
|
1046
|
+
color: rgb(var(--v-theme-on-secondary)) !important;
|
|
1047
|
+
font-size: 13px !important;
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
.v-icon {
|
|
1051
|
+
outline: none !important;
|
|
1052
|
+
}
|
|
@@ -18397,7 +18397,7 @@ body {
|
|
|
18397
18397
|
}
|
|
18398
18398
|
.v-switch.v-switch--inset:not(.v-input--disabled) .v-switch__track {
|
|
18399
18399
|
border: 1px solid rgba(var(--v-border-color), var(--v-switch-opacity));
|
|
18400
|
-
background-color:
|
|
18400
|
+
background-color: rgba(var(--v-theme-on-surface), var(--v-focus-opacity));
|
|
18401
18401
|
opacity: 1;
|
|
18402
18402
|
}
|
|
18403
18403
|
.v-switch.v-switch--inset .v-selection-control__input {
|
|
@@ -18405,7 +18405,7 @@ body {
|
|
|
18405
18405
|
--v-selection-control-size: 1.5rem;
|
|
18406
18406
|
}
|
|
18407
18407
|
.v-switch.v-switch--inset .v-selection-control__input .v-switch__thumb {
|
|
18408
|
-
background: rgb(var(--v-theme-on-success));
|
|
18408
|
+
background: rgb(var(--v-theme-on-success)) !important;
|
|
18409
18409
|
}
|
|
18410
18410
|
.v-switch.v-switch--inset .v-selection-control--dirty .v-switch__track {
|
|
18411
18411
|
border-color: rgba(var(--v-border-color), var(--v-switch-opacity));
|
|
@@ -18768,6 +18768,15 @@ body {
|
|
|
18768
18768
|
background: transparent;
|
|
18769
18769
|
}
|
|
18770
18770
|
|
|
18771
|
+
.v-tooltip > .v-overlay__content {
|
|
18772
|
+
color: rgb(var(--v-theme-on-secondary)) !important;
|
|
18773
|
+
font-size: 13px !important;
|
|
18774
|
+
}
|
|
18775
|
+
|
|
18776
|
+
.v-icon {
|
|
18777
|
+
outline: none !important;
|
|
18778
|
+
}
|
|
18779
|
+
|
|
18771
18780
|
.v-timeline-item .app-timeline-title {
|
|
18772
18781
|
color: rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity));
|
|
18773
18782
|
font-size: 15px;
|
package/dist/types.d.ts
CHANGED
|
@@ -4,4 +4,5 @@ export declare function formValidator(errors: ErrorResponseFiled[] | undefined,
|
|
|
4
4
|
getMessage: () => string;
|
|
5
5
|
hasError: () => boolean;
|
|
6
6
|
};
|
|
7
|
-
export declare function getErrorMessage(errors: ErrorResponseFiled[] | undefined, key: string): string;
|
|
7
|
+
export declare function getErrorMessage(errors: ErrorResponseFiled[] | undefined, key: string): string | undefined;
|
|
8
|
+
export declare function getErrorMessages(errors: ErrorResponseFiled[] | undefined, keys: string[]): string | undefined;
|
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.formValidator = formValidator;
|
|
7
7
|
exports.getErrorMessage = getErrorMessage;
|
|
8
|
+
exports.getErrorMessages = getErrorMessages;
|
|
8
9
|
function formValidator(errors = [], key) {
|
|
9
10
|
const getError = () => errors?.find(e => e.field == key);
|
|
10
11
|
const getMessage = () => getError()?.message || "";
|
|
@@ -16,5 +17,14 @@ function formValidator(errors = [], key) {
|
|
|
16
17
|
};
|
|
17
18
|
}
|
|
18
19
|
function getErrorMessage(errors = [], key) {
|
|
19
|
-
return errors?.find(e => e.field == key)?.message ||
|
|
20
|
+
return errors?.find(e => e.field == key)?.message || void 0;
|
|
21
|
+
}
|
|
22
|
+
function getErrorMessages(errors = [], keys) {
|
|
23
|
+
for (const key of keys) {
|
|
24
|
+
const error = errors?.find(e => e.field == key);
|
|
25
|
+
if (error?.message) {
|
|
26
|
+
return error.message;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return void 0;
|
|
20
30
|
}
|
|
@@ -9,5 +9,14 @@ export function formValidator(errors = [], key) {
|
|
|
9
9
|
};
|
|
10
10
|
}
|
|
11
11
|
export function getErrorMessage(errors = [], key) {
|
|
12
|
-
return errors?.find((e) => e.field == key)?.message ||
|
|
12
|
+
return errors?.find((e) => e.field == key)?.message || void 0;
|
|
13
|
+
}
|
|
14
|
+
export function getErrorMessages(errors = [], keys) {
|
|
15
|
+
for (const key of keys) {
|
|
16
|
+
const error = errors?.find((e) => e.field == key);
|
|
17
|
+
if (error?.message) {
|
|
18
|
+
return error.message;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return void 0;
|
|
13
22
|
}
|
package/dist/utils/utils.d.ts
CHANGED
|
@@ -7,3 +7,5 @@ export declare const buildFormData: <T>(data: T | T[], excludedKeys?: string[],
|
|
|
7
7
|
export declare const stripLeadingZero: (mobile: string) => string;
|
|
8
8
|
export declare const cloneObjectDeep: <T>(obj: T) => T;
|
|
9
9
|
export declare const mergeDeep: (target: any, source: any) => any;
|
|
10
|
+
export declare const normalizeArabicText: (text: string | number) => string;
|
|
11
|
+
export declare const searchArabicText: (value: string | number, query: string) => boolean;
|
package/dist/utils/utils.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.stripLeadingZero = exports.mergeDeep = exports.isNullOrUndefined = exports.isEmptyArray = exports.isEmpty = exports.generateUniqueId = exports.generateRandomId = exports.cloneObjectDeep = exports.buildFormData = void 0;
|
|
6
|
+
exports.stripLeadingZero = exports.searchArabicText = exports.normalizeArabicText = exports.mergeDeep = exports.isNullOrUndefined = exports.isEmptyArray = exports.isEmpty = exports.generateUniqueId = exports.generateRandomId = exports.cloneObjectDeep = exports.buildFormData = void 0;
|
|
7
7
|
const generateRandomId = length => {
|
|
8
8
|
const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
9
9
|
let result = "";
|
|
@@ -81,4 +81,20 @@ const mergeDeep = (target, source) => {
|
|
|
81
81
|
}
|
|
82
82
|
return output;
|
|
83
83
|
};
|
|
84
|
-
exports.mergeDeep = mergeDeep;
|
|
84
|
+
exports.mergeDeep = mergeDeep;
|
|
85
|
+
const normalizeArabicText = text => {
|
|
86
|
+
if (typeof text === "number") {
|
|
87
|
+
return text.toString();
|
|
88
|
+
}
|
|
89
|
+
return text.trim().replace(/أ|ا|إ|آ/g, "\u0627").replace(/ي|ى|ئ/g, "\u064A").replace(/ة/g, "\u0647");
|
|
90
|
+
};
|
|
91
|
+
exports.normalizeArabicText = normalizeArabicText;
|
|
92
|
+
const searchArabicText = (value, query) => {
|
|
93
|
+
if (!value || !query) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
const normalizedValue = normalizeArabicText(value.toString()).toLowerCase();
|
|
97
|
+
const normalizedQuery = normalizeArabicText(query).toLowerCase();
|
|
98
|
+
return normalizedValue.includes(normalizedQuery);
|
|
99
|
+
};
|
|
100
|
+
exports.searchArabicText = searchArabicText;
|
package/dist/utils/utils.mjs
CHANGED
|
@@ -65,3 +65,17 @@ export const mergeDeep = (target, source) => {
|
|
|
65
65
|
}
|
|
66
66
|
return output;
|
|
67
67
|
};
|
|
68
|
+
export const normalizeArabicText = (text) => {
|
|
69
|
+
if (typeof text === "number") {
|
|
70
|
+
return text.toString();
|
|
71
|
+
}
|
|
72
|
+
return text.trim().replace(/أ|ا|إ|آ/g, "\u0627").replace(/ي|ى|ئ/g, "\u064A").replace(/ة/g, "\u0647");
|
|
73
|
+
};
|
|
74
|
+
export const searchArabicText = (value, query) => {
|
|
75
|
+
if (!value || !query) {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
const normalizedValue = normalizeArabicText(value.toString()).toLowerCase();
|
|
79
|
+
const normalizedQuery = normalizeArabicText(query).toLowerCase();
|
|
80
|
+
return normalizedValue.includes(normalizedQuery);
|
|
81
|
+
};
|