@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
|
@@ -103,251 +103,39 @@
|
|
|
103
103
|
</v-dialog>
|
|
104
104
|
|
|
105
105
|
<!-- Preview Dialog -->
|
|
106
|
-
<
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
size="small"
|
|
131
|
-
class="mr-1 mb-1"
|
|
132
|
-
:color="
|
|
133
|
-
selectedCardInUnit?._id === card._id ? 'primary' : undefined
|
|
134
|
-
"
|
|
135
|
-
:variant="
|
|
136
|
-
selectedCardInUnit?._id === card._id ? 'flat' : 'tonal'
|
|
137
|
-
"
|
|
138
|
-
style="cursor: pointer"
|
|
139
|
-
@click="
|
|
140
|
-
selectedCardInUnit =
|
|
141
|
-
selectedCardInUnit?._id === card._id ? null : card
|
|
142
|
-
"
|
|
143
|
-
>
|
|
144
|
-
{{ card.cardNo }}
|
|
145
|
-
</v-chip>
|
|
146
|
-
</div>
|
|
147
|
-
<span v-else class="text-caption text-grey ml-1">None</span>
|
|
148
|
-
</v-col>
|
|
149
|
-
|
|
150
|
-
<!-- Available Non-Physical -->
|
|
151
|
-
<v-col cols="12" class="mt-2">
|
|
152
|
-
<strong>Available Non-Physical</strong>
|
|
153
|
-
<div
|
|
154
|
-
v-if="selectedCard?.available?.non_physical?.length"
|
|
155
|
-
class="mt-1"
|
|
156
|
-
>
|
|
157
|
-
<v-chip
|
|
158
|
-
v-for="card in selectedCard.available.non_physical"
|
|
159
|
-
:key="card._id"
|
|
160
|
-
size="small"
|
|
161
|
-
class="mr-1 mb-1"
|
|
162
|
-
:color="
|
|
163
|
-
selectedCardInUnit?._id === card._id ? 'primary' : undefined
|
|
164
|
-
"
|
|
165
|
-
:variant="
|
|
166
|
-
selectedCardInUnit?._id === card._id ? 'flat' : 'tonal'
|
|
167
|
-
"
|
|
168
|
-
style="cursor: pointer"
|
|
169
|
-
@click="
|
|
170
|
-
selectedCardInUnit =
|
|
171
|
-
selectedCardInUnit?._id === card._id ? null : card
|
|
172
|
-
"
|
|
173
|
-
>
|
|
174
|
-
{{ card.cardNo }}
|
|
175
|
-
</v-chip>
|
|
176
|
-
</div>
|
|
177
|
-
<span v-else class="text-caption text-grey ml-1">None</span>
|
|
178
|
-
</v-col>
|
|
179
|
-
|
|
180
|
-
<!-- Assigned Physical -->
|
|
181
|
-
<v-col cols="12" class="mt-2">
|
|
182
|
-
<strong>Assigned Physical</strong>
|
|
183
|
-
<div v-if="selectedCard?.assigned?.physical?.length" class="mt-1">
|
|
184
|
-
<v-chip
|
|
185
|
-
v-for="card in selectedCard.assigned.physical"
|
|
186
|
-
:key="card._id"
|
|
187
|
-
size="small"
|
|
188
|
-
class="mr-1 mb-1"
|
|
189
|
-
:color="
|
|
190
|
-
selectedCardInUnit?._id === card._id ? 'primary' : undefined
|
|
191
|
-
"
|
|
192
|
-
:variant="
|
|
193
|
-
selectedCardInUnit?._id === card._id ? 'flat' : 'tonal'
|
|
194
|
-
"
|
|
195
|
-
style="cursor: pointer"
|
|
196
|
-
@click="
|
|
197
|
-
selectedCardInUnit =
|
|
198
|
-
selectedCardInUnit?._id === card._id ? null : card
|
|
199
|
-
"
|
|
200
|
-
>
|
|
201
|
-
{{ card.cardNo }}
|
|
202
|
-
</v-chip>
|
|
203
|
-
</div>
|
|
204
|
-
<span v-else class="text-caption text-grey ml-1">None</span>
|
|
205
|
-
</v-col>
|
|
206
|
-
|
|
207
|
-
<!-- Assigned Non-Physical -->
|
|
208
|
-
<v-col cols="12" class="mt-2">
|
|
209
|
-
<strong>Assigned Non-Physical</strong>
|
|
210
|
-
<div
|
|
211
|
-
v-if="selectedCard?.assigned?.non_physical?.length"
|
|
212
|
-
class="mt-1"
|
|
213
|
-
>
|
|
214
|
-
<v-chip
|
|
215
|
-
v-for="card in selectedCard.assigned.non_physical"
|
|
216
|
-
:key="card._id"
|
|
217
|
-
size="small"
|
|
218
|
-
class="mr-1 mb-1"
|
|
219
|
-
:color="
|
|
220
|
-
selectedCardInUnit?._id === card._id ? 'primary' : undefined
|
|
221
|
-
"
|
|
222
|
-
:variant="
|
|
223
|
-
selectedCardInUnit?._id === card._id ? 'flat' : 'tonal'
|
|
224
|
-
"
|
|
225
|
-
style="cursor: pointer"
|
|
226
|
-
@click="
|
|
227
|
-
selectedCardInUnit =
|
|
228
|
-
selectedCardInUnit?._id === card._id ? null : card
|
|
229
|
-
"
|
|
230
|
-
>
|
|
231
|
-
{{ card.cardNo }}
|
|
232
|
-
</v-chip>
|
|
233
|
-
</div>
|
|
234
|
-
<span v-else class="text-caption text-grey ml-1">None</span>
|
|
235
|
-
</v-col>
|
|
236
|
-
</v-row></v-card-text
|
|
237
|
-
>
|
|
238
|
-
<v-toolbar class="pa-0" density="compact">
|
|
239
|
-
<v-row no-gutters>
|
|
240
|
-
<v-col cols="6" class="pa-0">
|
|
241
|
-
<v-btn
|
|
242
|
-
block
|
|
243
|
-
variant="text"
|
|
244
|
-
class="text-none"
|
|
245
|
-
size="large"
|
|
246
|
-
@click="previewDialog = false"
|
|
247
|
-
height="48"
|
|
248
|
-
>
|
|
249
|
-
Close
|
|
250
|
-
</v-btn>
|
|
251
|
-
</v-col>
|
|
252
|
-
<v-col cols="6" class="pa-0" v-if="canUpdate">
|
|
253
|
-
<v-menu>
|
|
254
|
-
<template #activator="{ props }">
|
|
255
|
-
<v-btn
|
|
256
|
-
block
|
|
257
|
-
variant="flat"
|
|
258
|
-
color="black"
|
|
259
|
-
class="text-none"
|
|
260
|
-
height="48"
|
|
261
|
-
v-bind="props"
|
|
262
|
-
tile
|
|
263
|
-
>
|
|
264
|
-
More actions
|
|
265
|
-
</v-btn>
|
|
266
|
-
</template>
|
|
267
|
-
<v-list class="pa-0">
|
|
268
|
-
<v-list-item
|
|
269
|
-
:disabled="selectedCardInUnit === null"
|
|
270
|
-
@click="openReplaceDialog()"
|
|
271
|
-
v-if="canReplaceAccessCard"
|
|
272
|
-
>
|
|
273
|
-
<v-list-item-title class="text-subtitle-2">
|
|
274
|
-
Replace Card
|
|
275
|
-
</v-list-item-title>
|
|
276
|
-
</v-list-item>
|
|
277
|
-
<v-list-item
|
|
278
|
-
@click="openDeleteDialog()"
|
|
279
|
-
class="text-red"
|
|
280
|
-
:disabled="selectedCardInUnit === null"
|
|
281
|
-
v-if="canDeleteAccessCard"
|
|
282
|
-
>
|
|
283
|
-
<v-list-item-title class="text-subtitle-2">
|
|
284
|
-
Delete Card
|
|
285
|
-
</v-list-item-title>
|
|
286
|
-
</v-list-item>
|
|
287
|
-
</v-list>
|
|
288
|
-
</v-menu>
|
|
289
|
-
</v-col>
|
|
290
|
-
</v-row>
|
|
291
|
-
</v-toolbar></v-card
|
|
292
|
-
>
|
|
106
|
+
<AccessCardPreviewDialog
|
|
107
|
+
v-model="previewDialog"
|
|
108
|
+
:unit="selectedCard"
|
|
109
|
+
v-model:selected-card-in-unit="selectedCardInUnit"
|
|
110
|
+
:can-update="canUpdate"
|
|
111
|
+
:can-replace-access-card="canReplaceAccessCard"
|
|
112
|
+
:can-delete-access-card="canDeleteAccessCard"
|
|
113
|
+
:is-selected-card-assigned-physical="isSelectedCardAssignedPhysical"
|
|
114
|
+
:is-selected-card-physical="isSelectedCardPhysical"
|
|
115
|
+
@replace="openReplaceDialog()"
|
|
116
|
+
@delete="openDeleteDialog()"
|
|
117
|
+
/>
|
|
118
|
+
|
|
119
|
+
<!-- Replace Card Dialog -->
|
|
120
|
+
<v-dialog v-model="replaceDialog" width="500" persistent>
|
|
121
|
+
<AccessCardReplaceForm
|
|
122
|
+
v-if="selectedCardInUnit"
|
|
123
|
+
:card="selectedCardInUnit"
|
|
124
|
+
:unit="selectedCard"
|
|
125
|
+
:site-id="siteId"
|
|
126
|
+
@cancel="replaceDialog = false"
|
|
127
|
+
@success="successReplace()"
|
|
128
|
+
@error="(msg: any) => showMessage(msg, 'error')"
|
|
129
|
+
/>
|
|
293
130
|
</v-dialog>
|
|
294
131
|
|
|
295
132
|
<!-- Delete Dialog -->
|
|
296
|
-
<
|
|
133
|
+
<AccessCardDeleteDialog
|
|
297
134
|
v-model="confirmDialog"
|
|
298
135
|
:loading="deleteLoading"
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
<v-card width="100%">
|
|
303
|
-
<v-toolbar density="compact" class="pl-4">
|
|
304
|
-
<span class="font-weight-medium text-h5">Delete Card</span>
|
|
305
|
-
</v-toolbar>
|
|
306
|
-
<v-card-text>
|
|
307
|
-
<p class="text-subtitle-2 text-center">
|
|
308
|
-
Are you sure you want to delete this card? This action cannot be
|
|
309
|
-
undone.
|
|
310
|
-
</p>
|
|
311
|
-
|
|
312
|
-
<v-row v-if="message" no-gutters justify="center" class="mt-4">
|
|
313
|
-
<span class="text-caption text-error text-center">
|
|
314
|
-
{{ message }}
|
|
315
|
-
</span>
|
|
316
|
-
</v-row></v-card-text
|
|
317
|
-
>
|
|
318
|
-
<v-toolbar density="compact">
|
|
319
|
-
<v-row no-gutters>
|
|
320
|
-
<v-col cols="6">
|
|
321
|
-
<v-btn
|
|
322
|
-
tile
|
|
323
|
-
block
|
|
324
|
-
size="48"
|
|
325
|
-
variant="text"
|
|
326
|
-
class="text-none"
|
|
327
|
-
@click="confirmDialog = false"
|
|
328
|
-
:disabled="deleteLoading"
|
|
329
|
-
>
|
|
330
|
-
Close
|
|
331
|
-
</v-btn>
|
|
332
|
-
</v-col>
|
|
333
|
-
<v-col cols="6">
|
|
334
|
-
<v-btn
|
|
335
|
-
tile
|
|
336
|
-
block
|
|
337
|
-
size="48"
|
|
338
|
-
color="black"
|
|
339
|
-
variant="flat"
|
|
340
|
-
class="text-none"
|
|
341
|
-
@click="handleDeleteCard"
|
|
342
|
-
:loading="deleteLoading"
|
|
343
|
-
>
|
|
344
|
-
Delete Card
|
|
345
|
-
</v-btn>
|
|
346
|
-
</v-col>
|
|
347
|
-
</v-row></v-toolbar
|
|
348
|
-
>
|
|
349
|
-
</v-card>
|
|
350
|
-
</v-dialog>
|
|
136
|
+
:error="deleteError"
|
|
137
|
+
@confirm="handleDeleteCard"
|
|
138
|
+
/>
|
|
351
139
|
|
|
352
140
|
<Snackbar v-model="messageSnackbar" :text="message" :color="messageColor" />
|
|
353
141
|
</v-row>
|
|
@@ -362,17 +150,17 @@ const props = defineProps({
|
|
|
362
150
|
type: Array as PropType<Array<Record<string, any>>>,
|
|
363
151
|
default: () => [
|
|
364
152
|
{
|
|
365
|
-
title: "
|
|
366
|
-
value: "name",
|
|
367
|
-
},
|
|
368
|
-
{
|
|
369
|
-
title: "Block",
|
|
153
|
+
title: "Building",
|
|
370
154
|
value: "block.name",
|
|
371
155
|
},
|
|
372
156
|
{
|
|
373
157
|
title: "Level",
|
|
374
158
|
value: "level.level",
|
|
375
159
|
},
|
|
160
|
+
{
|
|
161
|
+
title: "Unit",
|
|
162
|
+
value: "name",
|
|
163
|
+
},
|
|
376
164
|
{
|
|
377
165
|
title: "Avail. (P)",
|
|
378
166
|
value: "cardCounts.available.physical",
|
|
@@ -440,6 +228,7 @@ const createDialog = ref(false);
|
|
|
440
228
|
const assignDialog = ref(false);
|
|
441
229
|
const previewDialog = ref(false);
|
|
442
230
|
const deleteLoading = ref(false);
|
|
231
|
+
const deleteError = ref("");
|
|
443
232
|
const confirmDialog = ref(false);
|
|
444
233
|
const searchText = ref("");
|
|
445
234
|
const replaceDialog = ref(false);
|
|
@@ -458,8 +247,21 @@ watch(previewDialog, (val) => {
|
|
|
458
247
|
if (!val) selectedCardInUnit.value = null;
|
|
459
248
|
});
|
|
460
249
|
|
|
461
|
-
const
|
|
462
|
-
|
|
250
|
+
const isSelectedCardAssignedPhysical = computed(() =>
|
|
251
|
+
selectedCard.value?.assigned?.physical?.some(
|
|
252
|
+
(c: any) => c._id === selectedCardInUnit.value?._id
|
|
253
|
+
) ?? false
|
|
254
|
+
);
|
|
255
|
+
|
|
256
|
+
const isSelectedCardPhysical = computed(() =>
|
|
257
|
+
["available", "assigned", "replaced", "deleted"].some((state) =>
|
|
258
|
+
selectedCard.value?.[state]?.physical?.some(
|
|
259
|
+
(c: any) => c._id === selectedCardInUnit.value?._id
|
|
260
|
+
)
|
|
261
|
+
)
|
|
262
|
+
);
|
|
263
|
+
|
|
264
|
+
const { getUserTypeAccessCards, deleteCard: _deleteCard } = useAccessManagement();
|
|
463
265
|
|
|
464
266
|
const statsRef = ref<{ refresh: () => void } | null>(null);
|
|
465
267
|
|
|
@@ -528,24 +330,32 @@ function tableRowClickHandler(_: any, data: any) {
|
|
|
528
330
|
|
|
529
331
|
function openDeleteDialog() {
|
|
530
332
|
confirmDialog.value = true;
|
|
531
|
-
|
|
333
|
+
deleteError.value = "";
|
|
532
334
|
}
|
|
533
335
|
|
|
534
336
|
function openReplaceDialog() {
|
|
535
337
|
replaceDialog.value = true;
|
|
536
338
|
}
|
|
537
339
|
|
|
538
|
-
|
|
340
|
+
function successReplace() {
|
|
341
|
+
replaceDialog.value = false;
|
|
342
|
+
previewDialog.value = false;
|
|
343
|
+
getCards();
|
|
344
|
+
statsRef.value?.refresh();
|
|
345
|
+
showMessage("Access card replaced successfully!", "success");
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
async function handleDeleteCard(remarks: string) {
|
|
539
349
|
deleteLoading.value = true;
|
|
540
350
|
try {
|
|
541
|
-
await _deleteCard(
|
|
351
|
+
await _deleteCard({ cardId: selectedCardInUnit.value?._id ?? "", remarks });
|
|
542
352
|
await getCards();
|
|
543
353
|
statsRef.value?.refresh();
|
|
544
354
|
selectedCardId.value = null;
|
|
545
355
|
confirmDialog.value = false;
|
|
546
356
|
previewDialog.value = false;
|
|
547
357
|
} catch (error: any) {
|
|
548
|
-
|
|
358
|
+
deleteError.value = error?.response?._data?.message || "Failed to delete card";
|
|
549
359
|
} finally {
|
|
550
360
|
deleteLoading.value = false;
|
|
551
361
|
}
|
|
@@ -38,18 +38,20 @@
|
|
|
38
38
|
</v-col>
|
|
39
39
|
|
|
40
40
|
<!-- Create Dialog -->
|
|
41
|
-
<v-dialog v-model="createDialog" width="
|
|
41
|
+
<v-dialog v-model="createDialog" :width="smAndUp ? '70svw' : '100%'" persistent>
|
|
42
42
|
<BuildingUnitFormAdd :site="site" @cancel="createDialog = false" @success="successCreate()"
|
|
43
43
|
@success:create-more="getBuildingUnit()" />
|
|
44
44
|
</v-dialog>
|
|
45
45
|
|
|
46
46
|
<!-- Edit Dialog -->
|
|
47
|
-
<v-dialog v-model="dialogEdit" width="
|
|
47
|
+
<v-dialog v-model="dialogEdit" :width="smAndUp ? '70svw' : '100%'" persistent>
|
|
48
48
|
<BuildingUnitFormEdit v-if="selectedBuildingUnit" @cancel="dialogEdit = false" @success="successUpdate()"
|
|
49
49
|
:roomFacility="selectedBuildingUnit" />
|
|
50
50
|
</v-dialog>
|
|
51
51
|
|
|
52
52
|
<!-- Preview Dialog -->
|
|
53
|
+
|
|
54
|
+
|
|
53
55
|
<v-dialog v-if="canViewUnitDetails" v-model="dialogPreview" width="450" persistent>
|
|
54
56
|
<v-card width="100%">
|
|
55
57
|
<v-card-text style="max-height: 100vh; overflow-y: auto" class="pb-0">
|
|
@@ -73,6 +75,30 @@
|
|
|
73
75
|
{{ selectedBuildingUnit.category }}
|
|
74
76
|
</v-col>
|
|
75
77
|
|
|
78
|
+
<v-col cols="12">
|
|
79
|
+
<strong>Company Name:</strong>
|
|
80
|
+
{{ selectedBuildingUnit.companyName || "" }}
|
|
81
|
+
</v-col>
|
|
82
|
+
|
|
83
|
+
<v-col cols="12">
|
|
84
|
+
<strong>Company Registration Number:</strong>
|
|
85
|
+
{{ selectedBuildingUnit.companyRegistrationNumber || "" }}
|
|
86
|
+
</v-col>
|
|
87
|
+
|
|
88
|
+
<v-col cols="12">
|
|
89
|
+
<strong>Lease Start:</strong>
|
|
90
|
+
{{ formatDateDDMMYYYYLocal(selectedBuildingUnit.leaseStart) || "" }}
|
|
91
|
+
</v-col>
|
|
92
|
+
<v-col cols="12">
|
|
93
|
+
<strong>Lease End:</strong>
|
|
94
|
+
{{ formatDateDDMMYYYYLocal(selectedBuildingUnit.leaseEnd) || "" }}
|
|
95
|
+
</v-col>
|
|
96
|
+
|
|
97
|
+
<v-col cols="12">
|
|
98
|
+
<strong>Owner Name:</strong>
|
|
99
|
+
{{ selectedBuildingUnit.ownerName || "" }}
|
|
100
|
+
</v-col>
|
|
101
|
+
|
|
76
102
|
<template v-if="selectedBuildingUnit?.buildingUnitFiles.length > 0">
|
|
77
103
|
<v-col cols="12">
|
|
78
104
|
<strong>Uploaded Files:</strong>
|
|
@@ -164,6 +190,8 @@
|
|
|
164
190
|
</template>
|
|
165
191
|
|
|
166
192
|
<script setup lang="ts">
|
|
193
|
+
import { useDisplay } from 'vuetify/lib/composables/display.mjs';
|
|
194
|
+
|
|
167
195
|
const props = defineProps({
|
|
168
196
|
headers: {
|
|
169
197
|
type: Array as PropType<Array<Record<string, any>>>,
|
|
@@ -228,10 +256,13 @@ const props = defineProps({
|
|
|
228
256
|
const site = (useRoute().params.site as string) ?? "";
|
|
229
257
|
const status = (useRoute().params.status as string) ?? "active";
|
|
230
258
|
|
|
259
|
+
const { smAndUp } = useDisplay();
|
|
260
|
+
|
|
231
261
|
const { toOrdinal } = useUtils();
|
|
232
262
|
|
|
233
263
|
const { headerSearch } = useLocal();
|
|
234
264
|
const { getAll, deleteById } = useBuildingUnit();
|
|
265
|
+
const { formatDateDDMMYYYYLocal } = useUtils();
|
|
235
266
|
|
|
236
267
|
const page = ref(1);
|
|
237
268
|
const pages = ref(0);
|
|
@@ -23,25 +23,23 @@
|
|
|
23
23
|
|
|
24
24
|
<v-col cols="12">
|
|
25
25
|
<v-row>
|
|
26
|
-
<v-col cols="12" class="mt-2">
|
|
26
|
+
<v-col cols="12" md="6" class="mt-2">
|
|
27
27
|
<v-row no-gutters>
|
|
28
|
-
<InputLabel
|
|
29
|
-
class="text-capitalize"
|
|
30
|
-
title="Building"
|
|
31
|
-
required
|
|
32
|
-
/>
|
|
28
|
+
<InputLabel class="text-capitalize" title="Building" required />
|
|
33
29
|
<v-col cols="12">
|
|
34
|
-
<v-autocomplete
|
|
35
|
-
v-model="
|
|
36
|
-
:
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
30
|
+
<v-autocomplete v-model="buildingUnit.building" :items="buildings" item-title="name"
|
|
31
|
+
item-value="_id" v-model:search="searchBuilding" :hide-no-data="false" density="comfortable"
|
|
32
|
+
:rules="[requiredRule]" variant="outlined"></v-autocomplete>
|
|
33
|
+
</v-col>
|
|
34
|
+
</v-row>
|
|
35
|
+
</v-col>
|
|
36
|
+
|
|
37
|
+
<v-col cols="12" md="6" class="mt-2">
|
|
38
|
+
<v-row no-gutters>
|
|
39
|
+
<InputLabel class="text-capitalize" title="Category" required />
|
|
40
|
+
<v-col cols="12">
|
|
41
|
+
<v-autocomplete v-model="buildingUnit.category" :items="unitCategories" density="comfortable"
|
|
42
|
+
:rules="[requiredRule]"></v-autocomplete>
|
|
45
43
|
</v-col>
|
|
46
44
|
</v-row>
|
|
47
45
|
</v-col>
|
|
@@ -131,19 +129,7 @@
|
|
|
131
129
|
</v-row>
|
|
132
130
|
</v-col> -->
|
|
133
131
|
|
|
134
|
-
|
|
135
|
-
<v-row no-gutters>
|
|
136
|
-
<InputLabel class="text-capitalize" title="Category" required />
|
|
137
|
-
<v-col cols="12">
|
|
138
|
-
<v-autocomplete
|
|
139
|
-
v-model="buildingUnit.category"
|
|
140
|
-
:items="unitCategories"
|
|
141
|
-
density="comfortable"
|
|
142
|
-
:rules="[requiredRule]"
|
|
143
|
-
></v-autocomplete>
|
|
144
|
-
</v-col>
|
|
145
|
-
</v-row>
|
|
146
|
-
</v-col>
|
|
132
|
+
|
|
147
133
|
|
|
148
134
|
<v-col cols="12">
|
|
149
135
|
<v-row>
|
|
@@ -151,31 +137,18 @@
|
|
|
151
137
|
<v-row no-gutters>
|
|
152
138
|
<InputLabel class="text-capitalize" title="Level" required />
|
|
153
139
|
<v-col cols="12">
|
|
154
|
-
<v-select
|
|
155
|
-
|
|
156
|
-
:items="buildingLevels"
|
|
157
|
-
density="comfortable"
|
|
158
|
-
:rules="[requiredRule]"
|
|
159
|
-
></v-select>
|
|
140
|
+
<v-select v-model="buildingUnit.level" :items="buildingLevels" density="comfortable"
|
|
141
|
+
:rules="[requiredRule]"></v-select>
|
|
160
142
|
</v-col>
|
|
161
143
|
</v-row>
|
|
162
144
|
</v-col>
|
|
163
145
|
|
|
164
146
|
<v-col cols="6" class="mt-2">
|
|
165
147
|
<v-row no-gutters>
|
|
166
|
-
<InputLabel
|
|
167
|
-
class="text-capitalize"
|
|
168
|
-
title="No. of Units"
|
|
169
|
-
required
|
|
170
|
-
/>
|
|
148
|
+
<InputLabel class="text-capitalize" title="No. of Units" required />
|
|
171
149
|
<v-col cols="12">
|
|
172
|
-
<v-text-field
|
|
173
|
-
|
|
174
|
-
density="comfortable"
|
|
175
|
-
:rules="[requiredRule]"
|
|
176
|
-
type="number"
|
|
177
|
-
@update:model-value="setBuildingLevels()"
|
|
178
|
-
></v-text-field>
|
|
150
|
+
<v-text-field v-model.number="buildingUnitQty" density="comfortable" :rules="[requiredRule]"
|
|
151
|
+
type="number" @update:model-value="setBuildingLevels()"></v-text-field>
|
|
179
152
|
</v-col>
|
|
180
153
|
</v-row>
|
|
181
154
|
</v-col>
|
|
@@ -185,39 +158,31 @@
|
|
|
185
158
|
<v-col v-if="buildingLevels" cols="12">
|
|
186
159
|
<v-row justify="center">
|
|
187
160
|
<v-col cols="6">
|
|
188
|
-
<v-btn
|
|
189
|
-
|
|
190
|
-
color="primary"
|
|
191
|
-
variant="text"
|
|
192
|
-
class="text-none font-weight-bold"
|
|
193
|
-
text="Set unit labels"
|
|
194
|
-
@click="show = !show"
|
|
195
|
-
></v-btn>
|
|
161
|
+
<v-btn block color="primary" variant="text" class="text-none font-weight-bold" text="Set unit labels"
|
|
162
|
+
@click="show = !show"></v-btn>
|
|
196
163
|
</v-col>
|
|
197
164
|
</v-row>
|
|
198
165
|
</v-col>
|
|
199
166
|
|
|
200
167
|
<v-expand-transition>
|
|
201
168
|
<v-row v-show="show" no-gutters>
|
|
202
|
-
<
|
|
203
|
-
v-for="(unitLabel, unitLabelIndex) in unitLabels"
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
</v-col>
|
|
220
|
-
</template>
|
|
169
|
+
<v-row>
|
|
170
|
+
<template v-for="(unitLabel, unitLabelIndex) in unitLabels" :key="levelIndex">
|
|
171
|
+
<v-col cols="12" md="4">
|
|
172
|
+
<v-row>
|
|
173
|
+
<v-col cols="12">
|
|
174
|
+
<v-row no-gutters>
|
|
175
|
+
<InputLabel class="text-capitalize font-weight-bold" :title="`Unit ${unitLabelIndex + 1}`" />
|
|
176
|
+
<v-col cols="12">
|
|
177
|
+
<v-text-field v-model.trim="unitLabels[unitLabelIndex]"
|
|
178
|
+
density="comfortable"></v-text-field>
|
|
179
|
+
</v-col>
|
|
180
|
+
</v-row>
|
|
181
|
+
</v-col>
|
|
182
|
+
</v-row>
|
|
183
|
+
</v-col>
|
|
184
|
+
</template>
|
|
185
|
+
</v-row>
|
|
221
186
|
</v-row>
|
|
222
187
|
</v-expand-transition>
|
|
223
188
|
|
|
@@ -248,9 +213,7 @@
|
|
|
248
213
|
<v-col cols="12" class="my-2">
|
|
249
214
|
<v-row no-gutters>
|
|
250
215
|
<v-col cols="12" class="text-center">
|
|
251
|
-
<span
|
|
252
|
-
class="text-none text-subtitle-2 font-weight-medium text-error"
|
|
253
|
-
>
|
|
216
|
+
<span class="text-none text-subtitle-2 font-weight-medium text-error">
|
|
254
217
|
{{ message }}
|
|
255
218
|
</span>
|
|
256
219
|
</v-col>
|
|
@@ -263,31 +226,14 @@
|
|
|
263
226
|
<v-toolbar density="compact">
|
|
264
227
|
<v-row no-gutters>
|
|
265
228
|
<v-col cols="6">
|
|
266
|
-
<v-btn
|
|
267
|
-
tile
|
|
268
|
-
block
|
|
269
|
-
variant="text"
|
|
270
|
-
class="text-none"
|
|
271
|
-
size="48"
|
|
272
|
-
@click="cancel"
|
|
273
|
-
:disabled="disable"
|
|
274
|
-
>
|
|
229
|
+
<v-btn tile block variant="text" class="text-none" size="48" @click="cancel" :disabled="disable">
|
|
275
230
|
Cancel
|
|
276
231
|
</v-btn>
|
|
277
232
|
</v-col>
|
|
278
233
|
|
|
279
234
|
<v-col cols="6">
|
|
280
|
-
<v-btn
|
|
281
|
-
|
|
282
|
-
block
|
|
283
|
-
variant="flat"
|
|
284
|
-
color="black"
|
|
285
|
-
class="text-none"
|
|
286
|
-
size="48"
|
|
287
|
-
:disabled="!validForm || disable"
|
|
288
|
-
@click="submit"
|
|
289
|
-
:loading="disable"
|
|
290
|
-
>
|
|
235
|
+
<v-btn tile block variant="flat" color="black" class="text-none" size="48" :disabled="!validForm || disable"
|
|
236
|
+
@click="submit" :loading="disable">
|
|
291
237
|
Submit
|
|
292
238
|
</v-btn>
|
|
293
239
|
</v-col>
|
|
@@ -409,7 +355,7 @@ function setBuildingUnit() {
|
|
|
409
355
|
|
|
410
356
|
async function submit() {
|
|
411
357
|
disable.value = true;
|
|
412
|
-
const {buildingUnitFiles, companyName, companyRegistrationNumber, leaseStart, leaseEnd, ...rest} = buildingUnit.value;
|
|
358
|
+
const { buildingUnitFiles, companyName, companyRegistrationNumber, leaseStart, leaseEnd, ...rest } = buildingUnit.value;
|
|
413
359
|
try {
|
|
414
360
|
await add({
|
|
415
361
|
labels: unitLabels.value,
|