@7365admin1/layer-common 3.2.7 → 3.2.8-staging.201
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/assets/css/primitives.css +1113 -0
- package/assets/css/screens.css +1097 -0
- package/assets/css/shell.css +258 -0
- package/assets/css/tokens.css +236 -0
- package/components/AcceptDialog.vue +17 -18
- package/components/AccessCard/AvailableStats.vue +24 -16
- package/components/AccessCardAddForm.vue +42 -42
- package/components/AccessCardAssignToUnitForm.vue +13 -21
- package/components/AccessCardDeleteDialog.vue +41 -39
- package/components/AccessCardDetailsDialog.vue +125 -79
- package/components/AccessCardPreviewDialog.vue +58 -84
- package/components/AccessCardQrTagging.vue +60 -63
- package/components/AccessCardReplaceForm.vue +27 -23
- package/components/AccessManagement.vue +86 -85
- package/components/AddEqupmentForm.vue +18 -22
- package/components/AddPassKeyToVisitor.vue +95 -73
- package/components/AppButton.vue +62 -0
- package/components/AppCard.vue +20 -0
- package/components/AppDateField.vue +49 -0
- package/components/AppField.vue +76 -0
- package/components/AppKpiTile.vue +65 -0
- package/components/AppSegmented.vue +38 -0
- package/components/AppSelect.vue +247 -0
- package/components/AreaChecklistHistoryLogs.vue +51 -44
- package/components/AreaChecklistHistoryMain.vue +14 -7
- package/components/AreaFormDialog.vue +71 -59
- package/components/AreaMain.vue +73 -107
- package/components/AttachmentsViewer.vue +84 -22
- package/components/AttendanceCheckInOutDialog.vue +85 -88
- package/components/AttendanceDetailsDialog.vue +57 -63
- package/components/AttendanceMain.vue +4 -3
- package/components/AttendanceMapSearchDialog.vue +42 -44
- package/components/AttendanceSettingsDialog.vue +79 -63
- package/components/Avatar/Main.vue +54 -2
- package/components/BillingMain.vue +26 -30
- package/components/BtnUploadFile.vue +53 -11
- package/components/BuildingForm.vue +34 -27
- package/components/BuildingManagement/buildings.vue +39 -39
- package/components/BuildingManagement/units.vue +26 -42
- package/components/BuildingUnitFormAdd.vue +20 -23
- package/components/BuildingUnitFormEdit.vue +8 -4
- package/components/BulletinBoardForm.vue +19 -24
- package/components/BulletinBoardManagement.vue +49 -57
- package/components/BulletinBoardView.vue +9 -6
- package/components/BulletinExpirationChip.vue +13 -4
- package/components/Button/Close.vue +2 -2
- package/components/CameraForm.vue +21 -22
- package/components/CameraMain.vue +50 -49
- package/components/Card/DeleteConfirmation.vue +24 -22
- package/components/Card/MemberInfoSummary.vue +28 -3
- package/components/Card/Toggle.vue +15 -3
- package/components/CardToolbar.vue +37 -0
- package/components/Carousel.vue +56 -36
- package/components/Chat/Bubbles.vue +43 -14
- package/components/Chat/Information.vue +49 -32
- package/components/Chat/ListCard.vue +38 -9
- package/components/Chat/Message.vue +41 -15
- package/components/Chat/Navigation.vue +27 -15
- package/components/Chat/SkeletonLoader.vue +9 -2
- package/components/ChecklistItemRow.vue +25 -1
- package/components/CleaningScheduleMain.vue +44 -49
- package/components/ClientDetailForm.vue +81 -56
- package/components/ClientMain.vue +92 -82
- package/components/ConfirmDialog.vue +14 -8
- package/components/Container/Standard.vue +9 -7
- package/components/CreateSubsciptionPlan.vue +148 -89
- package/components/DashboardEmptyState.vue +48 -3
- package/components/DashboardMain.vue +924 -676
- package/components/DashboardPanel.vue +84 -21
- package/components/DeliveryCompany.vue +34 -20
- package/components/Dialog/DeleteConfirmation.vue +20 -21
- package/components/Dialog/ReplaceAutofillPrompt.vue +19 -26
- package/components/Dialog/ReusablePrompt.vue +30 -29
- package/components/Dialog/UpdateMoreAction.vue +62 -59
- package/components/DocumentForm.vue +14 -21
- package/components/DocumentManagement.vue +162 -108
- package/components/DocumentViewer.vue +29 -12
- package/components/DrawImage.vue +29 -21
- package/components/EntryPass/QrTemplatePreview.vue +27 -16
- package/components/EntryPassInformation.vue +40 -10
- package/components/EntryPassMain.vue +49 -27
- package/components/EquipmentItemMain.vue +84 -97
- package/components/EquipmentManagementMain.vue +81 -103
- package/components/Facility/BookingSetup.vue +43 -52
- package/components/Feedback/Form.vue +26 -12
- package/components/FeedbackMain.vue +35 -49
- package/components/FileInput.vue +75 -58
- package/components/FileInputWithList.vue +59 -12
- package/components/FormDialog.vue +60 -21
- package/components/HidAccessLogDashboard.vue +512 -490
- package/components/HidCameraCaptureDialog.vue +216 -0
- package/components/HidEnabledGate.vue +67 -9
- package/components/HidIntercomManagement.vue +1322 -653
- package/components/HidQrCodeConfiguration.vue +1030 -258
- package/components/HidReaderForm.vue +142 -59
- package/components/HidReaderManagement.vue +211 -323
- package/components/HidServiceSettingsPanel.vue +44 -13
- package/components/HidUserEnrollment.vue +1185 -412
- package/components/HygieneUpdateMoreAction.vue +44 -44
- package/components/IncidentReport/Authorities.vue +30 -18
- package/components/IncidentReport/IncidentInformation.vue +10 -10
- package/components/IncidentReport/IncidentInformationDownload.vue +3 -4
- package/components/IncidentReport/affectedEntities.vue +41 -20
- package/components/Input/Date.vue +3 -0
- package/components/Input/DatePicker.vue +1 -2
- package/components/Input/DateTimePicker.vue +1 -1
- package/components/Input/File.vue +55 -10
- package/components/Input/FileV2.vue +39 -6
- package/components/Input/InputPhoneNumberV2.vue +2 -1
- package/components/Input/ListGroupSelection.vue +56 -8
- package/components/Input/NRICNumber.vue +1 -0
- package/components/Input/NewDate.vue +1 -0
- package/components/Input/Number.vue +1 -0
- package/components/Input/Password.vue +1 -0
- package/components/Input/PhoneNumber.vue +21 -1
- package/components/Input/VehicleNumber.vue +1 -0
- package/components/InputLabel.vue +2 -2
- package/components/InvitationClientForm.vue +21 -19
- package/components/InvitationForm.vue +15 -21
- package/components/InvitationMain.vue +46 -61
- package/components/Layout/Header.vue +263 -36
- package/components/Layout/NavigationDrawer.vue +300 -30
- package/components/ListItem.vue +33 -3
- package/components/LocalPagination.vue +27 -3
- package/components/ManageChecklistMain.vue +136 -86
- package/components/MemberInformation.vue +32 -16
- package/components/MemberMain.vue +113 -93
- package/components/MyAttendanceMain.vue +3 -5
- package/components/NavigationItem.vue +83 -3
- package/components/Nfc/NFCPatrolReportMain.vue +47 -33
- package/components/Nfc/NFCPatrolRouteForm.vue +18 -20
- package/components/Nfc/NFCPatrolRouteMain.vue +116 -103
- package/components/Nfc/NFCPatrolSettings.vue +14 -4
- package/components/Nfc/NFCTagForm.vue +22 -8
- package/components/Nfc/NFCTagMain.vue +41 -43
- package/components/Nfc/PatrolReport/DailyReportTab.vue +8 -1
- package/components/Nfc/PatrolReport/MonthlyReportTab.vue +8 -1
- package/components/Nfc/PatrolReport/MonthlyReportTable.vue +5 -3
- package/components/Nfc/PatrolReport/PatrolActivityTable.vue +26 -6
- package/components/Nfc/PatrolReport/PatrolReportTab.vue +8 -0
- package/components/Nfc/PatrolReport/PatrolRouteSummary.vue +41 -9
- package/components/Nfc/PatrolReport/RemarksDialog.vue +39 -9
- package/components/Nfc/PatrolReport/ReportEmptyState.vue +29 -9
- package/components/Nfc/PatrolReport/ReportFilters.vue +19 -10
- package/components/Nfc/PatrolReport/ReportLocationHeader.vue +32 -6
- package/components/Nfc/PatrolReport/SummaryReportTable.vue +28 -6
- package/components/NotificationSettings.vue +373 -0
- package/components/NumberSettingField.vue +9 -2
- package/components/OnlineFormConfigurationForm.vue +725 -237
- package/components/OnlineFormFill.vue +213 -106
- package/components/OnlineFormRenderPreview.vue +25 -30
- package/components/OnlineFormsConfiguration.vue +113 -109
- package/components/OrgViewDialog.vue +34 -16
- package/components/OvernightParkingAvailability.vue +49 -26
- package/components/OvernightParkingManagement.vue +78 -18
- package/components/PageHeader.vue +43 -0
- package/components/PassInformation.vue +109 -53
- package/components/PasswordConfirmation.vue +44 -26
- package/components/PeopleForm.vue +41 -20
- package/components/PhotoUpload.vue +110 -48
- package/components/PlaceholderComponent.vue +35 -19
- package/components/PlanActionsMenu.vue +12 -2
- package/components/PlanStatusBadge.vue +7 -8
- package/components/PlateNumberDisplay.vue +9 -6
- package/components/QrTemplate/PrintDialog.vue +66 -43
- package/components/RolePermissionFormCreate.vue +104 -79
- package/components/RolePermissionFormPreviewUpdate.vue +111 -109
- package/components/RolePermissionMain.vue +183 -81
- package/components/ScanVisitorQRCode.vue +99 -35
- package/components/ScheduleAreaMain.vue +34 -59
- package/components/ScheduleTaskForm.vue +61 -42
- package/components/ScheduleTaskMain.vue +56 -69
- package/components/SearchVehicleNumberUser.vue +39 -37
- package/components/ServiceProviderFormCreate.vue +29 -20
- package/components/ServiceProviderInvitationPrompt.vue +155 -0
- package/components/ServiceProviderMain.vue +601 -432
- package/components/Signature.vue +40 -34
- package/components/SignaturePad.vue +5 -29
- package/components/SiteSettings.vue +41 -11
- package/components/SiteSettingsWorkOrder.vue +61 -30
- package/components/SlideCardGroup.vue +35 -11
- package/components/Snackbar.vue +36 -3
- package/components/SpecificAttr.vue +18 -8
- package/components/StatusChip.vue +156 -0
- package/components/StockCard.vue +17 -12
- package/components/SubscriptionPlanTable.vue +207 -140
- package/components/SwitchContext.vue +201 -9
- package/components/TableHygiene.vue +36 -46
- package/components/TableList.vue +10 -10
- package/components/TableListSecondary.vue +105 -54
- package/components/TableMain.vue +251 -78
- package/components/TableV3.vue +61 -70
- package/components/TiptapEditor.vue +33 -40
- package/components/TiptapEditorQr.vue +5 -2
- package/components/Tooltip/Info.vue +69 -24
- package/components/UnitMain.vue +40 -60
- package/components/UnitPersonCard.vue +42 -13
- package/components/VehicleAddSelection.vue +48 -32
- package/components/VehicleForm.vue +112 -129
- package/components/VehicleManagement.vue +26 -12
- package/components/VehicleUpdateMoreAction.vue +59 -46
- package/components/VisitorDataFromScannedQRCodeForm.vue +90 -65
- package/components/VisitorForm.vue +774 -210
- package/components/VisitorFormSelection.vue +40 -37
- package/components/VisitorManagement.vue +239 -82
- package/components/VisitorPassKeyQRScanner.vue +65 -18
- package/components/VisitorSearchResultSummary.vue +60 -16
- package/components/VisitorSocketPopUp.vue +22 -14
- package/components/VisitorsReportPreview.vue +44 -29
- package/components/WorkOrder/Create.vue +26 -17
- package/components/WorkOrder/ListView.vue +38 -7
- package/components/WorkOrder/Main.vue +62 -59
- package/composables/useFeedback.ts +3 -3
- package/composables/useHidAmico.ts +269 -0
- package/composables/useHidNavigation.ts +2 -9
- package/composables/useMember.ts +3 -3
- package/composables/useNFCPatrolDailyReport.ts +13 -0
- package/composables/useNFCPatrolMonthlyReport.ts +22 -56
- package/composables/useNFCPatrolReport.ts +13 -0
- package/composables/useNotificationPreference.ts +87 -0
- package/composables/useOnlineFormPages.ts +2 -0
- package/composables/useRole.ts +22 -0
- package/composables/useServiceProvider.ts +3 -3
- package/composables/useServiceProviderInvitation.ts +145 -0
- package/composables/useSipWebPhone.ts +336 -0
- package/composables/useSubscriptionPlan.ts +62 -0
- package/composables/useThemePreference.ts +63 -0
- package/composables/useVisitor.ts +6 -1
- package/composables/useWebUsb.ts +127 -37
- package/composables/useWorkOrder.ts +17 -3
- package/error.vue +30 -6
- package/nuxt.config.ts +36 -0
- package/package.json +25 -4
- package/pages/[org]/[site]/access-mgmt/administrator/index.vue +2 -2
- package/pages/[org]/[site]/access-mgmt/{identity-mapping → hid-cards}/index.vue +2 -2
- package/pages/[org]/[site]/access-mgmt/intercom/index.vue +1 -1
- package/pages/notification-settings.vue +19 -0
- package/pages/payment-method-linked.vue +34 -10
- package/pages/require-customer.vue +48 -10
- package/pages/require-organization-membership.vue +32 -8
- package/pages/unauthorized.vue +29 -4
- package/plugins/secure-member.client.ts +21 -56
- package/plugins/vuetify.ts +69 -2
- package/types/nfc-patrol-report.ts +3 -2
- package/types/site.d.ts +71 -0
- package/types/subscription.ts +18 -11
- package/utils/breadcrumb.test.ts +108 -0
- package/utils/breadcrumb.ts +82 -0
- package/utils/dashboard.test.ts +118 -0
- package/utils/dashboard.ts +53 -0
- package/utils/data.test.ts +95 -0
- package/utils/data.ts +40 -2
- package/utils/hid-discover.test.ts +102 -0
- package/utils/list-page.test.ts +60 -0
- package/utils/list-page.ts +38 -0
- package/utils/materialSymbols.ts +363 -0
- package/utils/nav-sections.test.ts +190 -0
- package/utils/nav-sections.ts +151 -0
- package/utils/nfc-patrol-report.test.ts +130 -0
- package/utils/nfc-patrol-report.ts +101 -0
- package/utils/role.test.ts +69 -0
- package/utils/role.ts +10 -0
- package/utils/route-name.test.ts +85 -0
- package/utils/route-name.ts +24 -0
- package/utils/status.test.ts +110 -0
- package/utils/status.ts +135 -0
- package/utils/table-card.test.ts +84 -0
- package/utils/theme-aa-ledger.ts +148 -0
- package/utils/theme.test.ts +485 -7
- package/utils/theme.ts +295 -110
- package/.changeset/README.md +0 -8
- package/.changeset/config.json +0 -11
- package/.editorconfig +0 -12
- package/.github/workflows/main.yml +0 -17
- package/.github/workflows/publish-staging.yml +0 -47
- package/.github/workflows/publish.yml +0 -39
- package/PUBLISHING.md +0 -269
- package/components/HidIdentityMapping.vue +0 -975
- package/components/ScheduleTaskAreaFormDialog.vue +0 -144
- package/components/ScheduleTaskAreaUpdateMoreAction.vue +0 -109
- package/components/ScheduleTastTicketMain.vue +0 -182
- package/components/TableWithButton.vue +0 -94
- package/test/visitor-socket.test.mjs +0 -36
|
@@ -9,36 +9,27 @@
|
|
|
9
9
|
>
|
|
10
10
|
<v-container class="d-flex justify-center" max-height="90vh">
|
|
11
11
|
<!-- QR code reader container -->
|
|
12
|
-
<v-card
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
<v-toolbar>
|
|
17
|
-
<v-card-title class="text-h5"> Scan QR Code </v-card-title>
|
|
18
|
-
<v-spacer />
|
|
19
|
-
<v-btn
|
|
20
|
-
color="grey-darken-1"
|
|
21
|
-
icon="mdi-close"
|
|
22
|
-
@click="closeDialog()"
|
|
23
|
-
/>
|
|
24
|
-
</v-toolbar>
|
|
25
|
-
|
|
26
|
-
<div
|
|
27
|
-
id="reader"
|
|
28
|
-
class="d-flex justify-center align-center w-100 h-100"
|
|
29
|
-
style="height: calc(100vh - 64px)"
|
|
30
|
-
>
|
|
31
|
-
<!-- The QR code scanner box -->
|
|
32
|
-
<!-- This is where the QR code scanner will be displayed -->
|
|
12
|
+
<v-card class="screen-modal qr-scanner">
|
|
13
|
+
<div class="qr-scanner__head">
|
|
14
|
+
<v-card-title>Scan QR Code</v-card-title>
|
|
15
|
+
<AppButton variant="icon" icon="mdi-close" @click="closeDialog()" />
|
|
33
16
|
</div>
|
|
34
|
-
|
|
35
|
-
<div
|
|
36
|
-
<
|
|
17
|
+
|
|
18
|
+
<div class="screen-modal__body qr-scanner__body">
|
|
19
|
+
<div id="reader" class="qr-scanner__reader">
|
|
20
|
+
<!-- The QR code scanner box -->
|
|
21
|
+
<!-- This is where the QR code scanner will be displayed -->
|
|
22
|
+
</div>
|
|
23
|
+
<!-- Show Error Messages -->
|
|
24
|
+
<p v-if="showNotFoundMessage" class="qr-scanner__error">{{ errorMessage }}</p>
|
|
25
|
+
<!-- Switch camera button inside the reader box -->
|
|
26
|
+
<AppButton
|
|
27
|
+
icon="mdi-camera-switch"
|
|
28
|
+
class="qr-scanner__switch"
|
|
29
|
+
aria-label="Switch camera"
|
|
30
|
+
@click="switchCamera()"
|
|
31
|
+
/>
|
|
37
32
|
</div>
|
|
38
|
-
<!-- Switch camera button inside the reader box -->
|
|
39
|
-
<v-btn color="primary" icon class="mt-4" @click="switchCamera()">
|
|
40
|
-
<v-icon icon="mdi-camera-switch" large />
|
|
41
|
-
</v-btn>
|
|
42
33
|
</v-card>
|
|
43
34
|
</v-container>
|
|
44
35
|
</v-dialog>
|
|
@@ -60,7 +51,9 @@ const props = defineProps({
|
|
|
60
51
|
|
|
61
52
|
const { standardFormatDate } = useUtils();
|
|
62
53
|
|
|
63
|
-
const { validateVisitorQrCode } = useVisitor();
|
|
54
|
+
const { validateVisitorQrCode, getVisitors } = useVisitor();
|
|
55
|
+
|
|
56
|
+
const { getPassKeysByPageSearch } = usePassKey();
|
|
64
57
|
|
|
65
58
|
const emits = defineEmits([
|
|
66
59
|
"closeDialog",
|
|
@@ -97,8 +90,6 @@ const handleScanVisitorQRCode = async () => {
|
|
|
97
90
|
showNotFoundMessage.value = false;
|
|
98
91
|
// Automatically navigate to the scanned URL if it's a valid link
|
|
99
92
|
if (isValidUrl(qrCodeMessage)) {
|
|
100
|
-
console.log("QR Code value", qrCodeMessage);
|
|
101
|
-
console.log("Last _id", qrCodeMessage.split("/").pop());
|
|
102
93
|
// get the last _id in the url
|
|
103
94
|
const id = qrCodeMessage.split("/").pop();
|
|
104
95
|
// check if it's a valid mongodb _id
|
|
@@ -108,7 +99,6 @@ const handleScanVisitorQRCode = async () => {
|
|
|
108
99
|
props.site as string,
|
|
109
100
|
id as string
|
|
110
101
|
);
|
|
111
|
-
console.log("validateVisitorQrCode", response);
|
|
112
102
|
if (response.errorMessage) {
|
|
113
103
|
showNotFoundMessage.value = true;
|
|
114
104
|
errorMessage.value =
|
|
@@ -122,9 +112,38 @@ const handleScanVisitorQRCode = async () => {
|
|
|
122
112
|
emits("openVisitorDataFromScannedQrCodeDialog", response);
|
|
123
113
|
}
|
|
124
114
|
} else {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
115
|
+
const result: any = await getPassKeysByPageSearch({
|
|
116
|
+
sites: [props.site as string],
|
|
117
|
+
search: qrCodeMessage,
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
if (result.items?.length < 1) {
|
|
121
|
+
showMessage(`Pass or Key ${qrCodeMessage} not found.`, "error");
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const data: any = await getVisitors({
|
|
126
|
+
site: props.site as string,
|
|
127
|
+
passOrKey: {
|
|
128
|
+
keyId: result.items[0]._id,
|
|
129
|
+
type: result.items[0].passType == "pass-key" ? "key" : "pass",
|
|
130
|
+
},
|
|
131
|
+
checkedOut: false,
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
if (data.items?.length < 1) {
|
|
135
|
+
showMessage(
|
|
136
|
+
`There are no unchecked-out visitor transactions for the scanned ${
|
|
137
|
+
result.items[0].passType == "pass-key" ? "Key" : "Pass"
|
|
138
|
+
} ${qrCodeMessage}.`,
|
|
139
|
+
"error"
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
closeDialog();
|
|
146
|
+
emits("openVisitorDataFromScannedQrCodeDialog", data.items[0]);
|
|
128
147
|
}
|
|
129
148
|
|
|
130
149
|
// window.location.href = qrCodeMessage;
|
|
@@ -197,3 +216,48 @@ const stopScanner = () => {
|
|
|
197
216
|
});
|
|
198
217
|
};
|
|
199
218
|
</script>
|
|
219
|
+
|
|
220
|
+
<style scoped>
|
|
221
|
+
/* Same scanner frame as the pass-key scanner: the card used to be `w-100`
|
|
222
|
+
inside the centring container, so keep that width. */
|
|
223
|
+
.qr-scanner {
|
|
224
|
+
width: 100%;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.qr-scanner__head {
|
|
228
|
+
display: flex;
|
|
229
|
+
align-items: center;
|
|
230
|
+
justify-content: space-between;
|
|
231
|
+
padding-right: 12px;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.qr-scanner__body {
|
|
235
|
+
display: flex;
|
|
236
|
+
flex-direction: column;
|
|
237
|
+
align-items: center;
|
|
238
|
+
gap: 16px;
|
|
239
|
+
padding: 4px 20px 20px;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
.qr-scanner__reader {
|
|
243
|
+
display: flex;
|
|
244
|
+
align-items: center;
|
|
245
|
+
justify-content: center;
|
|
246
|
+
width: 100%;
|
|
247
|
+
min-height: 320px;
|
|
248
|
+
border: 1px solid var(--border);
|
|
249
|
+
border-radius: var(--r-inner);
|
|
250
|
+
background: var(--thead);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
.qr-scanner__error {
|
|
254
|
+
margin: 0;
|
|
255
|
+
font-size: var(--fs-cell);
|
|
256
|
+
color: var(--err);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.qr-scanner__switch {
|
|
260
|
+
width: var(--btn-h);
|
|
261
|
+
padding: 0;
|
|
262
|
+
}
|
|
263
|
+
</style>
|
|
@@ -20,17 +20,18 @@
|
|
|
20
20
|
|
|
21
21
|
<template #extension>
|
|
22
22
|
<v-row no-gutters class="w-100 d-flex flex-column">
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
<!--
|
|
24
|
+
A bare `v-card` here paints Vuetify's own `surface`, a shade off
|
|
25
|
+
the table card it sits inside. A plain row on the card's own
|
|
26
|
+
background, with both filters on the design's field.
|
|
27
|
+
-->
|
|
28
|
+
<div class="w-100 filter-bar d-flex align-center ga-5">
|
|
28
29
|
<v-select
|
|
29
30
|
v-model="statusFilter"
|
|
30
31
|
:items="statusOptions"
|
|
31
32
|
density="compact"
|
|
32
33
|
hide-details
|
|
33
|
-
class="mx-2"
|
|
34
|
+
class="mx-2 filter-field"
|
|
34
35
|
style="max-width: 160px"
|
|
35
36
|
item-title="title"
|
|
36
37
|
item-value="value"
|
|
@@ -42,13 +43,13 @@
|
|
|
42
43
|
:items="typeOptions"
|
|
43
44
|
density="compact"
|
|
44
45
|
hide-details
|
|
45
|
-
class="mx-2"
|
|
46
|
+
class="mx-2 filter-field"
|
|
46
47
|
style="max-width: 160px"
|
|
47
48
|
item-title="title"
|
|
48
49
|
item-value="value"
|
|
49
50
|
label="Type"
|
|
50
51
|
/>
|
|
51
|
-
</
|
|
52
|
+
</div>
|
|
52
53
|
</v-row>
|
|
53
54
|
</template>
|
|
54
55
|
<template #actions>
|
|
@@ -68,20 +69,18 @@
|
|
|
68
69
|
<v-spacer />
|
|
69
70
|
|
|
70
71
|
<v-col cols="auto">
|
|
71
|
-
<
|
|
72
|
+
<StatusChip
|
|
72
73
|
v-if="isScheduleClosed"
|
|
73
|
-
|
|
74
|
-
variant="tonal"
|
|
74
|
+
status="Closed"
|
|
75
75
|
class="text-capitalize mr-2"
|
|
76
76
|
>
|
|
77
|
-
<v-icon
|
|
77
|
+
<v-icon size="14">mdi-lock</v-icon>
|
|
78
78
|
Closed – View Only
|
|
79
|
-
</
|
|
79
|
+
</StatusChip>
|
|
80
80
|
<v-btn
|
|
81
81
|
v-if="canViewHistory"
|
|
82
|
-
class="text-none mr-2"
|
|
83
|
-
|
|
84
|
-
color="primary"
|
|
82
|
+
class="text-none mr-2 screen-btn-primary"
|
|
83
|
+
variant="flat"
|
|
85
84
|
aria-label="History"
|
|
86
85
|
@click="openHistory"
|
|
87
86
|
>
|
|
@@ -89,9 +88,8 @@
|
|
|
89
88
|
</v-btn>
|
|
90
89
|
<v-btn
|
|
91
90
|
v-if="canGenerateChecklist"
|
|
92
|
-
class="text-none"
|
|
93
|
-
|
|
94
|
-
color="primary"
|
|
91
|
+
class="text-none screen-btn-primary"
|
|
92
|
+
variant="flat"
|
|
95
93
|
aria-label="Generate"
|
|
96
94
|
@click="_generateChecklist"
|
|
97
95
|
:loading="submitting"
|
|
@@ -109,25 +107,26 @@
|
|
|
109
107
|
(item.status && String(item.status).toLowerCase() === 'accepted')
|
|
110
108
|
"
|
|
111
109
|
>
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
110
|
+
<!--
|
|
111
|
+
`color`/`variant` on a plain `<span>` do nothing - Vuetify only
|
|
112
|
+
reads them on its own components, so this drew as bare cell text
|
|
113
|
+
while reading as a tonal green chip. It is the accepted chip the
|
|
114
|
+
sibling branches already use.
|
|
115
|
+
-->
|
|
116
|
+
<StatusChip
|
|
117
|
+
status="Accepted"
|
|
118
|
+
class="text-capitalize"
|
|
119
|
+
:label="item.acceptedByName || item.acceptedBy || 'Accepted'"
|
|
120
|
+
/>
|
|
115
121
|
</div>
|
|
116
122
|
<div v-else-if="isScheduleClosed">
|
|
117
|
-
<
|
|
118
|
-
size="small"
|
|
119
|
-
color="error"
|
|
120
|
-
variant="tonal"
|
|
121
|
-
class="text-capitalize"
|
|
122
|
-
>Closed</v-chip
|
|
123
|
-
>
|
|
123
|
+
<StatusChip status="Closed" class="text-capitalize" />
|
|
124
124
|
</div>
|
|
125
125
|
<div v-else>
|
|
126
126
|
<v-btn
|
|
127
127
|
v-if="canManageScheduleTasks"
|
|
128
128
|
variant="outlined"
|
|
129
|
-
|
|
130
|
-
class="text-capitalize px-4 py-2"
|
|
129
|
+
class="text-capitalize screen-btn-ghost"
|
|
131
130
|
@click.stop="() => _acceptAreaChecklist(item._id)"
|
|
132
131
|
>
|
|
133
132
|
Accept
|
|
@@ -146,14 +145,11 @@
|
|
|
146
145
|
</template>
|
|
147
146
|
|
|
148
147
|
<template #item.status="{ value }">
|
|
149
|
-
<
|
|
148
|
+
<StatusChip
|
|
150
149
|
class="text-capitalize"
|
|
151
|
-
:
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
>
|
|
155
|
-
{{ value || "No Status" }}
|
|
156
|
-
</v-chip>
|
|
150
|
+
:status="value"
|
|
151
|
+
:label="value || 'No Status'"
|
|
152
|
+
/>
|
|
157
153
|
</template>
|
|
158
154
|
</TableMain></v-col
|
|
159
155
|
>
|
|
@@ -262,27 +258,6 @@ watchEffect(() => {
|
|
|
262
258
|
}
|
|
263
259
|
});
|
|
264
260
|
|
|
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
261
|
function showMessage(msg: string, color: string = "error") {
|
|
287
262
|
message.value = msg;
|
|
288
263
|
messageColor.value = color;
|
|
@@ -1,26 +1,24 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-dialog v-model="show" max-width="680" persistent>
|
|
3
|
-
<v-card class="
|
|
4
|
-
<v-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
<v-card-text class="pa-4 flex-grow-1" style="overflow-y: auto">
|
|
3
|
+
<v-card class="screen-modal">
|
|
4
|
+
<v-card-title class="d-flex align-center">
|
|
5
|
+
{{
|
|
6
|
+
props.mode === "edit"
|
|
7
|
+
? "Edit Schedule Task"
|
|
8
|
+
: "Create Schedule Task"
|
|
9
|
+
}}
|
|
10
|
+
<v-spacer />
|
|
11
|
+
<v-btn
|
|
12
|
+
icon="mdi-close"
|
|
13
|
+
variant="text"
|
|
14
|
+
class="screen-modal__close"
|
|
15
|
+
aria-label="Close"
|
|
16
|
+
@click="close"
|
|
17
|
+
:disabled="submitting"
|
|
18
|
+
/>
|
|
19
|
+
</v-card-title>
|
|
20
|
+
|
|
21
|
+
<v-card-text class="screen-modal__body">
|
|
24
22
|
<v-form ref="formRef" v-model="valid">
|
|
25
23
|
<v-row dense>
|
|
26
24
|
<v-col cols="12">
|
|
@@ -30,15 +28,15 @@
|
|
|
30
28
|
v-model="subject"
|
|
31
29
|
variant="outlined"
|
|
32
30
|
density="comfortable"
|
|
31
|
+
class="filter-field mb-4"
|
|
33
32
|
placeholder="Enter task title"
|
|
34
33
|
hide-details="auto"
|
|
35
|
-
class="mb-4"
|
|
36
34
|
/>
|
|
37
35
|
</v-col>
|
|
38
36
|
|
|
39
37
|
<v-col cols="12">
|
|
40
38
|
<InputLabel for="date-range" title="Select Dates" required />
|
|
41
|
-
<
|
|
39
|
+
<div class="task-form__panel mb-4">
|
|
42
40
|
<v-date-picker
|
|
43
41
|
v-model="pickerDates"
|
|
44
42
|
multiple
|
|
@@ -49,7 +47,7 @@
|
|
|
49
47
|
class="ma-0"
|
|
50
48
|
/>
|
|
51
49
|
<v-divider class="my-3" />
|
|
52
|
-
<div class="
|
|
50
|
+
<div class="task-form__hint mb-2">
|
|
53
51
|
{{ selectedDates.length }} date(s) selected
|
|
54
52
|
</div>
|
|
55
53
|
<div
|
|
@@ -66,10 +64,10 @@
|
|
|
66
64
|
{{ date }}
|
|
67
65
|
</v-chip>
|
|
68
66
|
</div>
|
|
69
|
-
<div v-else class="
|
|
67
|
+
<div v-else class="task-form__hint">
|
|
70
68
|
No dates selected. Click on the calendar to select dates.
|
|
71
69
|
</div>
|
|
72
|
-
</
|
|
70
|
+
</div>
|
|
73
71
|
</v-col>
|
|
74
72
|
|
|
75
73
|
<v-col cols="12">
|
|
@@ -80,9 +78,9 @@
|
|
|
80
78
|
type="time"
|
|
81
79
|
variant="outlined"
|
|
82
80
|
density="comfortable"
|
|
81
|
+
class="filter-field mb-4"
|
|
83
82
|
hide-details="auto"
|
|
84
83
|
prepend-inner-icon="mdi-clock-outline"
|
|
85
|
-
class="mb-4"
|
|
86
84
|
/>
|
|
87
85
|
</v-col>
|
|
88
86
|
|
|
@@ -98,10 +96,10 @@
|
|
|
98
96
|
multiple
|
|
99
97
|
variant="outlined"
|
|
100
98
|
density="comfortable"
|
|
99
|
+
class="filter-field mb-4"
|
|
101
100
|
:loading="loadingAreas"
|
|
102
101
|
placeholder="Choose one or more areas"
|
|
103
102
|
hide-details="auto"
|
|
104
|
-
class="mb-4"
|
|
105
103
|
chips
|
|
106
104
|
closable-chips
|
|
107
105
|
>
|
|
@@ -116,7 +114,7 @@
|
|
|
116
114
|
</v-chip>
|
|
117
115
|
<span
|
|
118
116
|
v-if="index === 3"
|
|
119
|
-
class="
|
|
117
|
+
class="task-form__hint align-self-center"
|
|
120
118
|
>
|
|
121
119
|
(+{{ selectedAreas.length - 3 }} others)
|
|
122
120
|
</span>
|
|
@@ -215,7 +213,7 @@
|
|
|
215
213
|
</v-chip>
|
|
216
214
|
</div>
|
|
217
215
|
|
|
218
|
-
<span v-else class="
|
|
216
|
+
<span v-else class="task-form__hint">
|
|
219
217
|
No units configured
|
|
220
218
|
</span>
|
|
221
219
|
</v-card-text>
|
|
@@ -233,38 +231,34 @@
|
|
|
233
231
|
v-model="description"
|
|
234
232
|
variant="outlined"
|
|
235
233
|
density="comfortable"
|
|
234
|
+
class="filter-field mb-2"
|
|
236
235
|
rows="4"
|
|
237
236
|
placeholder="Add additional details about this task..."
|
|
238
237
|
hide-details="auto"
|
|
239
|
-
class="mb-2"
|
|
240
238
|
/>
|
|
241
239
|
</v-col>
|
|
242
240
|
</v-row>
|
|
243
241
|
</v-form>
|
|
244
242
|
</v-card-text>
|
|
245
243
|
|
|
246
|
-
<v-
|
|
244
|
+
<v-card-actions class="screen-modal__footer">
|
|
247
245
|
<v-row no-gutters>
|
|
248
|
-
<v-col cols="6" class="
|
|
246
|
+
<v-col cols="6" class="pr-2">
|
|
249
247
|
<v-btn
|
|
250
248
|
block
|
|
251
|
-
variant="
|
|
252
|
-
class="text-none"
|
|
253
|
-
size="large"
|
|
249
|
+
variant="outlined"
|
|
250
|
+
class="text-none screen-btn-ghost"
|
|
254
251
|
@click="close"
|
|
255
|
-
height="48"
|
|
256
252
|
:disabled="submitting"
|
|
257
253
|
>
|
|
258
254
|
Cancel
|
|
259
255
|
</v-btn>
|
|
260
256
|
</v-col>
|
|
261
|
-
<v-col cols="6" class="
|
|
257
|
+
<v-col cols="6" class="pl-2">
|
|
262
258
|
<v-btn
|
|
263
259
|
block
|
|
264
260
|
variant="flat"
|
|
265
|
-
|
|
266
|
-
class="text-none font-weight-bold rounded-0"
|
|
267
|
-
height="48"
|
|
261
|
+
class="text-none screen-btn-primary"
|
|
268
262
|
@click="submitTask"
|
|
269
263
|
:loading="submitting"
|
|
270
264
|
>
|
|
@@ -272,7 +266,7 @@
|
|
|
272
266
|
</v-btn>
|
|
273
267
|
</v-col>
|
|
274
268
|
</v-row>
|
|
275
|
-
</v-
|
|
269
|
+
</v-card-actions>
|
|
276
270
|
</v-card>
|
|
277
271
|
</v-dialog>
|
|
278
272
|
|
|
@@ -568,3 +562,28 @@ watch(
|
|
|
568
562
|
{ immediate: false }
|
|
569
563
|
);
|
|
570
564
|
</script>
|
|
565
|
+
|
|
566
|
+
<style scoped>
|
|
567
|
+
/* Was `<v-sheet border rounded color="grey-lighten-5">` - a fixed light grey
|
|
568
|
+
that stayed light on the dark theme. The design has no calendar panel, so
|
|
569
|
+
this is the estate's own card surface and border, nothing invented. */
|
|
570
|
+
.task-form__panel {
|
|
571
|
+
padding: 16px;
|
|
572
|
+
border: 1px solid var(--border);
|
|
573
|
+
border-radius: var(--r-inner);
|
|
574
|
+
background: var(--card);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
/* Replaces `text-caption text-disabled` / `text-medium-emphasis` / `text-grey`,
|
|
578
|
+
three different Vuetify greys doing the same job.
|
|
579
|
+
|
|
580
|
+
`--text2`, not `--muted`: the design is silent on this hint line, and `--muted`
|
|
581
|
+
at 12px measured 3.24:1 on the light card. That pairing would have been OURS,
|
|
582
|
+
not the design's, so it is fixed here with an existing token rather than
|
|
583
|
+
recorded. `--text2` measures 8.2:1. */
|
|
584
|
+
.task-form__hint {
|
|
585
|
+
font-size: var(--fs-chip-lg);
|
|
586
|
+
font-weight: 600;
|
|
587
|
+
color: var(--text2);
|
|
588
|
+
}
|
|
589
|
+
</style>
|