@7365admin1/layer-common 1.10.7 → 1.10.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/components/{AddSupplyForm.vue → AddEqupmentForm.vue} +5 -5
- package/components/BuildingManagement/units.vue +2 -2
- package/components/BuildingUnitFormAdd.vue +4 -4
- package/components/BuildingUnitFormEdit.vue +114 -68
- package/components/EntryPassInformation.vue +251 -23
- package/components/{CheckoutItemMain.vue → EquipmentItemMain.vue} +88 -85
- package/components/{SupplyManagement.vue → EquipmentManagement.vue} +3 -3
- package/components/Input/DateTimePicker.vue +17 -11
- package/components/ManageChecklistMain.vue +379 -41
- package/components/TableHygiene.vue +42 -452
- package/components/UnitPersonCard.vue +74 -14
- package/components/VisitorForm.vue +77 -21
- package/components/VisitorFormSelection.vue +13 -2
- package/components/VisitorManagement.vue +83 -55
- package/composables/useCleaningPermission.ts +7 -7
- package/composables/useDashboardData.ts +2 -2
- package/composables/{useSupply.ts → useEquipment.ts} +11 -11
- package/composables/{useCheckout.ts → useEquipmentItem.ts} +7 -7
- package/composables/{useCheckoutPermission.ts → useEquipmentItemPermission.ts} +13 -13
- package/composables/useEquipmentManagementPermission.ts +96 -0
- package/composables/{useSupplyPermission.ts → useEquipmentPermission.ts} +9 -9
- package/composables/useVehicle.ts +21 -2
- package/composables/useVisitor.ts +3 -3
- package/composables/useWorkOrder.ts +25 -3
- package/package.json +1 -1
- package/types/building.d.ts +1 -1
- package/types/{checkout-item.d.ts → equipment-item.d.ts} +3 -3
- package/types/{supply.d.ts → equipment.d.ts} +2 -2
- package/types/people.d.ts +3 -1
- package/types/vehicle.d.ts +2 -0
- package/types/visitor.d.ts +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<v-toolbar>
|
|
5
5
|
<v-row no-gutters class="fill-height px-6" align="center">
|
|
6
6
|
<span class="font-weight-bold text-h6 text-capitalize">
|
|
7
|
-
{{ prop.mode === "edit" ? "Edit
|
|
7
|
+
{{ prop.mode === "edit" ? "Edit Equipment" : "Add New Equipment" }}
|
|
8
8
|
</span>
|
|
9
9
|
</v-row>
|
|
10
10
|
</v-toolbar>
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
:rules="[requiredRule]"
|
|
20
20
|
density="comfortable"
|
|
21
21
|
variant="outlined"
|
|
22
|
-
placeholder="Enter
|
|
22
|
+
placeholder="Enter equipment name"
|
|
23
23
|
hide-details="auto"
|
|
24
24
|
class="mb-0"
|
|
25
25
|
/>
|
|
@@ -94,7 +94,7 @@ const prop = defineProps({
|
|
|
94
94
|
type: String,
|
|
95
95
|
default: "add",
|
|
96
96
|
},
|
|
97
|
-
|
|
97
|
+
equipmentData: {
|
|
98
98
|
type: Object,
|
|
99
99
|
default: null,
|
|
100
100
|
},
|
|
@@ -122,8 +122,8 @@ const unitOfMeasurementOptions = [
|
|
|
122
122
|
];
|
|
123
123
|
|
|
124
124
|
watchEffect(() => {
|
|
125
|
-
nameModel.value = prop.
|
|
126
|
-
unitOfMeasurementModel.value = prop.
|
|
125
|
+
nameModel.value = prop.equipmentData?.name || "";
|
|
126
|
+
unitOfMeasurementModel.value = prop.equipmentData?.unitOfMeasurement || "";
|
|
127
127
|
});
|
|
128
128
|
|
|
129
129
|
function close() {
|
|
@@ -98,11 +98,11 @@ const props = defineProps({
|
|
|
98
98
|
type: Array as PropType<Array<Record<string, any>>>,
|
|
99
99
|
default: () => [
|
|
100
100
|
{
|
|
101
|
-
title: "Name",
|
|
101
|
+
title: "Unit Name",
|
|
102
102
|
value: "name",
|
|
103
103
|
},
|
|
104
104
|
{
|
|
105
|
-
title: "
|
|
105
|
+
title: "Level",
|
|
106
106
|
value: "level",
|
|
107
107
|
},
|
|
108
108
|
{
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
</v-row>
|
|
64
64
|
</v-col>
|
|
65
65
|
|
|
66
|
-
<v-col cols="12" md="6" class="mt-2">
|
|
66
|
+
<!-- <v-col cols="12" md="6" class="mt-2">
|
|
67
67
|
<v-row no-gutters>
|
|
68
68
|
<InputLabel class="text-capitalize" title="Category" required />
|
|
69
69
|
<v-col cols="12">
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
:rules="[requiredRule]"></v-autocomplete>
|
|
72
72
|
</v-col>
|
|
73
73
|
</v-row>
|
|
74
|
-
</v-col>
|
|
74
|
+
</v-col> -->
|
|
75
75
|
</v-row>
|
|
76
76
|
</v-col>
|
|
77
77
|
|
|
@@ -282,7 +282,7 @@ const buildingUnit = ref<TBuildingUnit>({
|
|
|
282
282
|
buildingName: "",
|
|
283
283
|
block: 0,
|
|
284
284
|
level: "",
|
|
285
|
-
category: "",
|
|
285
|
+
// category: "",
|
|
286
286
|
status: "active",
|
|
287
287
|
buildingUnitFiles: [],
|
|
288
288
|
companyName: "",
|
|
@@ -344,7 +344,7 @@ function setBuildingUnit() {
|
|
|
344
344
|
buildingUnit.value.building = "";
|
|
345
345
|
buildingUnit.value.buildingName = "";
|
|
346
346
|
buildingUnit.value.level = "";
|
|
347
|
-
buildingUnit.value.category = "";
|
|
347
|
+
// buildingUnit.value.category = "";
|
|
348
348
|
buildingUnit.value.status = "active";
|
|
349
349
|
buildingUnit.value.buildingUnitFiles = [];
|
|
350
350
|
buildingUnitQty.value = 1;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<v-card width="100%" :loading="getUnitPeoplePending">
|
|
2
|
+
<v-card width="100%" :loading="getUnitPeoplePending || loading.ownerProcessing" :disabled="loading.ownerProcessing">
|
|
3
3
|
<v-toolbar>
|
|
4
4
|
<v-row no-gutters class="fill-height px-6" align="center">
|
|
5
5
|
<span class="font-weight-bold text-h5"> Unit Info ( {{ buildingUnit.name }} ) </span>
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
<v-row no-gutters>
|
|
59
59
|
<InputLabel class="text-capitalize font-weight-bold" title="Billing Address Line 1" />
|
|
60
60
|
<v-col cols="12">
|
|
61
|
-
<v-text-field :model-value="
|
|
61
|
+
<v-text-field :model-value="buildingUnit?.site?.address?.line1" density="compact" readonly
|
|
62
62
|
class="no-pointer"></v-text-field>
|
|
63
63
|
</v-col>
|
|
64
64
|
</v-row>
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
<v-row no-gutters>
|
|
68
68
|
<InputLabel class="text-capitalize font-weight-bold" title="Billing Address Line 2" />
|
|
69
69
|
<v-col cols="12">
|
|
70
|
-
<v-text-field :model-value="
|
|
70
|
+
<v-text-field :model-value="buildingUnit?.site?.address?.line2" density="compact" readonly
|
|
71
71
|
class="no-pointer"></v-text-field>
|
|
72
72
|
</v-col>
|
|
73
73
|
</v-row>
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
<v-row no-gutters>
|
|
77
77
|
<InputLabel class="text-capitalize font-weight-bold" title="City" />
|
|
78
78
|
<v-col cols="12">
|
|
79
|
-
<v-text-field :model-value="
|
|
79
|
+
<v-text-field :model-value="buildingUnit?.site?.address?.city" density="compact" readonly
|
|
80
80
|
class="no-pointer"></v-text-field>
|
|
81
81
|
</v-col>
|
|
82
82
|
</v-row>
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
<v-row no-gutters>
|
|
86
86
|
<InputLabel class="text-capitalize font-weight-bold" title="State" />
|
|
87
87
|
<v-col cols="12">
|
|
88
|
-
<v-text-field :model-value="
|
|
88
|
+
<v-text-field :model-value="buildingUnit?.site?.address?.state" density="compact" readonly
|
|
89
89
|
class="no-pointer"></v-text-field>
|
|
90
90
|
</v-col>
|
|
91
91
|
</v-row>
|
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
<v-row no-gutters>
|
|
95
95
|
<InputLabel class="text-capitalize font-weight-bold" title="Country" />
|
|
96
96
|
<v-col cols="12">
|
|
97
|
-
<v-text-field :model-value="
|
|
97
|
+
<v-text-field :model-value="buildingUnit?.site?.address?.country" density="compact" readonly
|
|
98
98
|
class="no-pointer"></v-text-field>
|
|
99
99
|
</v-col>
|
|
100
100
|
</v-row>
|
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
<v-row no-gutters>
|
|
104
104
|
<InputLabel class="text-capitalize font-weight-bold" title="Postal Code" />
|
|
105
105
|
<v-col cols="12">
|
|
106
|
-
<v-text-field :model-value="
|
|
106
|
+
<v-text-field :model-value="buildingUnit?.site?.address?.postalCode" density="compact" readonly
|
|
107
107
|
class="no-pointer"></v-text-field>
|
|
108
108
|
</v-col>
|
|
109
109
|
</v-row>
|
|
@@ -114,7 +114,7 @@
|
|
|
114
114
|
|
|
115
115
|
<template v-else-if="tab === 'residents'">
|
|
116
116
|
<v-card width="100%">
|
|
117
|
-
<v-expansion-panels v-model="panels" variant="accordion"
|
|
117
|
+
<v-expansion-panels v-model="panels" variant="accordion">
|
|
118
118
|
|
|
119
119
|
<!-- Residents -->
|
|
120
120
|
<v-expansion-panel value="residents">
|
|
@@ -123,10 +123,12 @@
|
|
|
123
123
|
</v-expansion-panel-title>
|
|
124
124
|
|
|
125
125
|
<v-expansion-panel-text>
|
|
126
|
-
<template v-if="unitResidentsArray.length" v-for="resident, residentIndex in unitResidentsArray"
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
126
|
+
<template v-if="unitResidentsArray.length" v-for="resident, residentIndex in unitResidentsArray"
|
|
127
|
+
:key="residentIndex">
|
|
128
|
+
<UnitPersonCard :person="resident" :readOnly="true" show-owner-option
|
|
129
|
+
@update:owner="handleUpdateOwner" :loading-owner-processing="loading.ownerProcessing" />
|
|
130
|
+
<v-divider v-if="(residentIndex + 1) !== unitResidentsArray.length" thickness="2" color="primary"
|
|
131
|
+
class="my-4" />
|
|
130
132
|
</template>
|
|
131
133
|
<p v-else class="font-weight-semibold text-caption ml-2 mt-5">
|
|
132
134
|
**No residents to display**
|
|
@@ -141,42 +143,32 @@
|
|
|
141
143
|
</v-expansion-panel-title>
|
|
142
144
|
|
|
143
145
|
<v-expansion-panel-text>
|
|
144
|
-
<template v-if="unitTenantsArray.length" v-for="(tenant, tenantIndex) in unitTenantsArray"
|
|
145
|
-
|
|
146
|
-
<
|
|
146
|
+
<template v-if="unitTenantsArray.length" v-for="(tenant, tenantIndex) in unitTenantsArray"
|
|
147
|
+
:key="tenant._id || tenantIndex">
|
|
148
|
+
<UnitPersonCard :person="tenant" :readOnly="true" />
|
|
149
|
+
<v-divider v-if="(tenantIndex + 1) !== unitTenantsArray.length" thickness="2" color="primary"
|
|
150
|
+
class="my-4" />
|
|
147
151
|
</template>
|
|
148
152
|
<p v-else class=" font-weight-semibold text-caption ml-2 mt-5">
|
|
149
153
|
**No tenants to display**
|
|
150
154
|
</p>
|
|
151
155
|
</v-expansion-panel-text>
|
|
152
156
|
</v-expansion-panel>
|
|
153
|
-
|
|
154
|
-
<!-- Guests -->
|
|
155
|
-
<v-expansion-panel value="guests">
|
|
156
|
-
<v-expansion-panel-title class="bg-primary">
|
|
157
|
-
Guests ({{ unitGuestsArray.length }})
|
|
158
|
-
</v-expansion-panel-title>
|
|
159
|
-
|
|
160
|
-
<v-expansion-panel-text>
|
|
161
|
-
<template v-if="unitGuestsArray.length" v-for="(guest, guestIndex) in unitGuestsArray" :key="guest._id || guestIndex">
|
|
162
|
-
<UnitPersonCard :person="guest" :readOnly="true" />
|
|
163
|
-
<v-divider v-if="(guestIndex + 1) !== unitGuestsArray.length" thickness="2" color="primary" class="my-4" />
|
|
164
|
-
</template>
|
|
165
|
-
<p v-else class=" font-weight-semibold text-caption ml-2 mt-5">
|
|
166
|
-
**No guests to display**
|
|
167
|
-
</p>
|
|
168
|
-
</v-expansion-panel-text>
|
|
169
|
-
</v-expansion-panel>
|
|
170
|
-
|
|
171
157
|
</v-expansion-panels>
|
|
172
158
|
</v-card>
|
|
173
159
|
</template>
|
|
174
160
|
<template v-else-if="tab === 'vehicles'">
|
|
175
|
-
<
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
161
|
+
<TableMain :headers="vehicleHeaders" :show-header="true" :page="vehiclePage" :pages="vehicleTotalPages"
|
|
162
|
+
:pageRange="vehiclePageRange" :items="unitVehicleItems" @refresh="getUnitVehiclesRefresh" @update:page="handleUpdateVehiclePage">
|
|
163
|
+
|
|
164
|
+
<template #item.status="{value}">
|
|
165
|
+
<v-chip :color="formatVehicleStatus(value).color" class="ma-0" small>
|
|
166
|
+
{{ formatVehicleStatus(value).label }}
|
|
167
|
+
</v-chip>
|
|
168
|
+
</template>
|
|
169
|
+
</TableMain>
|
|
170
|
+
</template>
|
|
171
|
+
|
|
180
172
|
<template v-else-if="tab === 'others'">
|
|
181
173
|
<v-row>
|
|
182
174
|
<!-- <v-col cols="12" md="6" class="mt-2">
|
|
@@ -294,24 +286,7 @@ const prop = defineProps({
|
|
|
294
286
|
},
|
|
295
287
|
roomFacility: {
|
|
296
288
|
type: Object as PropType<TBuildingUnit>,
|
|
297
|
-
|
|
298
|
-
_id: "",
|
|
299
|
-
site: "",
|
|
300
|
-
name: "",
|
|
301
|
-
owner: "",
|
|
302
|
-
ownerName: "",
|
|
303
|
-
building: "",
|
|
304
|
-
buildingName: "",
|
|
305
|
-
// category: "",
|
|
306
|
-
block: null,
|
|
307
|
-
level: 0,
|
|
308
|
-
status: "active",
|
|
309
|
-
buildingUnitFiles: [],
|
|
310
|
-
companyName: "",
|
|
311
|
-
companyRegistrationNumber: "",
|
|
312
|
-
leaseStart: "",
|
|
313
|
-
leaseEnd: "",
|
|
314
|
-
}),
|
|
289
|
+
required: true,
|
|
315
290
|
},
|
|
316
291
|
canUpdateUnit: {
|
|
317
292
|
type: Boolean,
|
|
@@ -325,7 +300,18 @@ const prop = defineProps({
|
|
|
325
300
|
|
|
326
301
|
const buildingUnit = ref({
|
|
327
302
|
_id: "",
|
|
328
|
-
site:
|
|
303
|
+
site: {
|
|
304
|
+
_id: "",
|
|
305
|
+
name: "",
|
|
306
|
+
address: {
|
|
307
|
+
line1: "",
|
|
308
|
+
line2: "",
|
|
309
|
+
city: "",
|
|
310
|
+
state: "",
|
|
311
|
+
country: "",
|
|
312
|
+
postalCode: "",
|
|
313
|
+
},
|
|
314
|
+
},
|
|
329
315
|
name: "",
|
|
330
316
|
owner: "",
|
|
331
317
|
ownerName: "",
|
|
@@ -343,8 +329,6 @@ const buildingUnit = ref({
|
|
|
343
329
|
});
|
|
344
330
|
|
|
345
331
|
|
|
346
|
-
const siteData = ref<TSite | null>(null);
|
|
347
|
-
|
|
348
332
|
buildingUnit.value = JSON.parse(JSON.stringify(prop.roomFacility));
|
|
349
333
|
|
|
350
334
|
const emit = defineEmits(["cancel", "success", "success:create-more", "delete-unit"]);
|
|
@@ -358,11 +342,29 @@ const tab = ref('general')
|
|
|
358
342
|
const validForm = ref(false);
|
|
359
343
|
|
|
360
344
|
const { getAll } = useBuilding();
|
|
361
|
-
const { getPeopleByUnit } = usePeople();
|
|
345
|
+
const { getPeopleByUnit, updateById: updatePeopleById } = usePeople();
|
|
362
346
|
const { debounce } = useUtils();
|
|
347
|
+
const { searchMultipleVehiclesByUnitId, formatVehicleStatus } = useVehicle();
|
|
348
|
+
|
|
349
|
+
const loading = reactive({
|
|
350
|
+
ownerProcessing: false,
|
|
351
|
+
})
|
|
363
352
|
|
|
364
353
|
const buildings = ref<Record<string, any>[]>([]);
|
|
365
354
|
const peopleItems = ref<TPeople[]>([]);
|
|
355
|
+
const unitVehicleItems = ref<TVehicle[]>([]);
|
|
356
|
+
|
|
357
|
+
const vehiclePage = ref(1);
|
|
358
|
+
const vehiclePageRange = ref("-- - -- of --");
|
|
359
|
+
const vehicleTotalPages = ref(0);
|
|
360
|
+
|
|
361
|
+
const vehicleHeaders = [
|
|
362
|
+
{ title: "Plate Number", value: "plateNumber" },
|
|
363
|
+
{ title: "Owner Name", value: "name" },
|
|
364
|
+
{ title: "NRIC", value: "nric" },
|
|
365
|
+
{ title: "Type", value: "type" },
|
|
366
|
+
{ title: "Status", value: "status" },
|
|
367
|
+
];
|
|
366
368
|
|
|
367
369
|
const { data: getBuildingReq } = useLazyAsyncData(
|
|
368
370
|
"get-all-buildings",
|
|
@@ -388,6 +390,18 @@ watch(getUnitPeople, (newData: TPeople[]) => {
|
|
|
388
390
|
peopleItems.value = newData ?? [];
|
|
389
391
|
});
|
|
390
392
|
|
|
393
|
+
const { data: getUnitVehicles, refresh: getUnitVehiclesRefresh } = useLazyAsyncData(
|
|
394
|
+
"get-unit-vehicles",
|
|
395
|
+
async () => await searchMultipleVehiclesByUnitId({unitId: buildingUnit.value._id, page: 1, limit: 10})
|
|
396
|
+
);
|
|
397
|
+
|
|
398
|
+
watch(getUnitVehicles, (newData) => {
|
|
399
|
+
unitVehicleItems.value = Array.isArray(newData?.items) ? newData.items : [];
|
|
400
|
+
vehiclePage.value = newData?.page || 1;
|
|
401
|
+
vehiclePageRange.value = newData?.pageRange || "-- - -- of --";
|
|
402
|
+
vehicleTotalPages.value = newData?.totalPages || 0;
|
|
403
|
+
});
|
|
404
|
+
|
|
391
405
|
const unitResidentsArray = computed(() => {
|
|
392
406
|
return peopleItems.value.filter((person) => person?.type === 'resident');
|
|
393
407
|
});
|
|
@@ -396,21 +410,19 @@ const unitTenantsArray = computed(() => {
|
|
|
396
410
|
return peopleItems.value.filter((person) => person?.type === 'tenant');
|
|
397
411
|
});
|
|
398
412
|
|
|
399
|
-
const unitGuestsArray = computed(() => {
|
|
400
|
-
return peopleItems.value.filter((person) => person?.type === 'guest');
|
|
401
|
-
});
|
|
402
413
|
|
|
403
|
-
buildingUnit.value.site = prop.site;
|
|
414
|
+
// buildingUnit.value.site = prop.site;
|
|
404
415
|
|
|
405
416
|
const selectedBuilding = computed(() => {
|
|
406
417
|
return buildings.value.find((b) => b.value === buildingUnit.value.building);
|
|
407
418
|
});
|
|
408
419
|
|
|
409
420
|
const buildingLevels = computed(() => {
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
421
|
+
const levels = selectedBuilding.value?.levels ?? [];
|
|
422
|
+
return levels.map((level: string) => ({
|
|
423
|
+
title: level,
|
|
424
|
+
value: level,
|
|
425
|
+
}))
|
|
414
426
|
});
|
|
415
427
|
|
|
416
428
|
const disable = ref(false);
|
|
@@ -468,6 +480,40 @@ async function submit() {
|
|
|
468
480
|
}
|
|
469
481
|
}
|
|
470
482
|
|
|
483
|
+
|
|
484
|
+
const handleUpdateOwner = async ({ person, isOwner }: { person: TPeople; isOwner: boolean }) => {
|
|
485
|
+
const owners = peopleItems.value.filter(p => p.isOwner)
|
|
486
|
+
message.value = ""
|
|
487
|
+
// console.log('Updating owner status for', person._id, 'to', isOwner)
|
|
488
|
+
|
|
489
|
+
const userId = person._id ?? null;
|
|
490
|
+
|
|
491
|
+
if (!isOwner && owners.length <= 1 && owners[0]._id === person._id) {
|
|
492
|
+
message.value = "There must be at least one owner for this unit."
|
|
493
|
+
return
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
if (!userId) return message.value = "Resident user ID is missing."
|
|
497
|
+
|
|
498
|
+
|
|
499
|
+
try {
|
|
500
|
+
loading.ownerProcessing = true;
|
|
501
|
+
await updatePeopleById(userId, { isOwner })
|
|
502
|
+
getUnitPeopleRefresh();
|
|
503
|
+
} catch (error: any) {
|
|
504
|
+
message.value = error.response?._data?.message || "Failed to update owner status."
|
|
505
|
+
} finally {
|
|
506
|
+
loading.ownerProcessing = false;
|
|
507
|
+
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
function handleUpdateVehiclePage(newPageNum: number) {
|
|
513
|
+
vehiclePage.value = newPageNum;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
|
|
471
517
|
function cancel() {
|
|
472
518
|
message.value = "";
|
|
473
519
|
emit("cancel");
|