@7365admin1/layer-common 1.8.4 → 1.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/components/Input/InputPhoneNumberV2.vue +121 -119
- package/components/SearchVehicleNumberUser.vue +2 -1
- package/components/VisitorForm.vue +93 -11
- package/components/VisitorManagement.vue +0 -5
- package/composables/usePeople.ts +8 -1
- package/package.json +1 -1
- package/tsconfig.json +2 -14
package/CHANGELOG.md
CHANGED
|
@@ -1,71 +1,83 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
2
|
+
<v-row no-gutters class="mb-5">
|
|
3
|
+
<v-col cols="12" class="d-flex ga-2">
|
|
4
|
+
<v-select
|
|
5
|
+
v-model="selectedCode"
|
|
6
|
+
:variant="variant"
|
|
7
|
+
:items="countries"
|
|
8
|
+
item-title="code"
|
|
9
|
+
item-value="code"
|
|
10
|
+
hide-details
|
|
11
|
+
class="px-0"
|
|
12
|
+
:density="density"
|
|
13
|
+
style="max-width: 95px"
|
|
14
|
+
:rules="[...props.rules]"
|
|
15
|
+
:readonly="props.readOnly"
|
|
16
|
+
@update:model-value="handleUpdateCountry"
|
|
17
|
+
>
|
|
18
|
+
<template v-slot:item="{ props: itemProps, item }">
|
|
19
|
+
<v-list-item
|
|
20
|
+
v-bind="itemProps"
|
|
21
|
+
:title="item.raw.name"
|
|
22
|
+
:subtitle="item.raw.dial_code"
|
|
23
|
+
/>
|
|
24
|
+
</template>
|
|
25
|
+
</v-select>
|
|
26
|
+
|
|
27
|
+
<v-mask-input
|
|
28
|
+
v-model="input"
|
|
29
|
+
:mask="currentMask"
|
|
30
|
+
:rules="[...props.rules, validatePhone]"
|
|
31
|
+
ref="maskRef"
|
|
32
|
+
:key="`mask-key-${maskKey}`"
|
|
33
|
+
:loading="loading"
|
|
34
|
+
:readonly="props.readOnly"
|
|
35
|
+
:variant="variant"
|
|
36
|
+
hint="Enter a valid phone number"
|
|
37
|
+
hide-details
|
|
38
|
+
persistent-hint
|
|
39
|
+
return-masked-value
|
|
40
|
+
:prefix="phonePrefix || ''"
|
|
41
|
+
persistent-placeholder
|
|
42
|
+
:density="density"
|
|
43
|
+
:placeholder="placeholder || currentMask"
|
|
44
|
+
/>
|
|
45
|
+
</v-col>
|
|
46
|
+
<span class="text-error text-caption w-100" v-if="errorMessage && !hideDetails">
|
|
47
|
+
{{ errorMessage }}
|
|
48
|
+
</span>
|
|
49
|
+
</v-row>
|
|
19
50
|
</template>
|
|
20
51
|
|
|
21
52
|
<script setup lang="ts">
|
|
22
|
-
import { ref, computed, type PropType } from 'vue'
|
|
23
|
-
import type { ValidationRule } from 'vuetify/lib/types.mjs'
|
|
53
|
+
import { ref, computed, watch, onMounted, type PropType } from 'vue'
|
|
24
54
|
//@ts-ignore
|
|
25
55
|
import phoneMasks from '~/utils/phoneMasks'
|
|
56
|
+
import type { ValidationRule } from 'vuetify/lib/types.mjs'
|
|
26
57
|
|
|
27
58
|
const props = defineProps({
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
density: {
|
|
37
|
-
type: String as PropType<Density>,
|
|
38
|
-
default: "default"
|
|
39
|
-
},
|
|
40
|
-
placeholder: {
|
|
41
|
-
type: String,
|
|
42
|
-
},
|
|
43
|
-
hideDetails: {
|
|
44
|
-
type: Boolean,
|
|
45
|
-
default: false
|
|
46
|
-
},
|
|
47
|
-
loading: {
|
|
48
|
-
type: Boolean,
|
|
49
|
-
default: false
|
|
50
|
-
},
|
|
51
|
-
readOnly: {
|
|
52
|
-
type: Boolean,
|
|
53
|
-
default: false
|
|
54
|
-
}
|
|
59
|
+
modelValue: { type: String as PropType<string>, default: '' },
|
|
60
|
+
rules: { type: Array as PropType<ValidationRule[]>, default: () => [] },
|
|
61
|
+
variant: { type: String as PropType<any>, default: 'outlined' },
|
|
62
|
+
density: { type: String as PropType<'default' | 'comfortable' | 'compact'>, default: 'default' },
|
|
63
|
+
placeholder: { type: String },
|
|
64
|
+
hideDetails: { type: Boolean, default: false },
|
|
65
|
+
loading: { type: Boolean, default: false },
|
|
66
|
+
readOnly: { type: Boolean, default: false },
|
|
55
67
|
})
|
|
56
68
|
|
|
57
|
-
|
|
69
|
+
const emit = defineEmits(['update:modelValue'])
|
|
58
70
|
|
|
59
|
-
type TPhoneMask =
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
71
|
+
type TPhoneMask = {
|
|
72
|
+
name: string
|
|
73
|
+
flag: string
|
|
74
|
+
code: string
|
|
75
|
+
dial_code: string
|
|
76
|
+
regex: string
|
|
77
|
+
}
|
|
67
78
|
|
|
68
|
-
|
|
79
|
+
// Main reactive values
|
|
80
|
+
const phone = ref(props.modelValue)
|
|
69
81
|
const input = ref('')
|
|
70
82
|
const selectedCode = ref('SG')
|
|
71
83
|
const countries = phoneMasks
|
|
@@ -73,92 +85,82 @@ const errorMessage = ref('')
|
|
|
73
85
|
const maskRef = ref()
|
|
74
86
|
const maskKey = ref(0)
|
|
75
87
|
|
|
88
|
+
|
|
76
89
|
const currentMask = computed(() => {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
90
|
+
const country = countries.find((c: TPhoneMask) => c.code === selectedCode.value)
|
|
91
|
+
if (!country) return '############'
|
|
92
|
+
return generateMaskFromRegex(country.regex)
|
|
80
93
|
})
|
|
81
94
|
|
|
82
95
|
|
|
83
|
-
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
if (!value) {
|
|
88
|
-
errorMessage.value = ''
|
|
89
|
-
return true;
|
|
90
|
-
}
|
|
91
|
-
const country = phoneMasks.find((c: any) => c.code === selectedCode.value)
|
|
92
|
-
if (!country) {
|
|
93
|
-
errorMessage.value = ''
|
|
94
|
-
return true
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const regex = new RegExp(country.regex)
|
|
98
|
-
const isValid = regex.test(value)
|
|
99
|
-
|
|
100
|
-
errorMessage.value = isValid ? '' : `Invalid ${country.name} phone number`
|
|
101
|
-
return isValid
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
|
|
96
|
+
const phonePrefix = computed(() => {
|
|
97
|
+
const country = countries.find((c: TPhoneMask) => c.code === selectedCode.value)
|
|
98
|
+
return country?.dial_code || ''
|
|
99
|
+
})
|
|
105
100
|
|
|
106
101
|
function generateMaskFromRegex(regex: string): string {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
102
|
+
let pattern = regex.replace(/^\^|\$$/g, '')
|
|
103
|
+
pattern = pattern.replace(/\(\?:\+?\d+\)\?/g, '')
|
|
104
|
+
pattern = pattern.replace(/\+?\d{1,4}/, '')
|
|
105
|
+
pattern = pattern.replace(/\\d\{(\d+)\}/g, (_, count) => '#'.repeat(Number(count)))
|
|
106
|
+
pattern = pattern.replace(/\\d/g, '#')
|
|
107
|
+
pattern = pattern.replace(/\\/g, '')
|
|
108
|
+
pattern = pattern.replace(/\(\?:/g, '')
|
|
109
|
+
return pattern.trim()
|
|
110
|
+
}
|
|
113
111
|
|
|
114
|
-
|
|
112
|
+
const validatePhone = (): boolean | string => {
|
|
113
|
+
if (props.readOnly) return true
|
|
114
|
+
if (!phone.value) return true
|
|
115
115
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
pattern = pattern.trim();
|
|
116
|
+
const country = countries.find((c: TPhoneMask) => c.code === selectedCode.value)
|
|
117
|
+
if (!country) return true
|
|
119
118
|
|
|
120
|
-
|
|
119
|
+
const regex = new RegExp(country.regex)
|
|
120
|
+
const isValid = regex.test(phone.value)
|
|
121
|
+
errorMessage.value = isValid ? '' : `Invalid ${country.name} phone number`
|
|
122
|
+
return isValid
|
|
121
123
|
}
|
|
122
124
|
|
|
123
|
-
const phonePrefix = computed(() => {
|
|
124
|
-
const country = phoneMasks.find((c: TPhoneMask) => c.code === selectedCode.value)
|
|
125
|
-
return country?.dial_code || ''
|
|
126
|
-
})
|
|
127
|
-
|
|
128
|
-
|
|
129
125
|
function handleUpdateCountry() {
|
|
130
|
-
|
|
126
|
+
const prefix = phonePrefix.value
|
|
127
|
+
if (phone.value?.startsWith(prefix)) {
|
|
128
|
+
input.value = phone.value.slice(prefix.length)
|
|
129
|
+
} else {
|
|
130
|
+
input.value = ''
|
|
131
|
+
}
|
|
131
132
|
}
|
|
132
133
|
|
|
133
|
-
const emit = defineEmits(['update:modelValue'])
|
|
134
|
-
|
|
135
|
-
watch(phone, (newVal) => {
|
|
136
|
-
emit('update:modelValue', newVal)
|
|
137
|
-
})
|
|
138
134
|
|
|
139
135
|
watch(input, (newInput) => {
|
|
140
|
-
|
|
136
|
+
const prefix = phonePrefix.value
|
|
137
|
+
if (!newInput) phone.value = ''
|
|
138
|
+
else phone.value = prefix + newInput
|
|
139
|
+
})
|
|
141
140
|
|
|
142
|
-
if (!newInput) {
|
|
143
|
-
return
|
|
144
|
-
}
|
|
145
141
|
|
|
146
|
-
|
|
142
|
+
watch(phone, (newVal) => {
|
|
143
|
+
const prefix = phonePrefix.value
|
|
144
|
+
if (!newVal) input.value = ''
|
|
145
|
+
else input.value = newVal.startsWith(prefix) ? newVal.slice(prefix.length) : newVal
|
|
146
|
+
emit('update:modelValue', newVal)
|
|
147
147
|
})
|
|
148
148
|
|
|
149
149
|
|
|
150
|
-
|
|
151
|
-
|
|
150
|
+
watch(selectedCode, () => {
|
|
151
|
+
const prefix = phonePrefix.value
|
|
152
|
+
if (phone.value?.startsWith(prefix)) input.value = phone.value.slice(prefix.length)
|
|
153
|
+
else input.value = phone.value || ''
|
|
154
|
+
})
|
|
152
155
|
|
|
153
|
-
const found = phoneMasks.find((c: any) => phone.value?.startsWith(c?.dial_code))
|
|
154
|
-
if (found) {
|
|
155
|
-
selectedCode.value = found.code
|
|
156
|
-
}
|
|
157
156
|
|
|
158
|
-
|
|
157
|
+
onMounted(() => {
|
|
158
|
+
if (phone.value) {
|
|
159
|
+
const found = countries.find((c: TPhoneMask) => phone.value.startsWith(c.dial_code))
|
|
160
|
+
if (found) selectedCode.value = found.code
|
|
161
|
+
const prefix = phonePrefix.value
|
|
162
|
+
input.value = phone.value.startsWith(prefix) ? phone.value.slice(prefix.length) : phone.value
|
|
159
163
|
maskKey.value++
|
|
164
|
+
}
|
|
160
165
|
})
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
166
|
</script>
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
</v-toolbar>
|
|
8
8
|
|
|
9
9
|
<v-card-text style="max-height: 100vh; overflow-y: auto">
|
|
10
|
-
<v-data-table :items="prop.vehicleNumberUsersList" hide-default-footer :headers="headers" density="comfortable"
|
|
10
|
+
<v-data-table :items="prop.vehicleNumberUsersList" hide-default-footer :headers="headers" density="comfortable"
|
|
11
11
|
item-key="_id ">
|
|
12
12
|
<template #item.name="{ item }">
|
|
13
13
|
<span class="d-flex align-center ga-2">
|
|
@@ -81,6 +81,7 @@ function handleSelectUser(item: TPeople){
|
|
|
81
81
|
function handleUpdateUserDetails(){
|
|
82
82
|
confirmAction.value = false;
|
|
83
83
|
emit('update:people', selectedPeople.value)
|
|
84
|
+
emit('close')
|
|
84
85
|
}
|
|
85
86
|
|
|
86
87
|
onMounted(() => {
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
|
|
63
63
|
<v-col v-if="shouldShowField('contact')" cols="12">
|
|
64
64
|
<InputLabel class="text-capitalize" title="Phone Number" required />
|
|
65
|
-
<InputPhoneNumberV2 v-model="visitor.contact" :rules="[requiredRule]" density="comfortable"
|
|
65
|
+
<InputPhoneNumberV2 v-model="visitor.contact" :rules="[requiredRule]" density="comfortable" :key="currentAutofillSource + 'phone-key'"
|
|
66
66
|
:loading="fetchPersonByContactPending" @update:model-value="handleUpdateContact" />
|
|
67
67
|
</v-col>
|
|
68
68
|
|
|
@@ -134,8 +134,8 @@
|
|
|
134
134
|
<v-col v-if="shouldShowField('unit')" cols="12">
|
|
135
135
|
<InputLabel class="text-capitalize" title="Unit" required />
|
|
136
136
|
<v-select v-model="visitor.unit" :items="unitsArray" density="comfortable" item-title="title"
|
|
137
|
-
item-value="value" :disabled="!visitor.level"
|
|
138
|
-
|
|
137
|
+
item-value="value" :disabled="!visitor.level" :loading="unitsStatus === 'pending'" :rules="[requiredRule]"
|
|
138
|
+
@update:model-value="handleUpdateUnit" />
|
|
139
139
|
</v-col>
|
|
140
140
|
|
|
141
141
|
<v-col v-if="shouldShowField('remarks')" cols="12">
|
|
@@ -189,6 +189,11 @@
|
|
|
189
189
|
</v-col>
|
|
190
190
|
</v-row>
|
|
191
191
|
</v-toolbar>
|
|
192
|
+
|
|
193
|
+
<v-dialog v-model="dialog.vehicleNumberUsersList" v-if="vehicleNumberUserItems.length > 0" persistent max-width="600">
|
|
194
|
+
<SearchVehicleNumberUser :vehicle-number="visitor.plateNumber ?? ''" :vehicle-number-users-list="vehicleNumberUserItems"
|
|
195
|
+
@close="dialog.vehicleNumberUsersList = false" @update:people="handleAutofillDataViaVehicleNumber" />
|
|
196
|
+
</v-dialog>
|
|
192
197
|
</v-card>
|
|
193
198
|
</template>
|
|
194
199
|
|
|
@@ -217,10 +222,14 @@ const prop = defineProps({
|
|
|
217
222
|
},
|
|
218
223
|
});
|
|
219
224
|
|
|
225
|
+
type AutofillSource = "nric" | "contact" | "vehicleNumber" | null;
|
|
226
|
+
const currentAutofillSource = ref<AutofillSource>(null);
|
|
227
|
+
|
|
228
|
+
|
|
220
229
|
const { requiredRule, debounce } = useUtils();
|
|
221
230
|
const { getSiteById, getSiteLevels, getSiteUnits } = useSiteSettings();
|
|
222
231
|
const { createVisitor, typeFieldMap, contractorTypes } = useVisitor();
|
|
223
|
-
const { findPersonByNRIC, findPersonByContact, searchCompanyList } = usePeople()
|
|
232
|
+
const { findPersonByNRIC, findPersonByContact, searchCompanyList, findUsersByPlateNumber } = usePeople()
|
|
224
233
|
|
|
225
234
|
const emit = defineEmits([
|
|
226
235
|
"back",
|
|
@@ -248,6 +257,10 @@ const visitor = reactive<Partial<TVisitorPayload>>({
|
|
|
248
257
|
members: [],
|
|
249
258
|
});
|
|
250
259
|
|
|
260
|
+
const dialog = reactive({
|
|
261
|
+
vehicleNumberUsersList: false,
|
|
262
|
+
});
|
|
263
|
+
|
|
251
264
|
const validForm = ref(false);
|
|
252
265
|
const formRef = ref<HTMLFormElement | null>(null);
|
|
253
266
|
const processing = ref(false);
|
|
@@ -267,6 +280,10 @@ const blocksArray = ref<TDefaultOptionObj[]>([]);
|
|
|
267
280
|
const levelsArray = ref<TDefaultOptionObj[]>([]);
|
|
268
281
|
const unitsArray = ref<TDefaultOptionObj[]>([]);
|
|
269
282
|
|
|
283
|
+
|
|
284
|
+
const vehicleNumberUserItems = ref<TPeople[]>([])
|
|
285
|
+
|
|
286
|
+
|
|
270
287
|
const shouldShowField = (fieldKey: keyof TVisitorPayload) => {
|
|
271
288
|
if (prop.type !== "contractor" || contractorStep.value === 1) {
|
|
272
289
|
const visibleFields = typeFieldMap[prop.type];
|
|
@@ -355,16 +372,20 @@ const {
|
|
|
355
372
|
|
|
356
373
|
watch(fetchPersonByNRICReq, (obj) => {
|
|
357
374
|
if (obj) {
|
|
375
|
+
currentAutofillSource.value = "nric";
|
|
358
376
|
companyNames.value = obj.companyName ?? []
|
|
359
377
|
visitor.name = obj.name
|
|
360
378
|
visitor.contact = obj.contact
|
|
361
379
|
if (!visitor.company) {
|
|
362
380
|
visitor.company = companyNames.value?.[0]
|
|
363
381
|
}
|
|
364
|
-
visitor.plateNumber = obj.plateNumber ?? ""
|
|
365
382
|
visitor.block = obj.block ?? ""
|
|
366
383
|
visitor.level = obj.level ?? ""
|
|
367
384
|
visitor.unit = obj.unit ?? ""
|
|
385
|
+
|
|
386
|
+
setTimeout(() => {
|
|
387
|
+
currentAutofillSource.value = null;
|
|
388
|
+
}, 1000);
|
|
368
389
|
}
|
|
369
390
|
})
|
|
370
391
|
|
|
@@ -381,16 +402,20 @@ const {
|
|
|
381
402
|
|
|
382
403
|
watch(fetchPersonByContactReq, (obj) => {
|
|
383
404
|
if (obj) {
|
|
405
|
+
currentAutofillSource.value = "contact";
|
|
384
406
|
companyNames.value = obj.companyName ?? []
|
|
385
|
-
visitor.name = obj.name
|
|
407
|
+
visitor.name = visitor.name ?? obj.name
|
|
386
408
|
if (!visitor.company) {
|
|
387
409
|
visitor.company = companyNames.value?.[0]
|
|
388
410
|
}
|
|
389
|
-
visitor.
|
|
390
|
-
visitor.
|
|
391
|
-
visitor.
|
|
392
|
-
visitor.
|
|
393
|
-
|
|
411
|
+
visitor.block = visitor.block ?? obj.block ?? ""
|
|
412
|
+
visitor.level = visitor.level ?? obj.level ?? ""
|
|
413
|
+
visitor.unit = visitor.unit ?? obj.unit ?? ""
|
|
414
|
+
visitor.nric = visitor.nric ?? obj.nric ?? ""
|
|
415
|
+
|
|
416
|
+
setTimeout(() => {
|
|
417
|
+
currentAutofillSource.value = null;
|
|
418
|
+
}, 1000);
|
|
394
419
|
}
|
|
395
420
|
})
|
|
396
421
|
|
|
@@ -410,6 +435,25 @@ watch(fetchCompanyListReq, (arr) => {
|
|
|
410
435
|
companyNames.value = arr?.flatMap(x => x?.companyName)
|
|
411
436
|
}
|
|
412
437
|
})
|
|
438
|
+
const {
|
|
439
|
+
data: fetchVehicleNumberUserReq,
|
|
440
|
+
refresh: fetchVehicleNumberUserRefresh,
|
|
441
|
+
pending: fetchVehicleNumberUserPending,
|
|
442
|
+
|
|
443
|
+
} = useLazyAsyncData(`fetch-vehicle-number-user-list`, () => {
|
|
444
|
+
if (!visitor.plateNumber) return Promise.resolve(null)
|
|
445
|
+
return findUsersByPlateNumber(visitor.plateNumber)
|
|
446
|
+
})
|
|
447
|
+
|
|
448
|
+
watch(fetchVehicleNumberUserReq, (arr) => {
|
|
449
|
+
const arrayData = arr?.data
|
|
450
|
+
if (Array.isArray(arrayData)) {
|
|
451
|
+
vehicleNumberUserItems.value = arrayData;
|
|
452
|
+
if (arrayData.length > 0) {
|
|
453
|
+
dialog.vehicleNumberUsersList = true
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
})
|
|
413
457
|
|
|
414
458
|
const debounceFetchCompany = debounce(async () => fetchCompanyListRefresh(), 200)
|
|
415
459
|
|
|
@@ -422,6 +466,41 @@ watch(companyNameInput, async (val) => {
|
|
|
422
466
|
})
|
|
423
467
|
|
|
424
468
|
|
|
469
|
+
const debounceSearchVehicleUsers = debounce(() => {
|
|
470
|
+
if (!visitor.plateNumber) {
|
|
471
|
+
vehicleNumberUserItems.value = [];
|
|
472
|
+
dialog.vehicleNumberUsersList = false;
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
fetchVehicleNumberUserRefresh();
|
|
476
|
+
}, 300);
|
|
477
|
+
|
|
478
|
+
watch(() => visitor.plateNumber, (newVal) => {
|
|
479
|
+
if(currentAutofillSource.value && currentAutofillSource.value !== "vehicleNumber") return;
|
|
480
|
+
debounceSearchVehicleUsers();
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
|
|
484
|
+
function handleAutofillDataViaVehicleNumber(item: TPeople){
|
|
485
|
+
|
|
486
|
+
currentAutofillSource.value = "vehicleNumber";
|
|
487
|
+
|
|
488
|
+
visitor.name = item.name
|
|
489
|
+
visitor.nric = item.nric
|
|
490
|
+
visitor.contact = item.contact
|
|
491
|
+
companyNames.value = item.companyName ?? []
|
|
492
|
+
if (!visitor.company) {
|
|
493
|
+
visitor.company = companyNames.value?.[0]
|
|
494
|
+
}
|
|
495
|
+
visitor.block = item.block ?? ""
|
|
496
|
+
visitor.level = item.level ?? ""
|
|
497
|
+
visitor.unit = item.unit ?? ""
|
|
498
|
+
|
|
499
|
+
setTimeout(() => {
|
|
500
|
+
currentAutofillSource.value = null;
|
|
501
|
+
}, 1000);
|
|
502
|
+
}
|
|
503
|
+
|
|
425
504
|
|
|
426
505
|
const {
|
|
427
506
|
data: siteData,
|
|
@@ -538,10 +617,12 @@ const debounceFetchNRIC = debounce(fetchPersonByNRICRefresh, 500)
|
|
|
538
617
|
const debounceFetchContact = debounce(fetchPersonByContactRefresh, 500)
|
|
539
618
|
|
|
540
619
|
function handleUpdateNRIC() {
|
|
620
|
+
if (currentAutofillSource.value && currentAutofillSource.value !== "nric") return;
|
|
541
621
|
debounceFetchNRIC()
|
|
542
622
|
}
|
|
543
623
|
|
|
544
624
|
function handleUpdateContact() {
|
|
625
|
+
if (currentAutofillSource.value && currentAutofillSource.value !== "contact") return;
|
|
545
626
|
debounceFetchContact()
|
|
546
627
|
}
|
|
547
628
|
|
|
@@ -650,6 +731,7 @@ watch(
|
|
|
650
731
|
|
|
651
732
|
onMounted(() => {
|
|
652
733
|
contractorStep.value = 1;
|
|
734
|
+
currentAutofillSource.value = null;
|
|
653
735
|
});
|
|
654
736
|
</script>
|
|
655
737
|
<style scoped>
|
|
@@ -145,10 +145,6 @@
|
|
|
145
145
|
</VehicleUpdateMoreAction>
|
|
146
146
|
</v-dialog>
|
|
147
147
|
|
|
148
|
-
<v-dialog v-model="dialog.vehicleNumberUsersList" persistent max-width="600">
|
|
149
|
-
<SearchVehicleNumberUser :vehicle-number="'123123'" @close="dialog.vehicleNumberUsersList = false" @update:people="handleUpdateAutofillDetails"/>
|
|
150
|
-
</v-dialog>
|
|
151
|
-
|
|
152
148
|
<v-dialog v-model="dialog.deleteConfirmation" width="450" persistent>
|
|
153
149
|
<CardDeleteConfirmation prompt-title="Are you sure want to delete this visitor?"
|
|
154
150
|
:loading="loading.deletingVisitor" @close="dialog.deleteConfirmation = false"
|
|
@@ -245,7 +241,6 @@ const dialog = reactive({
|
|
|
245
241
|
addVisitor: false,
|
|
246
242
|
viewVisitor: false,
|
|
247
243
|
deleteConfirmation: false,
|
|
248
|
-
vehicleNumberUsersList: false
|
|
249
244
|
});
|
|
250
245
|
|
|
251
246
|
const tabOptions = [
|
package/composables/usePeople.ts
CHANGED
|
@@ -30,6 +30,12 @@ export default function(){
|
|
|
30
30
|
method: "GET",
|
|
31
31
|
});
|
|
32
32
|
}
|
|
33
|
+
async function findUsersByPlateNumber(plateNumber: string): Promise<null | Partial<TPeople>> {
|
|
34
|
+
return await $fetch<Record<string, any>>(`/api/people/plateNumber/${plateNumber}`, {
|
|
35
|
+
method: "GET",
|
|
36
|
+
query: { limit: 20 }
|
|
37
|
+
});
|
|
38
|
+
}
|
|
33
39
|
|
|
34
40
|
async function searchCompanyList(company: string): Promise<null | Partial<TPeople>> {
|
|
35
41
|
return await $fetch<Record<string, any>>('/api/people/company', {
|
|
@@ -76,6 +82,7 @@ export default function(){
|
|
|
76
82
|
findPersonByNRIC,
|
|
77
83
|
findPersonByContact,
|
|
78
84
|
getPeopleByUnit,
|
|
79
|
-
searchCompanyList
|
|
85
|
+
searchCompanyList,
|
|
86
|
+
findUsersByPlateNumber
|
|
80
87
|
}
|
|
81
88
|
}
|
package/package.json
CHANGED
package/tsconfig.json
CHANGED
|
@@ -1,15 +1,3 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
|
|
4
|
-
"module": "ESNext",
|
|
5
|
-
"moduleResolution": "Node",
|
|
6
|
-
"strict": true,
|
|
7
|
-
"esModuleInterop": true,
|
|
8
|
-
"skipLibCheck": true,
|
|
9
|
-
"types": ["vite/client", "nuxt"],
|
|
10
|
-
"jsx": "preserve",
|
|
11
|
-
"resolveJsonModule": true,
|
|
12
|
-
"allowSyntheticDefaultImports": true
|
|
13
|
-
},
|
|
14
|
-
"include": ["./**/*.ts", "./**/*.vue"]
|
|
15
|
-
}
|
|
2
|
+
"extends": "./.playground/.nuxt/tsconfig.json"
|
|
3
|
+
}
|