@7365admin1/layer-common 3.2.1 → 3.2.2-staging.100

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.
Files changed (123) hide show
  1. package/.changeset/camera-wall-gated-endpoint.md +47 -0
  2. package/.changeset/camera-wall-plain-english.md +60 -0
  3. package/.changeset/camera-wall-selection-and-guidance.md +65 -0
  4. package/.changeset/dark-primary-contrast.md +39 -0
  5. package/.changeset/dashboard-dark-theme-contrast.md +15 -0
  6. package/.changeset/notification-preferences.md +17 -0
  7. package/.changeset/pm-sidebar-grouping-and-list-scaffold.md +27 -0
  8. package/.changeset/service-provider-invitation-actions.md +28 -0
  9. package/assets/css/primitives.css +680 -0
  10. package/assets/css/screens.css +541 -0
  11. package/assets/css/shell.css +258 -0
  12. package/assets/css/tokens.css +220 -0
  13. package/components/AccessCardQrTagging.vue +1 -1
  14. package/components/AccessManagement.vue +53 -72
  15. package/components/AppButton.vue +52 -0
  16. package/components/AppCard.vue +20 -0
  17. package/components/AppDateField.vue +35 -0
  18. package/components/AppField.vue +46 -0
  19. package/components/AppKpiTile.vue +65 -0
  20. package/components/AppSegmented.vue +38 -0
  21. package/components/AppSelect.vue +203 -0
  22. package/components/AreaChecklistHistoryMain.vue +6 -2
  23. package/components/AreaMain.vue +9 -17
  24. package/components/AttendanceMain.vue +4 -3
  25. package/components/Avatar/Main.vue +54 -2
  26. package/components/BillingMain.vue +26 -30
  27. package/components/BuildingManagement/buildings.vue +27 -38
  28. package/components/BuildingManagement/units.vue +26 -42
  29. package/components/BulletinBoardManagement.vue +23 -10
  30. package/components/CameraWall.vue +1034 -0
  31. package/components/CameraWallTile.vue +818 -0
  32. package/components/CardToolbar.vue +37 -0
  33. package/components/CleaningScheduleMain.vue +29 -46
  34. package/components/ClientMain.vue +90 -78
  35. package/components/DashboardEmptyState.vue +11 -1
  36. package/components/DashboardMain.vue +349 -275
  37. package/components/DashboardPanel.vue +1 -1
  38. package/components/DocumentManagement.vue +129 -93
  39. package/components/EntryPassInformation.vue +4 -4
  40. package/components/EntryPassMain.vue +49 -27
  41. package/components/EquipmentItemMain.vue +4 -6
  42. package/components/EquipmentManagementMain.vue +9 -7
  43. package/components/FeedbackMain.vue +42 -56
  44. package/components/FormDialog.vue +60 -21
  45. package/components/HidAccessLogDashboard.vue +119 -44
  46. package/components/HidCameraCaptureDialog.vue +199 -0
  47. package/components/HidIntercomManagement.vue +825 -202
  48. package/components/HidQrCodeConfiguration.vue +927 -93
  49. package/components/HidServiceSettingsPanel.vue +20 -1
  50. package/components/HidUserEnrollment.vue +454 -106
  51. package/components/InvitationMain.vue +46 -61
  52. package/components/Layout/Header.vue +289 -37
  53. package/components/Layout/NavigationDrawer.vue +340 -30
  54. package/components/ManageChecklistMain.vue +17 -17
  55. package/components/MemberMain.vue +79 -60
  56. package/components/MyAttendanceMain.vue +3 -5
  57. package/components/NavigationItem.vue +9 -0
  58. package/components/Nfc/NFCPatrolRouteMain.vue +116 -103
  59. package/components/NotificationSettings.vue +361 -0
  60. package/components/OnlineFormConfigurationForm.vue +620 -224
  61. package/components/OnlineFormFill.vue +36 -8
  62. package/components/OnlineFormsConfiguration.vue +7 -3
  63. package/components/PageHeader.vue +43 -0
  64. package/components/PassInformation.vue +104 -45
  65. package/components/QrTemplate/CreditCardLandscape.vue +19 -12
  66. package/components/QrTemplate/PrintDialog.vue +209 -196
  67. package/components/RolePermissionMain.vue +184 -91
  68. package/components/ScanVisitorQRCode.vue +35 -7
  69. package/components/ScheduleAreaMain.vue +15 -49
  70. package/components/ScheduleTaskMain.vue +23 -26
  71. package/components/ScheduleTastTicketMain.vue +18 -43
  72. package/components/ServiceProviderInvitationPrompt.vue +150 -0
  73. package/components/ServiceProviderMain.vue +346 -157
  74. package/components/SiteSettings.vue +25 -10
  75. package/components/SpecificAttr.vue +10 -2
  76. package/components/StatusChip.vue +93 -0
  77. package/components/SwitchContext.vue +33 -1
  78. package/components/TableHygiene.vue +29 -46
  79. package/components/TableList.vue +1 -1
  80. package/components/TableListSecondary.vue +1 -1
  81. package/components/TableMain.vue +161 -77
  82. package/components/TableV3.vue +61 -66
  83. package/components/UnitMain.vue +9 -17
  84. package/components/VehicleManagement.vue +20 -9
  85. package/components/VisitorForm.vue +294 -78
  86. package/components/VisitorManagement.vue +221 -71
  87. package/components/VisitorSocketPopUp.vue +56 -2
  88. package/components/WorkOrder/Main.vue +42 -51
  89. package/composables/useComment.ts +3 -3
  90. package/composables/useHidAmico.ts +151 -0
  91. package/composables/useHidNavigation.ts +0 -7
  92. package/composables/useLocalAuth.ts +9 -36
  93. package/composables/useNotificationPreference.ts +87 -0
  94. package/composables/useOnlineFormPages.ts +2 -0
  95. package/composables/useOrg.ts +1 -1
  96. package/composables/useRole.ts +22 -0
  97. package/composables/useServiceProviderInvitation.ts +145 -0
  98. package/composables/useSipWebPhone.ts +336 -0
  99. package/composables/useSiteSettings.ts +50 -0
  100. package/composables/useThemePreference.ts +63 -0
  101. package/composables/useVisitor.ts +6 -1
  102. package/composables/useVisitorSocket.ts +26 -0
  103. package/composables/useWebUsb.ts +127 -37
  104. package/nuxt.config.ts +31 -0
  105. package/package.json +4 -1
  106. package/pages/[org]/[site]/access-mgmt/intercom/index.vue +1 -1
  107. package/pages/notification-settings.vue +19 -0
  108. package/plugins/secure-member.client.ts +21 -56
  109. package/plugins/vuetify.ts +68 -9
  110. package/test/visitor-socket.test.mjs +36 -0
  111. package/types/org.d.ts +2 -0
  112. package/types/site.d.ts +71 -0
  113. package/utils/camera-wall.test.ts +571 -0
  114. package/utils/camera-wall.ts +926 -0
  115. package/utils/nav-sections.test.ts +190 -0
  116. package/utils/nav-sections.ts +151 -0
  117. package/utils/status.test.ts +77 -0
  118. package/utils/status.ts +90 -0
  119. package/utils/theme.test.ts +534 -0
  120. package/utils/theme.ts +294 -0
  121. package/components/HidIdentityMapping.vue +0 -975
  122. package/middleware/member.ts +0 -4
  123. package/pages/[org]/[site]/access-mgmt/identity-mapping/index.vue +0 -23
@@ -1,49 +1,46 @@
1
1
  <template>
2
- <v-row no-gutters>
3
- <v-col cols="12" class="mb-2">
4
- <v-row no-gutters>
5
- <v-btn
6
- class="text-none"
7
- rounded="pill"
8
- variant="tonal"
9
- @click="createDialog = true"
10
- size="large"
11
- v-if="canCreateRole"
12
- >
2
+ <div>
3
+ <!--
4
+ THE DESIGN'S PAGE SCAFFOLD (same shape as Service Providers).
5
+
6
+ `Create role` moves from a bare row above the card onto the title line,
7
+ on the right, where the design puts a screen's primary action. It is the
8
+ same button under the same `canCreateRole` permission opening the same
9
+ dialog. The refresh, the range, the pager and the table are unchanged.
10
+ -->
11
+ <PageHeader title="Roles and Permissions">
12
+ <template #actions>
13
+ <AppButton v-if="canCreateRole" @click="createDialog = true">
13
14
  Create role
14
- </v-btn>
15
- </v-row>
16
- </v-col>
17
- <v-col cols="12">
18
- <v-card
19
- width="100%"
20
- variant="outlined"
21
- border="thin"
22
- rounded="lg"
23
- :loading="loading"
24
- >
25
- <v-toolbar density="compact" color="grey-lighten-4">
26
- <template #prepend>
27
- <v-btn fab icon density="comfortable" @click="getRoles()">
28
- <v-icon>mdi-refresh</v-icon>
29
- </v-btn>
30
- </template>
31
-
32
- <template #append>
33
- <v-row no-gutters justify="end" align="center">
34
- <span class="mr-2 text-caption text-fontgray">
35
- {{ pageRange }}
36
- </span>
37
- <local-pagination
38
- v-model="page"
39
- :length="pages"
40
- @update:value="getRoles()"
41
- />
42
- </v-row>
43
- </template>
44
- </v-toolbar>
45
-
46
- <v-data-table
15
+ </AppButton>
16
+ </template>
17
+ </PageHeader>
18
+
19
+ <AppCard class="table-card">
20
+ <!-- `v-card`'s `:loading` bar, drawn explicitly: a loading screen must
21
+ still say so now that the card is not a `v-card`. -->
22
+ <v-progress-linear v-if="loading" indeterminate height="2" />
23
+
24
+ <CardToolbar :count="pageRange">
25
+ <template #left>
26
+ <AppButton
27
+ variant="icon"
28
+ icon="mdi-refresh"
29
+ aria-label="Refresh"
30
+ @click="getRoles()"
31
+ />
32
+ </template>
33
+
34
+ <template #right>
35
+ <local-pagination
36
+ v-model="page"
37
+ :length="pages"
38
+ @update:value="getRoles()"
39
+ />
40
+ </template>
41
+ </CardToolbar>
42
+
43
+ <v-data-table
47
44
  :headers="props.headers"
48
45
  :items="items"
49
46
  item-value="_id"
@@ -58,7 +55,11 @@
58
55
  <span class="text-caption font-weight-bold text-capitalize">
59
56
  permissions
60
57
  </span>
61
- <v-chip>{{ getPermissionCount(value) }}</v-chip>
58
+ <StatusChip
59
+ :dot="false"
60
+ tone="info"
61
+ :label="String(getPermissionCount(value))"
62
+ />
62
63
  </template>
63
64
 
64
65
  <template #item.action-table="{ item }" v-if="canDeleteRole">
@@ -73,9 +74,8 @@
73
74
  </v-list>
74
75
  </v-menu>
75
76
  </template>
76
- </v-data-table>
77
- </v-card>
78
- </v-col>
77
+ </v-data-table>
78
+ </AppCard>
79
79
 
80
80
  <!-- dialogs -->
81
81
  <v-dialog v-model="createDialog" width="500" persistent>
@@ -105,45 +105,93 @@
105
105
  />
106
106
  </v-dialog>
107
107
 
108
- <ConfirmDialog
109
- v-model="confirmDialog"
110
- :loading="deleteLoading"
111
- @submit="handleDeleteRole"
112
- >
113
- <template #title>
114
- <span class="font-weight-medium text-h5">Delete Role</span>
115
- </template>
116
-
117
- <template #description>
118
- <p class="text-subtitle-2">
119
- Are you sure you want to delete this role? This action cannot be
120
- undone.
121
- </p>
122
- </template>
108
+ <v-dialog v-model="confirmDialog" max-width="450">
109
+ <v-card>
110
+ <v-toolbar>
111
+ <v-row no-gutters class="fill-height px-6" align="center">
112
+ <span class="font-weight-bold text-h6 text-capitalize">
113
+ Delete Role
114
+ </span>
115
+ </v-row>
116
+ </v-toolbar>
123
117
 
124
- <template #footer>
125
- <div class="d-flex justify-center ga-3 w-100">
126
- <v-btn
127
- variant="text"
128
- @click="confirmDialog = false"
129
- :disabled="deleteLoading"
130
- >
131
- Close
132
- </v-btn>
133
- <v-btn
134
- color="primary"
135
- variant="flat"
136
- @click="handleDeleteRole"
137
- :loading="deleteLoading"
138
- >
139
- Delete Role
140
- </v-btn>
141
- </div>
142
- </template>
143
- </ConfirmDialog>
118
+ <v-card-text>
119
+ <span v-if="!hasAssignedMembers" class="text-subtitle-2">
120
+ Are you sure you want to delete this role? This action cannot be
121
+ undone.
122
+ </span>
123
+ <template v-else>
124
+ <p class="text-subtitle-2 mb-4">
125
+ There are currently
126
+ <span class="text-error font-weight-bold">
127
+ {{ deletionPreview.members.length }}
128
+ {{ deletionPreview.members.length === 1 ? "user" : "users" }}
129
+ </span>
130
+ assigned to this role. Reassign each user before deleting it so
131
+ they do not lose access.
132
+ </p>
133
+
134
+ <v-row
135
+ v-for="member in deletionPreview.members"
136
+ :key="member._id"
137
+ no-gutters
138
+ class="mb-3 pa-3 border rounded-lg"
139
+ align="center"
140
+ >
141
+ <v-col cols="12" sm="5" class="text-body-2 mb-2 mb-sm-0">
142
+ {{ member.name || member.user }}
143
+ </v-col>
144
+ <v-col cols="12" sm="7">
145
+ <v-select
146
+ v-model="memberReassignments[member._id]"
147
+ :items="deletionPreview.replacementRoles"
148
+ item-title="name"
149
+ item-value="_id"
150
+ label="Reassign role"
151
+ density="comfortable"
152
+ hide-details
153
+ />
154
+ </v-col>
155
+ </v-row>
156
+ </template>
157
+ </v-card-text>
158
+
159
+ <v-toolbar class="pa-0" density="compact">
160
+ <v-row no-gutters>
161
+ <v-col cols="6" class="pa-0">
162
+ <v-btn
163
+ block
164
+ variant="text"
165
+ class="text-none"
166
+ size="large"
167
+ height="48"
168
+ @click="closeDeleteDialog"
169
+ :disabled="deleteLoading"
170
+ >
171
+ Cancel
172
+ </v-btn>
173
+ </v-col>
174
+ <v-col cols="6" class="pa-0">
175
+ <v-btn
176
+ block
177
+ variant="flat"
178
+ color="black"
179
+ class="text-none font-weight-bold rounded-0"
180
+ height="48"
181
+ @click="handleDeleteRole"
182
+ :loading="deleteLoading"
183
+ :disabled="hasAssignedMembers && !canConfirmDeletion"
184
+ >
185
+ {{ hasAssignedMembers ? "Confirm" : "Delete" }}
186
+ </v-btn>
187
+ </v-col>
188
+ </v-row>
189
+ </v-toolbar>
190
+ </v-card>
191
+ </v-dialog>
144
192
 
145
193
  <Snackbar v-model="messageSnackbar" :text="message" :color="messageColor" />
146
- </v-row>
194
+ </div>
147
195
  </template>
148
196
 
149
197
  <script setup lang="ts">
@@ -367,10 +415,49 @@ async function refreshRolesAfterUpdate(savedPermissions: string[]) {
367
415
  const confirmDialog = ref(false);
368
416
  const selectedRoleId = ref<string | null>(null);
369
417
  const deleteLoading = ref(false);
418
+ const deletionPreview = ref({
419
+ members: [] as Array<Record<string, any>>,
420
+ replacementRoles: [] as Array<Record<string, any>>,
421
+ });
422
+ const memberReassignments = ref<Record<string, string>>({});
423
+
424
+ const hasAssignedMembers = computed(
425
+ () => deletionPreview.value.members.length > 0
426
+ );
427
+
428
+ const canConfirmDeletion = computed(() =>
429
+ deletionPreview.value.members.every(
430
+ (member) => Boolean(memberReassignments.value[member._id])
431
+ )
432
+ );
433
+
434
+ const { getDeletionPreview, deleteWithReassignments } = useRole();
370
435
 
371
- function openDeleteDialog(id: string) {
436
+ async function openDeleteDialog(id: string) {
372
437
  selectedRoleId.value = id;
373
- confirmDialog.value = true;
438
+ deletionPreview.value = { members: [], replacementRoles: [] };
439
+ memberReassignments.value = {};
440
+ deleteLoading.value = true;
441
+
442
+ try {
443
+ const res = await getDeletionPreview(id);
444
+ deletionPreview.value = res.data;
445
+ confirmDialog.value = true;
446
+ } catch (error: any) {
447
+ const errorMessage =
448
+ error?.response?._data?.message || "Failed to load role assignments.";
449
+ showMessage(errorMessage, "error");
450
+ selectedRoleId.value = null;
451
+ } finally {
452
+ deleteLoading.value = false;
453
+ }
454
+ }
455
+
456
+ function closeDeleteDialog() {
457
+ confirmDialog.value = false;
458
+ selectedRoleId.value = null;
459
+ deletionPreview.value = { members: [], replacementRoles: [] };
460
+ memberReassignments.value = {};
374
461
  }
375
462
 
376
463
  function showMessage(msg: string, color: string) {
@@ -383,17 +470,23 @@ async function handleDeleteRole() {
383
470
  if (!selectedRoleId.value) return;
384
471
  deleteLoading.value = true;
385
472
  try {
386
- const res = await deleteRole(selectedRoleId.value);
387
-
388
- confirmDialog.value = false;
473
+ const reassignments = deletionPreview.value.members.map((member) => ({
474
+ memberId: member._id,
475
+ roleId: memberReassignments.value[member._id],
476
+ }));
477
+ const res = hasAssignedMembers.value
478
+ ? await deleteWithReassignments(selectedRoleId.value, reassignments)
479
+ : await deleteRole(selectedRoleId.value);
480
+
481
+ closeDeleteDialog();
389
482
  showMessage(res.message, "success");
390
483
  getRoles();
391
484
  } catch (error: any) {
392
- const errorMessage = error?.response?._data?.message;
485
+ const errorMessage =
486
+ error?.response?._data?.message || "Failed to delete role.";
393
487
  showMessage(errorMessage, "error");
394
488
  } finally {
395
489
  deleteLoading.value = false;
396
- selectedRoleId.value = null;
397
490
  }
398
491
  }
399
492
  </script>
@@ -60,7 +60,9 @@ const props = defineProps({
60
60
 
61
61
  const { standardFormatDate } = useUtils();
62
62
 
63
- const { validateVisitorQrCode } = useVisitor();
63
+ const { validateVisitorQrCode, getVisitors } = useVisitor();
64
+
65
+ const { getPassKeysByPageSearch } = usePassKey();
64
66
 
65
67
  const emits = defineEmits([
66
68
  "closeDialog",
@@ -97,8 +99,6 @@ const handleScanVisitorQRCode = async () => {
97
99
  showNotFoundMessage.value = false;
98
100
  // Automatically navigate to the scanned URL if it's a valid link
99
101
  if (isValidUrl(qrCodeMessage)) {
100
- console.log("QR Code value", qrCodeMessage);
101
- console.log("Last _id", qrCodeMessage.split("/").pop());
102
102
  // get the last _id in the url
103
103
  const id = qrCodeMessage.split("/").pop();
104
104
  // check if it's a valid mongodb _id
@@ -108,7 +108,6 @@ const handleScanVisitorQRCode = async () => {
108
108
  props.site as string,
109
109
  id as string
110
110
  );
111
- console.log("validateVisitorQrCode", response);
112
111
  if (response.errorMessage) {
113
112
  showNotFoundMessage.value = true;
114
113
  errorMessage.value =
@@ -122,9 +121,38 @@ const handleScanVisitorQRCode = async () => {
122
121
  emits("openVisitorDataFromScannedQrCodeDialog", response);
123
122
  }
124
123
  } else {
125
- showNotFoundMessage.value = true;
126
- errorMessage.value = "Invalid mongodb _id.";
127
- showMessage(errorMessage.value, "error");
124
+ const result: any = await getPassKeysByPageSearch({
125
+ sites: [props.site as string],
126
+ search: qrCodeMessage,
127
+ });
128
+
129
+ if (result.items?.length < 1) {
130
+ showMessage(`Pass or Key ${qrCodeMessage} not found.`, "error");
131
+ return;
132
+ }
133
+
134
+ const data: any = await getVisitors({
135
+ site: props.site as string,
136
+ passOrKey: {
137
+ keyId: result.items[0]._id,
138
+ type: result.items[0].passType == "pass-key" ? "key" : "pass",
139
+ },
140
+ checkedOut: false,
141
+ });
142
+
143
+ if (data.items?.length < 1) {
144
+ showMessage(
145
+ `There are no unchecked-out visitor transactions for the scanned ${
146
+ result.items[0].passType == "pass-key" ? "Key" : "Pass"
147
+ } ${qrCodeMessage}.`,
148
+ "error"
149
+ );
150
+
151
+ return;
152
+ }
153
+
154
+ closeDialog();
155
+ emits("openVisitorDataFromScannedQrCodeDialog", data.items[0]);
128
156
  }
129
157
 
130
158
  // window.location.href = qrCodeMessage;
@@ -21,7 +21,7 @@
21
21
  <template #extension>
22
22
  <v-row no-gutters class="w-100 d-flex flex-column">
23
23
  <v-card
24
- class="w-100 px-3 d-flex align-center ga-5 py-2"
24
+ class="w-100 filter-bar d-flex align-center ga-5"
25
25
  flat
26
26
  :height="60"
27
27
  >
@@ -68,20 +68,18 @@
68
68
  <v-spacer />
69
69
 
70
70
  <v-col cols="auto">
71
- <v-chip
71
+ <StatusChip
72
72
  v-if="isScheduleClosed"
73
- color="error"
74
- variant="tonal"
73
+ status="Closed"
75
74
  class="text-capitalize mr-2"
76
75
  >
77
- <v-icon start>mdi-lock</v-icon>
76
+ <v-icon size="14">mdi-lock</v-icon>
78
77
  Closed – View Only
79
- </v-chip>
78
+ </StatusChip>
80
79
  <v-btn
81
80
  v-if="canViewHistory"
82
- class="text-none mr-2"
83
- size="large"
84
- color="primary"
81
+ class="text-none mr-2 screen-btn-primary"
82
+ variant="flat"
85
83
  aria-label="History"
86
84
  @click="openHistory"
87
85
  >
@@ -89,9 +87,8 @@
89
87
  </v-btn>
90
88
  <v-btn
91
89
  v-if="canGenerateChecklist"
92
- class="text-none"
93
- size="large"
94
- color="primary"
90
+ class="text-none screen-btn-primary"
91
+ variant="flat"
95
92
  aria-label="Generate"
96
93
  @click="_generateChecklist"
97
94
  :loading="submitting"
@@ -114,20 +111,13 @@
114
111
  </span>
115
112
  </div>
116
113
  <div v-else-if="isScheduleClosed">
117
- <v-chip
118
- size="small"
119
- color="error"
120
- variant="tonal"
121
- class="text-capitalize"
122
- >Closed</v-chip
123
- >
114
+ <StatusChip status="Closed" class="text-capitalize" />
124
115
  </div>
125
116
  <div v-else>
126
117
  <v-btn
127
118
  v-if="canManageScheduleTasks"
128
119
  variant="outlined"
129
- size="medium"
130
- class="text-capitalize px-4 py-2"
120
+ class="text-capitalize screen-btn-ghost"
131
121
  @click.stop="() => _acceptAreaChecklist(item._id)"
132
122
  >
133
123
  Accept
@@ -146,14 +136,11 @@
146
136
  </template>
147
137
 
148
138
  <template #item.status="{ value }">
149
- <v-chip
139
+ <StatusChip
150
140
  class="text-capitalize"
151
- :color="getStatusColor(value)"
152
- variant="flat"
153
- pill
154
- >
155
- {{ value || "No Status" }}
156
- </v-chip>
141
+ :status="value"
142
+ :label="value || 'No Status'"
143
+ />
157
144
  </template>
158
145
  </TableMain></v-col
159
146
  >
@@ -262,27 +249,6 @@ watchEffect(() => {
262
249
  }
263
250
  });
264
251
 
265
- const getStatusColor = (status: unknown): string => {
266
- if (!status) return "grey";
267
-
268
- const normalized = String(status).toLowerCase();
269
-
270
- switch (normalized) {
271
- case "open":
272
- return "grey";
273
- case "ongoing":
274
- return "primary";
275
- case "completed":
276
- case "accepted":
277
- return "success";
278
- case "closed":
279
- case "rejected":
280
- return "error";
281
- default:
282
- return "secondary";
283
- }
284
- };
285
-
286
252
  function showMessage(msg: string, color: string = "error") {
287
253
  message.value = msg;
288
254
  messageColor.value = color;
@@ -21,10 +21,8 @@
21
21
  <v-row no-gutters align="center" class="w-100">
22
22
  <v-col cols="auto" v-if="canCreateScheduleTask">
23
23
  <v-btn
24
- class="text-none"
25
- rounded="pill"
26
- variant="tonal"
27
- size="large"
24
+ class="text-none screen-btn-primary"
25
+ variant="flat"
28
26
  @click="openFormDialog"
29
27
  >
30
28
  Create Schedule Task
@@ -33,7 +31,7 @@
33
31
 
34
32
  <v-spacer />
35
33
 
36
- <v-col cols="auto">
34
+ <v-col cols="auto" class="filter-field">
37
35
  <v-text-field
38
36
  v-model="searchInput"
39
37
  density="compact"
@@ -49,28 +47,31 @@
49
47
 
50
48
  <template #item.areas="{ value }">
51
49
  <div v-if="value && value.length > 0">
52
- <v-chip
50
+ <StatusChip
53
51
  v-for="(area, idx) in value.slice(0, 2)"
54
52
  :key="idx"
55
- size="small"
56
53
  class="mr-1 mb-1"
57
- >
58
- {{ area.name }}
59
- </v-chip>
60
- <v-chip v-if="value.length > 2" size="small" class="mb-1">
61
- +{{ value.length - 2 }} more
62
- </v-chip>
54
+ :dot="false"
55
+ tone="neutral"
56
+ :label="area.name"
57
+ />
58
+ <StatusChip
59
+ v-if="value.length > 2"
60
+ class="mb-1"
61
+ :dot="false"
62
+ tone="neutral"
63
+ :label="`+${value.length - 2} more`"
64
+ />
63
65
  </div>
64
66
  <span v-else>N/A</span>
65
67
  </template>
66
68
 
67
69
  <template #item.status="{ value }">
68
- <v-chip
69
- :color="value === 'active' ? 'success' : 'default'"
70
+ <StatusChip
70
71
  class="text-capitalize"
71
- >
72
- {{ value || "N/A" }}
73
- </v-chip>
72
+ :status="value"
73
+ :label="value || 'N/A'"
74
+ />
74
75
  </template>
75
76
  </TableMain>
76
77
 
@@ -270,15 +271,11 @@
270
271
  Status:
271
272
  </v-col>
272
273
  <v-col cols="7" class="text-subtitle-2">
273
- <v-chip
274
- :color="
275
- selectedTask.status === 'active' ? 'success' : 'default'
276
- "
277
- size="small"
274
+ <StatusChip
278
275
  class="text-capitalize"
279
- >
280
- {{ selectedTask.status || "N/A" }}
281
- </v-chip>
276
+ :status="selectedTask.status"
277
+ :label="selectedTask.status || 'N/A'"
278
+ />
282
279
  </v-col>
283
280
  </v-row>
284
281