@7365admin1/layer-common 3.0.20 → 3.0.22

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.
@@ -19,7 +19,7 @@
19
19
 
20
20
  <v-toolbar class="pa-0" density="compact">
21
21
  <v-row no-gutters>
22
- <v-col cols="6" class="pa-0">
22
+ <v-col :cols="showMoreActions ? 6 : 12" class="pa-0">
23
23
  <v-btn
24
24
  block
25
25
  variant="text"
@@ -32,7 +32,7 @@
32
32
  </v-btn>
33
33
  </v-col>
34
34
 
35
- <v-col cols="6" class="pa-0">
35
+ <v-col v-if="showMoreActions" cols="6" class="pa-0">
36
36
  <v-menu>
37
37
  <template #activator="{ props }">
38
38
  <v-btn
@@ -204,6 +204,11 @@ const prop = defineProps({
204
204
  type: String,
205
205
  default: "Actions",
206
206
  },
207
+
208
+ showMoreActions: {
209
+ type: Boolean,
210
+ default: true,
211
+ },
207
212
  });
208
213
 
209
214
  const emit = defineEmits([
@@ -90,7 +90,7 @@
90
90
  v-if="props.cancelInvitation"
91
91
  >
92
92
  <template v-slot:activator="{ props }">
93
- <v-icon v-bind="props">mdi-dots-horizontal</v-icon>
93
+ <v-icon v-bind="props">mdi-dots-vertical</v-icon>
94
94
  </template>
95
95
  <v-list>
96
96
  <v-list-item @click="openConfirmDialog(item._id ?? '')" v-if="item.status === 'pending'">
@@ -99,6 +99,9 @@
99
99
  </v-list>
100
100
  </v-menu>
101
101
  </template>
102
+ <template #item.status="{value}">
103
+ {{ formatStatus(value) }}
104
+ </template>
102
105
  </v-data-table>
103
106
  </v-card>
104
107
  </v-col>
@@ -198,14 +201,27 @@ authenticate();
198
201
 
199
202
  const headers = computed(() => {
200
203
  const baseHeaders = [
204
+ {
205
+ title: "E-mail",
206
+ value: "email",
207
+ },
208
+ {
209
+ title: "Roles and Permission",
210
+ value: "roleName",
211
+ },
201
212
  {
202
213
  title: "Date",
203
214
  value: "createdAt",
204
215
  },
205
216
  {
206
- title: "E-mail",
207
- value: "email",
217
+ title: "Site Invited To",
218
+ value: "metadata.siteName",
219
+ },
220
+ {
221
+ title: "Status",
222
+ value: "status",
208
223
  },
224
+
209
225
  ];
210
226
 
211
227
  if (props.status === "pending" && props.cancelInvitation) {
@@ -318,6 +334,19 @@ watchEffect(() => {
318
334
  }
319
335
  });
320
336
 
337
+ const formatStatus = (status: string) => {
338
+ switch (status) {
339
+ case "pending":
340
+ return "Pending Invite";
341
+ case "expired":
342
+ return "Invitation expired";
343
+ case "accepted":
344
+ return "Accepted";
345
+ default:
346
+ return status?.[0]?.toUpperCase() + status?.slice(1) || "";
347
+ }
348
+ };
349
+
321
350
  const dialogMember = ref(false);
322
351
 
323
352
  function inviteMember() {
@@ -73,6 +73,9 @@
73
73
  <template #item.nature="{ item }">
74
74
  {{ replaceMatch(item.nature, "_", " ") }}
75
75
  </template>
76
+ <template #item.dateInvited="{ item }">
77
+ {{ formatDateInvited(item.dateInvited) }}
78
+ </template>
76
79
  <template #item.action-table="{ item }">
77
80
  <v-menu
78
81
  v-if="
@@ -87,7 +90,7 @@
87
90
  width="150"
88
91
  >
89
92
  <template v-slot:activator="{ props }">
90
- <v-icon v-bind="props">mdi-dots-horizontal</v-icon>
93
+ <v-icon v-bind="props">mdi-dots-vertical</v-icon>
91
94
  </template>
92
95
  <v-list>
93
96
  <v-list-item
@@ -289,19 +292,24 @@ const props = defineProps({
289
292
  value: "name",
290
293
  },
291
294
  {
292
- title: "Role",
295
+ title: "Email",
296
+
297
+ value: "email",
298
+ },
299
+ {
300
+ title: "Roles and Permission",
293
301
 
294
302
  value: "roleName",
295
303
  },
296
304
  {
297
- title: "Organization",
305
+ title: "Site Invited To",
298
306
 
299
- value: "orgName",
307
+ value: "siteName",
300
308
  },
301
309
  {
302
- title: "Status",
310
+ title: "Date",
303
311
 
304
- value: "status",
312
+ value: "dateInvited",
305
313
  },
306
314
  {
307
315
  title: "Action",
@@ -347,7 +355,7 @@ const normalizedRouteParams = computed(() => {
347
355
 
348
356
  const tabOptions = [
349
357
  { name: "Active", status: "active" },
350
- { name: "Suspended", status: "suspended" },
358
+ { name: "Inactive", status: "suspended" },
351
359
  ];
352
360
 
353
361
  function toRoute(status: any) {
@@ -477,6 +485,29 @@ function showMessage(msg: string, color: string) {
477
485
  messageSnackbar.value = true;
478
486
  }
479
487
 
488
+ function formatDateInvited(value?: string | null) {
489
+ if (!value) return "";
490
+
491
+ const date = new Date(value);
492
+ if (Number.isNaN(date.getTime())) return "";
493
+
494
+ const parts = new Intl.DateTimeFormat("en-US", {
495
+ month: "long",
496
+ day: "numeric",
497
+ year: "numeric",
498
+ hour: "2-digit",
499
+ minute: "2-digit",
500
+ hour12: true,
501
+ }).formatToParts(date);
502
+
503
+ const getPart = (type: Intl.DateTimeFormatPartTypes) =>
504
+ parts.find((part) => part.type === type)?.value ?? "";
505
+
506
+ return `${getPart("month")} ${getPart("day")}, ${getPart("year")} ${getPart(
507
+ "hour"
508
+ )}:${getPart("minute")}${getPart("dayPeriod").toUpperCase()}`;
509
+ }
510
+
480
511
  async function handleUpdateMemberStatus() {
481
512
  if (!selectedMemberId.value) return;
482
513
  updateLoading.value = true;
@@ -13,18 +13,7 @@
13
13
  Patrol Report Log
14
14
  </v-btn>
15
15
  </v-col>
16
- <v-col cols="12" md="6" class="d-flex justify-end">
17
- <v-btn
18
- color="primary"
19
-
20
- variant="flat"
21
- size="large"
22
- class="text-none px-8"
23
- prepend-icon="mdi-plus"
24
- >
25
- Create Routes & Schedule
26
- </v-btn>
27
- </v-col>
16
+
28
17
  </v-row>
29
18
 
30
19
  <!-- Tabs -->
@@ -74,18 +63,7 @@
74
63
  bg-color="white"
75
64
  />
76
65
  </v-col>
77
- <v-col cols="12" md="3" class="px-md-2 mb-2 mb-md-0">
78
- <v-btn
79
- color="primary"
80
- block
81
- size="large"
82
- rounded="lg"
83
- class="text-none"
84
- @click="loadReport"
85
- >
86
- Select Routes & Schedule
87
- </v-btn>
88
- </v-col>
66
+
89
67
  <v-col cols="12" md="2" class="pl-md-2">
90
68
  <v-btn
91
69
  variant="outlined"
@@ -312,7 +290,7 @@
312
290
  size="small"
313
291
  @click="dialogSelectRoute = false"
314
292
  />
315
- <span class="text-h6 ml-2">Select Routes & Schedule</span>
293
+ <span class="text-h6 ml-2">Select Routes & Schedule </span>
316
294
  </v-card-title>
317
295
 
318
296
  <v-card-text class="px-6 pb-6">
@@ -162,7 +162,9 @@
162
162
  class="mb-2"
163
163
  >
164
164
  <v-col cols="12">
165
- <div class="text-subtitle-2 font-weight-bold mb-2">Units Under Selected Areas:</div>
165
+ <div class="text-subtitle-2 font-weight-bold mb-2">
166
+ Units Under Selected Areas:
167
+ </div>
166
168
  <v-card variant="outlined" rounded>
167
169
  <v-list density="compact" nav>
168
170
  <template
@@ -179,33 +181,62 @@
179
181
  <v-icon size="16">
180
182
  {{
181
183
  openViewAreas.includes(area.value || area._id)
182
- ? 'mdi-chevron-down'
183
- : 'mdi-chevron-right'
184
+ ? "mdi-chevron-down"
185
+ : "mdi-chevron-right"
184
186
  }}
185
187
  </v-icon>
186
188
  </template>
187
189
  <template #append>
188
190
  <v-progress-circular
189
- v-if="loadingViewUnits && !(area.value || area._id in fetchedViewAreaUnits)"
191
+ v-if="
192
+ loadingViewUnits &&
193
+ !(
194
+ area.value ||
195
+ area._id in fetchedViewAreaUnits
196
+ )
197
+ "
190
198
  size="14"
191
199
  width="2"
192
200
  indeterminate
193
201
  color="primary"
194
202
  />
195
- <v-chip v-else size="x-small" variant="tonal" color="primary">
196
- {{ (fetchedViewAreaUnits[area.value || area._id] || []).length }}
203
+ <v-chip
204
+ v-else
205
+ size="x-small"
206
+ variant="tonal"
207
+ color="primary"
208
+ >
209
+ {{
210
+ (
211
+ fetchedViewAreaUnits[
212
+ area.value || area._id
213
+ ] || []
214
+ ).length
215
+ }}
197
216
  </v-chip>
198
217
  </template>
199
218
  </v-list-item>
200
219
  <v-expand-transition>
201
- <div v-show="openViewAreas.includes(area.value || area._id)">
220
+ <div
221
+ v-show="
222
+ openViewAreas.includes(area.value || area._id)
223
+ "
224
+ >
202
225
  <v-card-text class="px-3 py-2">
203
226
  <div
204
- v-if="(fetchedViewAreaUnits[area.value || area._id] || []).length > 0"
227
+ v-if="
228
+ (
229
+ fetchedViewAreaUnits[
230
+ area.value || area._id
231
+ ] || []
232
+ ).length > 0
233
+ "
205
234
  class="d-flex flex-wrap ga-3"
206
235
  >
207
236
  <v-chip
208
- v-for="unit in fetchedViewAreaUnits[area.value || area._id]"
237
+ v-for="unit in fetchedViewAreaUnits[
238
+ area.value || area._id
239
+ ]"
209
240
  :key="unit.unit"
210
241
  size="small"
211
242
  variant="tonal"
@@ -213,7 +244,9 @@
213
244
  {{ unit.name }}
214
245
  </v-chip>
215
246
  </div>
216
- <span v-else class="text-caption text-disabled">No units configured</span>
247
+ <span v-else class="text-caption text-disabled"
248
+ >No units configured</span
249
+ >
217
250
  </v-card-text>
218
251
  </div>
219
252
  </v-expand-transition>
@@ -371,7 +404,9 @@ const messageSnackbar = ref(false);
371
404
  const messageColor = ref("success");
372
405
 
373
406
  const loadingViewUnits = ref(false);
374
- const fetchedViewAreaUnits = ref<Record<string, { name: string; unit: string }[]>>({});
407
+ const fetchedViewAreaUnits = ref<
408
+ Record<string, { name: string; unit: string }[]>
409
+ >({});
375
410
  const openViewAreas = ref<string[]>([]);
376
411
 
377
412
  const toggleViewArea = (id: string) => {
@@ -528,7 +563,7 @@ async function _deleteScheduleTask() {
528
563
 
529
564
  const response = await deleteScheduleTask(id);
530
565
  dialogDeleteTask.value = false;
531
- showMessage(response?.message, "success");
566
+ showMessage("Scheduled task successfully deleted.", "success");
532
567
 
533
568
  await getTaskRefresh();
534
569
  } catch (error: any) {
@@ -197,7 +197,11 @@
197
197
  </v-card>
198
198
  </v-dialog>
199
199
 
200
- <Snackbar v-model="messageSnackbar" :text="message" :color="messageColor" />
200
+ <Snackbar
201
+ v-model="messageSnackbar"
202
+ :text="snackBarMessage"
203
+ :color="messageColor"
204
+ />
201
205
 
202
206
  <input
203
207
  ref="fileInput"
@@ -297,8 +301,11 @@ const dialogMode = ref<"add" | "edit">("add");
297
301
  const editingUnit = ref<Record<string, any>>({});
298
302
  const areaName = ref("");
299
303
 
304
+ const snackBarMessage = ref("");
305
+
300
306
  function showMessage(msg: string, color: string = "error") {
301
307
  message.value = msg;
308
+ snackBarMessage.value = msg;
302
309
  messageColor.value = color;
303
310
  messageSnackbar.value = true;
304
311
  }
@@ -1269,6 +1269,8 @@ async function submit() {
1269
1269
  payload.visitorPass = visitor.visitorPass;
1270
1270
  payload.passKeys = visitor.passKeys;
1271
1271
  }
1272
+
1273
+ delete payload.createdBy;
1272
1274
  }
1273
1275
 
1274
1276
  if (prop.type === "contractor") {
@@ -2034,6 +2034,29 @@ onMounted(() => {
2034
2034
  (route.query.checkedOut as string) == "true" || false;
2035
2035
  }
2036
2036
  });
2037
+
2038
+ const { socketUnregisteredVisitorTrigger, visitorSocketData } =
2039
+ useVisitorSocket();
2040
+
2041
+ watchEffect(async () => {
2042
+ if (visitorSocketData.value && visitorSocketData.value.reload && activeTab.value === "unregistered") {
2043
+ await getVisitorRefresh();
2044
+ visitorSocketData.value = null;
2045
+ socketUnregisteredVisitorTrigger.value = false;
2046
+ }
2047
+
2048
+ if(visitorSocketData.value && visitorSocketData.value.plateNumber && socketUnregisteredVisitorTrigger.value && activeTab.value === "unregistered" && dialog.showSelection === false) {
2049
+ // await getVisitorRefresh();
2050
+ // visitorSocketData.value = null;
2051
+ // socketUnregisteredVisitorTrigger.value = false;
2052
+ setTimeout(async() => {
2053
+ const { _id } = visitorSocketData.value;
2054
+ await handleRegistrationUnregisteredVisitor({ _id });
2055
+ socketUnregisteredVisitorTrigger.value = false;
2056
+ }, 1000)
2057
+ }
2058
+ })
2059
+
2037
2060
  </script>
2038
2061
 
2039
2062
  <style scoped></style>