@7365admin1/layer-common 1.11.29 → 1.11.30
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/VisitorManagement.vue +677 -227
- package/components/VisitorsReportPreview.vue +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,51 +1,137 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-row no-gutters>
|
|
3
|
-
<TableMain
|
|
4
|
-
:
|
|
5
|
-
|
|
3
|
+
<TableMain
|
|
4
|
+
:headers="headers"
|
|
5
|
+
:items="items"
|
|
6
|
+
:loading="getVisitorPending"
|
|
7
|
+
:page="page"
|
|
8
|
+
:pages="pages"
|
|
9
|
+
:extension-height="110"
|
|
10
|
+
:offset="300"
|
|
11
|
+
:pageRange="pageRange"
|
|
12
|
+
@refresh="getVisitorRefresh"
|
|
13
|
+
@update:page="handleUpdatePage"
|
|
14
|
+
show-header
|
|
15
|
+
@row-click="handleRowClick"
|
|
16
|
+
>
|
|
6
17
|
<template #actions>
|
|
7
18
|
<v-row no-gutters>
|
|
8
|
-
<v-btn
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
19
|
+
<v-btn
|
|
20
|
+
v-if="canAddVisitor"
|
|
21
|
+
class="text-none"
|
|
22
|
+
rounded="pill"
|
|
23
|
+
variant="tonal"
|
|
24
|
+
size="large"
|
|
25
|
+
@click="handleAddNew"
|
|
26
|
+
text="Add Visitor"
|
|
27
|
+
/>
|
|
28
|
+
<v-btn
|
|
29
|
+
v-if="canScanVisitorQRCode"
|
|
30
|
+
text="Scan QR Code"
|
|
31
|
+
class="text-none ml-2"
|
|
32
|
+
rounded="pill"
|
|
33
|
+
variant="tonal"
|
|
34
|
+
size="large"
|
|
35
|
+
@click="dialog.scanVisitorQRCode = true"
|
|
36
|
+
/>
|
|
12
37
|
<v-menu>
|
|
13
38
|
<template #activator="{ props }">
|
|
14
|
-
<v-btn
|
|
15
|
-
|
|
39
|
+
<v-btn
|
|
40
|
+
v-bind="props"
|
|
41
|
+
text="Download Report"
|
|
42
|
+
class="text-none ml-2"
|
|
43
|
+
prepend-icon="mdi-download"
|
|
44
|
+
rounded="pill"
|
|
45
|
+
variant="tonal"
|
|
46
|
+
size="large"
|
|
47
|
+
/>
|
|
16
48
|
</template>
|
|
17
49
|
<v-list>
|
|
18
|
-
<v-list-item
|
|
19
|
-
|
|
50
|
+
<v-list-item
|
|
51
|
+
prepend-icon="mdi-file-pdf"
|
|
52
|
+
title="Download PDF Report"
|
|
53
|
+
@click="handleDownloadPDFReport"
|
|
54
|
+
/>
|
|
55
|
+
<v-list-item
|
|
56
|
+
prepend-icon="mdi-file-csv"
|
|
57
|
+
title="Download CSV Report"
|
|
58
|
+
@click="handleDownloadCSVReport"
|
|
59
|
+
/>
|
|
20
60
|
</v-list>
|
|
21
61
|
</v-menu>
|
|
22
62
|
</v-row>
|
|
23
63
|
</template>
|
|
24
64
|
<template #extension>
|
|
25
65
|
<v-row no-gutters class="w-100 d-flex flex-column">
|
|
26
|
-
<v-tabs
|
|
27
|
-
|
|
66
|
+
<v-tabs
|
|
67
|
+
v-model="activeTab"
|
|
68
|
+
color="primary"
|
|
69
|
+
:height="40"
|
|
70
|
+
@update:model-value="toRoute"
|
|
71
|
+
class="w-100"
|
|
72
|
+
>
|
|
73
|
+
<v-tab
|
|
74
|
+
v-for="tab in tabOptions"
|
|
75
|
+
:value="tab.value"
|
|
76
|
+
:key="tab.value"
|
|
77
|
+
class="text-capitalize"
|
|
78
|
+
>
|
|
28
79
|
{{ tab.name }}
|
|
29
80
|
</v-tab>
|
|
30
81
|
</v-tabs>
|
|
31
82
|
|
|
32
|
-
<v-card
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
83
|
+
<v-card
|
|
84
|
+
class="w-100 px-3 d-flex align-center ga-5 py-2"
|
|
85
|
+
flat
|
|
86
|
+
:height="60"
|
|
87
|
+
>
|
|
88
|
+
<v-text-field
|
|
89
|
+
v-model="searchInput"
|
|
90
|
+
density="compact"
|
|
91
|
+
placeholder="Search"
|
|
92
|
+
clearable
|
|
93
|
+
max-width="300"
|
|
94
|
+
append-inner-icon="mdi-magnify"
|
|
95
|
+
hide-details
|
|
96
|
+
/>
|
|
97
|
+
<v-checkbox
|
|
98
|
+
v-model="displayNotCheckedOut"
|
|
99
|
+
class="text-subtitle-2"
|
|
100
|
+
hide-details
|
|
101
|
+
>
|
|
36
102
|
<template #label>
|
|
37
103
|
<span class="text-caption">Not Checked Out</span>
|
|
38
104
|
</template>
|
|
39
105
|
</v-checkbox>
|
|
40
|
-
<InputDatePicker
|
|
106
|
+
<InputDatePicker
|
|
107
|
+
v-model="dateFrom"
|
|
108
|
+
density="compact"
|
|
109
|
+
hide-details
|
|
110
|
+
/>
|
|
41
111
|
<InputDatePicker v-model="dateTo" density="compact" hide-details />
|
|
42
|
-
<v-select
|
|
43
|
-
|
|
44
|
-
|
|
112
|
+
<v-select
|
|
113
|
+
v-if="activeTab == 'registered'"
|
|
114
|
+
v-model="filterTypes"
|
|
115
|
+
label="Filter by types"
|
|
116
|
+
item-title="label"
|
|
117
|
+
item-value="value"
|
|
118
|
+
:items="visitorSelection"
|
|
119
|
+
density="compact"
|
|
120
|
+
clearable
|
|
121
|
+
multiple
|
|
122
|
+
max-width="200"
|
|
123
|
+
hide-details
|
|
124
|
+
>
|
|
45
125
|
<template v-slot:selection="{ item, index }">
|
|
46
126
|
<div class="d-flex align-center text-caption text-nowrap">
|
|
47
|
-
<v-chip
|
|
48
|
-
|
|
127
|
+
<v-chip
|
|
128
|
+
v-if="index === 0"
|
|
129
|
+
color="error"
|
|
130
|
+
:text="filterTypeSelectionLabel()"
|
|
131
|
+
size="x-small"
|
|
132
|
+
variant="tonal"
|
|
133
|
+
class="ml-2"
|
|
134
|
+
/>
|
|
49
135
|
</div>
|
|
50
136
|
</template>
|
|
51
137
|
</v-select>
|
|
@@ -60,8 +146,9 @@
|
|
|
60
146
|
</span>
|
|
61
147
|
<span class="text-capitalize">{{ item?.name }}</span>
|
|
62
148
|
</span>
|
|
63
|
-
<span class="text-grey text-caption" v-if="item?.members?.length > 0"
|
|
64
|
-
members)</span
|
|
149
|
+
<span class="text-grey text-caption" v-if="item?.members?.length > 0"
|
|
150
|
+
>( +{{ item?.members?.length }} members)</span
|
|
151
|
+
>
|
|
65
152
|
</template>
|
|
66
153
|
|
|
67
154
|
<template v-slot:item.email="{ value }">
|
|
@@ -70,7 +157,12 @@
|
|
|
70
157
|
|
|
71
158
|
<template v-slot:item.invited-by="{ item }">
|
|
72
159
|
<span class="d-flex align-center ga-2">
|
|
73
|
-
<AvatarMain
|
|
160
|
+
<AvatarMain
|
|
161
|
+
v-if="item?.inviterName"
|
|
162
|
+
:name="item?.inviterName"
|
|
163
|
+
:size="20"
|
|
164
|
+
:id="item?._id"
|
|
165
|
+
/>
|
|
74
166
|
<span class="text-capitalize">{{ item?.inviterName ?? "N/A" }}</span>
|
|
75
167
|
</span>
|
|
76
168
|
</template>
|
|
@@ -80,7 +172,7 @@
|
|
|
80
172
|
<v-icon icon="mdi-user" size="15" />
|
|
81
173
|
<span v-if="item.type === 'contractor'" class="text-capitalize">{{
|
|
82
174
|
formatCamelCaseToWords(item.contractorType)
|
|
83
|
-
|
|
175
|
+
}}</span>
|
|
84
176
|
<span v-else class="text-capitalize">{{ formatType(item) }}</span>
|
|
85
177
|
</span>
|
|
86
178
|
<span class="d-flex align-center ga-2">
|
|
@@ -116,76 +208,162 @@
|
|
|
116
208
|
<template v-slot:item.checkin-out="{ item }">
|
|
117
209
|
<v-row no-gutters class="d-flex flex-column py-2">
|
|
118
210
|
<span class="d-flex align-center ga-2">
|
|
119
|
-
<v-icon
|
|
120
|
-
|
|
121
|
-
|
|
211
|
+
<v-icon
|
|
212
|
+
icon="mdi-clock-time-eight-outline"
|
|
213
|
+
color="success"
|
|
214
|
+
size="20"
|
|
215
|
+
/>
|
|
216
|
+
<template v-if="!item.checkIn && canUpdateVisitor">
|
|
217
|
+
<v-btn
|
|
218
|
+
size="x-small"
|
|
219
|
+
class="text-capitalize"
|
|
220
|
+
color="success"
|
|
221
|
+
text="Checkin"
|
|
222
|
+
:disabled="isVisitorDataFromScannedQRCodeCheckingInOut"
|
|
223
|
+
@click.stop="handleCheckin(item)"
|
|
224
|
+
:loading="isVisitorDataFromScannedQRCodeCheckingInOut"
|
|
225
|
+
/>
|
|
226
|
+
</template>
|
|
227
|
+
<template v-else>
|
|
228
|
+
<span class="text-capitalize">{{
|
|
229
|
+
UTCToLocalTIme(item.checkIn)
|
|
122
230
|
}}</span>
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
231
|
+
<span>
|
|
232
|
+
<v-icon
|
|
233
|
+
v-if="item?.snapshotEntryImage"
|
|
234
|
+
size="17"
|
|
235
|
+
icon="mdi-image"
|
|
236
|
+
@click.stop="handleViewImage(item.snapshotEntryImage)"
|
|
237
|
+
/>
|
|
238
|
+
</span>
|
|
239
|
+
</template>
|
|
127
240
|
</span>
|
|
128
241
|
|
|
129
|
-
<span
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
item?.status === '
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
242
|
+
<span
|
|
243
|
+
v-if="
|
|
244
|
+
!item.checkOut &&
|
|
245
|
+
(item?.status === 'registered' ||
|
|
246
|
+
item?.status === 'unregistered') &&
|
|
247
|
+
canCheckoutVisitor
|
|
248
|
+
"
|
|
249
|
+
>
|
|
250
|
+
<span
|
|
251
|
+
class="d-flex align-center ga-2"
|
|
252
|
+
v-bind="menuProps"
|
|
253
|
+
style="cursor: pointer"
|
|
254
|
+
>
|
|
255
|
+
<v-icon
|
|
256
|
+
icon="mdi-clock-time-eight-outline"
|
|
257
|
+
color="red"
|
|
258
|
+
size="20"
|
|
259
|
+
/>
|
|
260
|
+
<v-btn
|
|
261
|
+
size="x-small"
|
|
262
|
+
class="text-capitalize"
|
|
263
|
+
color="red"
|
|
264
|
+
text="Checkout"
|
|
265
|
+
:loading="
|
|
266
|
+
loading.checkingOut && item?._id === selectedVisitorId
|
|
267
|
+
"
|
|
268
|
+
@click.stop="handleCheckout(item._id)"
|
|
269
|
+
/>
|
|
139
270
|
</span>
|
|
140
271
|
</span>
|
|
141
272
|
<span v-else class="d-flex align-center ga-2">
|
|
142
273
|
<v-icon icon="mdi-clock-time-eight-outline" color="red" size="20" />
|
|
143
274
|
<template v-if="item.checkOut">
|
|
144
275
|
<span class="text-capitalize">{{
|
|
145
|
-
UTCToLocalTIme(item.checkOut)
|
|
146
|
-
|
|
276
|
+
UTCToLocalTIme(item.checkOut)
|
|
277
|
+
}}</span>
|
|
147
278
|
<span>
|
|
148
|
-
<v-icon
|
|
149
|
-
|
|
279
|
+
<v-icon
|
|
280
|
+
v-if="item?.snapshotExitImage"
|
|
281
|
+
size="17"
|
|
282
|
+
icon="mdi-image"
|
|
283
|
+
@click.stop="handleViewImage(item.snapshotExitImage)"
|
|
284
|
+
/>
|
|
150
285
|
</span>
|
|
151
286
|
<span v-if="item?.manualCheckout">
|
|
152
|
-
<TooltipInfo
|
|
287
|
+
<TooltipInfo
|
|
288
|
+
text="Manual Checkout"
|
|
289
|
+
density="compact"
|
|
290
|
+
size="x-small"
|
|
291
|
+
/>
|
|
153
292
|
</span>
|
|
154
293
|
</template>
|
|
294
|
+
<template v-else> <span class="mt-1"> N/A </span> </template>
|
|
155
295
|
</span>
|
|
156
296
|
|
|
157
|
-
<div
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
297
|
+
<div
|
|
298
|
+
v-if="showAddPassKeyButton(item)"
|
|
299
|
+
class="d-flex flex-wrap ga-1 mt-1"
|
|
300
|
+
v-bind="menuProps"
|
|
301
|
+
style="cursor: pointer"
|
|
302
|
+
>
|
|
303
|
+
<v-chip
|
|
304
|
+
size="x-small"
|
|
305
|
+
variant="tonal"
|
|
306
|
+
prepend-icon="mdi-key"
|
|
307
|
+
@click.stop="handleOpenAddPassKey(item)"
|
|
308
|
+
>Add Pass/Key</v-chip
|
|
309
|
+
>
|
|
161
310
|
</div>
|
|
162
311
|
|
|
163
312
|
<v-menu :close-on-content-click="true">
|
|
164
313
|
<template v-slot:activator="{ props: menuProps }">
|
|
165
|
-
<div
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
314
|
+
<div
|
|
315
|
+
v-if="
|
|
316
|
+
(item.visitorPass?.length ?? 0) > 0 ||
|
|
317
|
+
(item.passKeys?.length ?? 0) > 0
|
|
318
|
+
"
|
|
319
|
+
class="d-flex flex-wrap ga-1 mt-1"
|
|
320
|
+
v-bind="menuProps"
|
|
321
|
+
style="cursor: pointer"
|
|
322
|
+
>
|
|
323
|
+
<v-chip
|
|
324
|
+
v-for="pass in item.visitorPass"
|
|
325
|
+
:key="(pass as any)._id ?? (pass as any).keyId"
|
|
326
|
+
prepend-icon="mdi-card-bulleted-outline"
|
|
327
|
+
size="x-small"
|
|
328
|
+
variant="tonal"
|
|
329
|
+
color="blue"
|
|
330
|
+
>
|
|
171
331
|
{{ (pass as any)?.prefixAndName }}
|
|
172
332
|
</v-chip>
|
|
173
|
-
<v-chip
|
|
174
|
-
|
|
333
|
+
<v-chip
|
|
334
|
+
v-for="key in item.passKeys"
|
|
335
|
+
:key="(key as any)._id ?? (key as any).keyId"
|
|
336
|
+
prepend-icon="mdi-key"
|
|
337
|
+
size="x-small"
|
|
338
|
+
variant="tonal"
|
|
339
|
+
color="orange"
|
|
340
|
+
>
|
|
175
341
|
{{ (key as any)?.prefixAndName }}
|
|
176
342
|
</v-chip>
|
|
177
343
|
</div>
|
|
178
344
|
</template>
|
|
179
345
|
<v-list density="compact">
|
|
180
|
-
<v-list-item
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
(item.
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
346
|
+
<v-list-item
|
|
347
|
+
v-if="!item?.checkOut"
|
|
348
|
+
prepend-icon="mdi-logout"
|
|
349
|
+
title="Checkout"
|
|
350
|
+
@click.stop="handleCheckout(item._id)"
|
|
351
|
+
/>
|
|
352
|
+
<v-list-item
|
|
353
|
+
v-if="
|
|
354
|
+
(item.visitorPass?.length ?? 0) > 0 ||
|
|
355
|
+
(item.passKeys?.length ?? 0) > 0
|
|
356
|
+
"
|
|
357
|
+
prepend-icon="mdi-card-bulleted-outline"
|
|
358
|
+
:title="item.checkOut ? 'View Pass/Key' : 'Edit Pass/Key'"
|
|
359
|
+
@click.stop="handleOpenEditPassKey(item)"
|
|
360
|
+
/>
|
|
361
|
+
<v-list-item
|
|
362
|
+
v-if="showAddPassKeyButton(item)"
|
|
363
|
+
prepend-icon="mdi-plus"
|
|
364
|
+
title="Add Pass/Key"
|
|
365
|
+
@click.stop="handleOpenAddPassKey(item)"
|
|
366
|
+
/>
|
|
189
367
|
</v-list>
|
|
190
368
|
</v-menu>
|
|
191
369
|
</v-row>
|
|
@@ -201,30 +379,30 @@
|
|
|
201
379
|
<v-icon icon="mdi-clock-time-four-outline" size="20" />
|
|
202
380
|
{{ item.arrivalTime ?? "N/A" }}
|
|
203
381
|
</span>
|
|
204
|
-
|
|
205
|
-
<span v-if="!item.checkIn && canUpdateVisitor">
|
|
206
|
-
<span class="d-flex align-center ga-2 cursor-pointer">
|
|
207
|
-
<v-icon icon="mdi-clock-time-eight-outline" color="success" size="20" />
|
|
208
|
-
<v-btn size="x-small" class="text-capitalize" color="success" text="Checkin"
|
|
209
|
-
@click.stop="handleCheckin(item)" />
|
|
210
|
-
</span>
|
|
211
|
-
</span>
|
|
212
382
|
</v-row>
|
|
213
383
|
</template>
|
|
214
384
|
|
|
215
385
|
<template v-slot:item.status="{ item }">
|
|
216
|
-
<v-card
|
|
386
|
+
<v-card
|
|
387
|
+
v-if="item?.overnightParking?.status"
|
|
388
|
+
size="small"
|
|
217
389
|
class="rounded-xl text-capitalize text-center elevation-0 py-1 px-2"
|
|
218
390
|
:color="getOvernightParkingRequestStatusColor(item?.overnightParking?.status as string)"
|
|
219
|
-
style="max-width: 150px; margin: auto"
|
|
391
|
+
style="max-width: 150px; margin: auto"
|
|
392
|
+
>
|
|
220
393
|
{{ item?.overnightParking?.status }}
|
|
221
394
|
</v-card>
|
|
222
395
|
<span v-else> N/A </span>
|
|
223
396
|
</template>
|
|
224
397
|
|
|
225
398
|
<template v-slot:item.action="{ item }">
|
|
226
|
-
<v-btn
|
|
227
|
-
|
|
399
|
+
<v-btn
|
|
400
|
+
v-if="activeTab === 'unregistered' && canAddVisitor"
|
|
401
|
+
size="small"
|
|
402
|
+
color="primary"
|
|
403
|
+
text="Register"
|
|
404
|
+
@click.stop="handleRegistrationUnregisteredVisitor(item)"
|
|
405
|
+
/>
|
|
228
406
|
<v-menu v-else-if="activeTab === 'overnight-parking'">
|
|
229
407
|
<template #activator="{ props }">
|
|
230
408
|
<v-avatar v-bind="props" class="rounded-xl border-md">
|
|
@@ -233,17 +411,20 @@
|
|
|
233
411
|
</template>
|
|
234
412
|
|
|
235
413
|
<v-card>
|
|
236
|
-
<v-list-item
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
414
|
+
<v-list-item
|
|
415
|
+
v-if="
|
|
416
|
+
!overNightParkingListActions[0].disabled ||
|
|
417
|
+
!['approved', 'rejected'].includes(
|
|
418
|
+
item?.overnightParking?.status
|
|
419
|
+
)
|
|
420
|
+
"
|
|
421
|
+
@click.stop="
|
|
422
|
+
openApproveRejectOverNightParkingRequestDialog(
|
|
423
|
+
item,
|
|
424
|
+
overNightParkingListActions[0].status
|
|
425
|
+
)
|
|
426
|
+
"
|
|
427
|
+
>
|
|
247
428
|
<template #title>
|
|
248
429
|
<span class="text-caption">
|
|
249
430
|
{{ overNightParkingListActions[0].text }}
|
|
@@ -251,30 +432,36 @@
|
|
|
251
432
|
</template>
|
|
252
433
|
</v-list-item>
|
|
253
434
|
<v-divider />
|
|
254
|
-
<v-list-item
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
435
|
+
<v-list-item
|
|
436
|
+
v-if="
|
|
437
|
+
!overNightParkingListActions[1].disabled ||
|
|
438
|
+
!['approved', 'rejected'].includes(
|
|
439
|
+
item?.overnightParking?.status
|
|
440
|
+
)
|
|
441
|
+
"
|
|
442
|
+
@click="
|
|
443
|
+
openApproveRejectOverNightParkingRequestDialog(
|
|
444
|
+
item,
|
|
445
|
+
overNightParkingListActions[1].status
|
|
446
|
+
)
|
|
447
|
+
"
|
|
448
|
+
>
|
|
265
449
|
<template #title>
|
|
266
450
|
<span class="text-caption">
|
|
267
451
|
{{ overNightParkingListActions[1].text }}
|
|
268
452
|
</span>
|
|
269
453
|
</template>
|
|
270
454
|
</v-list-item>
|
|
271
|
-
<v-list-item
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
455
|
+
<v-list-item
|
|
456
|
+
v-if="item?.overnightParking?.remarks"
|
|
457
|
+
@click="
|
|
458
|
+
openApproveRejectOverNightParkingRequestDialog(
|
|
459
|
+
item,
|
|
460
|
+
overNightParkingListActions[2].status,
|
|
461
|
+
item?.overnightParking?.remarks
|
|
462
|
+
)
|
|
463
|
+
"
|
|
464
|
+
>
|
|
278
465
|
<template #title>
|
|
279
466
|
<span class="text-caption">
|
|
280
467
|
{{ overNightParkingListActions[2].text }}
|
|
@@ -288,61 +475,118 @@
|
|
|
288
475
|
|
|
289
476
|
<template v-slot:item.checkInRemarks="{ item }">
|
|
290
477
|
<span>
|
|
291
|
-
<v-btn
|
|
292
|
-
|
|
293
|
-
|
|
478
|
+
<v-btn
|
|
479
|
+
variant="text"
|
|
480
|
+
color="blue-darken-2"
|
|
481
|
+
density="compact"
|
|
482
|
+
size="small"
|
|
483
|
+
@click.stop="handleOpenRemarks(item, 'checkIn')"
|
|
484
|
+
>{{ item.checkInRemarks ? "View Remarks" : "Add Remarks" }}</v-btn
|
|
485
|
+
>
|
|
294
486
|
</span>
|
|
295
487
|
</template>
|
|
296
488
|
<template v-slot:item.checkOutRemarks="{ item }">
|
|
297
489
|
<span>
|
|
298
|
-
<v-btn
|
|
299
|
-
|
|
300
|
-
|
|
490
|
+
<v-btn
|
|
491
|
+
variant="text"
|
|
492
|
+
color="blue-darken-2"
|
|
493
|
+
density="compact"
|
|
494
|
+
size="small"
|
|
495
|
+
@click.stop="handleOpenRemarks(item, 'checkOut')"
|
|
496
|
+
>{{ item.checkOutRemarks ? "View Remarks" : "Add Remarks" }}</v-btn
|
|
497
|
+
>
|
|
301
498
|
</span>
|
|
302
499
|
</template>
|
|
303
500
|
</TableMain>
|
|
304
501
|
|
|
305
502
|
<v-dialog v-model="dialog.showSelection" width="450" persistent>
|
|
306
|
-
<VisitorFormSelection
|
|
503
|
+
<VisitorFormSelection
|
|
504
|
+
:mode="mode"
|
|
505
|
+
@cancel="dialog.showSelection = false"
|
|
506
|
+
@select="handleSelectVisitorType"
|
|
507
|
+
/>
|
|
307
508
|
</v-dialog>
|
|
308
509
|
|
|
309
|
-
<v-dialog
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
510
|
+
<v-dialog
|
|
511
|
+
v-model="dialog.showForm"
|
|
512
|
+
v-if="activeVisitorFormType"
|
|
513
|
+
width="450"
|
|
514
|
+
persistent
|
|
515
|
+
>
|
|
516
|
+
<VisitorForm
|
|
517
|
+
:mode="mode"
|
|
518
|
+
:org="orgId"
|
|
519
|
+
:site="siteId"
|
|
520
|
+
:visitor-data="selectedVisitorDataObject"
|
|
521
|
+
:type="activeVisitorFormType"
|
|
522
|
+
@back="handleClickBack"
|
|
523
|
+
@done="handleVisitorFormDone"
|
|
524
|
+
@done:more="handleVisitorFormCreateMore"
|
|
525
|
+
@close:all="handleCloseAll"
|
|
526
|
+
/>
|
|
313
527
|
</v-dialog>
|
|
314
528
|
|
|
315
529
|
<v-dialog v-model="dialog.viewVisitor" width="450" persistent>
|
|
316
|
-
<VehicleUpdateMoreAction
|
|
317
|
-
|
|
530
|
+
<VehicleUpdateMoreAction
|
|
531
|
+
title="Preview"
|
|
532
|
+
:can-update="false"
|
|
533
|
+
:can-delete="false"
|
|
534
|
+
@close="dialog.viewVisitor = false"
|
|
535
|
+
edit-button-label="Edit Visitor"
|
|
536
|
+
>
|
|
318
537
|
<template v-slot:content>
|
|
319
538
|
<v-row no-gutters class="mb-4">
|
|
320
539
|
<v-col v-for="(label, key) in formattedFields" :key="key" cols="12">
|
|
321
|
-
<span
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
540
|
+
<span
|
|
541
|
+
v-if="
|
|
542
|
+
key === 'checkIn' &&
|
|
543
|
+
!selectedVisitorObject[key] &&
|
|
544
|
+
canUpdateVisitor
|
|
545
|
+
"
|
|
546
|
+
class="d-flex align-center"
|
|
547
|
+
>
|
|
326
548
|
<strong>{{ label }}:</strong>
|
|
327
|
-
<v-btn
|
|
328
|
-
|
|
329
|
-
|
|
549
|
+
<v-btn
|
|
550
|
+
size="x-small"
|
|
551
|
+
class="ml-3 text-capitalize"
|
|
552
|
+
color="success"
|
|
553
|
+
text="Checkin"
|
|
554
|
+
:disabled="isVisitorDataFromScannedQRCodeCheckingInOut"
|
|
555
|
+
@click="handleCheckin(selectedVisitorObject)"
|
|
556
|
+
:loading="isVisitorDataFromScannedQRCodeCheckingInOut"
|
|
557
|
+
/>
|
|
330
558
|
</span>
|
|
331
|
-
<span
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
559
|
+
<span
|
|
560
|
+
v-if="
|
|
561
|
+
key === 'checkOut' &&
|
|
562
|
+
selectedVisitorObject['checkIn'] &&
|
|
563
|
+
!selectedVisitorObject[key] &&
|
|
564
|
+
canCheckoutVisitor
|
|
565
|
+
"
|
|
566
|
+
class="d-flex align-center"
|
|
567
|
+
>
|
|
337
568
|
<strong>{{ label }}:</strong>
|
|
338
|
-
<v-btn
|
|
339
|
-
|
|
569
|
+
<v-btn
|
|
570
|
+
size="x-small"
|
|
571
|
+
class="ml-3 text-capitalize"
|
|
572
|
+
color="red"
|
|
573
|
+
text="Checkout"
|
|
574
|
+
:disabled="loading.checkingOut"
|
|
575
|
+
@click="handleCheckout(selectedVisitorId as string)"
|
|
576
|
+
/>
|
|
340
577
|
</span>
|
|
341
578
|
|
|
342
|
-
<span
|
|
343
|
-
|
|
579
|
+
<span
|
|
580
|
+
v-else-if="selectedVisitorObject[key]"
|
|
581
|
+
class="d-flex ga-3 align-center"
|
|
582
|
+
><strong>{{ label }}:</strong>
|
|
344
583
|
{{ formatValues(key, selectedVisitorObject[key]) }}
|
|
345
|
-
<TooltipInfo
|
|
584
|
+
<TooltipInfo
|
|
585
|
+
v-if="key === 'checkOut'"
|
|
586
|
+
text="Manual Checkout"
|
|
587
|
+
density="compact"
|
|
588
|
+
size="x-small"
|
|
589
|
+
/>
|
|
346
590
|
</span>
|
|
347
591
|
</v-col>
|
|
348
592
|
</v-row>
|
|
@@ -354,7 +598,11 @@
|
|
|
354
598
|
<v-card>
|
|
355
599
|
<v-card-title class="d-flex justify-space-between align-center">
|
|
356
600
|
<span>Snapshot</span>
|
|
357
|
-
<v-btn
|
|
601
|
+
<v-btn
|
|
602
|
+
icon="mdi-close"
|
|
603
|
+
variant="text"
|
|
604
|
+
@click="dialog.snapshotImage = false"
|
|
605
|
+
/>
|
|
358
606
|
</v-card-title>
|
|
359
607
|
<v-card-text class="pa-2 d-flex justify-center">
|
|
360
608
|
<v-img :src="snapshotImageUrl" max-height="600" contain />
|
|
@@ -364,25 +612,51 @@
|
|
|
364
612
|
|
|
365
613
|
<v-dialog v-model="dialog.remarks" max-width="450" persistent>
|
|
366
614
|
<v-card>
|
|
367
|
-
<v-card-title
|
|
615
|
+
<v-card-title
|
|
616
|
+
class="d-flex justify-space-between align-center pt-4 px-4"
|
|
617
|
+
>
|
|
368
618
|
<span>{{
|
|
369
619
|
remarksType === "checkIn" ? "Check-In Remarks" : "Check-Out Remarks"
|
|
370
|
-
|
|
371
|
-
<v-btn
|
|
620
|
+
}}</span>
|
|
621
|
+
<v-btn
|
|
622
|
+
icon="mdi-close"
|
|
623
|
+
variant="text"
|
|
624
|
+
@click="dialog.remarks = false"
|
|
625
|
+
/>
|
|
372
626
|
</v-card-title>
|
|
373
627
|
<v-card-text class="px-4 pb-2">
|
|
374
|
-
<v-textarea
|
|
375
|
-
|
|
628
|
+
<v-textarea
|
|
629
|
+
v-model="remarksInput"
|
|
630
|
+
label="Remarks"
|
|
631
|
+
rows="4"
|
|
632
|
+
auto-grow
|
|
633
|
+
variant="outlined"
|
|
634
|
+
:readonly="remarksViewOnly"
|
|
635
|
+
/>
|
|
376
636
|
</v-card-text>
|
|
377
637
|
<v-toolbar class="pa-0" density="compact">
|
|
378
638
|
<v-row no-gutters>
|
|
379
639
|
<v-col cols="6">
|
|
380
|
-
<v-btn
|
|
381
|
-
|
|
640
|
+
<v-btn
|
|
641
|
+
variant="text"
|
|
642
|
+
block
|
|
643
|
+
:disabled="loading.savingRemarks"
|
|
644
|
+
@click="dialog.remarks = false"
|
|
645
|
+
>Cancel</v-btn
|
|
646
|
+
>
|
|
382
647
|
</v-col>
|
|
383
648
|
<v-col cols="6">
|
|
384
|
-
<v-btn
|
|
385
|
-
|
|
649
|
+
<v-btn
|
|
650
|
+
color="primary"
|
|
651
|
+
variant="flat"
|
|
652
|
+
height="48"
|
|
653
|
+
rounded="0"
|
|
654
|
+
block
|
|
655
|
+
:loading="loading.savingRemarks"
|
|
656
|
+
:disabled="!remarksInput.trim()"
|
|
657
|
+
@click="handleSaveRemarks"
|
|
658
|
+
>Save</v-btn
|
|
659
|
+
>
|
|
386
660
|
</v-col>
|
|
387
661
|
</v-row>
|
|
388
662
|
</v-toolbar>
|
|
@@ -392,9 +666,16 @@
|
|
|
392
666
|
<v-dialog v-model="dialog.returnPassesKeys" max-width="450" persistent>
|
|
393
667
|
<v-card>
|
|
394
668
|
<v-toolbar density="compact" color="">
|
|
395
|
-
<v-row
|
|
669
|
+
<v-row
|
|
670
|
+
no-gutters
|
|
671
|
+
class="d-flex fill-height justify-space-between align-center px-4"
|
|
672
|
+
>
|
|
396
673
|
<span class="font-weight-bold">Return Passes & Keys</span>
|
|
397
|
-
<v-btn
|
|
674
|
+
<v-btn
|
|
675
|
+
icon="mdi-close"
|
|
676
|
+
variant="text"
|
|
677
|
+
@click="dialog.returnPassesKeys = false"
|
|
678
|
+
/>
|
|
398
679
|
</v-row>
|
|
399
680
|
</v-toolbar>
|
|
400
681
|
<v-card-text class="px-4 pb-2">
|
|
@@ -404,55 +685,134 @@
|
|
|
404
685
|
|
|
405
686
|
<div>
|
|
406
687
|
<InputLabel class="text-capitalize" title="Full Name" />
|
|
407
|
-
<v-text-field
|
|
688
|
+
<v-text-field
|
|
689
|
+
v-model="selectedVisitorObject.name"
|
|
690
|
+
density="comfortable"
|
|
691
|
+
readonly
|
|
692
|
+
/>
|
|
408
693
|
</div>
|
|
409
694
|
|
|
410
695
|
<div>
|
|
411
696
|
<InputLabel class="text-capitalize" title="Location" />
|
|
412
|
-
<v-text-field
|
|
697
|
+
<v-text-field
|
|
698
|
+
v-model="selectedVisitorObject.location"
|
|
699
|
+
density="comfortable"
|
|
700
|
+
readonly
|
|
701
|
+
/>
|
|
413
702
|
</div>
|
|
414
703
|
|
|
415
704
|
<div v-if="passReturnStatuses.length > 0" class="mb-2">
|
|
416
705
|
<p class="text-caption text-medium-emphasis mb-1">Passes</p>
|
|
417
|
-
<v-row
|
|
418
|
-
|
|
419
|
-
|
|
706
|
+
<v-row
|
|
707
|
+
no-gutters
|
|
708
|
+
v-for="pass in passReturnStatuses"
|
|
709
|
+
:key="(pass as any)._id ?? (pass as any).keyId"
|
|
710
|
+
class="d-flex flex-wrap justify-space-between align-center ga-5 mb-2"
|
|
711
|
+
>
|
|
712
|
+
<v-chip
|
|
713
|
+
prepend-icon="mdi-card-bulleted-outline"
|
|
714
|
+
size="small"
|
|
715
|
+
variant="tonal"
|
|
716
|
+
color="blue"
|
|
717
|
+
>
|
|
420
718
|
{{ (pass as any)?.prefixAndName }}
|
|
421
719
|
</v-chip>
|
|
422
|
-
<v-select
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
density="compact"
|
|
720
|
+
<v-select
|
|
721
|
+
hide-details
|
|
722
|
+
max-width="200px"
|
|
723
|
+
density="compact"
|
|
724
|
+
:items="passStatusOptions"
|
|
725
|
+
item-title="label"
|
|
726
|
+
item-value="value"
|
|
727
|
+
v-model="pass.status"
|
|
728
|
+
:disabled="selectedVisitorObject.checkOut"
|
|
729
|
+
></v-select>
|
|
730
|
+
<v-textarea
|
|
731
|
+
v-if="pass.status === 'Lost' || pass.status === 'Damaged'"
|
|
732
|
+
no-resize
|
|
733
|
+
rows="3"
|
|
734
|
+
class="w-100"
|
|
735
|
+
density="compact"
|
|
736
|
+
v-model="pass.remarks"
|
|
737
|
+
:disabled="selectedVisitorObject.checkOut"
|
|
738
|
+
></v-textarea>
|
|
426
739
|
</v-row>
|
|
427
740
|
</div>
|
|
428
741
|
<div v-if="keyReturnStatuses.length > 0" class="mb-2">
|
|
429
742
|
<p class="text-caption text-medium-emphasis mb-1">Keys</p>
|
|
430
|
-
<v-row
|
|
431
|
-
|
|
432
|
-
|
|
743
|
+
<v-row
|
|
744
|
+
no-gutters
|
|
745
|
+
v-for="key in keyReturnStatuses"
|
|
746
|
+
:key="(key as any)._id ?? (key as any).keyId"
|
|
747
|
+
class="d-flex flex-wrap justify-space-between align-center ga-5 mb-2"
|
|
748
|
+
>
|
|
749
|
+
<v-chip
|
|
750
|
+
prepend-icon="mdi-key"
|
|
751
|
+
size="small"
|
|
752
|
+
variant="tonal"
|
|
753
|
+
color="orange"
|
|
754
|
+
>
|
|
433
755
|
{{ (key as any)?.prefixAndName }}
|
|
434
756
|
</v-chip>
|
|
435
|
-
<v-select
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
density="compact"
|
|
757
|
+
<v-select
|
|
758
|
+
hide-details
|
|
759
|
+
max-width="200px"
|
|
760
|
+
density="compact"
|
|
761
|
+
:items="passStatusOptions"
|
|
762
|
+
item-title="label"
|
|
763
|
+
item-value="value"
|
|
764
|
+
v-model="key.status"
|
|
765
|
+
:disabled="selectedVisitorObject.checkOut"
|
|
766
|
+
></v-select>
|
|
767
|
+
<v-textarea
|
|
768
|
+
v-if="key.status === 'Lost' || key.status === 'Damaged'"
|
|
769
|
+
no-resize
|
|
770
|
+
rows="3"
|
|
771
|
+
class="w-100"
|
|
772
|
+
density="compact"
|
|
773
|
+
v-model="key.remarks"
|
|
774
|
+
:disabled="selectedVisitorObject.checkOut"
|
|
775
|
+
></v-textarea>
|
|
439
776
|
</v-row>
|
|
440
777
|
</div>
|
|
441
778
|
|
|
442
779
|
<v-row no-gutters class="my-5">
|
|
443
|
-
<v-btn
|
|
444
|
-
|
|
445
|
-
|
|
780
|
+
<v-btn
|
|
781
|
+
variant="flat"
|
|
782
|
+
color="blue"
|
|
783
|
+
density="comfortable"
|
|
784
|
+
class="text-capitalize"
|
|
785
|
+
:disabled="selectedVisitorObject.checkOut"
|
|
786
|
+
:loading="loading.updatingPassKeys"
|
|
787
|
+
@click.stop="handleUpdatePassKeys"
|
|
788
|
+
>Update Pass/Keys</v-btn
|
|
789
|
+
>
|
|
446
790
|
</v-row>
|
|
447
791
|
</v-card-text>
|
|
448
792
|
<v-toolbar class="pa-0" density="compact">
|
|
449
793
|
<v-row no-gutters>
|
|
450
794
|
<v-col cols="6">
|
|
451
|
-
<v-btn
|
|
795
|
+
<v-btn
|
|
796
|
+
variant="text"
|
|
797
|
+
block
|
|
798
|
+
@click="dialog.returnPassesKeys = false"
|
|
799
|
+
>Close</v-btn
|
|
800
|
+
>
|
|
452
801
|
</v-col>
|
|
453
802
|
<v-col cols="6">
|
|
454
|
-
<v-btn
|
|
455
|
-
|
|
803
|
+
<v-btn
|
|
804
|
+
color="red"
|
|
805
|
+
variant="flat"
|
|
806
|
+
height="48"
|
|
807
|
+
rounded="0"
|
|
808
|
+
block
|
|
809
|
+
:loading="loading.checkingOut"
|
|
810
|
+
:disabled="
|
|
811
|
+
!canConfirmCheckout || selectedVisitorObject.checkOut
|
|
812
|
+
"
|
|
813
|
+
@click="proceedCheckout"
|
|
814
|
+
>Confirm Checkout</v-btn
|
|
815
|
+
>
|
|
456
816
|
</v-col>
|
|
457
817
|
</v-row>
|
|
458
818
|
</v-toolbar>
|
|
@@ -460,50 +820,87 @@
|
|
|
460
820
|
</v-dialog>
|
|
461
821
|
|
|
462
822
|
<v-dialog v-model="dialog.addPassKey" width="450" persistent>
|
|
463
|
-
<AddPassKeyToVisitor
|
|
464
|
-
|
|
823
|
+
<AddPassKeyToVisitor
|
|
824
|
+
mode="add"
|
|
825
|
+
:visitor="selectedVisitorDataObject"
|
|
826
|
+
:site="siteId"
|
|
827
|
+
@close="dialog.addPassKey = false"
|
|
828
|
+
@done="
|
|
465
829
|
() => {
|
|
466
830
|
dialog.addPassKey = false;
|
|
467
831
|
getVisitorRefresh();
|
|
468
832
|
}
|
|
469
|
-
"
|
|
833
|
+
"
|
|
834
|
+
/>
|
|
470
835
|
</v-dialog>
|
|
471
836
|
|
|
472
837
|
<v-dialog v-model="dialog.editPassKey" width="450" persistent>
|
|
473
|
-
<AddPassKeyToVisitor
|
|
474
|
-
|
|
838
|
+
<AddPassKeyToVisitor
|
|
839
|
+
mode="edit"
|
|
840
|
+
:visitor="selectedVisitorDataObject"
|
|
841
|
+
:site="siteId"
|
|
842
|
+
@close="dialog.editPassKey = false"
|
|
843
|
+
@done="
|
|
475
844
|
() => {
|
|
476
845
|
dialog.editPassKey = false;
|
|
477
846
|
getVisitorRefresh();
|
|
478
847
|
}
|
|
479
|
-
"
|
|
848
|
+
"
|
|
849
|
+
/>
|
|
480
850
|
</v-dialog>
|
|
481
851
|
|
|
482
|
-
<ScanVisitorQRCode
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
852
|
+
<ScanVisitorQRCode
|
|
853
|
+
:dialog="dialog.scanVisitorQRCode"
|
|
854
|
+
:site="siteId"
|
|
855
|
+
@open-visitor-data-from-scanned-qr-code-dialog="
|
|
856
|
+
handleShowVisitorDataFromScannedQRCodeDialog
|
|
857
|
+
"
|
|
858
|
+
@close-dialog="dialog.scanVisitorQRCode = false"
|
|
859
|
+
/>
|
|
860
|
+
|
|
861
|
+
<v-dialog
|
|
862
|
+
v-model="dialog.showVisitorDataFromScannedQRCode"
|
|
863
|
+
width="450"
|
|
864
|
+
persistent
|
|
865
|
+
>
|
|
866
|
+
<VisitorDataFromScannedQRCodeForm
|
|
867
|
+
:site="siteId"
|
|
868
|
+
:visitor-data="visitorDataFromScannedQRCode"
|
|
488
869
|
@check-in-out="handleVisitorDataFromScannedQRCodeCheckInOut"
|
|
489
870
|
:processing="isVisitorDataFromScannedQRCodeCheckingInOut"
|
|
490
|
-
@close="handleCloseVisitorDataFromScannedQRCodeDialog"
|
|
871
|
+
@close="handleCloseVisitorDataFromScannedQRCodeDialog"
|
|
872
|
+
/>
|
|
491
873
|
</v-dialog>
|
|
492
874
|
|
|
493
|
-
<v-dialog
|
|
494
|
-
|
|
875
|
+
<v-dialog
|
|
876
|
+
v-model="dialog.approveRejectOvernightParkingRequestDialog"
|
|
877
|
+
transition="dialog-bottom-transition"
|
|
878
|
+
persistent
|
|
879
|
+
width="60vh"
|
|
880
|
+
>
|
|
495
881
|
<v-card>
|
|
496
882
|
<v-toolbar density="compact">
|
|
497
|
-
<v-row
|
|
883
|
+
<v-row
|
|
884
|
+
no-gutters
|
|
885
|
+
class="d-flex fill-height justify-space-between align-center px-4"
|
|
886
|
+
>
|
|
498
887
|
<span class="font-weight-bold"> Overnight Parking Request </span>
|
|
499
|
-
<v-btn
|
|
888
|
+
<v-btn
|
|
889
|
+
icon="mdi-close"
|
|
890
|
+
variant="text"
|
|
891
|
+
@click="dialog.approveRejectOvernightParkingRequestDialog = false"
|
|
892
|
+
/>
|
|
500
893
|
</v-row>
|
|
501
894
|
</v-toolbar>
|
|
502
895
|
<v-card-text class="px-4 pb-6">
|
|
503
896
|
<v-row no-gutters justify="center" align-content="center">
|
|
504
|
-
<v-col
|
|
505
|
-
|
|
506
|
-
|
|
897
|
+
<v-col
|
|
898
|
+
v-if="
|
|
899
|
+
approveRejectOvernightParkingRequestDialog.status !== 'remarks'
|
|
900
|
+
"
|
|
901
|
+
cols="12"
|
|
902
|
+
class="text-h6 text-center"
|
|
903
|
+
>
|
|
507
904
|
{{
|
|
508
905
|
`Are you sure you want to ${approveRejectOvernightParkingRequestDialog.text} the visitor's overnight
|
|
509
906
|
parking
|
|
@@ -512,28 +909,58 @@
|
|
|
512
909
|
</v-col>
|
|
513
910
|
|
|
514
911
|
<v-col cols="12" md="8" class="mt-4">
|
|
515
|
-
<v-textarea
|
|
516
|
-
|
|
912
|
+
<v-textarea
|
|
913
|
+
v-model="overNightParkingRequestApproveRejectRemarks"
|
|
914
|
+
label="Remarks"
|
|
915
|
+
placeholder="Enter remarks"
|
|
916
|
+
outlined
|
|
917
|
+
rows="3"
|
|
918
|
+
clearable
|
|
919
|
+
:hide-details="
|
|
920
|
+
approveRejectOvernightParkingRequestDialog.status ===
|
|
921
|
+
'remarks'
|
|
922
|
+
"
|
|
923
|
+
:readonly="
|
|
924
|
+
approveRejectOvernightParkingRequestDialog.status ===
|
|
517
925
|
'remarks'
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
" />
|
|
926
|
+
"
|
|
927
|
+
/>
|
|
521
928
|
</v-col>
|
|
522
929
|
</v-row>
|
|
523
930
|
</v-card-text>
|
|
524
|
-
<v-toolbar
|
|
525
|
-
|
|
931
|
+
<v-toolbar
|
|
932
|
+
v-if="approveRejectOvernightParkingRequestDialog.status !== 'remarks'"
|
|
933
|
+
class="pa-0"
|
|
934
|
+
density="compact"
|
|
935
|
+
>
|
|
526
936
|
<v-row no-gutters>
|
|
527
937
|
<v-col cols="6">
|
|
528
|
-
<v-btn
|
|
938
|
+
<v-btn
|
|
939
|
+
text="No"
|
|
940
|
+
color="grey-lighten-3"
|
|
941
|
+
variant="flat"
|
|
942
|
+
height="48"
|
|
943
|
+
tile
|
|
944
|
+
block
|
|
529
945
|
:disabled="isApprovingRejectingOvernightParkingRequest"
|
|
530
|
-
@click="closeApproveRejectOvernightParkingDialog"
|
|
946
|
+
@click="closeApproveRejectOvernightParkingDialog"
|
|
947
|
+
/>
|
|
531
948
|
</v-col>
|
|
532
949
|
<v-col cols="6">
|
|
533
|
-
<v-btn
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
950
|
+
<v-btn
|
|
951
|
+
text="Yes"
|
|
952
|
+
color="success"
|
|
953
|
+
variant="flat"
|
|
954
|
+
height="48"
|
|
955
|
+
tile
|
|
956
|
+
block
|
|
957
|
+
:disabled="
|
|
958
|
+
!overNightParkingRequestApproveRejectRemarks ||
|
|
959
|
+
isApprovingRejectingOvernightParkingRequest
|
|
960
|
+
"
|
|
961
|
+
@click="updateOvernightParkingRequestStatus"
|
|
962
|
+
:loading="isApprovingRejectingOvernightParkingRequest"
|
|
963
|
+
/>
|
|
537
964
|
</v-col>
|
|
538
965
|
</v-row>
|
|
539
966
|
</v-toolbar>
|
|
@@ -615,8 +1042,14 @@ const selectedVisitorId = ref<string | null>(""); // selected visitor for viewin
|
|
|
615
1042
|
|
|
616
1043
|
//filter states
|
|
617
1044
|
const searchInput = ref("");
|
|
618
|
-
|
|
619
|
-
const
|
|
1045
|
+
|
|
1046
|
+
const today = new Date();
|
|
1047
|
+
const oneMonthAgo = new Date();
|
|
1048
|
+
oneMonthAgo.setMonth(today.getMonth() - 1);
|
|
1049
|
+
|
|
1050
|
+
const dateTo = ref(normalizeDateOnly(today.toISOString()));
|
|
1051
|
+
const dateFrom = ref(normalizeDateOnly(oneMonthAgo.toISOString()));
|
|
1052
|
+
|
|
620
1053
|
const filterTypes = ref<TVisitorType[]>([]);
|
|
621
1054
|
const displayNotCheckedOut = ref<boolean>(false);
|
|
622
1055
|
const mode = ref<"add" | "edit" | "register">("add");
|
|
@@ -869,8 +1302,12 @@ const {
|
|
|
869
1302
|
page: page.value,
|
|
870
1303
|
site: siteId,
|
|
871
1304
|
search: searchInput.value,
|
|
872
|
-
dateTo: dateTo.value
|
|
873
|
-
|
|
1305
|
+
dateTo: dateTo.value
|
|
1306
|
+
? moment(dateTo.value).endOf("day").toISOString()
|
|
1307
|
+
: undefined,
|
|
1308
|
+
dateFrom: dateFrom.value
|
|
1309
|
+
? moment(dateFrom.value).startOf("day").toISOString()
|
|
1310
|
+
: undefined,
|
|
874
1311
|
type:
|
|
875
1312
|
filterTypes.value.length === 0 && activeTab.value === "registered"
|
|
876
1313
|
? "contractor,delivery,walk-in,pick-up,drop-off,guest"
|
|
@@ -1298,8 +1735,12 @@ function buildReportParams(): any {
|
|
|
1298
1735
|
const params: any = {
|
|
1299
1736
|
site: siteId,
|
|
1300
1737
|
search: searchInput.value,
|
|
1301
|
-
dateTo: dateTo.value
|
|
1302
|
-
|
|
1738
|
+
dateTo: dateTo.value
|
|
1739
|
+
? moment(dateTo.value).endOf("day").toISOString()
|
|
1740
|
+
: undefined,
|
|
1741
|
+
dateFrom: dateFrom.value
|
|
1742
|
+
? moment(dateFrom.value).startOf("day").toISOString()
|
|
1743
|
+
: undefined,
|
|
1303
1744
|
type:
|
|
1304
1745
|
filterTypes.value.length === 0 && activeTab.value === "registered"
|
|
1305
1746
|
? "contractor,delivery,walk-in,pick-up,drop-off,guest"
|
|
@@ -1323,7 +1764,6 @@ function buildReportParams(): any {
|
|
|
1323
1764
|
return params;
|
|
1324
1765
|
}
|
|
1325
1766
|
|
|
1326
|
-
|
|
1327
1767
|
async function handleDownloadPDFReport() {
|
|
1328
1768
|
try {
|
|
1329
1769
|
showMessage("Generating PDF report...", "info");
|
|
@@ -1333,13 +1773,18 @@ async function handleDownloadPDFReport() {
|
|
|
1333
1773
|
if (searchInput.value) queryParams.append("search", searchInput.value);
|
|
1334
1774
|
if (dateFrom.value) queryParams.append("dateFrom", dateFrom.value);
|
|
1335
1775
|
if (dateTo.value) queryParams.append("dateTo", dateTo.value);
|
|
1336
|
-
if (filterTypes.value.length > 0)
|
|
1776
|
+
if (filterTypes.value.length > 0)
|
|
1777
|
+
queryParams.append("type", filterTypes.value.join(","));
|
|
1337
1778
|
if (activeTab.value) queryParams.append("tab", activeTab.value);
|
|
1338
1779
|
if (displayNotCheckedOut.value) queryParams.append("checkedOut", "true");
|
|
1339
1780
|
|
|
1340
1781
|
const queryString = queryParams.toString();
|
|
1341
|
-
const url = `/${route.params.org}/${siteId}/visitor-management/preview${
|
|
1342
|
-
|
|
1782
|
+
const url = `/${route.params.org}/${siteId}/visitor-management/preview${
|
|
1783
|
+
queryString ? "?" + queryString : ""
|
|
1784
|
+
}`;
|
|
1785
|
+
const title = `Visitor-Report-${siteId}-${
|
|
1786
|
+
new Date().toISOString().split("T")[0]
|
|
1787
|
+
}`;
|
|
1343
1788
|
|
|
1344
1789
|
await downloadPDF({ url, title, orientation: "P", appKey: "SECURITY" });
|
|
1345
1790
|
showMessage("PDF report downloaded successfully!", "success");
|
|
@@ -1396,8 +1841,12 @@ function generateCSVData(visitors: any[]): string {
|
|
|
1396
1841
|
visitor.plateNumber || "",
|
|
1397
1842
|
formatDate(visitor.checkIn) || "",
|
|
1398
1843
|
formatDate(visitor.checkOut) || "",
|
|
1399
|
-
visitor.snapshotEntryImage
|
|
1400
|
-
|
|
1844
|
+
visitor.snapshotEntryImage
|
|
1845
|
+
? getFileUrlAnpr(`${siteId}/${visitor.snapshotEntryImage}`)
|
|
1846
|
+
: "",
|
|
1847
|
+
visitor.snapshotExitImage
|
|
1848
|
+
? getFileUrlAnpr(`${siteId}/${visitor.snapshotExitImage}`)
|
|
1849
|
+
: "",
|
|
1401
1850
|
]);
|
|
1402
1851
|
|
|
1403
1852
|
const csvContent = [
|
|
@@ -1496,17 +1945,18 @@ watch([searchInput, dateFrom, dateTo, filterTypes, activeTab], () => {
|
|
|
1496
1945
|
onMounted(() => {
|
|
1497
1946
|
activeTab.value = (route.query.tab as string) || "unregistered";
|
|
1498
1947
|
searchInput.value = (route.query.search as string) || "";
|
|
1499
|
-
|
|
1500
|
-
|
|
1948
|
+
if (route.query.dateFrom) {
|
|
1949
|
+
dateFrom.value = normalizeDateOnly(route.query.dateFrom as string);
|
|
1950
|
+
}
|
|
1951
|
+
if (route.query.dateTo) {
|
|
1952
|
+
dateTo.value = normalizeDateOnly(route.query.dateTo as string);
|
|
1953
|
+
}
|
|
1501
1954
|
filterTypes.value = ((route.query.type as string)?.split(",") || []).filter(
|
|
1502
1955
|
Boolean
|
|
1503
1956
|
) as TVisitorType[];
|
|
1504
1957
|
displayNotCheckedOut.value =
|
|
1505
1958
|
(route.query.checkedOut as string) == "true" || false;
|
|
1506
1959
|
});
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
1960
|
</script>
|
|
1511
1961
|
|
|
1512
1962
|
<style scoped></style>
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
</v-row>
|
|
14
14
|
<div style="overflow-x: auto; max-width: 100%;">
|
|
15
15
|
<v-data-table :headers="headers" :items="items" show-header :items-per-page="100" hide-default-footer class="text-black"
|
|
16
|
-
|
|
16
|
+
no-data-text="No entries to display">
|
|
17
17
|
|
|
18
18
|
<template v-slot:item.typeCompany="{ item }">
|
|
19
19
|
<span class="d-flex align-center ga-2" style="flex-wrap: wrap;">
|