@7365admin1/layer-common 1.10.3 → 1.10.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/components/AccessCardDeleteDialog.vue +109 -0
- package/components/AccessCardHistoryDialog.vue +133 -0
- package/components/AccessCardPreviewDialog.vue +308 -0
- package/components/AccessCardQrTagging.vue +183 -0
- package/components/AccessCardReplaceForm.vue +179 -0
- package/components/AccessManagement.vue +61 -251
- package/components/AreaChecklistHistoryLogs.vue +1 -1
- package/components/BuildingManagement/units.vue +33 -2
- package/components/BuildingUnitFormAdd.vue +45 -99
- package/components/BuildingUnitFormEdit.vue +59 -148
- package/components/BulletinBoardManagement.vue +6 -1
- package/components/BulletinBoardView.vue +2 -2
- package/components/Button/Close.vue +3 -1
- package/components/CleaningScheduleMain.vue +20 -9
- package/components/IncidentReport/IncidentInformation.vue +45 -6
- package/components/IncidentReport/affectedEntities.vue +29 -0
- package/components/PeopleForm.vue +1 -1
- package/components/PlateNumberDisplay.vue +45 -0
- package/components/ScheduleAreaMain.vue +5 -2
- package/components/ScheduleTaskForm.vue +59 -114
- package/components/ScheduleTaskMain.vue +19 -15
- package/components/VehicleAddSelection.vue +58 -0
- package/components/VehicleForm.vue +600 -0
- package/components/VehicleManagement.vue +298 -0
- package/components/VisitorForm.vue +1 -1
- package/composables/useAccessManagement.ts +16 -0
- package/composables/useBulletin.ts +11 -9
- package/composables/useCard.ts +14 -0
- package/composables/useScheduleTask.ts +4 -8
- package/composables/useVehicle.ts +114 -0
- package/package.json +1 -1
- package/types/bulletin-board.d.ts +1 -1
- package/types/checkout-item.d.ts +1 -0
- package/types/cleaner-schedule.d.ts +1 -1
- package/types/people.d.ts +1 -1
- package/types/vehicle.d.ts +43 -0
|
@@ -12,10 +12,7 @@
|
|
|
12
12
|
<v-row>
|
|
13
13
|
<v-col cols="12" class="mt-2">
|
|
14
14
|
<v-row no-gutters>
|
|
15
|
-
<InputLabel
|
|
16
|
-
class="text-capitalize font-weight-bold"
|
|
17
|
-
title="Building"
|
|
18
|
-
/>
|
|
15
|
+
<InputLabel class="text-capitalize font-weight-bold" title="Building" />
|
|
19
16
|
<v-col cols="12">
|
|
20
17
|
{{ buildingUnit.buildingName }}
|
|
21
18
|
</v-col>
|
|
@@ -28,10 +25,7 @@
|
|
|
28
25
|
<v-row>
|
|
29
26
|
<v-col cols="12" class="mt-2">
|
|
30
27
|
<v-row no-gutters>
|
|
31
|
-
<InputLabel
|
|
32
|
-
class="text-capitalize font-weight-bold"
|
|
33
|
-
title="Block"
|
|
34
|
-
/>
|
|
28
|
+
<InputLabel class="text-capitalize font-weight-bold" title="Block" />
|
|
35
29
|
<v-col cols="12">
|
|
36
30
|
{{ buildingUnit.block }}
|
|
37
31
|
</v-col>
|
|
@@ -42,162 +36,96 @@
|
|
|
42
36
|
|
|
43
37
|
<v-col cols="12">
|
|
44
38
|
<v-row>
|
|
45
|
-
<v-col cols="12" class="mt-2">
|
|
39
|
+
<v-col cols="12" md="6" class="mt-2">
|
|
46
40
|
<v-row no-gutters>
|
|
47
|
-
<InputLabel
|
|
48
|
-
class="text-capitalize font-weight-bold"
|
|
49
|
-
title="Unit Name"
|
|
50
|
-
/>
|
|
41
|
+
<InputLabel class="text-capitalize font-weight-bold" title="Unit Name" />
|
|
51
42
|
<v-col cols="12">
|
|
52
|
-
<v-text-field
|
|
53
|
-
|
|
54
|
-
density="comfortable"
|
|
55
|
-
:rules="[requiredRule]"
|
|
56
|
-
></v-text-field>
|
|
43
|
+
<v-text-field v-model="buildingUnit.name" density="comfortable"
|
|
44
|
+
:rules="[requiredRule]"></v-text-field>
|
|
57
45
|
</v-col>
|
|
58
46
|
</v-row>
|
|
59
47
|
</v-col>
|
|
60
|
-
</v-row>
|
|
61
|
-
</v-col>
|
|
62
48
|
|
|
63
|
-
|
|
64
|
-
<v-row>
|
|
65
|
-
<v-col cols="12" class="mt-2">
|
|
49
|
+
<v-col cols="12" md="6" class="mt-2">
|
|
66
50
|
<v-row no-gutters>
|
|
67
|
-
<InputLabel
|
|
68
|
-
class="text-capitalize font-weight-bold"
|
|
69
|
-
title="Owner"
|
|
70
|
-
/>
|
|
51
|
+
<InputLabel class="text-capitalize font-weight-bold" title="Owner" />
|
|
71
52
|
<v-col cols="12">
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
item-title="name"
|
|
76
|
-
return-object
|
|
77
|
-
density="comfortable">
|
|
78
|
-
</v-autocomplete>
|
|
53
|
+
<v-autocomplete v-model="buildingUnit.ownerName" v-model:search="ownerNameInput"
|
|
54
|
+
:items="peopleItems" item-title="name" return-object density="comfortable">
|
|
55
|
+
</v-autocomplete>
|
|
79
56
|
</v-col>
|
|
80
57
|
</v-row>
|
|
81
58
|
</v-col>
|
|
82
59
|
</v-row>
|
|
83
60
|
</v-col>
|
|
84
61
|
|
|
62
|
+
|
|
85
63
|
<v-col cols="12">
|
|
86
64
|
<v-row>
|
|
87
|
-
<v-col cols="12" class="mt-2">
|
|
65
|
+
<v-col cols="12" md="6" class="mt-2">
|
|
88
66
|
<v-row no-gutters>
|
|
89
|
-
<InputLabel
|
|
90
|
-
class="text-capitalize"
|
|
91
|
-
title="Company Name"
|
|
92
|
-
required
|
|
93
|
-
/>
|
|
67
|
+
<InputLabel class="text-capitalize" title="Company Name" required />
|
|
94
68
|
<v-col cols="12">
|
|
95
|
-
<v-text-field
|
|
96
|
-
|
|
97
|
-
density="comfortable"
|
|
98
|
-
:rules="[requiredRule]"
|
|
99
|
-
></v-text-field>
|
|
69
|
+
<v-text-field v-model="buildingUnit.companyName" density="comfortable"
|
|
70
|
+
:rules="[requiredRule]"></v-text-field>
|
|
100
71
|
</v-col>
|
|
101
72
|
</v-row>
|
|
102
73
|
</v-col>
|
|
103
|
-
</v-row>
|
|
104
|
-
</v-col>
|
|
105
74
|
|
|
106
|
-
|
|
107
|
-
<v-row>
|
|
108
|
-
<v-col cols="12" class="mt-2">
|
|
75
|
+
<v-col cols="12" md="6" class="mt-2">
|
|
109
76
|
<v-row no-gutters>
|
|
110
|
-
<InputLabel
|
|
111
|
-
class="text-capitalize"
|
|
112
|
-
title="Company Registration Number"
|
|
113
|
-
/>
|
|
77
|
+
<InputLabel class="text-capitalize" title="Company Registration Number" />
|
|
114
78
|
<v-col cols="12">
|
|
115
|
-
<v-text-field
|
|
116
|
-
v-model="buildingUnit.companyRegistrationNumber"
|
|
117
|
-
density="comfortable"
|
|
118
|
-
></v-text-field>
|
|
79
|
+
<v-text-field v-model="buildingUnit.companyRegistrationNumber" density="comfortable"></v-text-field>
|
|
119
80
|
</v-col>
|
|
120
81
|
</v-row>
|
|
121
82
|
</v-col>
|
|
122
83
|
</v-row>
|
|
123
84
|
</v-col>
|
|
124
85
|
|
|
86
|
+
|
|
125
87
|
<v-col cols="12">
|
|
126
88
|
<v-row>
|
|
127
|
-
<v-col cols="12" class="mt-2">
|
|
89
|
+
<v-col cols="12" md="6" class="mt-2">
|
|
128
90
|
<v-row no-gutters>
|
|
129
|
-
<InputLabel
|
|
130
|
-
class="text-capitalize"
|
|
131
|
-
title="Lease Start"
|
|
132
|
-
required
|
|
133
|
-
/>
|
|
91
|
+
<InputLabel class="text-capitalize" title="Lease Start" required />
|
|
134
92
|
<v-col cols="12">
|
|
135
|
-
<InputDateTimePicker
|
|
136
|
-
ref="startDateRef"
|
|
137
|
-
v-model="buildingUnit.leaseStart"
|
|
138
|
-
:rules="[requiredRule]"
|
|
139
|
-
/>
|
|
93
|
+
<InputDateTimePicker ref="startDateRef" v-model="buildingUnit.leaseStart" :rules="[requiredRule]" />
|
|
140
94
|
</v-col>
|
|
141
95
|
</v-row>
|
|
142
96
|
</v-col>
|
|
143
|
-
</v-row>
|
|
144
|
-
</v-col>
|
|
145
97
|
|
|
146
|
-
|
|
147
|
-
<v-row>
|
|
148
|
-
<v-col cols="12" class="mt-2">
|
|
98
|
+
<v-col cols="12" md="6" class="mt-2">
|
|
149
99
|
<v-row no-gutters>
|
|
150
|
-
<InputLabel
|
|
151
|
-
class="text-capitalize"
|
|
152
|
-
title="Lease End"
|
|
153
|
-
required
|
|
154
|
-
/>
|
|
100
|
+
<InputLabel class="text-capitalize" title="Lease End" required />
|
|
155
101
|
<v-col cols="12">
|
|
156
|
-
<InputDateTimePicker
|
|
157
|
-
ref="endDateRef"
|
|
158
|
-
v-model="buildingUnit.leaseEnd"
|
|
159
|
-
:rules="[requiredRule]"
|
|
160
|
-
/>
|
|
102
|
+
<InputDateTimePicker ref="endDateRef" v-model="buildingUnit.leaseEnd" :rules="[requiredRule]" />
|
|
161
103
|
</v-col>
|
|
162
104
|
</v-row>
|
|
163
105
|
</v-col>
|
|
106
|
+
|
|
164
107
|
</v-row>
|
|
165
108
|
</v-col>
|
|
166
109
|
|
|
167
|
-
|
|
110
|
+
|
|
111
|
+
<v-col cols="12" md="6" class="mt-2">
|
|
168
112
|
<v-row no-gutters>
|
|
169
|
-
<InputLabel
|
|
170
|
-
class="text-capitalize font-weight-bold"
|
|
171
|
-
title="Category"
|
|
172
|
-
required
|
|
173
|
-
/>
|
|
113
|
+
<InputLabel class="text-capitalize font-weight-bold" title="Category" required />
|
|
174
114
|
<v-col cols="12">
|
|
175
|
-
<v-autocomplete
|
|
176
|
-
|
|
177
|
-
:items="unitCategories"
|
|
178
|
-
density="comfortable"
|
|
179
|
-
:rules="[requiredRule]"
|
|
180
|
-
></v-autocomplete>
|
|
115
|
+
<v-autocomplete v-model="buildingUnit.category" :items="unitCategories" density="comfortable"
|
|
116
|
+
:rules="[requiredRule]"></v-autocomplete>
|
|
181
117
|
</v-col>
|
|
182
118
|
</v-row>
|
|
183
119
|
</v-col>
|
|
184
120
|
|
|
185
121
|
<v-col cols="12">
|
|
186
122
|
<v-row>
|
|
187
|
-
<v-col cols="6" class="mt-2">
|
|
123
|
+
<v-col cols="6" md="6" class="mt-2">
|
|
188
124
|
<v-row no-gutters>
|
|
189
|
-
<InputLabel
|
|
190
|
-
class="text-capitalize font-weight-bold"
|
|
191
|
-
title="Level"
|
|
192
|
-
required
|
|
193
|
-
/>
|
|
125
|
+
<InputLabel class="text-capitalize font-weight-bold" title="Level" required />
|
|
194
126
|
<v-col cols="12">
|
|
195
|
-
<v-select
|
|
196
|
-
|
|
197
|
-
:items="buildingLevels"
|
|
198
|
-
density="comfortable"
|
|
199
|
-
:rules="[requiredRule]"
|
|
200
|
-
></v-select>
|
|
127
|
+
<v-select v-model="buildingUnit.level" :items="buildingLevels" density="comfortable"
|
|
128
|
+
:rules="[requiredRule]"></v-select>
|
|
201
129
|
</v-col>
|
|
202
130
|
</v-row>
|
|
203
131
|
</v-col>
|
|
@@ -205,25 +133,15 @@
|
|
|
205
133
|
</v-col>
|
|
206
134
|
|
|
207
135
|
<v-col cols="12" class="mt-5">
|
|
208
|
-
<InputLabel
|
|
209
|
-
|
|
210
|
-
title="Upload Files
|
|
211
|
-
/>
|
|
212
|
-
<InputFileV2
|
|
213
|
-
v-model="buildingUnit.buildingUnitFiles"
|
|
214
|
-
:multiple="false"
|
|
215
|
-
:max-length="10"
|
|
216
|
-
title="Upload PDF Files"
|
|
217
|
-
accept="application/pdf"
|
|
218
|
-
/>
|
|
136
|
+
<InputLabel class="text-capitalize" title="Upload Files (Lease of Contract, Cert. of Occupancy)" />
|
|
137
|
+
<InputFileV2 v-model="buildingUnit.buildingUnitFiles" :multiple="false" :max-length="10"
|
|
138
|
+
title="Upload PDF Files" accept="application/pdf" />
|
|
219
139
|
</v-col>
|
|
220
140
|
|
|
221
141
|
<v-col cols="12" class="my-2">
|
|
222
142
|
<v-row no-gutters>
|
|
223
143
|
<v-col cols="12" class="text-center">
|
|
224
|
-
<span
|
|
225
|
-
class="text-none text-subtitle-2 font-weight-medium text-error"
|
|
226
|
-
>
|
|
144
|
+
<span class="text-none text-subtitle-2 font-weight-medium text-error">
|
|
227
145
|
{{ message }}
|
|
228
146
|
</span>
|
|
229
147
|
</v-col>
|
|
@@ -236,30 +154,14 @@
|
|
|
236
154
|
<v-toolbar density="compact">
|
|
237
155
|
<v-row no-gutters>
|
|
238
156
|
<v-col cols="6">
|
|
239
|
-
<v-btn
|
|
240
|
-
tile
|
|
241
|
-
block
|
|
242
|
-
variant="text"
|
|
243
|
-
class="text-none"
|
|
244
|
-
size="48"
|
|
245
|
-
@click="cancel"
|
|
246
|
-
>
|
|
157
|
+
<v-btn tile block variant="text" class="text-none" size="48" @click="cancel">
|
|
247
158
|
Cancel
|
|
248
159
|
</v-btn>
|
|
249
160
|
</v-col>
|
|
250
161
|
|
|
251
162
|
<v-col cols="6">
|
|
252
|
-
<v-btn
|
|
253
|
-
|
|
254
|
-
block
|
|
255
|
-
variant="flat"
|
|
256
|
-
color="black"
|
|
257
|
-
class="text-none"
|
|
258
|
-
size="48"
|
|
259
|
-
:disabled="!validForm || disable"
|
|
260
|
-
@click="submit"
|
|
261
|
-
:loading="disable"
|
|
262
|
-
>
|
|
163
|
+
<v-btn tile block variant="flat" color="black" class="text-none" size="48" :disabled="!validForm || disable"
|
|
164
|
+
@click="submit" :loading="disable">
|
|
263
165
|
Submit
|
|
264
166
|
</v-btn>
|
|
265
167
|
</v-col>
|
|
@@ -320,10 +222,13 @@ buildingUnit.value = JSON.parse(JSON.stringify(prop.roomFacility));
|
|
|
320
222
|
|
|
321
223
|
const emit = defineEmits(["cancel", "success", "success:create-more"]);
|
|
322
224
|
|
|
225
|
+
const ownerNameInput = ref("");
|
|
226
|
+
|
|
323
227
|
const validForm = ref(false);
|
|
324
228
|
|
|
325
229
|
const { getAll } = useBuilding();
|
|
326
|
-
const {
|
|
230
|
+
const { getAll: getAllPeople } = usePeople();
|
|
231
|
+
const { debounce } = useUtils();
|
|
327
232
|
|
|
328
233
|
const buildings = ref<Record<string, any>[]>([]);
|
|
329
234
|
const peopleItems = ref<Array<Record<string, any>>>([]);
|
|
@@ -343,15 +248,13 @@ watchEffect(() => {
|
|
|
343
248
|
}
|
|
344
249
|
});
|
|
345
250
|
|
|
346
|
-
const { data: getUnitPeople } = useLazyAsyncData(
|
|
251
|
+
const { data: getUnitPeople, refresh: getUnitPeopleRefresh } = useLazyAsyncData(
|
|
347
252
|
"get-unit-people",
|
|
348
|
-
async () =>
|
|
253
|
+
async () => getAllPeople({ limit: 10, site: prop.site, type: "tenant", search: ownerNameInput.value })
|
|
349
254
|
);
|
|
350
255
|
|
|
351
256
|
watch(getUnitPeople, (newData: any) => {
|
|
352
|
-
|
|
353
|
-
peopleItems.value = newData ?? [];
|
|
354
|
-
}
|
|
257
|
+
peopleItems.value = newData ?? [];
|
|
355
258
|
});
|
|
356
259
|
|
|
357
260
|
buildingUnit.value.site = prop.site;
|
|
@@ -394,7 +297,7 @@ const hasChanges = computed(() => {
|
|
|
394
297
|
async function submit() {
|
|
395
298
|
disable.value = true;
|
|
396
299
|
try {
|
|
397
|
-
|
|
300
|
+
|
|
398
301
|
if (buildingUnit.value.ownerName) {
|
|
399
302
|
buildingUnit.value.owner = (buildingUnit.value.ownerName as any)._id
|
|
400
303
|
buildingUnit.value.ownerName = (buildingUnit.value.ownerName as any).name
|
|
@@ -426,4 +329,12 @@ function cancel() {
|
|
|
426
329
|
message.value = "";
|
|
427
330
|
emit("cancel");
|
|
428
331
|
}
|
|
332
|
+
|
|
333
|
+
const debounceSearchOwner = debounce(() => {
|
|
334
|
+
getUnitPeopleRefresh();
|
|
335
|
+
}, 500);
|
|
336
|
+
|
|
337
|
+
watch(ownerNameInput, (newVal) => {
|
|
338
|
+
debounceSearchOwner();
|
|
339
|
+
}, { immediate: false });
|
|
429
340
|
</script>
|
|
@@ -83,6 +83,11 @@ const props = defineProps({
|
|
|
83
83
|
}, canDeleteBulletinBoard: {
|
|
84
84
|
type: Boolean,
|
|
85
85
|
default: true
|
|
86
|
+
},
|
|
87
|
+
recipients: {
|
|
88
|
+
type: String,
|
|
89
|
+
default: "",
|
|
90
|
+
required: false
|
|
86
91
|
}
|
|
87
92
|
})
|
|
88
93
|
|
|
@@ -158,7 +163,7 @@ const {
|
|
|
158
163
|
pending: getAnnouncementPending,
|
|
159
164
|
} = await useLazyAsyncData(
|
|
160
165
|
`get-all-announcements-${page.value}`,
|
|
161
|
-
() => getAll({ page: page.value, site: siteId, status: status.value }),
|
|
166
|
+
() => getAll({ page: page.value, site: siteId, status: status.value, recipients: props.recipients }),
|
|
162
167
|
{
|
|
163
168
|
watch: [page, () => route.query],
|
|
164
169
|
}
|
|
@@ -54,13 +54,13 @@
|
|
|
54
54
|
|
|
55
55
|
<v-toolbar class="pa-0" density="compact">
|
|
56
56
|
<v-row no-gutters>
|
|
57
|
-
<v-col
|
|
57
|
+
<v-col :col="(!canUpdate && !canDelete) ? 12 : 6" class="pa-0">
|
|
58
58
|
<v-btn block variant="text" height="48" class="text-none" @click="emit('close')">
|
|
59
59
|
Close
|
|
60
60
|
</v-btn>
|
|
61
61
|
</v-col>
|
|
62
62
|
|
|
63
|
-
<v-col cols="6" class="pa-0">
|
|
63
|
+
<v-col v-if="canUpdate || canDelete" cols="6" class="pa-0">
|
|
64
64
|
<v-menu contained>
|
|
65
65
|
<template #activator="{ props }">
|
|
66
66
|
<v-btn block variant="flat" color="black" height="48" class="text-none" tile v-bind="props">
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<v-btn text="Close" class="bg-grey-lighten-2 text-capitalize" :height="prop.height" @click="emit('click')" />
|
|
2
|
+
<v-btn v-if="!prop.iconOnly" text="Close" class="bg-grey-lighten-2 text-capitalize" :height="prop.height" @click="emit('click')" />
|
|
3
|
+
<v-btn v-else icon="mdi-close" size="small" class="bg-grey-lighten-2 text-capitalize" :height="prop.height" @click="emit('click')" />
|
|
3
4
|
</template>
|
|
4
5
|
|
|
5
6
|
<script setup lang="ts">
|
|
6
7
|
const prop = defineProps<{
|
|
7
8
|
height?: string | number;
|
|
9
|
+
iconOnly?: boolean;
|
|
8
10
|
}>();
|
|
9
11
|
|
|
10
12
|
const emit = defineEmits<{
|
|
@@ -57,10 +57,9 @@
|
|
|
57
57
|
}}
|
|
58
58
|
</template>
|
|
59
59
|
<template #item.closeIn="{ item }">
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}}</v-chip>
|
|
60
|
+
<v-chip class="text-capitalize" variant="flat" color="primary" pill>
|
|
61
|
+
{{ remainingTime[item._id] || "No Status" }}
|
|
62
|
+
</v-chip>
|
|
64
63
|
</template>
|
|
65
64
|
<template #item.status="{ value }">
|
|
66
65
|
<v-chip
|
|
@@ -112,7 +111,7 @@ const endDate = ref("");
|
|
|
112
111
|
const status = ref<TScheduleAreaStatus>("All");
|
|
113
112
|
const statusOptions = [
|
|
114
113
|
{ title: "All", value: "all" },
|
|
115
|
-
{ title: "
|
|
114
|
+
{ title: "Open", value: "open" },
|
|
116
115
|
{ title: "Ongoing", value: "ongoing" },
|
|
117
116
|
{ title: "Completed", value: "completed" },
|
|
118
117
|
] as const;
|
|
@@ -129,7 +128,8 @@ const headers = [
|
|
|
129
128
|
{ title: "Completion Date", value: "completionDate" },
|
|
130
129
|
{ title: "", value: "download" },
|
|
131
130
|
];
|
|
132
|
-
const remainingTime = ref({} as
|
|
131
|
+
const remainingTime = ref({} as Record<string, string>);
|
|
132
|
+
const remainingSeconds = ref({} as Record<string, number>);
|
|
133
133
|
const downloadingId = ref<string | null>(null);
|
|
134
134
|
|
|
135
135
|
const { getCleaningSchedules, downloadChecklistPdf } = useCleaningSchedules();
|
|
@@ -141,18 +141,29 @@ const getStatusColor = (status: unknown): string => {
|
|
|
141
141
|
const normalized = String(status).toLowerCase();
|
|
142
142
|
|
|
143
143
|
switch (normalized) {
|
|
144
|
-
case "
|
|
144
|
+
case "open":
|
|
145
145
|
return "grey";
|
|
146
146
|
case "ongoing":
|
|
147
147
|
return "primary";
|
|
148
148
|
case "completed":
|
|
149
149
|
case "accepted":
|
|
150
150
|
return "success";
|
|
151
|
+
case "closed":
|
|
152
|
+
case "rejected":
|
|
153
|
+
return "error";
|
|
151
154
|
default:
|
|
152
155
|
return "secondary";
|
|
153
156
|
}
|
|
154
157
|
};
|
|
155
158
|
|
|
159
|
+
const getCloseInColor = (id: string): string => {
|
|
160
|
+
const secs = remainingSeconds.value[id];
|
|
161
|
+
if (secs === undefined) return "primary";
|
|
162
|
+
if (secs <= 0) return "error";
|
|
163
|
+
if (secs < 3 * 3600) return "warning";
|
|
164
|
+
return "primary";
|
|
165
|
+
};
|
|
166
|
+
|
|
156
167
|
const {
|
|
157
168
|
canDownloadSchedule,
|
|
158
169
|
canViewSchedules,
|
|
@@ -205,11 +216,11 @@ const formatTime = (seconds: number) => {
|
|
|
205
216
|
};
|
|
206
217
|
|
|
207
218
|
const updateRemainingTime = () => {
|
|
208
|
-
console.log(items.value);
|
|
209
219
|
items.value.forEach((item) => {
|
|
210
220
|
const itemId = item._id as string;
|
|
211
221
|
const _time = calculateRemainingTime(item.date as string);
|
|
212
|
-
|
|
222
|
+
remainingSeconds.value[itemId] = _time;
|
|
223
|
+
remainingTime.value[itemId] = _time <= 0 ? "00h 00m" : formatTime(_time);
|
|
213
224
|
});
|
|
214
225
|
};
|
|
215
226
|
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
<p class="my-1 text-h6">
|
|
64
64
|
{{
|
|
65
65
|
toLocalDate(
|
|
66
|
-
incidentInformation?.incidentTypeAndTime?.dateOfIncident
|
|
66
|
+
incidentInformation?.incidentTypeAndTime?.dateOfIncident
|
|
67
67
|
) || "NA"
|
|
68
68
|
}}
|
|
69
69
|
</p>
|
|
@@ -137,9 +137,24 @@
|
|
|
137
137
|
</p>
|
|
138
138
|
</v-col>
|
|
139
139
|
<v-col cols="12" sm="4" md="3">
|
|
140
|
-
<
|
|
140
|
+
<div>
|
|
141
|
+
<InputLabel class="text-capitalize mr-1" title="NRIC/WP Number" />
|
|
142
|
+
<v-icon
|
|
143
|
+
v-if="incidentInformation?.complaintInfo?.nric"
|
|
144
|
+
size="small"
|
|
145
|
+
color="blue"
|
|
146
|
+
class="cursor-pointer"
|
|
147
|
+
@click="showNRICComplainant = !showNRICComplainant"
|
|
148
|
+
>
|
|
149
|
+
{{ showNRICComplainant ? "mdi-eye-off" : "mdi-eye" }}
|
|
150
|
+
</v-icon>
|
|
151
|
+
</div>
|
|
141
152
|
<p class="my-1 text-h6 text-capitalize">
|
|
142
|
-
{{
|
|
153
|
+
{{
|
|
154
|
+
showNRICComplainant
|
|
155
|
+
? incidentInformation?.complaintInfo?.nric || "NA"
|
|
156
|
+
: maskNRIC(incidentInformation?.complaintInfo?.nric)
|
|
157
|
+
}}
|
|
143
158
|
</p>
|
|
144
159
|
</v-col>
|
|
145
160
|
<v-col cols="12" sm="4" md="3">
|
|
@@ -164,9 +179,24 @@
|
|
|
164
179
|
</p>
|
|
165
180
|
</v-col>
|
|
166
181
|
<v-col cols="12" sm="4" md="3">
|
|
167
|
-
<
|
|
182
|
+
<div>
|
|
183
|
+
<InputLabel class="text-capitalize" title="NRIC/WP Number" />
|
|
184
|
+
<v-icon
|
|
185
|
+
v-if="incidentInformation?.recipientOfComplaint?.nric"
|
|
186
|
+
size="small"
|
|
187
|
+
color="blue"
|
|
188
|
+
class="cursor-pointer"
|
|
189
|
+
@click="showNRICRecipient = !showNRICRecipient"
|
|
190
|
+
>
|
|
191
|
+
{{ showNRICRecipient ? "mdi-eye-off" : "mdi-eye" }}
|
|
192
|
+
</v-icon>
|
|
193
|
+
</div>
|
|
168
194
|
<p class="my-1 text-h6 text-capitalize">
|
|
169
|
-
{{
|
|
195
|
+
{{
|
|
196
|
+
showNRICRecipient
|
|
197
|
+
? incidentInformation?.recipientOfComplaint?.nric || "NA"
|
|
198
|
+
: maskNRIC(incidentInformation?.recipientOfComplaint?.nric)
|
|
199
|
+
}}
|
|
170
200
|
</p>
|
|
171
201
|
</v-col>
|
|
172
202
|
<v-col cols="12" sm="4" md="3">
|
|
@@ -234,7 +264,10 @@ const { getSiteById } = useSiteSettings();
|
|
|
234
264
|
// state
|
|
235
265
|
const siteName = ref("");
|
|
236
266
|
|
|
237
|
-
const siteId = computed(() => props.incidentInformation?.siteInfo?.site
|
|
267
|
+
const siteId = computed(() => props.incidentInformation?.siteInfo?.site);
|
|
268
|
+
|
|
269
|
+
const showNRICComplainant = ref(false);
|
|
270
|
+
const showNRICRecipient = ref(false);
|
|
238
271
|
|
|
239
272
|
watch(
|
|
240
273
|
siteId,
|
|
@@ -255,4 +288,10 @@ function toLocalDate(utcString: string) {
|
|
|
255
288
|
day: "2-digit",
|
|
256
289
|
});
|
|
257
290
|
}
|
|
291
|
+
|
|
292
|
+
const maskNRIC = (value: any) => {
|
|
293
|
+
if (!value) return "NA";
|
|
294
|
+
|
|
295
|
+
return value.replace(/.(?=.{3})/g, "*");
|
|
296
|
+
};
|
|
258
297
|
</script>
|
|
@@ -76,6 +76,26 @@
|
|
|
76
76
|
style="max-height: calc(100vh - (200px))"
|
|
77
77
|
class="border mt-5"
|
|
78
78
|
>
|
|
79
|
+
<template #header.nric>
|
|
80
|
+
<div class="d-flex align-center">
|
|
81
|
+
NRIC
|
|
82
|
+
<v-icon
|
|
83
|
+
class="cursor-pointer ml-1"
|
|
84
|
+
size="18"
|
|
85
|
+
color="blue"
|
|
86
|
+
@click="isShowNRIC = !isShowNRIC"
|
|
87
|
+
>
|
|
88
|
+
{{ isShowNRIC ? "mdi-eye-off-outline" : "mdi-eye-outline" }}
|
|
89
|
+
</v-icon>
|
|
90
|
+
</div>
|
|
91
|
+
</template>
|
|
92
|
+
<template #item.nric="{ value }">
|
|
93
|
+
<tr>
|
|
94
|
+
{{
|
|
95
|
+
maskedNric(value)
|
|
96
|
+
}}
|
|
97
|
+
</tr>
|
|
98
|
+
</template>
|
|
79
99
|
</v-data-table>
|
|
80
100
|
</v-col>
|
|
81
101
|
|
|
@@ -142,6 +162,7 @@ const injuredTableHeader = [
|
|
|
142
162
|
value: "contact",
|
|
143
163
|
},
|
|
144
164
|
];
|
|
165
|
+
|
|
145
166
|
const damagePropertyTableHeader = [
|
|
146
167
|
{
|
|
147
168
|
title: "Description",
|
|
@@ -164,4 +185,12 @@ const damagePropertyTableHeader = [
|
|
|
164
185
|
value: "action",
|
|
165
186
|
},
|
|
166
187
|
];
|
|
188
|
+
|
|
189
|
+
const isShowNRIC = ref(false);
|
|
190
|
+
|
|
191
|
+
const maskedNric = (nric: string) => {
|
|
192
|
+
if (!nric) return "";
|
|
193
|
+
if (isShowNRIC.value) return nric;
|
|
194
|
+
return nric[0] + "*".repeat(nric.length - 5) + nric.slice(-4);
|
|
195
|
+
};
|
|
167
196
|
</script>
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
<v-col cols="12">
|
|
34
34
|
<v-row>
|
|
35
35
|
<v-col cols="12">
|
|
36
|
-
<InputLabel class="text-capitalize" title="NRIC
|
|
36
|
+
<InputLabel class="text-capitalize" title="NRIC" />
|
|
37
37
|
<InputNRICNumber v-model.trim="form.nric" density="comfortable" />
|
|
38
38
|
</v-col>
|
|
39
39
|
</v-row>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="d-flex align-center ga-2 flex-wrap">
|
|
3
|
+
<span v-if="formatted">
|
|
4
|
+
{{ formatted }}
|
|
5
|
+
</span>
|
|
6
|
+
|
|
7
|
+
<v-chip
|
|
8
|
+
v-if="extraCount > 0"
|
|
9
|
+
density="comfortable"
|
|
10
|
+
size="small"
|
|
11
|
+
>
|
|
12
|
+
+ {{ extraCount }}
|
|
13
|
+
</v-chip>
|
|
14
|
+
</div>
|
|
15
|
+
</template>
|
|
16
|
+
|
|
17
|
+
<script setup lang="ts">
|
|
18
|
+
const props = defineProps({
|
|
19
|
+
plateNumbers: {
|
|
20
|
+
type: Array as PropType<string[]>,
|
|
21
|
+
default: () => []
|
|
22
|
+
},
|
|
23
|
+
defaultValue: {
|
|
24
|
+
type: String,
|
|
25
|
+
default: ""
|
|
26
|
+
}
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
const formatted = computed(() => {
|
|
30
|
+
if (!props.plateNumbers?.length) return props.defaultValue || ""
|
|
31
|
+
|
|
32
|
+
const firstTwo = props.plateNumbers
|
|
33
|
+
.slice(0, 2)
|
|
34
|
+
.map((v: any) => v?.plateNumber || "")
|
|
35
|
+
|
|
36
|
+
return firstTwo.join(", ")
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
const extraCount = computed(() => {
|
|
40
|
+
if (!props.plateNumbers) return 0
|
|
41
|
+
return props.plateNumbers.length > 2
|
|
42
|
+
? props.plateNumbers.length - 2
|
|
43
|
+
: 0
|
|
44
|
+
})
|
|
45
|
+
</script>
|