@7365admin1/layer-common 1.11.40 → 1.11.41
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
CHANGED
|
@@ -5,6 +5,96 @@
|
|
|
5
5
|
:site-id="siteId"
|
|
6
6
|
/>
|
|
7
7
|
|
|
8
|
+
<!-- Assign to Person Dialog -->
|
|
9
|
+
<v-dialog :model-value="showAssignForm" width="420" persistent>
|
|
10
|
+
<v-card width="100%">
|
|
11
|
+
<v-toolbar density="compact" color="surface">
|
|
12
|
+
<v-row no-gutters class="fill-height px-4" align="center">
|
|
13
|
+
<span class="font-weight-bold">Assign Card to Person</span>
|
|
14
|
+
</v-row>
|
|
15
|
+
</v-toolbar>
|
|
16
|
+
|
|
17
|
+
<v-card-text class="pa-4">
|
|
18
|
+
<div class="text-caption text-grey mb-4">
|
|
19
|
+
Card: <strong class="text-body-2 text-black">{{ selectedCardInUnit?.cardNo }}</strong>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
<!-- Person Type Filter -->
|
|
23
|
+
<div class="text-caption font-weight-bold mb-1 text-uppercase text-grey-darken-1">Person Type</div>
|
|
24
|
+
<v-btn-toggle
|
|
25
|
+
v-model="assignPersonType"
|
|
26
|
+
color="primary"
|
|
27
|
+
density="compact"
|
|
28
|
+
variant="outlined"
|
|
29
|
+
rounded="pill"
|
|
30
|
+
class="mb-4"
|
|
31
|
+
>
|
|
32
|
+
<v-btn value="" size="small" class="text-none px-3">All</v-btn>
|
|
33
|
+
<v-btn value="owner" size="small" class="text-none px-3">Unit Owner</v-btn>
|
|
34
|
+
<v-btn value="resident" size="small" class="text-none px-3">Resident</v-btn>
|
|
35
|
+
<v-btn value="tenant" size="small" class="text-none px-3">Tenant</v-btn>
|
|
36
|
+
</v-btn-toggle>
|
|
37
|
+
|
|
38
|
+
<!-- Person Selector -->
|
|
39
|
+
<div class="text-caption font-weight-bold mb-1 text-uppercase text-grey-darken-1">
|
|
40
|
+
Person <span class="text-error">*</span>
|
|
41
|
+
</div>
|
|
42
|
+
<v-autocomplete
|
|
43
|
+
v-model="assignPerson"
|
|
44
|
+
:items="filteredPeopleItems"
|
|
45
|
+
density="compact"
|
|
46
|
+
item-title="name"
|
|
47
|
+
item-value="_id"
|
|
48
|
+
hide-details="auto"
|
|
49
|
+
placeholder="Select person..."
|
|
50
|
+
persistent-placeholder
|
|
51
|
+
:loading="peopleLoading"
|
|
52
|
+
return-object
|
|
53
|
+
no-data-text="No residents or tenants found for this unit"
|
|
54
|
+
>
|
|
55
|
+
<template #item="{ props: itemProps, item }">
|
|
56
|
+
<v-list-item v-bind="itemProps" :subtitle="personTypeLabel(item.raw)" />
|
|
57
|
+
</template>
|
|
58
|
+
<template #selection="{ item }">
|
|
59
|
+
<span>{{ item.raw.name }}</span>
|
|
60
|
+
<v-chip size="x-small" class="ml-2" color="grey" variant="tonal">
|
|
61
|
+
{{ personTypeLabel(item.raw) }}
|
|
62
|
+
</v-chip>
|
|
63
|
+
</template>
|
|
64
|
+
</v-autocomplete>
|
|
65
|
+
</v-card-text>
|
|
66
|
+
|
|
67
|
+
<v-toolbar density="compact">
|
|
68
|
+
<v-row no-gutters>
|
|
69
|
+
<v-col cols="6" class="pa-0">
|
|
70
|
+
<v-btn
|
|
71
|
+
block
|
|
72
|
+
variant="text"
|
|
73
|
+
class="text-none"
|
|
74
|
+
height="48"
|
|
75
|
+
@click="cancelAssign"
|
|
76
|
+
>
|
|
77
|
+
Cancel
|
|
78
|
+
</v-btn>
|
|
79
|
+
</v-col>
|
|
80
|
+
<v-col cols="6" class="pa-0">
|
|
81
|
+
<v-btn
|
|
82
|
+
block
|
|
83
|
+
variant="flat"
|
|
84
|
+
color="black"
|
|
85
|
+
class="text-none"
|
|
86
|
+
height="48"
|
|
87
|
+
:disabled="!assignPerson"
|
|
88
|
+
@click="confirmAssign"
|
|
89
|
+
>
|
|
90
|
+
Assign
|
|
91
|
+
</v-btn>
|
|
92
|
+
</v-col>
|
|
93
|
+
</v-row>
|
|
94
|
+
</v-toolbar>
|
|
95
|
+
</v-card>
|
|
96
|
+
</v-dialog>
|
|
97
|
+
|
|
8
98
|
<v-dialog :model-value="modelValue" width="450" persistent>
|
|
9
99
|
<v-card width="100%">
|
|
10
100
|
<v-card-text style="max-height: 100vh; overflow-y: auto" class="pb-0">
|
|
@@ -211,6 +301,14 @@
|
|
|
211
301
|
</v-btn>
|
|
212
302
|
</template>
|
|
213
303
|
<v-list class="pa-0">
|
|
304
|
+
<v-list-item
|
|
305
|
+
v-if="canAssignToPerson && isSelectedCardAvailable"
|
|
306
|
+
@click="openAssignForm"
|
|
307
|
+
>
|
|
308
|
+
<v-list-item-title class="text-subtitle-2">
|
|
309
|
+
Assign to Person
|
|
310
|
+
</v-list-item-title>
|
|
311
|
+
</v-list-item>
|
|
214
312
|
<v-list-item
|
|
215
313
|
:disabled="!isSelectedCardAssignedPhysical"
|
|
216
314
|
@click="emit('replace')"
|
|
@@ -270,6 +368,10 @@ const props = defineProps({
|
|
|
270
368
|
type: Boolean,
|
|
271
369
|
default: true,
|
|
272
370
|
},
|
|
371
|
+
canAssignToPerson: {
|
|
372
|
+
type: Boolean,
|
|
373
|
+
default: true,
|
|
374
|
+
},
|
|
273
375
|
isSelectedCardAssignedPhysical: {
|
|
274
376
|
type: Boolean,
|
|
275
377
|
default: false,
|
|
@@ -289,9 +391,26 @@ const emit = defineEmits<{
|
|
|
289
391
|
"update:selectedCardInUnit": [value: Record<string, any> | null];
|
|
290
392
|
replace: [];
|
|
291
393
|
delete: [];
|
|
394
|
+
"assign-to-person": [{ card: Record<string, any> | null; person: Record<string, any> | null }];
|
|
292
395
|
}>();
|
|
293
396
|
|
|
397
|
+
const { getPeopleByUnit: _getPeopleByUnit } = usePeople();
|
|
398
|
+
|
|
294
399
|
const historyDialog = ref(false);
|
|
400
|
+
const showAssignForm = ref(false);
|
|
401
|
+
const assignPersonType = ref<string>("");
|
|
402
|
+
const assignPerson = ref<Record<string, any> | null>(null);
|
|
403
|
+
const peopleItems = ref<Record<string, any>[]>([]);
|
|
404
|
+
const peopleLoading = ref(false);
|
|
405
|
+
|
|
406
|
+
const isSelectedCardAvailable = computed(() => {
|
|
407
|
+
if (!props.selectedCardInUnit?._id) return false;
|
|
408
|
+
const id = props.selectedCardInUnit._id;
|
|
409
|
+
return [
|
|
410
|
+
...(props.unit?.available?.physical ?? []),
|
|
411
|
+
...(props.unit?.available?.non_physical ?? []),
|
|
412
|
+
].some((c) => c._id === id);
|
|
413
|
+
});
|
|
295
414
|
|
|
296
415
|
const isSelectedCardDeletable = computed(() => {
|
|
297
416
|
if (!props.selectedCardInUnit?._id) return false;
|
|
@@ -304,6 +423,51 @@ const isSelectedCardDeletable = computed(() => {
|
|
|
304
423
|
].some((c) => c._id === id);
|
|
305
424
|
});
|
|
306
425
|
|
|
426
|
+
const filteredPeopleItems = computed(() => {
|
|
427
|
+
if (!assignPersonType.value) return peopleItems.value;
|
|
428
|
+
if (assignPersonType.value === "owner") return peopleItems.value.filter((p) => p.isOwner);
|
|
429
|
+
return peopleItems.value.filter((p) => p.type === assignPersonType.value && !p.isOwner);
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
const personTypeLabel = (person: Record<string, any>) => {
|
|
433
|
+
if (person.isOwner) return "Unit Owner";
|
|
434
|
+
if (person.type === "resident") return "Resident";
|
|
435
|
+
if (person.type === "tenant") return "Tenant";
|
|
436
|
+
return person.type ?? "";
|
|
437
|
+
};
|
|
438
|
+
|
|
439
|
+
async function openAssignForm() {
|
|
440
|
+
showAssignForm.value = true;
|
|
441
|
+
assignPerson.value = null;
|
|
442
|
+
assignPersonType.value = "";
|
|
443
|
+
peopleItems.value = [];
|
|
444
|
+
|
|
445
|
+
if (!props.unit?._id) return;
|
|
446
|
+
peopleLoading.value = true;
|
|
447
|
+
try {
|
|
448
|
+
const res = await _getPeopleByUnit(props.unit._id);
|
|
449
|
+
peopleItems.value = res?.data ?? [];
|
|
450
|
+
} catch {
|
|
451
|
+
peopleItems.value = [];
|
|
452
|
+
} finally {
|
|
453
|
+
peopleLoading.value = false;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
function cancelAssign() {
|
|
458
|
+
showAssignForm.value = false;
|
|
459
|
+
assignPerson.value = null;
|
|
460
|
+
assignPersonType.value = "";
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
function confirmAssign() {
|
|
464
|
+
emit("assign-to-person", {
|
|
465
|
+
card: props.selectedCardInUnit,
|
|
466
|
+
person: assignPerson.value,
|
|
467
|
+
});
|
|
468
|
+
cancelAssign();
|
|
469
|
+
}
|
|
470
|
+
|
|
307
471
|
function toggleCard(card: Record<string, any>) {
|
|
308
472
|
emit(
|
|
309
473
|
"update:selectedCardInUnit",
|
|
@@ -24,16 +24,11 @@
|
|
|
24
24
|
>
|
|
25
25
|
<template #activator="{ props: tooltipProps }">
|
|
26
26
|
<div v-bind="tooltipProps">
|
|
27
|
-
<NavigationItem
|
|
28
|
-
:
|
|
29
|
-
:icon="item.icon"
|
|
30
|
-
:route="item.route"
|
|
31
|
-
:link="item.link"
|
|
32
|
-
:class="{
|
|
27
|
+
<NavigationItem :title="item.title" :icon="item.icon" :route="item.route" :link="item.link"
|
|
28
|
+
:children="item.children" :class="{
|
|
33
29
|
'opacity-50 pointer-events-none': item.disabled
|
|
34
|
-
}"
|
|
35
|
-
|
|
36
|
-
/>
|
|
30
|
+
}" @click="() => handleClick(item)" />
|
|
31
|
+
|
|
37
32
|
</div>
|
|
38
33
|
</template>
|
|
39
34
|
|
|
@@ -53,14 +53,15 @@
|
|
|
53
53
|
<v-col v-if="shouldShowField('nric')" cols="12">
|
|
54
54
|
<InputLabel class="text-capitalize" title="NRIC" required />
|
|
55
55
|
<InputNRICNumber v-model="vehicle.nric" density="comfortable" :rules="[requiredRule]"
|
|
56
|
-
:disabled="disablePrefilledInputs && type !== 'blocklist'" />
|
|
56
|
+
:disabled="disablePrefilledInputs && type !== 'blocklist' && prop.mode !== 'edit'" />
|
|
57
57
|
</v-col>
|
|
58
58
|
|
|
59
59
|
<v-col v-if="shouldShowField('name')" cols="12">
|
|
60
60
|
<v-row>
|
|
61
61
|
<v-col cols="12">
|
|
62
62
|
<InputLabel class="text-capitalize" title="Full Name" required />
|
|
63
|
-
<v-text-field v-model.trim="vehicle.name" density="comfortable" :rules="[requiredRule]"
|
|
63
|
+
<v-text-field v-model.trim="vehicle.name" density="comfortable" :rules="[requiredRule]"
|
|
64
|
+
:disabled="disablePrefilledInputs && type !== 'blocklist' && prop.mode !== 'edit'" />
|
|
64
65
|
</v-col>
|
|
65
66
|
</v-row>
|
|
66
67
|
</v-col>
|
|
@@ -777,6 +778,7 @@ onMounted(() => {
|
|
|
777
778
|
vehicle.start = prop.vehicleData.start || '';
|
|
778
779
|
vehicle.plateNumber = prop.vehicleData.plateNumber
|
|
779
780
|
vehicle.peopleId = prop.vehicleData.peopleId || '';
|
|
781
|
+
vehicle.block = prop.vehicleData.block === 0 ? null : prop.vehicleData.block || null;
|
|
780
782
|
|
|
781
783
|
if(prop.type === "seasonpass"){
|
|
782
784
|
showSubscriptionDateOptions.value = true;
|