@7365admin1/layer-common 1.11.22 → 1.11.23
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/AttendanceMain.vue +6 -6
- package/components/CleaningScheduleMain.vue +8 -7
- package/components/ManageChecklistMain.vue +4 -3
- package/components/MemberInformation.vue +49 -13
- package/components/MyAttendanceMain.vue +6 -3
- package/components/PassInformation.vue +197 -144
- package/components/ScanVisitorQRCode.vue +47 -12
- package/components/ScheduleAreaMain.vue +6 -3
- package/components/ScheduleTaskMain.vue +11 -8
- package/components/VisitorDataFromScannedQRCodeForm.vue +262 -0
- package/components/VisitorManagement.vue +126 -13
- package/components/VisitorPassKeyQRScanner.vue +138 -0
- package/composables/useVisitor.ts +89 -28
- package/package.json +2 -1
- package/types/visitor.d.ts +45 -15
package/CHANGELOG.md
CHANGED
|
@@ -61,20 +61,20 @@
|
|
|
61
61
|
|
|
62
62
|
<script setup lang="ts">
|
|
63
63
|
import useAttendance from "../composables/useAttendance";
|
|
64
|
-
import { useAttendancePermission } from "../composables/useAttendancePermission";
|
|
65
64
|
import useUtils from "../composables/useUtils";
|
|
66
65
|
|
|
67
66
|
const props = defineProps({
|
|
68
67
|
orgId: { type: String, default: "" },
|
|
69
68
|
site: { type: String, default: "" },
|
|
70
69
|
serviceType: { type: String, default: "" },
|
|
70
|
+
canViewAllAttendance: { type: Boolean, default: true },
|
|
71
|
+
canViewAttendanceDetails: { type: Boolean, default: true },
|
|
72
|
+
canManageAttendanceSettings: { type: Boolean, default: false },
|
|
71
73
|
});
|
|
72
74
|
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
canManageAttendanceSettings,
|
|
77
|
-
} = useAttendancePermission();
|
|
75
|
+
const canViewAllAttendance = computed(() => props.canViewAllAttendance);
|
|
76
|
+
const canViewAttendanceDetails = computed(() => props.canViewAttendanceDetails);
|
|
77
|
+
const canManageAttendanceSettings = computed(() => props.canManageAttendanceSettings);
|
|
78
78
|
|
|
79
79
|
const submitting = ref(false);
|
|
80
80
|
const page = ref(1);
|
|
@@ -102,7 +102,6 @@
|
|
|
102
102
|
</template>
|
|
103
103
|
|
|
104
104
|
<script lang="ts" setup>
|
|
105
|
-
import { useCleaningSchedulePermission } from "../composables/useCleaningSchedulePermission";
|
|
106
105
|
import useCleaningSchedules from "../composables/useCleaningSchedules";
|
|
107
106
|
import useUtils from "../composables/useUtils";
|
|
108
107
|
|
|
@@ -112,6 +111,10 @@ const props = defineProps({
|
|
|
112
111
|
type: { type: String, required: true },
|
|
113
112
|
serviceType: { type: String, default: "" },
|
|
114
113
|
scheduleRoute: { type: String, default: "cleaning-schedule" },
|
|
114
|
+
canViewSchedules: { type: Boolean, default: true },
|
|
115
|
+
canViewScheduleDetails: { type: Boolean, default: true },
|
|
116
|
+
canDownloadSchedule: { type: Boolean, default: false },
|
|
117
|
+
canManageScheduleTasks: { type: Boolean, default: false },
|
|
115
118
|
});
|
|
116
119
|
|
|
117
120
|
const startDate = ref("");
|
|
@@ -172,12 +175,10 @@ const getCloseInColor = (id: string): string => {
|
|
|
172
175
|
return "primary";
|
|
173
176
|
};
|
|
174
177
|
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
canManageScheduleTasks,
|
|
180
|
-
} = useCleaningSchedulePermission();
|
|
178
|
+
const canDownloadSchedule = computed(() => props.canDownloadSchedule);
|
|
179
|
+
const canViewSchedules = computed(() => props.canViewSchedules);
|
|
180
|
+
const canViewScheduleDetails = computed(() => props.canViewScheduleDetails);
|
|
181
|
+
const canManageScheduleTasks = computed(() => props.canManageScheduleTasks);
|
|
181
182
|
|
|
182
183
|
const {
|
|
183
184
|
data: getCleanerChecklistReq,
|
|
@@ -300,7 +300,6 @@
|
|
|
300
300
|
</template>
|
|
301
301
|
|
|
302
302
|
<script setup lang="ts">
|
|
303
|
-
import { useCleaningSchedulePermission } from "../composables/useCleaningSchedulePermission";
|
|
304
303
|
import useCleaningSchedules from "../composables/useCleaningSchedules";
|
|
305
304
|
import useCustomerSite from "../composables/useCustomerSite";
|
|
306
305
|
import useFile from "../composables/useFile";
|
|
@@ -313,13 +312,15 @@ const props = defineProps({
|
|
|
313
312
|
scheduleAreaId: { type: String, default: "" },
|
|
314
313
|
type: { type: String, default: "cleaner" },
|
|
315
314
|
serviceType: { type: String, default: "" },
|
|
315
|
+
canAddRemarks: { type: Boolean, default: false },
|
|
316
|
+
canManageScheduleTasks: { type: Boolean, default: false },
|
|
316
317
|
});
|
|
317
318
|
|
|
318
319
|
const { getUnitCleanerChecklist, updateUnitChecklist } = useCleaningSchedules();
|
|
319
320
|
const { getBySiteAsServiceProvider } = useCustomerSite();
|
|
320
321
|
const { back } = useUtils();
|
|
321
|
-
const
|
|
322
|
-
|
|
322
|
+
const canAddRemarks = computed(() => props.canAddRemarks);
|
|
323
|
+
const canManageScheduleTasks = computed(() => props.canManageScheduleTasks);
|
|
323
324
|
|
|
324
325
|
const selectedScheduleStatus = useState<string>(
|
|
325
326
|
"selectedScheduleStatus",
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
<v-row no-gutters class="w-100">
|
|
3
3
|
<v-card class="w-100">
|
|
4
4
|
<v-card-text>
|
|
5
|
-
<v-btn block color="primary-button" :height="40" text="Scan QR Code" class="text-capitalize"
|
|
6
|
-
prepend-icon="mdi-qrcode" />
|
|
7
|
-
<v-form ref="formRef" v-model="validForm" :disabled="processing" @click="
|
|
5
|
+
<v-btn block color="primary-button" :height="40" text="Scan QR Code" class="text-capitalize"
|
|
6
|
+
prepend-icon="mdi-qrcode" @click="handleScanQRPass" />
|
|
7
|
+
<v-form ref="formRef" v-model="validForm" :disabled="processing" @click="errorScanPassMessage = ''">
|
|
8
8
|
<v-row no-gutters class="pt-5 ga-2">
|
|
9
9
|
<v-col cols="12">
|
|
10
10
|
<InputLabel class="text-capitalize" title="Full Name" required />
|
|
@@ -19,10 +19,10 @@
|
|
|
19
19
|
</v-col>
|
|
20
20
|
|
|
21
21
|
<v-col cols="12">
|
|
22
|
-
<v-autocomplete v-model="selectedPass" v-model:search="passInput"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
<v-autocomplete v-model="selectedPass" v-model:search="passInput" :hide-no-data="false"
|
|
23
|
+
class="mt-3" :items="passItemsFilteredFinal" item-title="prefixAndName" item-value="_id"
|
|
24
|
+
label="Pass (optional)" variant="outlined" density="compact" :error-messages="errorScanPassMessage"
|
|
25
|
+
persistent-hint small-chips>
|
|
26
26
|
<template v-slot:no-data>
|
|
27
27
|
<v-list-item density="compact">
|
|
28
28
|
<v-list-item-title v-if="passInput">
|
|
@@ -35,8 +35,7 @@
|
|
|
35
35
|
</template>
|
|
36
36
|
|
|
37
37
|
<template v-slot:chip="{ props, item }">
|
|
38
|
-
<v-chip v-if="selectedPass" v-bind="props"
|
|
39
|
-
prepend-icon="mdi-card-bulleted-outline"
|
|
38
|
+
<v-chip v-if="selectedPass" v-bind="props" prepend-icon="mdi-card-bulleted-outline"
|
|
40
39
|
:text="item.raw?.prefixAndName"></v-chip>
|
|
41
40
|
</template>
|
|
42
41
|
</v-autocomplete>
|
|
@@ -62,12 +61,15 @@
|
|
|
62
61
|
</v-form>
|
|
63
62
|
</v-card-text>
|
|
64
63
|
</v-card>
|
|
64
|
+
<visitor-pass-key-q-r-scanner :dialog="dialog.scanQRCode" v-model:scannedValue="scannedPassValue"
|
|
65
|
+
@close-dialog="dialog.scanQRCode = false" />
|
|
65
66
|
<v-divider class="my-3" />
|
|
66
67
|
<v-row v-if="committedMembers.length > 0" no-gutters class="w-100 mt-5 ga-3">
|
|
67
68
|
<template v-for="member, index in committedMembers" :key="member.nric">
|
|
68
69
|
<CardMemberInfoSummary :member="membersDisplayed[index]" @remove="handleRemoveMember(index)" />
|
|
69
70
|
</template>
|
|
70
71
|
</v-row>
|
|
72
|
+
<!-- <Snackbar v-model="messageSnackbar" :text="message" :color="messageColor" /> -->
|
|
71
73
|
</v-row>
|
|
72
74
|
</template>
|
|
73
75
|
|
|
@@ -103,18 +105,33 @@ const { getPassKeysByPageSearch } = usePassKey()
|
|
|
103
105
|
const memberForm = reactive<TMemberInfo>({
|
|
104
106
|
name: "",
|
|
105
107
|
nric: "",
|
|
106
|
-
visitorPass:
|
|
108
|
+
visitorPass: [] as { keyId: string }[],
|
|
107
109
|
contact: ""
|
|
108
110
|
})
|
|
109
111
|
|
|
110
112
|
const validForm = ref(false)
|
|
111
113
|
const formRef = ref<HTMLFormElement>()
|
|
112
114
|
const processing = ref(false);
|
|
113
|
-
const
|
|
115
|
+
const errorScanPassMessage = ref('')
|
|
116
|
+
|
|
117
|
+
const message = ref("");
|
|
118
|
+
const messageColor = ref("");
|
|
119
|
+
const messageSnackbar = ref(false);
|
|
120
|
+
|
|
121
|
+
function showMessage(msg: string, color: string) {
|
|
122
|
+
message.value = msg;
|
|
123
|
+
messageColor.value = color;
|
|
124
|
+
messageSnackbar.value = true;
|
|
125
|
+
}
|
|
114
126
|
|
|
115
127
|
// pass
|
|
116
128
|
const passInput = ref('')
|
|
117
129
|
const passItems = ref<TPassKey[]>([])
|
|
130
|
+
const scannedPassValue = ref<string>("")
|
|
131
|
+
|
|
132
|
+
const dialog = reactive({
|
|
133
|
+
scanQRCode: false,
|
|
134
|
+
})
|
|
118
135
|
|
|
119
136
|
const selectedPass = ref<string>('')
|
|
120
137
|
|
|
@@ -160,7 +177,7 @@ watch(passesData, (data: any) => {
|
|
|
160
177
|
|
|
161
178
|
const passItemsFilteredFinal = computed(() => {
|
|
162
179
|
return passItems.value.filter((item: TPassKey) => {
|
|
163
|
-
return !props.selectedVisitorPass.some((pass: TPassKeyPayload) => pass.keyId === item._id) && !committedMembers.value.some((member: TMemberInfo) => member.visitorPass === item._id)
|
|
180
|
+
return !props.selectedVisitorPass.some((pass: TPassKeyPayload) => pass.keyId === item._id) && !committedMembers.value.some((member: TMemberInfo) => member.visitorPass?.some((pass) => pass.keyId === item._id))
|
|
164
181
|
})
|
|
165
182
|
})
|
|
166
183
|
|
|
@@ -168,15 +185,34 @@ const membersDisplayed = computed(() => {
|
|
|
168
185
|
return committedMembers.value.map((member: TMemberInfo) => {
|
|
169
186
|
return {
|
|
170
187
|
...member,
|
|
171
|
-
visitorPass: passItems.value.find((item: TPassKey) => item._id === member.visitorPass)?.prefixAndName || ""
|
|
188
|
+
visitorPass: passItems.value.find((item: TPassKey) => item._id === member.visitorPass?.[0]?.keyId)?.prefixAndName || ""
|
|
172
189
|
}
|
|
173
190
|
})
|
|
174
191
|
})
|
|
175
192
|
|
|
193
|
+
function handleScanQRPass() {
|
|
194
|
+
errorScanPassMessage.value = ""
|
|
195
|
+
dialog.scanQRCode = true
|
|
196
|
+
}
|
|
197
|
+
|
|
176
198
|
watch(selectedPass, (newVal) => {
|
|
177
199
|
memberForm.visitorPass = [{ keyId: newVal }]
|
|
178
200
|
})
|
|
179
201
|
|
|
202
|
+
watch(scannedPassValue, (newVal) => {
|
|
203
|
+
if (!newVal) return
|
|
204
|
+
|
|
205
|
+
const matchedPass = passItemsFilteredFinal.value.find((p) => p.prefixAndName === newVal)
|
|
206
|
+
|
|
207
|
+
if (matchedPass) {
|
|
208
|
+
selectedPass.value = matchedPass._id ?? ""
|
|
209
|
+
return
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
errorScanPassMessage.value = "Scanned pass not available"
|
|
213
|
+
showMessage("Scanned pass not available", "error")
|
|
214
|
+
})
|
|
215
|
+
|
|
180
216
|
|
|
181
217
|
|
|
182
218
|
function handleClearForm() {
|
|
@@ -79,16 +79,19 @@
|
|
|
79
79
|
|
|
80
80
|
<script setup lang="ts">
|
|
81
81
|
import useAttendance from "../composables/useAttendance";
|
|
82
|
-
import { useAttendancePermission } from "../composables/useAttendancePermission";
|
|
83
82
|
|
|
84
83
|
const props = defineProps({
|
|
85
84
|
orgId: { type: String, default: "" },
|
|
86
85
|
site: { type: String, default: "" },
|
|
87
86
|
serviceType: { type: String, default: "" },
|
|
87
|
+
canViewOwnAttendance: { type: Boolean, default: true },
|
|
88
|
+
canCheckInOut: { type: Boolean, default: false },
|
|
89
|
+
canViewAttendanceDetails: { type: Boolean, default: true },
|
|
88
90
|
});
|
|
89
91
|
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
+
const canViewOwnAttendance = computed(() => props.canViewOwnAttendance);
|
|
93
|
+
const canCheckInOut = computed(() => props.canCheckInOut);
|
|
94
|
+
const canViewAttendanceDetails = computed(() => props.canViewAttendanceDetails);
|
|
92
95
|
|
|
93
96
|
const searchInput = ref("");
|
|
94
97
|
const dialogShowForm = ref(false);
|
|
@@ -1,171 +1,224 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
</v-
|
|
40
|
-
|
|
2
|
+
<v-row no-gutters class="w-100">
|
|
3
|
+
<v-card class="w-100">
|
|
4
|
+
<v-card-text>
|
|
5
|
+
<v-btn
|
|
6
|
+
block
|
|
7
|
+
color="primary-button"
|
|
8
|
+
:height="40"
|
|
9
|
+
text="Scan QR Code"
|
|
10
|
+
class="text-capitalize"
|
|
11
|
+
disabled
|
|
12
|
+
prepend-icon="mdi-qrcode"
|
|
13
|
+
/>
|
|
14
|
+
<v-autocomplete
|
|
15
|
+
v-model="selectedPass"
|
|
16
|
+
v-model:search="passInput"
|
|
17
|
+
:hide-no-data="false"
|
|
18
|
+
class="mt-3"
|
|
19
|
+
:items="passItems"
|
|
20
|
+
:rules="props.passRules"
|
|
21
|
+
item-title="prefixAndName"
|
|
22
|
+
item-value="_id"
|
|
23
|
+
label="Pass"
|
|
24
|
+
variant="outlined"
|
|
25
|
+
hide-details
|
|
26
|
+
density="compact"
|
|
27
|
+
persistent-hint
|
|
28
|
+
small-chips
|
|
29
|
+
:clearable="props.clearable"
|
|
30
|
+
>
|
|
31
|
+
<template v-slot:chip="{ props, item }">
|
|
32
|
+
<v-chip
|
|
33
|
+
v-if="selectedPass"
|
|
34
|
+
v-bind="props"
|
|
35
|
+
prepend-icon="mdi-card-bulleted-outline"
|
|
36
|
+
:text="item.raw?.prefixAndName"
|
|
37
|
+
></v-chip>
|
|
38
|
+
</template>
|
|
39
|
+
</v-autocomplete>
|
|
40
|
+
|
|
41
|
+
<template v-if="!props.hideKeys">
|
|
42
|
+
<v-autocomplete
|
|
43
|
+
v-model="selectedKeys"
|
|
44
|
+
v-model:search="keyInput"
|
|
45
|
+
:hide-no-data="false"
|
|
46
|
+
class="mt-3"
|
|
47
|
+
:items="keyItems"
|
|
48
|
+
:rules="props.passRules"
|
|
49
|
+
item-title="prefixAndName"
|
|
50
|
+
item-value="_id"
|
|
51
|
+
label="Keys"
|
|
52
|
+
multiple
|
|
53
|
+
variant="outlined"
|
|
54
|
+
hide-details
|
|
55
|
+
density="compact"
|
|
56
|
+
persistent-hint
|
|
57
|
+
small-chips
|
|
58
|
+
:clearable="props.clearable"
|
|
59
|
+
>
|
|
60
|
+
<template v-slot:chip="{ props, item }">
|
|
61
|
+
<v-chip
|
|
62
|
+
v-if="selectedKeys.length > 0"
|
|
63
|
+
v-bind="props"
|
|
64
|
+
prepend-icon="mdi-key"
|
|
65
|
+
:text="item.raw?.prefixAndName"
|
|
66
|
+
></v-chip>
|
|
67
|
+
</template>
|
|
68
|
+
</v-autocomplete>
|
|
69
|
+
</template>
|
|
70
|
+
|
|
71
|
+
<v-divider class="my-4 w-100" />
|
|
72
|
+
|
|
73
|
+
<template v-if="selectedType">
|
|
74
|
+
<v-number-input
|
|
75
|
+
v-model="count"
|
|
76
|
+
variant="outlined"
|
|
77
|
+
:min="1"
|
|
78
|
+
:precision="0"
|
|
79
|
+
density="compact"
|
|
80
|
+
:rules="countRules"
|
|
81
|
+
/>
|
|
82
|
+
</template>
|
|
83
|
+
</v-card-text>
|
|
84
|
+
</v-card>
|
|
85
|
+
</v-row>
|
|
41
86
|
</template>
|
|
42
87
|
|
|
43
88
|
<script setup lang="ts">
|
|
44
|
-
import type { PropType } from
|
|
45
|
-
import type { ValidationRule } from
|
|
46
|
-
import usePassKey from
|
|
47
|
-
import useKey from
|
|
89
|
+
import type { PropType } from "vue";
|
|
90
|
+
import type { ValidationRule } from "vuetify/lib/types.mjs";
|
|
91
|
+
import usePassKey from "../composables/usePassKey";
|
|
92
|
+
import useKey from "../composables/useKey";
|
|
48
93
|
|
|
49
94
|
const props = defineProps({
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const
|
|
81
|
-
const
|
|
82
|
-
const
|
|
83
|
-
const
|
|
84
|
-
const
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
const
|
|
95
|
+
passRules: {
|
|
96
|
+
type: Array as PropType<ValidationRule[]>,
|
|
97
|
+
default: [],
|
|
98
|
+
},
|
|
99
|
+
countRules: {
|
|
100
|
+
type: Array as PropType<ValidationRule[]>,
|
|
101
|
+
default: [],
|
|
102
|
+
},
|
|
103
|
+
site: {
|
|
104
|
+
type: String,
|
|
105
|
+
required: true,
|
|
106
|
+
},
|
|
107
|
+
type: {
|
|
108
|
+
type: String as PropType<TVisitorType>,
|
|
109
|
+
required: true,
|
|
110
|
+
},
|
|
111
|
+
contractorType: {
|
|
112
|
+
type: String,
|
|
113
|
+
default: "",
|
|
114
|
+
},
|
|
115
|
+
hideKeys: {
|
|
116
|
+
type: Boolean,
|
|
117
|
+
default: false,
|
|
118
|
+
},
|
|
119
|
+
clearable: {
|
|
120
|
+
type: Boolean,
|
|
121
|
+
default: false,
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
const pass = defineModel<TPassKeyPayload[]>("pass", { default: [] });
|
|
126
|
+
const keys = defineModel<TPassKeyPayload[]>("keys", { default: [] });
|
|
127
|
+
const selectedPass = ref<string>("");
|
|
128
|
+
const selectedKeys = ref<string[]>([]);
|
|
129
|
+
const passInput = ref("");
|
|
130
|
+
const keyInput = ref("");
|
|
131
|
+
const passItems = ref<TPassKey[]>([]);
|
|
132
|
+
const keyItems = ref<any[]>([]);
|
|
133
|
+
const selectedType = ref<"qr-pass" | "nfc-card">();
|
|
134
|
+
const count = ref(1);
|
|
135
|
+
|
|
136
|
+
const { getPassKeysByPageSearch } = usePassKey();
|
|
88
137
|
|
|
89
138
|
const typeItems = [
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
]
|
|
139
|
+
{
|
|
140
|
+
label: "QR Pass",
|
|
141
|
+
value: "qr-pass",
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
label: "NFC Card",
|
|
145
|
+
value: "nfc-card",
|
|
146
|
+
},
|
|
147
|
+
];
|
|
99
148
|
|
|
100
149
|
const passTypesComputed = computed(() => {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
} else {
|
|
105
|
-
return ["contractor-pass"]
|
|
106
|
-
}
|
|
150
|
+
if (props.type === "contractor") {
|
|
151
|
+
if (props.contractorType === "property-agent") {
|
|
152
|
+
return ["agent-pass"];
|
|
107
153
|
} else {
|
|
108
|
-
|
|
154
|
+
return ["contractor-pass"];
|
|
109
155
|
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
156
|
+
} else {
|
|
157
|
+
return ["visitor-pass"];
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
const {
|
|
162
|
+
data: passesData,
|
|
163
|
+
refresh: refreshPassesData,
|
|
164
|
+
pending: fetchPassesPending,
|
|
165
|
+
} = await useLazyAsyncData("get-pass-keys", () => {
|
|
166
|
+
return getPassKeysByPageSearch({
|
|
167
|
+
search: passInput.value,
|
|
168
|
+
page: 1,
|
|
169
|
+
limit: 500,
|
|
170
|
+
passTypes: passTypesComputed.value,
|
|
171
|
+
sites: [props.site],
|
|
172
|
+
statuses: ["Available"],
|
|
173
|
+
});
|
|
174
|
+
});
|
|
122
175
|
|
|
123
176
|
watch(passesData, (data: any) => {
|
|
124
|
-
|
|
125
|
-
})
|
|
126
|
-
|
|
127
|
-
const {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
177
|
+
passItems.value = data?.items || [];
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
const {
|
|
181
|
+
data: keysData,
|
|
182
|
+
refresh: refreshKeysData,
|
|
183
|
+
pending: fetchKeysPending,
|
|
184
|
+
} = await useLazyAsyncData("get-keys", () => {
|
|
185
|
+
return getPassKeysByPageSearch({
|
|
186
|
+
search: keyInput.value,
|
|
187
|
+
statuses: ["Available"],
|
|
188
|
+
passTypes: ["pass-key"],
|
|
189
|
+
page: 1,
|
|
190
|
+
limit: 500,
|
|
191
|
+
sites: [props.site],
|
|
192
|
+
});
|
|
193
|
+
});
|
|
137
194
|
|
|
138
195
|
watch(keysData, (data: any) => {
|
|
139
|
-
|
|
140
|
-
})
|
|
196
|
+
keyItems.value = data?.items || [];
|
|
197
|
+
});
|
|
141
198
|
|
|
142
199
|
watch(selectedPass, (newVal) => {
|
|
143
|
-
|
|
144
|
-
})
|
|
200
|
+
pass.value = [{ keyId: newVal }];
|
|
201
|
+
});
|
|
145
202
|
|
|
146
203
|
watch(selectedKeys, (newVal) => {
|
|
147
|
-
|
|
148
|
-
})
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
204
|
+
keys.value = newVal.map((key) => ({ keyId: key }));
|
|
205
|
+
});
|
|
152
206
|
|
|
153
207
|
//prevent negative value;
|
|
154
208
|
watch(count, (newCount) => {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
})
|
|
209
|
+
if (newCount < 1) {
|
|
210
|
+
count.value = 1;
|
|
211
|
+
}
|
|
212
|
+
});
|
|
159
213
|
|
|
160
214
|
onMounted(() => {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
})
|
|
168
|
-
|
|
215
|
+
if (pass.value.length > 0) {
|
|
216
|
+
selectedPass.value = pass.value[0].keyId;
|
|
217
|
+
}
|
|
218
|
+
if (keys.value.length > 0) {
|
|
219
|
+
selectedKeys.value = keys.value.map((k) => k.keyId);
|
|
220
|
+
}
|
|
221
|
+
});
|
|
169
222
|
</script>
|
|
170
223
|
|
|
171
|
-
<style scoped></style>
|
|
224
|
+
<style scoped></style>
|