@7365admin1/layer-common 1.11.21 → 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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # @iservice365/layer-common
2
2
 
3
+ ## 1.11.23
4
+
5
+ ### Patch Changes
6
+
7
+ - 6d68511: Update layer-comon qr code package
8
+
9
+ ## 1.11.22
10
+
11
+ ### Patch Changes
12
+
13
+ - 00a8179: Update Layer-common changes
14
+
3
15
  ## 1.11.21
4
16
 
5
17
  ### Patch Changes
@@ -123,7 +123,7 @@ const emit = defineEmits<{
123
123
  }>()
124
124
 
125
125
  const { getPassKeysByPageSearch } = usePassKey()
126
- const { updateVisitor } = useVisitor()
126
+ const { updateVisitorPassKey } = useVisitor()
127
127
 
128
128
  const processing = ref(false)
129
129
  const errorMessage = ref('')
@@ -232,28 +232,28 @@ async function handleSubmit() {
232
232
  processing.value = true
233
233
 
234
234
  try {
235
- const payload: Partial<TVisitorPayload> = {}
235
+ const payload: any = {}
236
236
 
237
237
  // Build final pass list: kept existing + newly selected
238
- const finalPasses: { keyId: string; status: string }[] = []
238
+ const finalPasses: { keyId: string }[] = []
239
239
  if (existingPass.value) {
240
- finalPasses.push({ keyId: existingPass.value.keyId, status: 'In Use' })
240
+ finalPasses.push({ keyId: existingPass.value.keyId })
241
241
  }
242
242
  if (selectedPass.value) {
243
- finalPasses.push({ keyId: selectedPass.value, status: 'In Use' })
243
+ finalPasses.push({ keyId: selectedPass.value})
244
244
  }
245
245
  payload.visitorPass = finalPasses
246
246
 
247
247
  // Build final keys list: kept existing + newly selected
248
248
  if (showKeys.value) {
249
- const finalKeys: { keyId: string; status: string }[] = [
250
- ...existingKeys.value.map(k => ({ keyId: k.keyId, status: 'In Use' })),
251
- ...selectedKeys.value.map(keyId => ({ keyId, status: 'In Use' })),
249
+ const finalKeys: { keyId: string}[] = [
250
+ ...existingKeys.value.map(k => ({ keyId: k.keyId })),
251
+ ...selectedKeys.value.map(keyId => ({ keyId })),
252
252
  ]
253
253
  payload.passKeys = finalKeys
254
254
  }
255
255
 
256
- await updateVisitor(prop.visitor._id, payload)
256
+ await updateVisitorPassKey(prop.visitor._id, payload)
257
257
  emit('done')
258
258
  emit('close')
259
259
  } catch (error: any) {
@@ -357,7 +357,6 @@
357
357
  import QrcodeVue from "qrcode.vue";
358
358
  import useAreas from "../composables/useAreas";
359
359
  import useUnits from "../composables/useUnits";
360
- import { useAreaPermission } from "../composables/useAreaPermission";
361
360
  import useSiteSettings from "../composables/useSiteSettings";
362
361
  import useUtils from "../composables/useUtils";
363
362
 
@@ -367,6 +366,11 @@ const props = defineProps({
367
366
  type: { type: String, default: "" },
368
367
  serviceType: { type: String, default: "" },
369
368
  scheduleRoute: { type: String, default: "cleaning-schedule" },
369
+ canViewAreas: { type: Boolean, default: true },
370
+ canCreateArea: { type: Boolean, default: false },
371
+ canUpdateArea: { type: Boolean, default: false },
372
+ canDeleteArea: { type: Boolean, default: false },
373
+ canImportArea: { type: Boolean, default: false },
370
374
  });
371
375
 
372
376
  const isCleanerArea = computed(() => {
@@ -553,13 +557,11 @@ function showMessage(msg: string, color: string = "error") {
553
557
  messageSnackbar.value = true;
554
558
  }
555
559
 
556
- const {
557
- canCreateArea,
558
- canUpdateArea,
559
- canDeleteArea,
560
- canImportArea,
561
- canViewAreas,
562
- } = useAreaPermission();
560
+ const canCreateArea = computed(() => props.canCreateArea);
561
+ const canUpdateArea = computed(() => props.canUpdateArea);
562
+ const canDeleteArea = computed(() => props.canDeleteArea);
563
+ const canImportArea = computed(() => props.canImportArea);
564
+ const canViewAreas = computed(() => props.canViewAreas);
563
565
 
564
566
  async function handleDownloadExcel() {
565
567
  try {
@@ -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
- canViewAllAttendance,
75
- canViewAttendanceDetails,
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
- canDownloadSchedule,
177
- canViewSchedules,
178
- canViewScheduleDetails,
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 { canAddRemarks, canManageScheduleTasks } =
322
- useCleaningSchedulePermission();
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" disabled
6
- prepend-icon="mdi-qrcode" />
7
- <v-form ref="formRef" v-model="validForm" :disabled="processing" @click="errorMessage = ''">
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
- :hide-no-data="false" class="mt-3" :items="passItemsFilteredFinal"
24
- item-title="prefixAndName" item-value="_id" label="Pass (optional)" variant="outlined"
25
- hide-details density="compact" persistent-hint small-chips>
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 errorMessage = ref('')
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 { canViewOwnAttendance, canCheckInOut, canViewAttendanceDetails } =
91
- useAttendancePermission();
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);