@7365admin1/layer-common 1.11.17 → 1.11.19
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 +12 -0
- package/components/AddPassKeyToVisitor.vue +207 -0
- package/components/BuildingUnitFormEdit.vue +41 -1
- package/components/Card/MemberInfoSummary.vue +5 -1
- package/components/Input/FileV2.vue +4 -3
- package/components/MemberInformation.vue +98 -20
- package/components/PassInformation.vue +75 -30
- package/components/VehicleManagement.vue +107 -34
- package/components/VisitorForm.vue +72 -30
- package/components/VisitorManagement.vue +278 -27
- package/composables/useKey.ts +4 -0
- package/composables/useLocalAuth.ts +2 -4
- package/composables/useSiteSettings.ts +14 -0
- package/composables/useTemplateReusable.ts +5 -1
- package/composables/useVehicle.ts +3 -3
- package/package.json +1 -1
- package/types/vehicle.d.ts +2 -1
- package/types/visitor.d.ts +13 -2
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
<v-row no-gutters class="px-5 py-1 d-flex align-center justify-end ga-3">
|
|
10
10
|
<v-text-field v-model="searchInput" density="compact" placeholder="Search" clearable max-width="300"
|
|
11
11
|
append-inner-icon="mdi-magnify" hide-details />
|
|
12
|
-
<v-select v-model="vehicleTypeFilter" density="compact" item-title="label" item-value="value"
|
|
13
|
-
placeholder="Filter by Type" clearable max-width="200" hide-details :items="typeOptions" />
|
|
12
|
+
<!-- <v-select v-model="vehicleTypeFilter" density="compact" item-title="label" item-value="value"
|
|
13
|
+
placeholder="Filter by Type" clearable max-width="200" hide-details :items="typeOptions" /> -->
|
|
14
14
|
</v-row>
|
|
15
15
|
</template>
|
|
16
16
|
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
</v-dialog>
|
|
38
38
|
|
|
39
39
|
<v-dialog v-model="dialog.createVehicle" v-if="vehicleType" width="450" persistent>
|
|
40
|
-
<VehicleForm :type="vehicleType" mode="add" :vehicle-data="selectedVehicleObject" @back="handleBackToSelection"
|
|
41
|
-
:org="org" :site="props.site" @close:all="handleCloseAll" />
|
|
40
|
+
<VehicleForm :type="vehicleType" mode="add" :vehicle-data="selectedVehicleObject" @back="handleBackToSelection"
|
|
41
|
+
@done="handleAddVehicleComplete" :org="org" :site="props.site" @close:all="handleCloseAll" />
|
|
42
42
|
</v-dialog>
|
|
43
43
|
|
|
44
44
|
<!-- <v-dialog v-model="dialog.updateVehicle" v-if="vehicleType" width="450" persistent>
|
|
@@ -65,10 +65,23 @@
|
|
|
65
65
|
{{ formatVehicleStatus(value).label }}
|
|
66
66
|
</v-chip>
|
|
67
67
|
</template>
|
|
68
|
-
<template #item.action="{ item }">
|
|
69
|
-
<v-btn v-if="canDeleteVehicle && (
|
|
70
|
-
|
|
71
|
-
|
|
68
|
+
<template #item.action="{ item: plateNumberItem, value }">
|
|
69
|
+
<v-btn v-if="canDeleteVehicle && (plateNumberItem as TPlateNumber)?.status == 'active'"
|
|
70
|
+
text="Delete" color="error" flat size="x-small"
|
|
71
|
+
@click="handleDeleteVehicleAction(plateNumberItem as TPlateNumber)" />
|
|
72
|
+
<v-btn
|
|
73
|
+
v-if="props.app === 'property_management_agency' && (plateNumberItem as TPlateNumber)?.status == 'pending'"
|
|
74
|
+
text="Approve" color="success" flat size="x-small"
|
|
75
|
+
@click="handleApproveVehicle(plateNumberItem as TPlateNumber)" />
|
|
76
|
+
<v-btn v-if="(plateNumberItem as TPlateNumber)?.status == 'deleted'" text="Restore"
|
|
77
|
+
color="orange" flat size="x-small"
|
|
78
|
+
@click="handleRestoreVehicle(plateNumberItem as TPlateNumber)" />
|
|
79
|
+
<v-btn
|
|
80
|
+
v-if="((plateNumberItem as TPlateNumber)?.type === 'whitelist' || (plateNumberItem as TPlateNumber)?.type === 'blocklist') && plateNumberItem?.status == 'active'"
|
|
81
|
+
variant="outlined"
|
|
82
|
+
:text="(plateNumberItem as TPlateNumber)?.type === 'blocklist' ? 'Whitelist' : 'Blocklist'"
|
|
83
|
+
:color="(plateNumberItem as TPlateNumber)?.type === 'blocklist' ? 'primary' : 'red'" flat
|
|
84
|
+
size="x-small" class="ml-1" @click="handleUpdateType(plateNumberItem as TPlateNumber)" />
|
|
72
85
|
</template>
|
|
73
86
|
</v-data-table>
|
|
74
87
|
<v-btn text="Add Vehicle Number" class="mt-6 text-capitalize" prepend-icon="mdi-plus"
|
|
@@ -81,7 +94,7 @@
|
|
|
81
94
|
<v-col v-else-if="selectedVehicleObject[key]" cols="12">
|
|
82
95
|
<span class="d-flex ga-3 align-center"><strong>{{ label }}:</strong> {{ formatValues(key,
|
|
83
96
|
selectedVehicleObject[key])
|
|
84
|
-
|
|
97
|
+
}}</span>
|
|
85
98
|
</v-col>
|
|
86
99
|
</template>
|
|
87
100
|
</v-row>
|
|
@@ -89,16 +102,24 @@
|
|
|
89
102
|
</DialogUpdateMoreAction>
|
|
90
103
|
</v-dialog>
|
|
91
104
|
<v-dialog v-model="dialog.deleteVehicle" persistent width="540">
|
|
92
|
-
<DialogDeleteConfirmation :loading="deletingVehicle"
|
|
105
|
+
<DialogDeleteConfirmation :loading="deletingVehicle"
|
|
106
|
+
:prompt-title="`Are you sure want to delete this vehicle - ${selectedPlateNumberObject?.plateNumber}?`"
|
|
93
107
|
@delete="submitDelete" @close="closeDeleteDialog" />
|
|
94
108
|
</v-dialog>
|
|
95
109
|
<v-dialog v-model="dialog.approveVehicle" persistent width="540">
|
|
96
|
-
<DialogReusablePrompt :loading="approvingVehicle"
|
|
97
|
-
|
|
110
|
+
<DialogReusablePrompt :loading="approvingVehicle"
|
|
111
|
+
:prompt-title="`Are you sure want to approve this vehicle - ${selectedPlateNumberObject?.plateNumber}?`"
|
|
112
|
+
@proceed="submitApprove" @close="dialog.approveVehicle = false" />
|
|
98
113
|
</v-dialog>
|
|
99
114
|
<v-dialog v-model="dialog.restoreVehicle" persistent width="540">
|
|
100
|
-
<DialogReusablePrompt :loading="restoringVehicle"
|
|
101
|
-
|
|
115
|
+
<DialogReusablePrompt :loading="restoringVehicle"
|
|
116
|
+
:prompt-title="`Are you sure want to restore this vehicle - ${selectedPlateNumberObject?.plateNumber}?`"
|
|
117
|
+
@proceed="submitRestore" @close="dialog.restoreVehicle = false" />
|
|
118
|
+
</v-dialog>
|
|
119
|
+
<v-dialog v-model="dialog.updateVehicleType" persistent width="540">
|
|
120
|
+
<DialogReusablePrompt :loading="updatingType"
|
|
121
|
+
:prompt-title="`Are you sure want to update the type of this vehicle - ${selectedPlateNumberObject?.plateNumber}?`"
|
|
122
|
+
@proceed="submitUpdateType" @close="dialog.updateVehicleType = false" />
|
|
102
123
|
</v-dialog>
|
|
103
124
|
<Snackbar v-model="messageSnackbar" :text="message" :color="messageColor" />
|
|
104
125
|
</v-row>
|
|
@@ -147,7 +168,7 @@ const plateHeaders = [
|
|
|
147
168
|
|
|
148
169
|
|
|
149
170
|
const { formatCamelCaseToWords, formatDate, debounce } = useUtils();
|
|
150
|
-
const { getVehicles, deleteVehicle, formatVehicleStatus, approveVehicle } = useVehicle();
|
|
171
|
+
const { getVehicles, deleteVehicle, formatVehicleStatus, approveVehicle, updateVehicle } = useVehicle();
|
|
151
172
|
|
|
152
173
|
const items = ref<Array<Record<string, any>>>([]);
|
|
153
174
|
const page = ref(1);
|
|
@@ -160,6 +181,7 @@ const loading = ref(false);
|
|
|
160
181
|
const deletingVehicle = ref(false);
|
|
161
182
|
const approvingVehicle = ref(false);
|
|
162
183
|
const restoringVehicle = ref(false);
|
|
184
|
+
const updatingType = ref(false);
|
|
163
185
|
|
|
164
186
|
const selectedVehicleId = ref<string | null>(null)
|
|
165
187
|
const vehicleType = ref<TVehicleType | null>(null);
|
|
@@ -185,7 +207,8 @@ const dialog = reactive({
|
|
|
185
207
|
deleteVehicle: false,
|
|
186
208
|
showMoreActions: false,
|
|
187
209
|
approveVehicle: false,
|
|
188
|
-
restoreVehicle: false
|
|
210
|
+
restoreVehicle: false,
|
|
211
|
+
updateVehicleType: false
|
|
189
212
|
});
|
|
190
213
|
|
|
191
214
|
|
|
@@ -280,19 +303,24 @@ function handleEditVehicleAction() {
|
|
|
280
303
|
}
|
|
281
304
|
|
|
282
305
|
function handleDeleteVehicleAction(item: TPlateNumber) {
|
|
283
|
-
selectedPlateNumberObject.value = item || null;
|
|
306
|
+
selectedPlateNumberObject.value = item || null;
|
|
284
307
|
dialog.deleteVehicle = true;
|
|
285
308
|
}
|
|
286
309
|
|
|
287
310
|
function handleApproveVehicle(item: TPlateNumber) {
|
|
288
|
-
selectedPlateNumberObject.value = item || null;
|
|
311
|
+
selectedPlateNumberObject.value = item || null;
|
|
289
312
|
dialog.approveVehicle = true;
|
|
290
313
|
}
|
|
291
314
|
function handleRestoreVehicle(item: TPlateNumber) {
|
|
292
|
-
selectedPlateNumberObject.value = item || null;
|
|
315
|
+
selectedPlateNumberObject.value = item || null;
|
|
293
316
|
dialog.restoreVehicle = true;
|
|
294
317
|
}
|
|
295
318
|
|
|
319
|
+
function handleUpdateType(item: TPlateNumber) {
|
|
320
|
+
selectedPlateNumberObject.value = item || null;
|
|
321
|
+
dialog.updateVehicleType = true;
|
|
322
|
+
}
|
|
323
|
+
|
|
296
324
|
function handleSelectVehicleStatus(value: TVehicleType) {
|
|
297
325
|
vehicleType.value = value;
|
|
298
326
|
dialog.showSelection = false;
|
|
@@ -341,6 +369,7 @@ async function submitDelete() {
|
|
|
341
369
|
|
|
342
370
|
const plateNumberId = selectedPlateNumberObject.value?._id;
|
|
343
371
|
const type = selectedPlateNumberObject.value?.type as TVehicleType;
|
|
372
|
+
const recNo = selectedPlateNumberObject.value?.recNo;
|
|
344
373
|
if (!plateNumberId) {
|
|
345
374
|
showMessage("Invalid plate number selected for deletion.", "error");
|
|
346
375
|
return;
|
|
@@ -348,12 +377,11 @@ async function submitDelete() {
|
|
|
348
377
|
|
|
349
378
|
try {
|
|
350
379
|
deletingVehicle.value = true;
|
|
351
|
-
const res = await deleteVehicle({ site: props.site, id: plateNumberId as string,
|
|
380
|
+
const res = await deleteVehicle({ site: props.site, recno: recNo, id: plateNumberId as string, type }
|
|
352
381
|
);
|
|
353
382
|
dialog.deleteVehicle = false;
|
|
354
|
-
selectedVehicleId.value = null
|
|
355
383
|
showMessage(res.message, "success");
|
|
356
|
-
getVehiclesRefresh();
|
|
384
|
+
await getVehiclesRefresh();
|
|
357
385
|
} catch (error: any) {
|
|
358
386
|
console.error("Error deleting vehicle:", error);
|
|
359
387
|
message.value = error.response._data.message;
|
|
@@ -366,24 +394,21 @@ async function submitDelete() {
|
|
|
366
394
|
|
|
367
395
|
async function submitRestore() {
|
|
368
396
|
|
|
369
|
-
|
|
370
|
-
const plateNumberId = selectedPlateNumberObject.value?._id;
|
|
371
|
-
|
|
397
|
+
const vehicleId = selectedPlateNumberObject.value?._id;
|
|
372
398
|
|
|
373
|
-
if (!
|
|
374
|
-
showMessage("Invalid
|
|
399
|
+
if (!vehicleId) {
|
|
400
|
+
showMessage("Invalid vehicle Id selected for restoration.", "error");
|
|
375
401
|
return;
|
|
376
402
|
}
|
|
377
403
|
|
|
378
404
|
try {
|
|
379
|
-
restoringVehicle.value = true;
|
|
405
|
+
restoringVehicle.value = true;
|
|
380
406
|
// reactivate and restore will use the same endpoint, just with different payload
|
|
381
|
-
const res = await approveVehicle({ site: props.site, org: props.org, id:
|
|
407
|
+
const res = await approveVehicle({ site: props.site, org: props.org, id: vehicleId as string }
|
|
382
408
|
);
|
|
383
409
|
dialog.restoreVehicle = false;
|
|
384
|
-
selectedVehicleId.value = null
|
|
385
410
|
showMessage(res.message, "success");
|
|
386
|
-
getVehiclesRefresh();
|
|
411
|
+
await getVehiclesRefresh();
|
|
387
412
|
} catch (error: any) {
|
|
388
413
|
console.error("Error restoring vehicle:", error);
|
|
389
414
|
const errMessage = error?.response?._data?.message || "Failed to restore vehicle";
|
|
@@ -395,6 +420,55 @@ async function submitRestore() {
|
|
|
395
420
|
}
|
|
396
421
|
|
|
397
422
|
|
|
423
|
+
async function submitUpdateType() {
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
const vehicleId = selectedPlateNumberObject.value?._id;
|
|
427
|
+
const type = selectedPlateNumberObject.value?.type as TVehicleType;
|
|
428
|
+
const recNo = selectedPlateNumberObject.value?.recNo;
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
if (!type) {
|
|
432
|
+
showMessage("Invalid vehicle type.", "error");
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
// if(!recNo){
|
|
437
|
+
// showMessage("Invalid vehicle record number.", "error");
|
|
438
|
+
// return;
|
|
439
|
+
// }
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
const payload = {
|
|
443
|
+
site: props.site,
|
|
444
|
+
plateNumber: selectedPlateNumberObject.value?.plateNumber as string,
|
|
445
|
+
type: type === "whitelist" ? "blocklist" : "whitelist" as TVehicleType,
|
|
446
|
+
// recno: recNo
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
if (!vehicleId) {
|
|
451
|
+
showMessage("Invalid vehicle Id selected for updating type.", "error");
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
try {
|
|
456
|
+
updatingType.value = true;
|
|
457
|
+
const res = await updateVehicle(vehicleId as string, payload);
|
|
458
|
+
dialog.updateVehicleType = false;
|
|
459
|
+
showMessage(res.message, "success");
|
|
460
|
+
await getVehiclesRefresh();
|
|
461
|
+
} catch (error: any) {
|
|
462
|
+
console.error("Error updating vehicle type:", error);
|
|
463
|
+
const errMessage = error?.response?._data?.message || "Failed to update vehicle type";
|
|
464
|
+
showMessage(errMessage, "error");
|
|
465
|
+
// message.value = error.response._data.message;
|
|
466
|
+
} finally {
|
|
467
|
+
updatingType.value = false;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
|
|
398
472
|
async function submitApprove() {
|
|
399
473
|
|
|
400
474
|
const plateNumberId = selectedPlateNumberObject.value?._id;
|
|
@@ -404,14 +478,13 @@ async function submitApprove() {
|
|
|
404
478
|
}
|
|
405
479
|
|
|
406
480
|
try {
|
|
407
|
-
approvingVehicle.value = true;
|
|
481
|
+
approvingVehicle.value = true;
|
|
408
482
|
const res = await approveVehicle({ site: props.site, org: props.org, id: plateNumberId as string }
|
|
409
483
|
|
|
410
484
|
);
|
|
411
485
|
dialog.approveVehicle = false;
|
|
412
|
-
selectedVehicleId.value = null
|
|
413
486
|
showMessage(res.message, "success");
|
|
414
|
-
getVehiclesRefresh();
|
|
487
|
+
await getVehiclesRefresh();
|
|
415
488
|
} catch (error: any) {
|
|
416
489
|
console.error("Error approving vehicle:", error);
|
|
417
490
|
const errMessage = error?.response?._data?.message || "Failed to approve vehicle";
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
<div class="w-100 d-flex justify-space-between ga-2">
|
|
13
13
|
<span class="text-subtitle-1 w-100 font-weight-bold mb-3">{{
|
|
14
14
|
formTitle
|
|
15
|
-
|
|
16
|
-
<span v-if="
|
|
17
|
-
<span class="text-primary-button">{{ contractorStep }}</span>/3</span>
|
|
15
|
+
}}</span>
|
|
16
|
+
<span v-if="withStep2 || withStep3" class="text-subtitle-2 font-weight-bold" style="text-wrap: nowrap">Step
|
|
17
|
+
<span class="text-primary-button">{{ contractorStep }}</span>/{{ withStep3 ? 3 : withStep2 ? 2 : 1 }}</span>
|
|
18
18
|
</div>
|
|
19
19
|
<v-form ref="formRef" v-model="validForm" :disabled="processing" @click="errorMessage = ''">
|
|
20
20
|
<v-row no-gutters class="pt-4">
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<v-list-item-title @click.stop="handleAddNewContractorType" class="d-flex align-center ga-1">
|
|
31
31
|
<span><v-icon icon="mdi-plus" /></span> Add "<strong>{{
|
|
32
32
|
contractorTypeInput
|
|
33
|
-
|
|
33
|
+
}}</strong>" as custom contractor type.
|
|
34
34
|
</v-list-item-title>
|
|
35
35
|
</v-list-item>
|
|
36
36
|
</template>
|
|
@@ -115,8 +115,7 @@
|
|
|
115
115
|
<InputLabel class="text-capitalize" title="Delivery Company" />
|
|
116
116
|
<v-combobox v-model="deliveryCompany" v-model:search="deliveryCompanyInput" ref="companyCombo"
|
|
117
117
|
autocomplete="off" :hide-no-data="false" :items="deliveryCompanyList" item-value="value"
|
|
118
|
-
:loading="siteDataPending" variant="outlined"
|
|
119
|
-
density="comfortable" persistent-hint small-chips>
|
|
118
|
+
:loading="siteDataPending" variant="outlined" density="comfortable" persistent-hint small-chips>
|
|
120
119
|
<template v-slot:no-data>
|
|
121
120
|
<v-list-item>
|
|
122
121
|
<v-list-item-title v-if="fetchCompanyListPending">
|
|
@@ -183,22 +182,17 @@
|
|
|
183
182
|
<v-textarea v-model="visitor.remarks" density="comfortable" :rows="3" no-resize />
|
|
184
183
|
</v-col>
|
|
185
184
|
|
|
186
|
-
<v-col v-if="
|
|
187
|
-
<PassInformation :
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
v-model="
|
|
191
|
-
|
|
192
|
-
v-model:cards="passCards"
|
|
193
|
-
:settings="entryPassSettings"
|
|
194
|
-
:loading="entryPassSettingsPending"
|
|
195
|
-
:site-id="prop.site"
|
|
196
|
-
:unit-id="visitor.unit || null"
|
|
197
|
-
/>
|
|
185
|
+
<v-col v-if="(withStep2 || withStep3) && contractorStep === 2" cols="12">
|
|
186
|
+
<PassInformation v-model:pass="visitor.visitorPass" v-model:keys="visitor.passKeys" :site="prop.site"
|
|
187
|
+
:type="prop.type" :contractor-type="visitor.contractorType" :hide-keys="!showShowKeysField" />
|
|
188
|
+
<EntryPassInformation v-if="entryPassSettings?.data?.settings?.nfcPass" v-model="passType"
|
|
189
|
+
v-model:quantity="passQuantity" v-model:cards="passCards" :settings="entryPassSettings"
|
|
190
|
+
:loading="entryPassSettingsPending" :site-id="prop.site" :unit-id="visitor.unit || null" />
|
|
198
191
|
</v-col>
|
|
199
192
|
|
|
200
|
-
<v-col v-if="
|
|
201
|
-
<MemberInformation v-model="visitor.members"
|
|
193
|
+
<v-col v-if="withStep3 && contractorStep === 3" cols="12">
|
|
194
|
+
<MemberInformation v-model="visitor.members" :type="prop.type" :contractor-type="visitor.contractorType"
|
|
195
|
+
:site="prop.site" :selected-visitor-pass="visitor.visitorPass" />
|
|
202
196
|
</v-col>
|
|
203
197
|
|
|
204
198
|
<v-col v-if="prop.mode === 'add'" cols="12" class="mt-2">
|
|
@@ -224,7 +218,7 @@
|
|
|
224
218
|
<v-col cols="6">
|
|
225
219
|
<v-btn v-if="
|
|
226
220
|
prop.mode === 'add' &&
|
|
227
|
-
|
|
221
|
+
(withStep2 || withStep3) &&
|
|
228
222
|
contractorStep > 1
|
|
229
223
|
" tile block variant="text" class="text-none" size="48" @click="handleGoToPreviousPage" text="Back" />
|
|
230
224
|
<v-btn v-else-if="prop.mode === 'add' || prop.mode === 'register'" tile block variant="text" class="text-none"
|
|
@@ -232,10 +226,11 @@
|
|
|
232
226
|
<v-btn v-else tile block variant="text" class="text-none" size="48" @click="emit('close:all')" text="Close" />
|
|
233
227
|
</v-col>
|
|
234
228
|
<v-col cols="6">
|
|
235
|
-
<v-btn v-if="
|
|
236
|
-
|
|
229
|
+
<v-btn v-if="showNextButton" tile block variant="flat" color="primary-button" class="text-none" size="48"
|
|
230
|
+
:disabled="processing" @click="handleNextPage" :text="'Next'" />
|
|
237
231
|
<v-btn v-else tile block variant="flat" color="black" class="text-none" size="48"
|
|
238
|
-
:disabled="!validForm || processing" @click="submit"
|
|
232
|
+
:disabled="!validForm || processing || membersFieldIncomplete" @click="submit"
|
|
233
|
+
:text="prop.mode == 'add' ? 'Submit' : 'Update'" />
|
|
239
234
|
</v-col>
|
|
240
235
|
</v-row>
|
|
241
236
|
</v-toolbar>
|
|
@@ -353,6 +348,8 @@ const visitor = reactive<Partial<TVisitorPayload>>({
|
|
|
353
348
|
remarks: "",
|
|
354
349
|
attachments: [],
|
|
355
350
|
members: [],
|
|
351
|
+
visitorPass: [],
|
|
352
|
+
passKeys: []
|
|
356
353
|
});
|
|
357
354
|
|
|
358
355
|
const passType = ref<string | null>(null);
|
|
@@ -400,12 +397,34 @@ const vehicleNumberUserItems = ref<TPeople[]>([])
|
|
|
400
397
|
|
|
401
398
|
|
|
402
399
|
const shouldShowField = (fieldKey: keyof TVisitorPayload | 'delivery-company') => {
|
|
403
|
-
if (
|
|
400
|
+
if ((!withStep2.value && !withStep3.value) || contractorStep.value === 1) {
|
|
404
401
|
const visibleFields = typeFieldMap[prop.type];
|
|
405
402
|
return visibleFields?.includes(fieldKey);
|
|
406
403
|
}
|
|
407
404
|
};
|
|
408
405
|
|
|
406
|
+
const withStep2 = computed(() => {
|
|
407
|
+
const step2Types = ["guest", "walk-in"];
|
|
408
|
+
return step2Types.includes(prop.type);
|
|
409
|
+
})
|
|
410
|
+
|
|
411
|
+
const withStep3 = computed(() => {
|
|
412
|
+
const step3Types = ["contractor"];
|
|
413
|
+
return step3Types.includes(prop.type);
|
|
414
|
+
})
|
|
415
|
+
|
|
416
|
+
const showNextButton = computed(() => {
|
|
417
|
+
if (withStep3.value) {
|
|
418
|
+
return contractorStep.value === 1 || contractorStep.value === 2
|
|
419
|
+
} else if (withStep2.value) {
|
|
420
|
+
return contractorStep.value === 1
|
|
421
|
+
} else return false
|
|
422
|
+
})
|
|
423
|
+
|
|
424
|
+
const showShowKeysField = computed(() => {
|
|
425
|
+
return prop.type === "contractor"
|
|
426
|
+
})
|
|
427
|
+
|
|
409
428
|
const requireNRIC = computed(() => {
|
|
410
429
|
return prop.type !== 'walk-in' && prop.type !== 'guest';
|
|
411
430
|
})
|
|
@@ -415,8 +434,10 @@ const companyAutofillDataArray = ref<{ companyName: string[], unit: string, bloc
|
|
|
415
434
|
|
|
416
435
|
const formTitle = computed(() => {
|
|
417
436
|
const isContractorForm = prop.type === "contractor";
|
|
437
|
+
const isDriveInForm = prop.type === "guest";
|
|
438
|
+
const isWalkInForm = prop.type === "walk-in";
|
|
418
439
|
const step = contractorStep.value;
|
|
419
|
-
if (isContractorForm && step === 2) {
|
|
440
|
+
if ((isContractorForm || isDriveInForm || isWalkInForm) && step === 2) {
|
|
420
441
|
return "Pass & Keys Information";
|
|
421
442
|
} else if (isContractorForm && step === 3) {
|
|
422
443
|
return "Members Information";
|
|
@@ -519,7 +540,7 @@ const {
|
|
|
519
540
|
}
|
|
520
541
|
);
|
|
521
542
|
|
|
522
|
-
watch(fetchPersonByContactReq, (obj) => {
|
|
543
|
+
watch(fetchPersonByContactReq, (obj: Partial<TPerson>) => {
|
|
523
544
|
if (obj) {
|
|
524
545
|
currentAutofillSource.value = "contact";
|
|
525
546
|
companyNames.value = obj.companyName ?? []
|
|
@@ -568,7 +589,7 @@ watch(fetchVisitorListByVehicleNumberReq, (arr: any) => {
|
|
|
568
589
|
const itemsArray = arr?.items || []
|
|
569
590
|
const isValidArray = Array.isArray(itemsArray)
|
|
570
591
|
matchingPlateNumberNonCheckedOutArr.value = isValidArray ? itemsArray : []
|
|
571
|
-
if(matchingPlateNumberNonCheckedOutArr.value.length > 0) {
|
|
592
|
+
if (matchingPlateNumberNonCheckedOutArr.value.length > 0) {
|
|
572
593
|
dialog.showNonCheckedOutDialog = true;
|
|
573
594
|
} else {
|
|
574
595
|
dialog.showNonCheckedOutDialog = false;
|
|
@@ -603,7 +624,7 @@ async function handleCheckout(visitorId: string) {
|
|
|
603
624
|
checkOut: new Date().toISOString(),
|
|
604
625
|
});
|
|
605
626
|
if (res) {
|
|
606
|
-
await fetchVisitorListByVehicleNumberRefresh();
|
|
627
|
+
await fetchVisitorListByVehicleNumberRefresh();
|
|
607
628
|
|
|
608
629
|
}
|
|
609
630
|
} catch (error: any) {
|
|
@@ -876,6 +897,15 @@ async function submit() {
|
|
|
876
897
|
};
|
|
877
898
|
}
|
|
878
899
|
}
|
|
900
|
+
|
|
901
|
+
const isGuest = prop.type === "guest";
|
|
902
|
+
const isWalkIn = prop.type === "walk-in";
|
|
903
|
+
const isContractor = prop.type === "contractor";
|
|
904
|
+
if (isGuest || isWalkIn || isContractor) {
|
|
905
|
+
payload.visitorPass = visitor.visitorPass;
|
|
906
|
+
payload.passKeys = visitor.passKeys;
|
|
907
|
+
}
|
|
908
|
+
|
|
879
909
|
}
|
|
880
910
|
|
|
881
911
|
|
|
@@ -888,7 +918,7 @@ async function submit() {
|
|
|
888
918
|
};
|
|
889
919
|
}
|
|
890
920
|
|
|
891
|
-
if(prop.type === "delivery"){
|
|
921
|
+
if (prop.type === "delivery") {
|
|
892
922
|
payload = {
|
|
893
923
|
...payload,
|
|
894
924
|
company: deliveryCompany.value
|
|
@@ -969,6 +999,18 @@ watch(
|
|
|
969
999
|
}
|
|
970
1000
|
);
|
|
971
1001
|
|
|
1002
|
+
const membersFieldIncomplete = computed(() => {
|
|
1003
|
+
if (!visitor.members || visitor.members.length === 0) return false;
|
|
1004
|
+
|
|
1005
|
+
return visitor.members.some((member) => {
|
|
1006
|
+
const hasName = !!member.name;
|
|
1007
|
+
const hasNric = !!member.nric;
|
|
1008
|
+
const hasContact = !!member.contact;
|
|
1009
|
+
|
|
1010
|
+
return !hasName || !hasNric || !hasContact;
|
|
1011
|
+
});
|
|
1012
|
+
});
|
|
1013
|
+
|
|
972
1014
|
onMounted(() => {
|
|
973
1015
|
contractorStep.value = 2;
|
|
974
1016
|
currentAutofillSource.value = null;
|