@7365admin1/layer-common 1.11.41 → 1.11.43
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/AttachmentsViewer.vue +44 -15
- package/components/BulletinBoardForm.vue +11 -2
- package/components/BulletinBoardManagement.vue +2 -1
- package/components/ClientMain.vue +36 -22
- package/components/Input/DateTimePicker.vue +14 -1
- package/components/InvitationClientForm.vue +114 -60
- package/components/InvitationForm.vue +15 -4
- package/components/Layout/NavigationDrawer.vue +20 -19
- package/components/MemberMain.vue +9 -12
- package/components/TableMain.vue +1 -1
- package/components/VisitorManagement.vue +215 -628
- package/composables/useFile.ts +1 -1
- package/composables/useLocalAuth.ts +12 -0
- package/composables/useMember.ts +41 -14
- package/composables/useOrg.ts +49 -1
- package/composables/useUser.ts +46 -14
- package/package.json +1 -1
- package/types/nuxt-app.d.ts +7 -0
|
@@ -1,137 +1,51 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-row no-gutters>
|
|
3
|
-
<TableMain
|
|
4
|
-
:
|
|
5
|
-
:
|
|
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
|
-
>
|
|
3
|
+
<TableMain :headers="headers" :items="items" :loading="getVisitorPending" :page="page" :pages="pages"
|
|
4
|
+
:extension-height="110" :offset="300" :pageRange="pageRange" @refresh="getVisitorRefresh"
|
|
5
|
+
@update:page="handleUpdatePage" show-header @row-click="handleRowClick">
|
|
17
6
|
<template #actions>
|
|
18
7
|
<v-row no-gutters>
|
|
19
|
-
<v-btn
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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
|
-
/>
|
|
8
|
+
<v-btn v-if="canAddVisitor" class="text-none" rounded="pill" variant="tonal" size="large"
|
|
9
|
+
@click="handleAddNew" text="Add Visitor" />
|
|
10
|
+
<v-btn v-if="canScanVisitorQRCode" text="Scan QR Code" class="text-none ml-2" rounded="pill" variant="tonal"
|
|
11
|
+
size="large" @click="dialog.scanVisitorQRCode = true" />
|
|
37
12
|
<v-menu>
|
|
38
13
|
<template #activator="{ props }">
|
|
39
|
-
<v-btn
|
|
40
|
-
|
|
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
|
-
/>
|
|
14
|
+
<v-btn v-bind="props" text="Download Report" class="text-none ml-2" prepend-icon="mdi-download"
|
|
15
|
+
rounded="pill" variant="tonal" size="large" />
|
|
48
16
|
</template>
|
|
49
17
|
<v-list>
|
|
50
|
-
<v-list-item
|
|
51
|
-
|
|
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
|
-
/>
|
|
18
|
+
<v-list-item prepend-icon="mdi-file-pdf" title="Download PDF Report" @click="handleDownloadPDFReport" />
|
|
19
|
+
<v-list-item prepend-icon="mdi-file-csv" title="Download CSV Report" @click="handleDownloadCSVReport" />
|
|
60
20
|
</v-list>
|
|
61
21
|
</v-menu>
|
|
62
22
|
</v-row>
|
|
63
23
|
</template>
|
|
64
24
|
<template #extension>
|
|
65
25
|
<v-row no-gutters class="w-100 d-flex flex-column">
|
|
66
|
-
<v-tabs
|
|
67
|
-
v-
|
|
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
|
-
>
|
|
26
|
+
<v-tabs v-model="activeTab" color="primary" :height="40" @update:model-value="toRoute" class="w-100">
|
|
27
|
+
<v-tab v-for="tab in tabOptions" :value="tab.value" :key="tab.value" class="text-capitalize">
|
|
79
28
|
{{ tab.name }}
|
|
80
29
|
</v-tab>
|
|
81
30
|
</v-tabs>
|
|
82
31
|
|
|
83
|
-
<v-card
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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
|
-
>
|
|
32
|
+
<v-card class="w-100 px-3 d-flex align-center ga-5 py-2" flat :height="60">
|
|
33
|
+
<v-text-field v-model="searchInput" density="compact" placeholder="Search" clearable max-width="300"
|
|
34
|
+
append-inner-icon="mdi-magnify" hide-details />
|
|
35
|
+
<v-checkbox v-model="displayNotCheckedOut" class="text-subtitle-2" hide-details>
|
|
102
36
|
<template #label>
|
|
103
37
|
<span class="text-caption">Not Checked Out</span>
|
|
104
38
|
</template>
|
|
105
39
|
</v-checkbox>
|
|
106
|
-
<InputDatePicker
|
|
107
|
-
v-model="dateFrom"
|
|
108
|
-
density="compact"
|
|
109
|
-
hide-details
|
|
110
|
-
/>
|
|
40
|
+
<InputDatePicker v-model="dateFrom" density="compact" hide-details />
|
|
111
41
|
<InputDatePicker v-model="dateTo" density="compact" hide-details />
|
|
112
|
-
<v-select
|
|
113
|
-
|
|
114
|
-
|
|
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
|
-
>
|
|
42
|
+
<v-select v-if="activeTab == 'registered'" v-model="filterTypes" label="Filter by types" item-title="label"
|
|
43
|
+
item-value="value" :items="visitorSelection" density="compact" clearable multiple max-width="200"
|
|
44
|
+
hide-details>
|
|
125
45
|
<template v-slot:selection="{ item, index }">
|
|
126
46
|
<div class="d-flex align-center text-caption text-nowrap">
|
|
127
|
-
<v-chip
|
|
128
|
-
|
|
129
|
-
color="error"
|
|
130
|
-
:text="filterTypeSelectionLabel()"
|
|
131
|
-
size="x-small"
|
|
132
|
-
variant="tonal"
|
|
133
|
-
class="ml-2"
|
|
134
|
-
/>
|
|
47
|
+
<v-chip v-if="index === 0" color="error" :text="filterTypeSelectionLabel()" size="x-small"
|
|
48
|
+
variant="tonal" class="ml-2" />
|
|
135
49
|
</div>
|
|
136
50
|
</template>
|
|
137
51
|
</v-select>
|
|
@@ -146,9 +60,8 @@
|
|
|
146
60
|
</span>
|
|
147
61
|
<span class="text-capitalize">{{ item?.name }}</span>
|
|
148
62
|
</span>
|
|
149
|
-
<span class="text-grey text-caption" v-if="item?.members?.length > 0"
|
|
150
|
-
|
|
151
|
-
>
|
|
63
|
+
<span class="text-grey text-caption" v-if="item?.members?.length > 0">( +{{ item?.members?.length }}
|
|
64
|
+
members)</span>
|
|
152
65
|
</template>
|
|
153
66
|
|
|
154
67
|
<template v-slot:item.email="{ value }">
|
|
@@ -157,12 +70,7 @@
|
|
|
157
70
|
|
|
158
71
|
<template v-slot:item.invited-by="{ item }">
|
|
159
72
|
<span class="d-flex align-center ga-2">
|
|
160
|
-
<AvatarMain
|
|
161
|
-
v-if="item?.inviterName"
|
|
162
|
-
:name="item?.inviterName"
|
|
163
|
-
:size="20"
|
|
164
|
-
:id="item?._id"
|
|
165
|
-
/>
|
|
73
|
+
<AvatarMain v-if="item?.inviterName" :name="item?.inviterName" :size="20" :id="item?._id" />
|
|
166
74
|
<span class="text-capitalize">{{ item?.inviterName ?? "N/A" }}</span>
|
|
167
75
|
</span>
|
|
168
76
|
</template>
|
|
@@ -172,7 +80,7 @@
|
|
|
172
80
|
<v-icon icon="mdi-user" size="15" />
|
|
173
81
|
<span v-if="item.type === 'contractor'" class="text-capitalize">{{
|
|
174
82
|
formatCamelCaseToWords(item.contractorType)
|
|
175
|
-
|
|
83
|
+
}}</span>
|
|
176
84
|
<span v-else class="text-capitalize">{{ formatType(item) }}</span>
|
|
177
85
|
</span>
|
|
178
86
|
<span class="d-flex align-center ga-2">
|
|
@@ -208,52 +116,26 @@
|
|
|
208
116
|
<template v-slot:item.checkin-out="{ item }">
|
|
209
117
|
<v-row no-gutters class="d-flex flex-column py-2">
|
|
210
118
|
<span class="d-flex align-center ga-2">
|
|
211
|
-
<v-icon
|
|
212
|
-
icon="mdi-clock-time-four-outline"
|
|
213
|
-
color="green"
|
|
214
|
-
size="20"
|
|
215
|
-
/>
|
|
119
|
+
<v-icon icon="mdi-clock-time-four-outline" color="green" size="20" />
|
|
216
120
|
<span class="text-capitalize">{{
|
|
217
121
|
UTCToLocalTIme(item.checkIn) || "-"
|
|
218
|
-
|
|
122
|
+
}}</span>
|
|
219
123
|
<span>
|
|
220
|
-
<v-icon
|
|
221
|
-
|
|
222
|
-
size="17"
|
|
223
|
-
icon="mdi-image"
|
|
224
|
-
@click.stop="handleViewImage(item.snapshotEntryImage)"
|
|
225
|
-
/>
|
|
124
|
+
<v-icon v-if="item?.snapshotEntryImage" size="17" icon="mdi-image"
|
|
125
|
+
@click.stop="handleViewImage(item.snapshotEntryImage)" />
|
|
226
126
|
</span>
|
|
227
127
|
</span>
|
|
228
128
|
|
|
229
|
-
<span
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
"
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
v-bind="menuProps"
|
|
240
|
-
style="cursor: pointer"
|
|
241
|
-
>
|
|
242
|
-
<v-icon
|
|
243
|
-
icon="mdi-clock-time-eight-outline"
|
|
244
|
-
color="red"
|
|
245
|
-
size="20"
|
|
246
|
-
/>
|
|
247
|
-
<v-btn
|
|
248
|
-
size="x-small"
|
|
249
|
-
class="text-capitalize"
|
|
250
|
-
color="red"
|
|
251
|
-
text="Checkout"
|
|
252
|
-
:loading="
|
|
253
|
-
loading.checkingOut && item?._id === selectedVisitorId
|
|
254
|
-
"
|
|
255
|
-
@click.stop="handleCheckout(item._id)"
|
|
256
|
-
/>
|
|
129
|
+
<span v-if="
|
|
130
|
+
!item.checkOut &&
|
|
131
|
+
(item?.status === 'registered' ||
|
|
132
|
+
item?.status === 'unregistered') &&
|
|
133
|
+
canCheckoutVisitor
|
|
134
|
+
">
|
|
135
|
+
<span class="d-flex align-center ga-2" v-bind="menuProps" style="cursor: pointer">
|
|
136
|
+
<v-icon icon="mdi-clock-time-eight-outline" color="red" size="20" />
|
|
137
|
+
<v-btn size="x-small" class="text-capitalize" color="red" text="Checkout" :loading="loading.checkingOut && item?._id === selectedVisitorId
|
|
138
|
+
" @click.stop="handleCheckout(item._id)" />
|
|
257
139
|
</span>
|
|
258
140
|
</span>
|
|
259
141
|
<span v-else class="d-flex align-center ga-2">
|
|
@@ -261,96 +143,50 @@
|
|
|
261
143
|
<template v-if="item.checkOut">
|
|
262
144
|
<span class="text-capitalize">{{
|
|
263
145
|
UTCToLocalTIme(item.checkOut)
|
|
264
|
-
|
|
146
|
+
}}</span>
|
|
265
147
|
<span>
|
|
266
|
-
<v-icon
|
|
267
|
-
|
|
268
|
-
size="17"
|
|
269
|
-
icon="mdi-image"
|
|
270
|
-
@click.stop="handleViewImage(item.snapshotExitImage)"
|
|
271
|
-
/>
|
|
148
|
+
<v-icon v-if="item?.snapshotExitImage" size="17" icon="mdi-image"
|
|
149
|
+
@click.stop="handleViewImage(item.snapshotExitImage)" />
|
|
272
150
|
</span>
|
|
273
151
|
<span v-if="item?.manualCheckout">
|
|
274
|
-
<TooltipInfo
|
|
275
|
-
text="Manual Checkout"
|
|
276
|
-
density="compact"
|
|
277
|
-
size="x-small"
|
|
278
|
-
/>
|
|
152
|
+
<TooltipInfo text="Manual Checkout" density="compact" size="x-small" />
|
|
279
153
|
</span>
|
|
280
154
|
</template>
|
|
281
155
|
<template v-else> <span class="mt-1"> N/A </span> </template>
|
|
282
156
|
</span>
|
|
283
157
|
|
|
284
|
-
<div
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
style="cursor: pointer"
|
|
289
|
-
>
|
|
290
|
-
<v-chip
|
|
291
|
-
size="x-small"
|
|
292
|
-
variant="tonal"
|
|
293
|
-
prepend-icon="mdi-key"
|
|
294
|
-
@click.stop="handleOpenAddPassKey(item)"
|
|
295
|
-
>Add Pass/Key</v-chip
|
|
296
|
-
>
|
|
158
|
+
<div v-if="showAddPassKeyButton(item)" class="d-flex flex-wrap ga-1 mt-1" v-bind="menuProps"
|
|
159
|
+
style="cursor: pointer">
|
|
160
|
+
<v-chip size="x-small" variant="tonal" prepend-icon="mdi-key" @click.stop="handleOpenAddPassKey(item)">Add
|
|
161
|
+
Pass/Key</v-chip>
|
|
297
162
|
</div>
|
|
298
163
|
|
|
299
164
|
<v-menu :close-on-content-click="true">
|
|
300
165
|
<template v-slot:activator="{ props: menuProps }">
|
|
301
|
-
<div
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
"
|
|
306
|
-
|
|
307
|
-
v-bind="menuProps"
|
|
308
|
-
style="cursor: pointer"
|
|
309
|
-
>
|
|
310
|
-
<v-chip
|
|
311
|
-
v-for="pass in item.visitorPass"
|
|
312
|
-
:key="(pass as any)._id ?? (pass as any).keyId"
|
|
313
|
-
prepend-icon="mdi-card-bulleted-outline"
|
|
314
|
-
size="x-small"
|
|
315
|
-
variant="tonal"
|
|
316
|
-
color="blue"
|
|
317
|
-
>
|
|
166
|
+
<div v-if="
|
|
167
|
+
(item.visitorPass?.length ?? 0) > 0 ||
|
|
168
|
+
(item.passKeys?.length ?? 0) > 0
|
|
169
|
+
" class="d-flex flex-wrap ga-1 mt-1" v-bind="menuProps" style="cursor: pointer">
|
|
170
|
+
<v-chip v-for="pass in item.visitorPass" :key="(pass as any)._id ?? (pass as any).keyId"
|
|
171
|
+
prepend-icon="mdi-card-bulleted-outline" size="x-small" variant="tonal" color="blue">
|
|
318
172
|
{{ (pass as any)?.prefixAndName }}
|
|
319
173
|
</v-chip>
|
|
320
|
-
<v-chip
|
|
321
|
-
|
|
322
|
-
:key="(key as any)._id ?? (key as any).keyId"
|
|
323
|
-
prepend-icon="mdi-key"
|
|
324
|
-
size="x-small"
|
|
325
|
-
variant="tonal"
|
|
326
|
-
color="orange"
|
|
327
|
-
>
|
|
174
|
+
<v-chip v-for="key in item.passKeys" :key="(key as any)._id ?? (key as any).keyId"
|
|
175
|
+
prepend-icon="mdi-key" size="x-small" variant="tonal" color="orange">
|
|
328
176
|
{{ (key as any)?.prefixAndName }}
|
|
329
177
|
</v-chip>
|
|
330
178
|
</div>
|
|
331
179
|
</template>
|
|
332
180
|
<v-list density="compact">
|
|
333
|
-
<v-list-item
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
(item.passKeys?.length ?? 0) > 0
|
|
343
|
-
"
|
|
344
|
-
prepend-icon="mdi-card-bulleted-outline"
|
|
345
|
-
:title="item.checkOut ? 'View Pass/Key' : 'Edit Pass/Key'"
|
|
346
|
-
@click.stop="handleOpenEditPassKey(item)"
|
|
347
|
-
/>
|
|
348
|
-
<v-list-item
|
|
349
|
-
v-if="showAddPassKeyButton(item)"
|
|
350
|
-
prepend-icon="mdi-plus"
|
|
351
|
-
title="Add Pass/Key"
|
|
352
|
-
@click.stop="handleOpenAddPassKey(item)"
|
|
353
|
-
/>
|
|
181
|
+
<v-list-item v-if="!item?.checkOut" prepend-icon="mdi-logout" title="Checkout"
|
|
182
|
+
@click.stop="handleCheckout(item._id)" />
|
|
183
|
+
<v-list-item v-if="
|
|
184
|
+
(item.visitorPass?.length ?? 0) > 0 ||
|
|
185
|
+
(item.passKeys?.length ?? 0) > 0
|
|
186
|
+
" prepend-icon="mdi-card-bulleted-outline" :title="item.checkOut ? 'View Pass/Key' : 'Edit Pass/Key'"
|
|
187
|
+
@click.stop="handleOpenEditPassKey(item)" />
|
|
188
|
+
<v-list-item v-if="showAddPassKeyButton(item)" prepend-icon="mdi-plus" title="Add Pass/Key"
|
|
189
|
+
@click.stop="handleOpenAddPassKey(item)" />
|
|
354
190
|
</v-list>
|
|
355
191
|
</v-menu>
|
|
356
192
|
</v-row>
|
|
@@ -369,44 +205,27 @@
|
|
|
369
205
|
|
|
370
206
|
<span v-if="!item.checkIn && canUpdateVisitor">
|
|
371
207
|
<span class="d-flex align-center ga-2 cursor-pointer">
|
|
372
|
-
<v-icon
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
size="20"
|
|
376
|
-
/>
|
|
377
|
-
<v-btn
|
|
378
|
-
size="x-small"
|
|
379
|
-
class="text-capitalize"
|
|
380
|
-
color="success"
|
|
381
|
-
text="Checkin"
|
|
382
|
-
@click.stop="handleCheckin(item)"
|
|
383
|
-
/>
|
|
208
|
+
<v-icon icon="mdi-clock-time-eight-outline" color="success" size="20" />
|
|
209
|
+
<v-btn size="x-small" class="text-capitalize" color="success" text="Checkin"
|
|
210
|
+
@click.stop="handleCheckin(item)" />
|
|
384
211
|
</span>
|
|
385
212
|
</span>
|
|
386
213
|
</v-row>
|
|
387
214
|
</template>
|
|
388
215
|
|
|
389
216
|
<template v-slot:item.status="{ item }">
|
|
390
|
-
<v-card
|
|
391
|
-
v-if="item?.overnightParking?.status"
|
|
392
|
-
size="small"
|
|
217
|
+
<v-card v-if="item?.overnightParking?.status" size="small"
|
|
393
218
|
class="rounded-xl text-capitalize text-center elevation-0 py-1 px-2"
|
|
394
219
|
:color="getOvernightParkingRequestStatusColor(item?.overnightParking?.status as string)"
|
|
395
|
-
style="max-width: 150px; margin: auto"
|
|
396
|
-
>
|
|
220
|
+
style="max-width: 150px; margin: auto">
|
|
397
221
|
{{ item?.overnightParking?.status }}
|
|
398
222
|
</v-card>
|
|
399
223
|
<span v-else> N/A </span>
|
|
400
224
|
</template>
|
|
401
225
|
|
|
402
226
|
<template v-slot:item.action="{ item }">
|
|
403
|
-
<v-btn
|
|
404
|
-
|
|
405
|
-
size="small"
|
|
406
|
-
color="primary"
|
|
407
|
-
text="Register"
|
|
408
|
-
@click.stop="handleRegistrationUnregisteredVisitor(item)"
|
|
409
|
-
/>
|
|
227
|
+
<v-btn v-if="activeTab === 'unregistered' && canAddVisitor" size="small" color="primary" text="Register"
|
|
228
|
+
@click.stop="handleRegistrationUnregisteredVisitor(item)" />
|
|
410
229
|
<v-menu v-else-if="activeTab === 'overnight-parking'">
|
|
411
230
|
<template #activator="{ props }">
|
|
412
231
|
<v-avatar v-bind="props" class="rounded-xl border-md">
|
|
@@ -415,20 +234,17 @@
|
|
|
415
234
|
</template>
|
|
416
235
|
|
|
417
236
|
<v-card>
|
|
418
|
-
<v-list-item
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
"
|
|
425
|
-
@click.stop="
|
|
237
|
+
<v-list-item v-if="
|
|
238
|
+
!overNightParkingListActions[0].disabled ||
|
|
239
|
+
!['approved', 'rejected'].includes(
|
|
240
|
+
item?.overnightParking?.status
|
|
241
|
+
)
|
|
242
|
+
" @click.stop="
|
|
426
243
|
openApproveRejectOverNightParkingRequestDialog(
|
|
427
244
|
item,
|
|
428
245
|
overNightParkingListActions[0].status
|
|
429
246
|
)
|
|
430
|
-
|
|
431
|
-
>
|
|
247
|
+
">
|
|
432
248
|
<template #title>
|
|
433
249
|
<span class="text-caption">
|
|
434
250
|
{{ overNightParkingListActions[0].text }}
|
|
@@ -436,36 +252,30 @@
|
|
|
436
252
|
</template>
|
|
437
253
|
</v-list-item>
|
|
438
254
|
<v-divider />
|
|
439
|
-
<v-list-item
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
"
|
|
446
|
-
@click="
|
|
255
|
+
<v-list-item v-if="
|
|
256
|
+
!overNightParkingListActions[1].disabled ||
|
|
257
|
+
!['approved', 'rejected'].includes(
|
|
258
|
+
item?.overnightParking?.status
|
|
259
|
+
)
|
|
260
|
+
" @click="
|
|
447
261
|
openApproveRejectOverNightParkingRequestDialog(
|
|
448
262
|
item,
|
|
449
263
|
overNightParkingListActions[1].status
|
|
450
264
|
)
|
|
451
|
-
|
|
452
|
-
>
|
|
265
|
+
">
|
|
453
266
|
<template #title>
|
|
454
267
|
<span class="text-caption">
|
|
455
268
|
{{ overNightParkingListActions[1].text }}
|
|
456
269
|
</span>
|
|
457
270
|
</template>
|
|
458
271
|
</v-list-item>
|
|
459
|
-
<v-list-item
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
)
|
|
467
|
-
"
|
|
468
|
-
>
|
|
272
|
+
<v-list-item v-if="item?.overnightParking?.remarks" @click="
|
|
273
|
+
openApproveRejectOverNightParkingRequestDialog(
|
|
274
|
+
item,
|
|
275
|
+
overNightParkingListActions[2].status,
|
|
276
|
+
item?.overnightParking?.remarks
|
|
277
|
+
)
|
|
278
|
+
">
|
|
469
279
|
<template #title>
|
|
470
280
|
<span class="text-caption">
|
|
471
281
|
{{ overNightParkingListActions[2].text }}
|
|
@@ -479,118 +289,70 @@
|
|
|
479
289
|
|
|
480
290
|
<template v-slot:item.checkInRemarks="{ item }">
|
|
481
291
|
<span>
|
|
482
|
-
<v-btn
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
density="compact"
|
|
486
|
-
size="small"
|
|
487
|
-
@click.stop="handleOpenRemarks(item, 'checkIn')"
|
|
488
|
-
>{{ item.checkInRemarks ? "View Remarks" : "Add Remarks" }}</v-btn
|
|
489
|
-
>
|
|
292
|
+
<v-btn variant="text" color="blue-darken-2" density="compact" size="small"
|
|
293
|
+
@click.stop="handleOpenRemarks(item, 'checkIn')">{{ item.checkInRemarks ? "View Remarks" : "Add Remarks"
|
|
294
|
+
}}</v-btn>
|
|
490
295
|
</span>
|
|
491
296
|
</template>
|
|
492
297
|
<template v-slot:item.checkOutRemarks="{ item }">
|
|
493
298
|
<span>
|
|
494
|
-
<v-btn
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
density="compact"
|
|
498
|
-
size="small"
|
|
499
|
-
@click.stop="handleOpenRemarks(item, 'checkOut')"
|
|
500
|
-
>{{ item.checkOutRemarks ? "View Remarks" : "Add Remarks" }}</v-btn
|
|
501
|
-
>
|
|
299
|
+
<v-btn variant="text" color="blue-darken-2" density="compact" size="small"
|
|
300
|
+
@click.stop="handleOpenRemarks(item, 'checkOut')">{{ item.checkOutRemarks ? "View Remarks" : "Add Remarks"
|
|
301
|
+
}}</v-btn>
|
|
502
302
|
</span>
|
|
503
303
|
</template>
|
|
504
304
|
</TableMain>
|
|
505
305
|
|
|
506
306
|
<v-dialog v-model="dialog.showSelection" width="450" persistent>
|
|
507
|
-
<VisitorFormSelection
|
|
508
|
-
:mode="mode"
|
|
509
|
-
@cancel="dialog.showSelection = false"
|
|
510
|
-
@select="handleSelectVisitorType"
|
|
511
|
-
/>
|
|
307
|
+
<VisitorFormSelection :mode="mode" @cancel="dialog.showSelection = false" @select="handleSelectVisitorType" />
|
|
512
308
|
</v-dialog>
|
|
513
309
|
|
|
514
|
-
<v-dialog
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
persistent
|
|
519
|
-
>
|
|
520
|
-
<VisitorForm
|
|
521
|
-
:mode="mode"
|
|
522
|
-
:org="orgId"
|
|
523
|
-
:site="siteId"
|
|
524
|
-
:visitor-data="selectedVisitorDataObject"
|
|
525
|
-
:type="activeVisitorFormType"
|
|
526
|
-
@back="handleClickBack"
|
|
527
|
-
@done="handleVisitorFormDone"
|
|
528
|
-
@done:more="handleVisitorFormCreateMore"
|
|
529
|
-
@close:all="handleCloseAll"
|
|
530
|
-
/>
|
|
310
|
+
<v-dialog v-model="dialog.showForm" v-if="activeVisitorFormType" width="450" persistent>
|
|
311
|
+
<VisitorForm :mode="mode" :org="orgId" :site="siteId" :visitor-data="selectedVisitorDataObject"
|
|
312
|
+
:type="activeVisitorFormType" @back="handleClickBack" @done="handleVisitorFormDone"
|
|
313
|
+
@done:more="handleVisitorFormCreateMore" @close:all="handleCloseAll" />
|
|
531
314
|
</v-dialog>
|
|
532
315
|
|
|
533
316
|
<v-dialog v-model="dialog.viewVisitor" width="450" persistent>
|
|
534
|
-
<VehicleUpdateMoreAction
|
|
535
|
-
|
|
536
|
-
:can-update="false"
|
|
537
|
-
:can-delete="false"
|
|
538
|
-
@close="dialog.viewVisitor = false"
|
|
539
|
-
edit-button-label="Edit Visitor"
|
|
540
|
-
>
|
|
317
|
+
<VehicleUpdateMoreAction title="Preview" :can-update="false" :can-delete="false"
|
|
318
|
+
@close="dialog.viewVisitor = false" edit-button-label="Edit Visitor">
|
|
541
319
|
<template v-slot:content>
|
|
542
320
|
<v-row no-gutters class="mb-4">
|
|
543
321
|
<v-col v-for="(label, key) in formattedFields" :key="key" cols="12">
|
|
544
|
-
<span
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
"
|
|
550
|
-
class="d-flex align-center"
|
|
551
|
-
>
|
|
322
|
+
<span v-if="
|
|
323
|
+
key === 'checkIn' &&
|
|
324
|
+
!selectedVisitorObject[key] &&
|
|
325
|
+
canUpdateVisitor
|
|
326
|
+
" class="d-flex align-center">
|
|
552
327
|
<strong>{{ label }}:</strong>
|
|
553
|
-
<v-btn
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
color="success"
|
|
557
|
-
text="Checkin"
|
|
558
|
-
:disabled="isVisitorDataFromScannedQRCodeCheckingInOut"
|
|
559
|
-
@click="handleCheckin(selectedVisitorObject)"
|
|
560
|
-
:loading="isVisitorDataFromScannedQRCodeCheckingInOut"
|
|
561
|
-
/>
|
|
328
|
+
<v-btn size="x-small" class="ml-3 text-capitalize" color="success" text="Checkin"
|
|
329
|
+
:disabled="isVisitorDataFromScannedQRCodeCheckingInOut" @click="handleCheckin(selectedVisitorObject)"
|
|
330
|
+
:loading="isVisitorDataFromScannedQRCodeCheckingInOut" />
|
|
562
331
|
</span>
|
|
563
|
-
<span
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
"
|
|
570
|
-
class="d-flex align-center"
|
|
571
|
-
>
|
|
332
|
+
<span v-if="
|
|
333
|
+
key === 'checkOut' &&
|
|
334
|
+
selectedVisitorObject['checkIn'] &&
|
|
335
|
+
!selectedVisitorObject[key] &&
|
|
336
|
+
canCheckoutVisitor
|
|
337
|
+
" class="d-flex align-center">
|
|
572
338
|
<strong>{{ label }}:</strong>
|
|
573
|
-
<v-btn
|
|
574
|
-
|
|
575
|
-
class="ml-3 text-capitalize"
|
|
576
|
-
color="red"
|
|
577
|
-
text="Checkout"
|
|
578
|
-
:disabled="loading.checkingOut"
|
|
579
|
-
@click="handleCheckout(selectedVisitorId as string)"
|
|
580
|
-
/>
|
|
339
|
+
<v-btn size="x-small" class="ml-3 text-capitalize" color="red" text="Checkout"
|
|
340
|
+
:disabled="loading.checkingOut" @click="handleCheckout(selectedVisitorId as string)" />
|
|
581
341
|
</span>
|
|
582
342
|
|
|
583
|
-
<span
|
|
584
|
-
|
|
585
|
-
class="
|
|
586
|
-
|
|
343
|
+
<span v-else-if="key === 'attachments' && selectedVisitorObject?.[key]?.length > 0"
|
|
344
|
+
class="d-flex flex-column">
|
|
345
|
+
<strong class="w-full">{{ label }}:</strong>
|
|
346
|
+
<div class="d-flex flex-wrap ga-2">
|
|
347
|
+
<AttachmentsViewer :files="mappedAttachments(selectedVisitorObject.attachments)" title=""
|
|
348
|
+
show-file-type-title />
|
|
349
|
+
</div>
|
|
350
|
+
</span>
|
|
351
|
+
|
|
352
|
+
<span v-else-if="selectedVisitorObject[key]" class="d-flex ga-3 align-center"><strong>{{ label
|
|
353
|
+
}}:</strong>
|
|
587
354
|
{{ formatValues(key, selectedVisitorObject[key]) }}
|
|
588
|
-
<TooltipInfo
|
|
589
|
-
v-if="key === 'checkOut'"
|
|
590
|
-
text="Manual Checkout"
|
|
591
|
-
density="compact"
|
|
592
|
-
size="x-small"
|
|
593
|
-
/>
|
|
355
|
+
<TooltipInfo v-if="key === 'checkOut'" text="Manual Checkout" density="compact" size="x-small" />
|
|
594
356
|
</span>
|
|
595
357
|
</v-col>
|
|
596
358
|
</v-row>
|
|
@@ -602,11 +364,7 @@
|
|
|
602
364
|
<v-card>
|
|
603
365
|
<v-card-title class="d-flex justify-space-between align-center">
|
|
604
366
|
<span>Snapshot</span>
|
|
605
|
-
<v-btn
|
|
606
|
-
icon="mdi-close"
|
|
607
|
-
variant="text"
|
|
608
|
-
@click="dialog.snapshotImage = false"
|
|
609
|
-
/>
|
|
367
|
+
<v-btn icon="mdi-close" variant="text" @click="dialog.snapshotImage = false" />
|
|
610
368
|
</v-card-title>
|
|
611
369
|
<v-card-text class="pa-2 d-flex justify-center">
|
|
612
370
|
<v-img :src="snapshotImageUrl" max-height="600" contain />
|
|
@@ -616,51 +374,25 @@
|
|
|
616
374
|
|
|
617
375
|
<v-dialog v-model="dialog.remarks" max-width="450" persistent>
|
|
618
376
|
<v-card>
|
|
619
|
-
<v-card-title
|
|
620
|
-
class="d-flex justify-space-between align-center pt-4 px-4"
|
|
621
|
-
>
|
|
377
|
+
<v-card-title class="d-flex justify-space-between align-center pt-4 px-4">
|
|
622
378
|
<span>{{
|
|
623
379
|
remarksType === "checkIn" ? "Check-In Remarks" : "Check-Out Remarks"
|
|
624
|
-
|
|
625
|
-
<v-btn
|
|
626
|
-
icon="mdi-close"
|
|
627
|
-
variant="text"
|
|
628
|
-
@click="dialog.remarks = false"
|
|
629
|
-
/>
|
|
380
|
+
}}</span>
|
|
381
|
+
<v-btn icon="mdi-close" variant="text" @click="dialog.remarks = false" />
|
|
630
382
|
</v-card-title>
|
|
631
383
|
<v-card-text class="px-4 pb-2">
|
|
632
|
-
<v-textarea
|
|
633
|
-
|
|
634
|
-
label="Remarks"
|
|
635
|
-
rows="4"
|
|
636
|
-
auto-grow
|
|
637
|
-
variant="outlined"
|
|
638
|
-
:readonly="remarksViewOnly"
|
|
639
|
-
/>
|
|
384
|
+
<v-textarea v-model="remarksInput" label="Remarks" rows="4" auto-grow variant="outlined"
|
|
385
|
+
:readonly="remarksViewOnly" />
|
|
640
386
|
</v-card-text>
|
|
641
387
|
<v-toolbar class="pa-0" density="compact">
|
|
642
388
|
<v-row no-gutters>
|
|
643
389
|
<v-col cols="6">
|
|
644
|
-
<v-btn
|
|
645
|
-
|
|
646
|
-
block
|
|
647
|
-
:disabled="loading.savingRemarks"
|
|
648
|
-
@click="dialog.remarks = false"
|
|
649
|
-
>Cancel</v-btn
|
|
650
|
-
>
|
|
390
|
+
<v-btn variant="text" block :disabled="loading.savingRemarks"
|
|
391
|
+
@click="dialog.remarks = false">Cancel</v-btn>
|
|
651
392
|
</v-col>
|
|
652
393
|
<v-col cols="6">
|
|
653
|
-
<v-btn
|
|
654
|
-
|
|
655
|
-
variant="flat"
|
|
656
|
-
height="48"
|
|
657
|
-
rounded="0"
|
|
658
|
-
block
|
|
659
|
-
:loading="loading.savingRemarks"
|
|
660
|
-
:disabled="!remarksInput.trim()"
|
|
661
|
-
@click="handleSaveRemarks"
|
|
662
|
-
>Save</v-btn
|
|
663
|
-
>
|
|
394
|
+
<v-btn color="primary" variant="flat" height="48" rounded="0" block :loading="loading.savingRemarks"
|
|
395
|
+
:disabled="!remarksInput.trim()" @click="handleSaveRemarks">Save</v-btn>
|
|
664
396
|
</v-col>
|
|
665
397
|
</v-row>
|
|
666
398
|
</v-toolbar>
|
|
@@ -670,16 +402,9 @@
|
|
|
670
402
|
<v-dialog v-model="dialog.returnPassesKeys" max-width="450" persistent>
|
|
671
403
|
<v-card>
|
|
672
404
|
<v-toolbar density="compact" color="">
|
|
673
|
-
<v-row
|
|
674
|
-
no-gutters
|
|
675
|
-
class="d-flex fill-height justify-space-between align-center px-4"
|
|
676
|
-
>
|
|
405
|
+
<v-row no-gutters class="d-flex fill-height justify-space-between align-center px-4">
|
|
677
406
|
<span class="font-weight-bold">Return Passes & Keys</span>
|
|
678
|
-
<v-btn
|
|
679
|
-
icon="mdi-close"
|
|
680
|
-
variant="text"
|
|
681
|
-
@click="dialog.returnPassesKeys = false"
|
|
682
|
-
/>
|
|
407
|
+
<v-btn icon="mdi-close" variant="text" @click="dialog.returnPassesKeys = false" />
|
|
683
408
|
</v-row>
|
|
684
409
|
</v-toolbar>
|
|
685
410
|
<v-card-text class="px-4 pb-2">
|
|
@@ -689,134 +414,55 @@
|
|
|
689
414
|
|
|
690
415
|
<div>
|
|
691
416
|
<InputLabel class="text-capitalize" title="Full Name" />
|
|
692
|
-
<v-text-field
|
|
693
|
-
v-model="selectedVisitorObject.name"
|
|
694
|
-
density="comfortable"
|
|
695
|
-
readonly
|
|
696
|
-
/>
|
|
417
|
+
<v-text-field v-model="selectedVisitorObject.name" density="comfortable" readonly />
|
|
697
418
|
</div>
|
|
698
419
|
|
|
699
420
|
<div>
|
|
700
421
|
<InputLabel class="text-capitalize" title="Location" />
|
|
701
|
-
<v-text-field
|
|
702
|
-
v-model="selectedVisitorObject.location"
|
|
703
|
-
density="comfortable"
|
|
704
|
-
readonly
|
|
705
|
-
/>
|
|
422
|
+
<v-text-field v-model="selectedVisitorObject.location" density="comfortable" readonly />
|
|
706
423
|
</div>
|
|
707
424
|
|
|
708
425
|
<div v-if="passReturnStatuses.length > 0" class="mb-2">
|
|
709
426
|
<p class="text-caption text-medium-emphasis mb-1">Passes</p>
|
|
710
|
-
<v-row
|
|
711
|
-
|
|
712
|
-
v-
|
|
713
|
-
:key="(pass as any)._id ?? (pass as any).keyId"
|
|
714
|
-
class="d-flex flex-wrap justify-space-between align-center ga-5 mb-2"
|
|
715
|
-
>
|
|
716
|
-
<v-chip
|
|
717
|
-
prepend-icon="mdi-card-bulleted-outline"
|
|
718
|
-
size="small"
|
|
719
|
-
variant="tonal"
|
|
720
|
-
color="blue"
|
|
721
|
-
>
|
|
427
|
+
<v-row no-gutters v-for="pass in passReturnStatuses" :key="(pass as any)._id ?? (pass as any).keyId"
|
|
428
|
+
class="d-flex flex-wrap justify-space-between align-center ga-5 mb-2">
|
|
429
|
+
<v-chip prepend-icon="mdi-card-bulleted-outline" size="small" variant="tonal" color="blue">
|
|
722
430
|
{{ (pass as any)?.prefixAndName }}
|
|
723
431
|
</v-chip>
|
|
724
|
-
<v-select
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
density="compact"
|
|
728
|
-
:items="passStatusOptions"
|
|
729
|
-
item-title="label"
|
|
730
|
-
item-value="value"
|
|
731
|
-
v-model="pass.status"
|
|
732
|
-
:disabled="selectedVisitorObject.checkOut"
|
|
733
|
-
></v-select>
|
|
734
|
-
<v-textarea
|
|
735
|
-
v-if="pass.status === 'Lost' || pass.status === 'Damaged'"
|
|
736
|
-
no-resize
|
|
737
|
-
rows="3"
|
|
738
|
-
class="w-100"
|
|
739
|
-
density="compact"
|
|
740
|
-
v-model="pass.remarks"
|
|
741
|
-
:disabled="selectedVisitorObject.checkOut"
|
|
742
|
-
></v-textarea>
|
|
432
|
+
<v-select hide-details max-width="200px" density="compact" :items="passStatusOptions" item-title="label"
|
|
433
|
+
item-value="value" v-model="pass.status" :disabled="selectedVisitorObject.checkOut"></v-select>
|
|
434
|
+
<v-textarea v-if="pass.status === 'Lost' || pass.status === 'Damaged'" no-resize rows="3" class="w-100"
|
|
435
|
+
density="compact" v-model="pass.remarks" :disabled="selectedVisitorObject.checkOut"></v-textarea>
|
|
743
436
|
</v-row>
|
|
744
437
|
</div>
|
|
745
438
|
<div v-if="keyReturnStatuses.length > 0" class="mb-2">
|
|
746
439
|
<p class="text-caption text-medium-emphasis mb-1">Keys</p>
|
|
747
|
-
<v-row
|
|
748
|
-
|
|
749
|
-
v-
|
|
750
|
-
:key="(key as any)._id ?? (key as any).keyId"
|
|
751
|
-
class="d-flex flex-wrap justify-space-between align-center ga-5 mb-2"
|
|
752
|
-
>
|
|
753
|
-
<v-chip
|
|
754
|
-
prepend-icon="mdi-key"
|
|
755
|
-
size="small"
|
|
756
|
-
variant="tonal"
|
|
757
|
-
color="orange"
|
|
758
|
-
>
|
|
440
|
+
<v-row no-gutters v-for="key in keyReturnStatuses" :key="(key as any)._id ?? (key as any).keyId"
|
|
441
|
+
class="d-flex flex-wrap justify-space-between align-center ga-5 mb-2">
|
|
442
|
+
<v-chip prepend-icon="mdi-key" size="small" variant="tonal" color="orange">
|
|
759
443
|
{{ (key as any)?.prefixAndName }}
|
|
760
444
|
</v-chip>
|
|
761
|
-
<v-select
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
density="compact"
|
|
765
|
-
:items="passStatusOptions"
|
|
766
|
-
item-title="label"
|
|
767
|
-
item-value="value"
|
|
768
|
-
v-model="key.status"
|
|
769
|
-
:disabled="selectedVisitorObject.checkOut"
|
|
770
|
-
></v-select>
|
|
771
|
-
<v-textarea
|
|
772
|
-
v-if="key.status === 'Lost' || key.status === 'Damaged'"
|
|
773
|
-
no-resize
|
|
774
|
-
rows="3"
|
|
775
|
-
class="w-100"
|
|
776
|
-
density="compact"
|
|
777
|
-
v-model="key.remarks"
|
|
778
|
-
:disabled="selectedVisitorObject.checkOut"
|
|
779
|
-
></v-textarea>
|
|
445
|
+
<v-select hide-details max-width="200px" density="compact" :items="passStatusOptions" item-title="label"
|
|
446
|
+
item-value="value" v-model="key.status" :disabled="selectedVisitorObject.checkOut"></v-select>
|
|
447
|
+
<v-textarea v-if="key.status === 'Lost' || key.status === 'Damaged'" no-resize rows="3" class="w-100"
|
|
448
|
+
density="compact" v-model="key.remarks" :disabled="selectedVisitorObject.checkOut"></v-textarea>
|
|
780
449
|
</v-row>
|
|
781
450
|
</div>
|
|
782
451
|
|
|
783
452
|
<v-row no-gutters class="my-5">
|
|
784
|
-
<v-btn
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
density="comfortable"
|
|
788
|
-
class="text-capitalize"
|
|
789
|
-
:disabled="selectedVisitorObject.checkOut"
|
|
790
|
-
:loading="loading.updatingPassKeys"
|
|
791
|
-
@click.stop="handleUpdatePassKeys"
|
|
792
|
-
>Update Pass/Keys</v-btn
|
|
793
|
-
>
|
|
453
|
+
<v-btn variant="flat" color="blue" density="comfortable" class="text-capitalize"
|
|
454
|
+
:disabled="selectedVisitorObject.checkOut" :loading="loading.updatingPassKeys"
|
|
455
|
+
@click.stop="handleUpdatePassKeys">Update Pass/Keys</v-btn>
|
|
794
456
|
</v-row>
|
|
795
457
|
</v-card-text>
|
|
796
458
|
<v-toolbar class="pa-0" density="compact">
|
|
797
459
|
<v-row no-gutters>
|
|
798
460
|
<v-col cols="6">
|
|
799
|
-
<v-btn
|
|
800
|
-
variant="text"
|
|
801
|
-
block
|
|
802
|
-
@click="dialog.returnPassesKeys = false"
|
|
803
|
-
>Close</v-btn
|
|
804
|
-
>
|
|
461
|
+
<v-btn variant="text" block @click="dialog.returnPassesKeys = false">Close</v-btn>
|
|
805
462
|
</v-col>
|
|
806
463
|
<v-col cols="6">
|
|
807
|
-
<v-btn
|
|
808
|
-
|
|
809
|
-
variant="flat"
|
|
810
|
-
height="48"
|
|
811
|
-
rounded="0"
|
|
812
|
-
block
|
|
813
|
-
:loading="loading.checkingOut"
|
|
814
|
-
:disabled="
|
|
815
|
-
!canConfirmCheckout || selectedVisitorObject.checkOut
|
|
816
|
-
"
|
|
817
|
-
@click="proceedCheckout"
|
|
818
|
-
>Confirm Checkout</v-btn
|
|
819
|
-
>
|
|
464
|
+
<v-btn color="red" variant="flat" height="48" rounded="0" block :loading="loading.checkingOut" :disabled="!canConfirmCheckout || selectedVisitorObject.checkOut
|
|
465
|
+
" @click="proceedCheckout">Confirm Checkout</v-btn>
|
|
820
466
|
</v-col>
|
|
821
467
|
</v-row>
|
|
822
468
|
</v-toolbar>
|
|
@@ -824,87 +470,50 @@
|
|
|
824
470
|
</v-dialog>
|
|
825
471
|
|
|
826
472
|
<v-dialog v-model="dialog.addPassKey" width="450" persistent>
|
|
827
|
-
<AddPassKeyToVisitor
|
|
828
|
-
|
|
829
|
-
:visitor="selectedVisitorDataObject"
|
|
830
|
-
:site="siteId"
|
|
831
|
-
@close="dialog.addPassKey = false"
|
|
832
|
-
@done="
|
|
473
|
+
<AddPassKeyToVisitor mode="add" :visitor="selectedVisitorDataObject" :site="siteId"
|
|
474
|
+
@close="dialog.addPassKey = false" @done="
|
|
833
475
|
() => {
|
|
834
476
|
dialog.addPassKey = false;
|
|
835
477
|
getVisitorRefresh();
|
|
836
478
|
}
|
|
837
|
-
"
|
|
838
|
-
/>
|
|
479
|
+
" />
|
|
839
480
|
</v-dialog>
|
|
840
481
|
|
|
841
482
|
<v-dialog v-model="dialog.editPassKey" width="450" persistent>
|
|
842
|
-
<AddPassKeyToVisitor
|
|
843
|
-
|
|
844
|
-
:visitor="selectedVisitorDataObject"
|
|
845
|
-
:site="siteId"
|
|
846
|
-
@close="dialog.editPassKey = false"
|
|
847
|
-
@done="
|
|
483
|
+
<AddPassKeyToVisitor mode="edit" :visitor="selectedVisitorDataObject" :site="siteId"
|
|
484
|
+
@close="dialog.editPassKey = false" @done="
|
|
848
485
|
() => {
|
|
849
486
|
dialog.editPassKey = false;
|
|
850
487
|
getVisitorRefresh();
|
|
851
488
|
}
|
|
852
|
-
"
|
|
853
|
-
/>
|
|
489
|
+
" />
|
|
854
490
|
</v-dialog>
|
|
855
491
|
|
|
856
|
-
<ScanVisitorQRCode
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
"
|
|
862
|
-
@close-dialog="dialog.scanVisitorQRCode = false"
|
|
863
|
-
/>
|
|
864
|
-
|
|
865
|
-
<v-dialog
|
|
866
|
-
v-model="dialog.showVisitorDataFromScannedQRCode"
|
|
867
|
-
width="450"
|
|
868
|
-
persistent
|
|
869
|
-
>
|
|
870
|
-
<VisitorDataFromScannedQRCodeForm
|
|
871
|
-
:site="siteId"
|
|
872
|
-
:visitor-data="visitorDataFromScannedQRCode"
|
|
492
|
+
<ScanVisitorQRCode :dialog="dialog.scanVisitorQRCode" :site="siteId" @open-visitor-data-from-scanned-qr-code-dialog="
|
|
493
|
+
handleShowVisitorDataFromScannedQRCodeDialog
|
|
494
|
+
" @close-dialog="dialog.scanVisitorQRCode = false" />
|
|
495
|
+
|
|
496
|
+
<v-dialog v-model="dialog.showVisitorDataFromScannedQRCode" width="450" persistent>
|
|
497
|
+
<VisitorDataFromScannedQRCodeForm :site="siteId" :visitor-data="visitorDataFromScannedQRCode"
|
|
873
498
|
@check-in-out="handleVisitorDataFromScannedQRCodeCheckInOut"
|
|
874
499
|
:processing="isVisitorDataFromScannedQRCodeCheckingInOut"
|
|
875
|
-
@close="handleCloseVisitorDataFromScannedQRCodeDialog"
|
|
876
|
-
/>
|
|
500
|
+
@close="handleCloseVisitorDataFromScannedQRCodeDialog" />
|
|
877
501
|
</v-dialog>
|
|
878
502
|
|
|
879
|
-
<v-dialog
|
|
880
|
-
|
|
881
|
-
transition="dialog-bottom-transition"
|
|
882
|
-
persistent
|
|
883
|
-
width="60vh"
|
|
884
|
-
>
|
|
503
|
+
<v-dialog v-model="dialog.approveRejectOvernightParkingRequestDialog" transition="dialog-bottom-transition"
|
|
504
|
+
persistent width="60vh">
|
|
885
505
|
<v-card>
|
|
886
506
|
<v-toolbar density="compact">
|
|
887
|
-
<v-row
|
|
888
|
-
no-gutters
|
|
889
|
-
class="d-flex fill-height justify-space-between align-center px-4"
|
|
890
|
-
>
|
|
507
|
+
<v-row no-gutters class="d-flex fill-height justify-space-between align-center px-4">
|
|
891
508
|
<span class="font-weight-bold"> Overnight Parking Request </span>
|
|
892
|
-
<v-btn
|
|
893
|
-
icon="mdi-close"
|
|
894
|
-
variant="text"
|
|
895
|
-
@click="dialog.approveRejectOvernightParkingRequestDialog = false"
|
|
896
|
-
/>
|
|
509
|
+
<v-btn icon="mdi-close" variant="text" @click="dialog.approveRejectOvernightParkingRequestDialog = false" />
|
|
897
510
|
</v-row>
|
|
898
511
|
</v-toolbar>
|
|
899
512
|
<v-card-text class="px-4 pb-6">
|
|
900
513
|
<v-row no-gutters justify="center" align-content="center">
|
|
901
|
-
<v-col
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
"
|
|
905
|
-
cols="12"
|
|
906
|
-
class="text-h6 text-center"
|
|
907
|
-
>
|
|
514
|
+
<v-col v-if="
|
|
515
|
+
approveRejectOvernightParkingRequestDialog.status !== 'remarks'
|
|
516
|
+
" cols="12" class="text-h6 text-center">
|
|
908
517
|
{{
|
|
909
518
|
`Are you sure you want to ${approveRejectOvernightParkingRequestDialog.text} the visitor's overnight
|
|
910
519
|
parking
|
|
@@ -913,58 +522,28 @@
|
|
|
913
522
|
</v-col>
|
|
914
523
|
|
|
915
524
|
<v-col cols="12" md="8" class="mt-4">
|
|
916
|
-
<v-textarea
|
|
917
|
-
|
|
918
|
-
label="Remarks"
|
|
919
|
-
placeholder="Enter remarks"
|
|
920
|
-
outlined
|
|
921
|
-
rows="3"
|
|
922
|
-
clearable
|
|
923
|
-
:hide-details="
|
|
924
|
-
approveRejectOvernightParkingRequestDialog.status ===
|
|
525
|
+
<v-textarea v-model="overNightParkingRequestApproveRejectRemarks" label="Remarks"
|
|
526
|
+
placeholder="Enter remarks" outlined rows="3" clearable :hide-details="approveRejectOvernightParkingRequestDialog.status ===
|
|
925
527
|
'remarks'
|
|
926
|
-
|
|
927
|
-
:readonly="
|
|
928
|
-
approveRejectOvernightParkingRequestDialog.status ===
|
|
528
|
+
" :readonly="approveRejectOvernightParkingRequestDialog.status ===
|
|
929
529
|
'remarks'
|
|
930
|
-
|
|
931
|
-
/>
|
|
530
|
+
" />
|
|
932
531
|
</v-col>
|
|
933
532
|
</v-row>
|
|
934
533
|
</v-card-text>
|
|
935
|
-
<v-toolbar
|
|
936
|
-
|
|
937
|
-
class="pa-0"
|
|
938
|
-
density="compact"
|
|
939
|
-
>
|
|
534
|
+
<v-toolbar v-if="approveRejectOvernightParkingRequestDialog.status !== 'remarks'" class="pa-0"
|
|
535
|
+
density="compact">
|
|
940
536
|
<v-row no-gutters>
|
|
941
537
|
<v-col cols="6">
|
|
942
|
-
<v-btn
|
|
943
|
-
text="No"
|
|
944
|
-
color="grey-lighten-3"
|
|
945
|
-
variant="flat"
|
|
946
|
-
height="48"
|
|
947
|
-
tile
|
|
948
|
-
block
|
|
538
|
+
<v-btn text="No" color="grey-lighten-3" variant="flat" height="48" tile block
|
|
949
539
|
:disabled="isApprovingRejectingOvernightParkingRequest"
|
|
950
|
-
@click="closeApproveRejectOvernightParkingDialog"
|
|
951
|
-
/>
|
|
540
|
+
@click="closeApproveRejectOvernightParkingDialog" />
|
|
952
541
|
</v-col>
|
|
953
542
|
<v-col cols="6">
|
|
954
|
-
<v-btn
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
height="48"
|
|
959
|
-
tile
|
|
960
|
-
block
|
|
961
|
-
:disabled="
|
|
962
|
-
!overNightParkingRequestApproveRejectRemarks ||
|
|
963
|
-
isApprovingRejectingOvernightParkingRequest
|
|
964
|
-
"
|
|
965
|
-
@click="updateOvernightParkingRequestStatus"
|
|
966
|
-
:loading="isApprovingRejectingOvernightParkingRequest"
|
|
967
|
-
/>
|
|
543
|
+
<v-btn text="Yes" color="success" variant="flat" height="48" tile block :disabled="!overNightParkingRequestApproveRejectRemarks ||
|
|
544
|
+
isApprovingRejectingOvernightParkingRequest
|
|
545
|
+
" @click="updateOvernightParkingRequestStatus"
|
|
546
|
+
:loading="isApprovingRejectingOvernightParkingRequest" />
|
|
968
547
|
</v-col>
|
|
969
548
|
</v-row>
|
|
970
549
|
</v-toolbar>
|
|
@@ -1230,6 +809,15 @@ function closeApproveRejectOvernightParkingDialog() {
|
|
|
1230
809
|
overNightParkingRequestApproveRejectRemarks.value = "";
|
|
1231
810
|
}
|
|
1232
811
|
|
|
812
|
+
function mappedAttachments(attachments: string[]) {
|
|
813
|
+
return attachments.map((x, index) => {
|
|
814
|
+
return {
|
|
815
|
+
id: x,
|
|
816
|
+
name: `Attachment ${index + 1}`
|
|
817
|
+
}
|
|
818
|
+
});
|
|
819
|
+
}
|
|
820
|
+
|
|
1233
821
|
function normalizeDateOnly(value: string) {
|
|
1234
822
|
if (!value) return "";
|
|
1235
823
|
if (/^\d{4}-\d{2}-\d{2}$/.test(value)) return value;
|
|
@@ -1264,6 +852,7 @@ const formattedFields = {
|
|
|
1264
852
|
checkOut: "Check Out",
|
|
1265
853
|
snapshotExitImage: "Exit Image",
|
|
1266
854
|
remarks: "Remarks",
|
|
855
|
+
attachments: "Attachments",
|
|
1267
856
|
} as const;
|
|
1268
857
|
|
|
1269
858
|
function filterTypeSelectionLabel() {
|
|
@@ -1793,12 +1382,10 @@ async function handleDownloadPDFReport() {
|
|
|
1793
1382
|
if (displayNotCheckedOut.value) queryParams.append("checkedOut", "true");
|
|
1794
1383
|
|
|
1795
1384
|
const queryString = queryParams.toString();
|
|
1796
|
-
const url = `/${route.params.org}/${siteId}/visitor-management/preview${
|
|
1797
|
-
|
|
1798
|
-
}
|
|
1799
|
-
|
|
1800
|
-
new Date().toISOString().split("T")[0]
|
|
1801
|
-
}`;
|
|
1385
|
+
const url = `/${route.params.org}/${siteId}/visitor-management/preview${queryString ? "?" + queryString : ""
|
|
1386
|
+
}`;
|
|
1387
|
+
const title = `Visitor-Report-${siteId}-${new Date().toISOString().split("T")[0]
|
|
1388
|
+
}`;
|
|
1802
1389
|
|
|
1803
1390
|
await downloadPDF({ url, title, orientation: "P", appKey: "SECURITY" });
|
|
1804
1391
|
showMessage("PDF report downloaded successfully!", "success");
|