@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
|
@@ -1,30 +1,40 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-dialog v-model="showDialog" max-width="450">
|
|
3
|
-
<v-card>
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
3
|
+
<v-card class="screen-modal">
|
|
4
|
+
<!-- Was a bare `v-toolbar`, which Vuetify paints from its own `surface` -
|
|
5
|
+
a grey slab across the top of the card, visibly lighter than the card
|
|
6
|
+
on the dark theme - carrying a `text-h6` (20px/500 Roboto) heading.
|
|
7
|
+
The design's modal heading is the `v-card-title` row on the card's own
|
|
8
|
+
surface, and it carries the design's own title size and weight. The
|
|
9
|
+
`header` slot keeps its title/close payload unchanged. -->
|
|
10
|
+
<template v-if="$slots.header">
|
|
11
|
+
<slot
|
|
12
|
+
name="header"
|
|
13
|
+
:title="
|
|
14
|
+
prop.mode === 'edit'
|
|
15
|
+
? `Edit ${prop.entityType}`
|
|
16
|
+
: `Add New ${prop.entityType}`
|
|
17
|
+
"
|
|
18
|
+
:close="close"
|
|
19
|
+
/>
|
|
20
|
+
</template>
|
|
21
|
+
<v-card-title v-else class="d-flex align-center text-capitalize">
|
|
22
|
+
{{
|
|
23
|
+
prop.mode === "edit"
|
|
24
|
+
? `Edit ${prop.entityType}`
|
|
25
|
+
: `Add New ${prop.entityType}`
|
|
26
|
+
}}
|
|
27
|
+
<v-spacer />
|
|
28
|
+
<v-btn
|
|
29
|
+
variant="text"
|
|
30
|
+
icon="mdi-close"
|
|
31
|
+
class="screen-modal__close"
|
|
32
|
+
aria-label="Close"
|
|
33
|
+
@click="close"
|
|
34
|
+
/>
|
|
35
|
+
</v-card-title>
|
|
26
36
|
|
|
27
|
-
<v-card-text class="
|
|
37
|
+
<v-card-text class="screen-modal__body">
|
|
28
38
|
<v-form ref="formRef" v-model="valid">
|
|
29
39
|
<v-row no-gutters class="pa-0">
|
|
30
40
|
<v-col v-if="prop.showType" cols="12" class="pa-0 mb-2">
|
|
@@ -35,7 +45,7 @@
|
|
|
35
45
|
density="comfortable"
|
|
36
46
|
variant="outlined"
|
|
37
47
|
hide-details
|
|
38
|
-
class="w-100 mb-0"
|
|
48
|
+
class="filter-field w-100 mb-0"
|
|
39
49
|
/>
|
|
40
50
|
</v-col>
|
|
41
51
|
|
|
@@ -49,7 +59,7 @@
|
|
|
49
59
|
<v-text-field
|
|
50
60
|
v-model="model"
|
|
51
61
|
:rules="[requiredRule]"
|
|
52
|
-
class="mb-0"
|
|
62
|
+
class="filter-field mb-0"
|
|
53
63
|
/>
|
|
54
64
|
</v-col>
|
|
55
65
|
|
|
@@ -68,18 +78,21 @@
|
|
|
68
78
|
chips
|
|
69
79
|
closable-chips
|
|
70
80
|
placeholder="Select units"
|
|
71
|
-
class="mb-0"
|
|
81
|
+
class="filter-field mb-0"
|
|
72
82
|
/>
|
|
73
83
|
</v-col>
|
|
74
84
|
|
|
75
85
|
<v-col v-if="prop.showOptional" cols="12" class="mb-4">
|
|
76
86
|
<v-row dense justify="center">
|
|
77
87
|
<v-col cols="6" class="pa-0">
|
|
88
|
+
<!-- `color="primary"` on a `v-btn` is the design's FOREGROUND
|
|
89
|
+
token; this is a plain text toggle, so it takes the
|
|
90
|
+
accent's INK form, which the theme test already holds at
|
|
91
|
+
>= 4.5:1 on the card. -->
|
|
78
92
|
<v-btn
|
|
79
93
|
block
|
|
80
|
-
color="primary"
|
|
81
94
|
variant="text"
|
|
82
|
-
class="text-none font-weight-bold"
|
|
95
|
+
class="text-none font-weight-bold area-form-dialog__optional"
|
|
83
96
|
text="Optional"
|
|
84
97
|
@click="show = !show"
|
|
85
98
|
></v-btn>
|
|
@@ -101,6 +114,7 @@
|
|
|
101
114
|
density="comfortable"
|
|
102
115
|
type="number"
|
|
103
116
|
min="1"
|
|
117
|
+
class="filter-field"
|
|
104
118
|
></v-text-field>
|
|
105
119
|
</v-col>
|
|
106
120
|
</v-row>
|
|
@@ -111,36 +125,24 @@
|
|
|
111
125
|
</v-form>
|
|
112
126
|
</v-card-text>
|
|
113
127
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
variant="flat"
|
|
133
|
-
color="black"
|
|
134
|
-
class="text-none font-weight-bold rounded-0"
|
|
135
|
-
height="48"
|
|
136
|
-
:loading="submitting"
|
|
137
|
-
@click="submit"
|
|
138
|
-
>
|
|
139
|
-
{{ prop.mode === "edit" ? "Save" : "Create" }}
|
|
140
|
-
</v-btn>
|
|
141
|
-
</v-col>
|
|
142
|
-
</v-row>
|
|
143
|
-
</v-toolbar>
|
|
128
|
+
<!-- Was a second `v-toolbar` holding two square 48px bars - the primary a
|
|
129
|
+
hardcoded `color="black"`, which is neither theme's accent and reads
|
|
130
|
+
as a hole in the dark modal - with `rounded-0` forcing 0px corners.
|
|
131
|
+
This is the design's shared modal footer: a bordered strip with a
|
|
132
|
+
ghost secondary and the primary beside it, both 40px at 10px. -->
|
|
133
|
+
<div class="screen-modal__footer">
|
|
134
|
+
<v-btn class="text-none screen-btn-ghost" variant="outlined" @click="close">
|
|
135
|
+
Cancel
|
|
136
|
+
</v-btn>
|
|
137
|
+
<v-btn
|
|
138
|
+
class="text-none screen-btn-primary"
|
|
139
|
+
variant="flat"
|
|
140
|
+
:loading="submitting"
|
|
141
|
+
@click="submit"
|
|
142
|
+
>
|
|
143
|
+
{{ prop.mode === "edit" ? "Save" : "Create" }}
|
|
144
|
+
</v-btn>
|
|
145
|
+
</div>
|
|
144
146
|
</v-card>
|
|
145
147
|
</v-dialog>
|
|
146
148
|
</template>
|
|
@@ -268,3 +270,13 @@ async function submit() {
|
|
|
268
270
|
}
|
|
269
271
|
}
|
|
270
272
|
</script>
|
|
273
|
+
|
|
274
|
+
<style scoped>
|
|
275
|
+
/* The "Optional" reveal is plain text, not a filled button, so it takes the
|
|
276
|
+
accent's INK form. `--accent-strong` is the FILL that a white label sits on;
|
|
277
|
+
`--accent-text` is the one `utils/theme.test.ts` holds at >= 4.5:1 against
|
|
278
|
+
the card in both themes. */
|
|
279
|
+
.area-form-dialog__optional {
|
|
280
|
+
color: var(--accent-text);
|
|
281
|
+
}
|
|
282
|
+
</style>
|
package/components/AreaMain.vue
CHANGED
|
@@ -19,23 +19,24 @@
|
|
|
19
19
|
>
|
|
20
20
|
<template #extension>
|
|
21
21
|
<v-row no-gutters class="w-100 d-flex flex-column">
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
<!--
|
|
23
|
+
A bare `v-card` here paints Vuetify's own `surface`, a slab a
|
|
24
|
+
shade off the table card it sits inside. A plain row on the
|
|
25
|
+
card's own background, with the filter on the design's field.
|
|
26
|
+
-->
|
|
27
|
+
<div class="w-100 px-3 d-flex align-center ga-5 py-2">
|
|
27
28
|
<v-select
|
|
28
29
|
v-model="areaTypeFilter"
|
|
29
30
|
:items="typeOptions"
|
|
30
31
|
density="compact"
|
|
31
32
|
hide-details
|
|
32
|
-
class="mx-2"
|
|
33
|
+
class="mx-2 filter-field"
|
|
33
34
|
style="max-width: 160px"
|
|
34
35
|
item-title="title"
|
|
35
36
|
item-value="value"
|
|
36
37
|
label="Type"
|
|
37
38
|
/>
|
|
38
|
-
</
|
|
39
|
+
</div>
|
|
39
40
|
</v-row>
|
|
40
41
|
</template>
|
|
41
42
|
|
|
@@ -49,10 +50,8 @@
|
|
|
49
50
|
<!-- Primary action -->
|
|
50
51
|
<v-btn
|
|
51
52
|
v-if="canCreateArea"
|
|
52
|
-
class="text-none mr-3"
|
|
53
|
-
|
|
54
|
-
variant="tonal"
|
|
55
|
-
size="large"
|
|
53
|
+
class="text-none mr-3 screen-btn-primary"
|
|
54
|
+
variant="flat"
|
|
56
55
|
@click="onCreateItem"
|
|
57
56
|
>
|
|
58
57
|
{{ createLabel }}
|
|
@@ -63,10 +62,8 @@
|
|
|
63
62
|
<template #activator="{ props: t }">
|
|
64
63
|
<v-btn
|
|
65
64
|
v-bind="t"
|
|
66
|
-
class="ma-1"
|
|
67
|
-
variant="
|
|
68
|
-
size="large"
|
|
69
|
-
rounded="pill"
|
|
65
|
+
class="ma-1 screen-icon-btn"
|
|
66
|
+
variant="flat"
|
|
70
67
|
href="/files/area-sample-data.xlsx"
|
|
71
68
|
target="_blank"
|
|
72
69
|
download
|
|
@@ -81,10 +78,8 @@
|
|
|
81
78
|
<template #activator="{ props: t }">
|
|
82
79
|
<v-btn
|
|
83
80
|
v-bind="t"
|
|
84
|
-
class="ma-1"
|
|
85
|
-
variant="
|
|
86
|
-
size="large"
|
|
87
|
-
rounded="pill"
|
|
81
|
+
class="ma-1 screen-icon-btn"
|
|
82
|
+
variant="flat"
|
|
88
83
|
@click="onImportData"
|
|
89
84
|
>
|
|
90
85
|
<v-icon>mdi-upload</v-icon>
|
|
@@ -97,10 +92,8 @@
|
|
|
97
92
|
<template #activator="{ props: t }">
|
|
98
93
|
<v-btn
|
|
99
94
|
v-bind="t"
|
|
100
|
-
class="ma-1"
|
|
101
|
-
variant="
|
|
102
|
-
size="large"
|
|
103
|
-
rounded="pill"
|
|
95
|
+
class="ma-1 screen-icon-btn"
|
|
96
|
+
variant="flat"
|
|
104
97
|
@click="handleDownloadExcel"
|
|
105
98
|
:loading="isDownloading"
|
|
106
99
|
>
|
|
@@ -114,7 +107,7 @@
|
|
|
114
107
|
|
|
115
108
|
<v-spacer />
|
|
116
109
|
|
|
117
|
-
<v-col cols="auto">
|
|
110
|
+
<v-col cols="auto" class="filter-field">
|
|
118
111
|
<v-text-field
|
|
119
112
|
v-model="searchInput"
|
|
120
113
|
density="compact"
|
|
@@ -221,64 +214,50 @@
|
|
|
221
214
|
</HygieneUpdateMoreAction>
|
|
222
215
|
</v-dialog>
|
|
223
216
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
<v-card-text>
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
217
|
+
<!--
|
|
218
|
+
Both dialogs were `v-toolbar` title bars over toolbar footers of two block
|
|
219
|
+
buttons, the confirm one on `color="black"` - not a token, so it painted a
|
|
220
|
+
light-theme fill on the dark theme, and the toolbar surface sat visibly
|
|
221
|
+
lighter than the card. The shared `.screen-modal` shape now, same copy,
|
|
222
|
+
same labels, same handlers, same busy states.
|
|
223
|
+
-->
|
|
224
|
+
<v-dialog v-model="dialogDeleteItem" max-width="520">
|
|
225
|
+
<v-card class="screen-modal">
|
|
226
|
+
<v-card-title class="text-capitalize">
|
|
227
|
+
Delete {{ selectedItem?.name || entityTypeLabel }}
|
|
228
|
+
</v-card-title>
|
|
229
|
+
|
|
230
|
+
<v-card-text class="screen-modal__body">
|
|
231
|
+
Are you sure you want to delete this {{ entityTypeLabel }}?
|
|
237
232
|
</v-card-text>
|
|
238
233
|
|
|
239
|
-
<
|
|
240
|
-
<v-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
variant="flat"
|
|
258
|
-
color="black"
|
|
259
|
-
class="text-none font-weight-bold rounded-0"
|
|
260
|
-
height="48"
|
|
261
|
-
:loading="submitting"
|
|
262
|
-
@click="_deleteItem"
|
|
263
|
-
>
|
|
264
|
-
Delete
|
|
265
|
-
</v-btn>
|
|
266
|
-
</v-col>
|
|
267
|
-
</v-row>
|
|
268
|
-
</v-toolbar>
|
|
234
|
+
<div class="screen-modal__footer">
|
|
235
|
+
<v-btn
|
|
236
|
+
class="screen-btn-ghost"
|
|
237
|
+
variant="outlined"
|
|
238
|
+
:disabled="submitting"
|
|
239
|
+
@click="dialogDeleteItem = false"
|
|
240
|
+
>
|
|
241
|
+
Cancel
|
|
242
|
+
</v-btn>
|
|
243
|
+
<v-btn
|
|
244
|
+
class="screen-btn-primary"
|
|
245
|
+
variant="flat"
|
|
246
|
+
:loading="submitting"
|
|
247
|
+
@click="_deleteItem"
|
|
248
|
+
>
|
|
249
|
+
Delete
|
|
250
|
+
</v-btn>
|
|
251
|
+
</div>
|
|
269
252
|
</v-card>
|
|
270
253
|
</v-dialog>
|
|
271
254
|
|
|
272
|
-
<v-dialog v-if="isToiletLocation" v-model="dialogShowQR" max-width="
|
|
273
|
-
<v-card>
|
|
274
|
-
<v-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
</span>
|
|
279
|
-
</v-row>
|
|
280
|
-
</v-toolbar>
|
|
281
|
-
<v-card-text class="d-flex justify-center pa-6">
|
|
255
|
+
<v-dialog v-if="isToiletLocation" v-model="dialogShowQR" max-width="520">
|
|
256
|
+
<v-card class="screen-modal">
|
|
257
|
+
<v-card-title class="text-capitalize">
|
|
258
|
+
QR Code for {{ selectedItem?.name || "Toilet Location" }}
|
|
259
|
+
</v-card-title>
|
|
260
|
+
<v-card-text class="screen-modal__body d-flex justify-center">
|
|
282
261
|
<v-row no-gutters class="d-flex justify-center">
|
|
283
262
|
<v-col cols="12" class="text-center">
|
|
284
263
|
<div v-if="qrLoading" class="d-flex flex-column align-center">
|
|
@@ -309,36 +288,23 @@
|
|
|
309
288
|
</v-row>
|
|
310
289
|
</v-card-text>
|
|
311
290
|
|
|
312
|
-
<
|
|
313
|
-
<v-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
block
|
|
330
|
-
variant="flat"
|
|
331
|
-
color="black"
|
|
332
|
-
class="text-none font-weight-bold rounded-0"
|
|
333
|
-
height="48"
|
|
334
|
-
:loading="qrLoading"
|
|
335
|
-
@click="onDownloadQrCode"
|
|
336
|
-
>
|
|
337
|
-
Download
|
|
338
|
-
</v-btn>
|
|
339
|
-
</v-col>
|
|
340
|
-
</v-row>
|
|
341
|
-
</v-toolbar>
|
|
291
|
+
<div class="screen-modal__footer">
|
|
292
|
+
<v-btn
|
|
293
|
+
class="screen-btn-ghost"
|
|
294
|
+
variant="outlined"
|
|
295
|
+
@click="dialogShowQR = false"
|
|
296
|
+
>
|
|
297
|
+
Cancel
|
|
298
|
+
</v-btn>
|
|
299
|
+
<v-btn
|
|
300
|
+
class="screen-btn-primary"
|
|
301
|
+
variant="flat"
|
|
302
|
+
:loading="qrLoading"
|
|
303
|
+
@click="onDownloadQrCode"
|
|
304
|
+
>
|
|
305
|
+
Download
|
|
306
|
+
</v-btn>
|
|
307
|
+
</div>
|
|
342
308
|
</v-card>
|
|
343
309
|
</v-dialog>
|
|
344
310
|
|
|
@@ -6,8 +6,10 @@
|
|
|
6
6
|
|
|
7
7
|
<!-- Loading Skeleton -->
|
|
8
8
|
<template v-if="loading && files?.length > 0">
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
<!-- `border="sm black"` painted a literal black hairline on
|
|
10
|
+
both themes; the design's rule is `--border`. -->
|
|
11
|
+
<v-card v-for="(file, index) in files" :key="index" height="50px" flat
|
|
12
|
+
class="att-skeleton mb-2">
|
|
11
13
|
<v-skeleton-loader type="list-item" class="mb-2" />
|
|
12
14
|
</v-card>
|
|
13
15
|
</template>
|
|
@@ -17,7 +19,7 @@
|
|
|
17
19
|
|
|
18
20
|
<!-- Videos -->
|
|
19
21
|
<template v-if="videosArray.length > 0">
|
|
20
|
-
<div v-if="showFileTypeTitle" class="
|
|
22
|
+
<div v-if="showFileTypeTitle" class="att-group mb-1">Videos ({{
|
|
21
23
|
videosArray.length }})</div>
|
|
22
24
|
<v-list density="compact" class="pa-0 rounded-lg border mb-2">
|
|
23
25
|
<template v-for="(item, i) in videosArray" :key="item._id">
|
|
@@ -26,11 +28,11 @@
|
|
|
26
28
|
:subtitle="item.mimeType" class="cursor-pointer"
|
|
27
29
|
@click="openMediaViewer(item._id, item.mimeType)">
|
|
28
30
|
<template #prepend>
|
|
29
|
-
<v-icon :
|
|
31
|
+
<v-icon :class="[getFileIconClass(item.mimeType), 'mr-3']">{{
|
|
30
32
|
getFileIcon(item.mimeType) }}</v-icon>
|
|
31
33
|
</template>
|
|
32
34
|
<template #append>
|
|
33
|
-
<v-icon size="16"
|
|
35
|
+
<v-icon size="16" class="att-icon--muted">mdi-play-circle-outline</v-icon>
|
|
34
36
|
</template>
|
|
35
37
|
</v-list-item>
|
|
36
38
|
</template>
|
|
@@ -39,7 +41,7 @@
|
|
|
39
41
|
|
|
40
42
|
<!-- Photos -->
|
|
41
43
|
<template v-if="photosArray.length > 0">
|
|
42
|
-
<div v-if="showFileTypeTitle" class="
|
|
44
|
+
<div v-if="showFileTypeTitle" class="att-group mb-1"
|
|
43
45
|
:class="{ 'mt-3': videosArray.length > 0 }">
|
|
44
46
|
Photos ({{ photosArray.length }})</div>
|
|
45
47
|
<v-list density="compact" class="pa-0 rounded-lg border mb-2">
|
|
@@ -50,16 +52,16 @@
|
|
|
50
52
|
<v-avatar size="36" rounded="sm" class="mr-3">
|
|
51
53
|
<v-img :src="imageCover(item._id)" cover>
|
|
52
54
|
<template #error>
|
|
53
|
-
<v-icon
|
|
55
|
+
<v-icon size="20" class="att-icon--ok">mdi-image</v-icon>
|
|
54
56
|
</template>
|
|
55
57
|
</v-img>
|
|
56
58
|
</v-avatar>
|
|
57
59
|
</template>
|
|
58
|
-
<v-list-item-title class="
|
|
59
|
-
<v-list-item-subtitle class="
|
|
60
|
+
<v-list-item-title class="att-name">{{ item.file.name }}</v-list-item-title>
|
|
61
|
+
<v-list-item-subtitle class="att-meta">{{ item.mimeType
|
|
60
62
|
}}</v-list-item-subtitle>
|
|
61
63
|
<template #append>
|
|
62
|
-
<v-icon size="16"
|
|
64
|
+
<v-icon size="16" class="att-icon--muted">mdi-eye-outline</v-icon>
|
|
63
65
|
</template>
|
|
64
66
|
</v-list-item>
|
|
65
67
|
</template>
|
|
@@ -68,7 +70,7 @@
|
|
|
68
70
|
|
|
69
71
|
<!-- Documents & Other Files -->
|
|
70
72
|
<template v-if="filesArray.length > 0">
|
|
71
|
-
<div v-if="showFileTypeTitle" class="
|
|
73
|
+
<div v-if="showFileTypeTitle" class="att-group mb-1"
|
|
72
74
|
:class="{ 'mt-3': videosArray.length > 0 || photosArray.length > 0 }">Files ({{
|
|
73
75
|
filesArray.length }})</div>
|
|
74
76
|
<v-list density="compact" class="pa-0 rounded-lg border mb-2">
|
|
@@ -77,14 +79,14 @@
|
|
|
77
79
|
<v-list-item class="cursor-pointer"
|
|
78
80
|
@click="openDocumentViewer(item._id, item.file.name, item.mimeType)">
|
|
79
81
|
<template #prepend>
|
|
80
|
-
<v-icon :
|
|
82
|
+
<v-icon :class="[getFileIconClass(item.mimeType), 'mr-3']">{{
|
|
81
83
|
getFileIcon(item.mimeType) }}</v-icon>
|
|
82
84
|
</template>
|
|
83
|
-
<v-list-item-title class="
|
|
84
|
-
<v-list-item-subtitle class="
|
|
85
|
+
<v-list-item-title class="att-name">{{ item.file.name }}</v-list-item-title>
|
|
86
|
+
<v-list-item-subtitle class="att-meta">{{ item.mimeType
|
|
85
87
|
}}</v-list-item-subtitle>
|
|
86
88
|
<template #append>
|
|
87
|
-
<v-icon size="16"
|
|
89
|
+
<v-icon size="16" class="att-icon--muted">mdi-open-in-new</v-icon>
|
|
88
90
|
</template>
|
|
89
91
|
</v-list-item>
|
|
90
92
|
</template>
|
|
@@ -185,13 +187,20 @@ function getFileIcon(mimeType: string): string {
|
|
|
185
187
|
return 'mdi-file-outline';
|
|
186
188
|
}
|
|
187
189
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
190
|
+
/**
|
|
191
|
+
* Was Vuetify's raw palette names - `red`, `blue`, `green`, `orange`, `purple`,
|
|
192
|
+
* `grey` - which are the same six hexes in both themes and none of them a token.
|
|
193
|
+
* The handoff draws NO file-type icon palette, so this keeps the distinctions
|
|
194
|
+
* the screen already made and states each one in the token that already carries
|
|
195
|
+
* that tone. `purple` has no counterpart at all, so video takes the muted tone
|
|
196
|
+
* with the rest; that one IS a change of meaning and is recorded as such.
|
|
197
|
+
*/
|
|
198
|
+
function getFileIconClass(mimeType: string): string {
|
|
199
|
+
if (mimeType === 'application/pdf') return 'att-icon--err';
|
|
200
|
+
if (mimeType.includes('word') || mimeType.includes('document')) return 'att-icon--info';
|
|
201
|
+
if (mimeType.includes('excel') || mimeType.includes('spreadsheet')) return 'att-icon--ok';
|
|
202
|
+
if (mimeType.includes('powerpoint') || mimeType.includes('presentation')) return 'att-icon--warn';
|
|
203
|
+
return 'att-icon--muted';
|
|
195
204
|
}
|
|
196
205
|
|
|
197
206
|
function getByType(prefix: 'image/' | 'video/' | 'other') {
|
|
@@ -311,3 +320,56 @@ function inferMimeType(ext?: string): string {
|
|
|
311
320
|
return mimeMap[ext] || 'application/octet-stream';
|
|
312
321
|
}
|
|
313
322
|
</script>
|
|
323
|
+
|
|
324
|
+
<style scoped>
|
|
325
|
+
/* The group heading was `text-caption text-medium-emphasis` - Vuetify's 12px
|
|
326
|
+
Roboto at 60% alpha. The design's sub-line is `--muted` at the card's own
|
|
327
|
+
caption size. */
|
|
328
|
+
.att-group {
|
|
329
|
+
font-family: var(--font-sans);
|
|
330
|
+
font-size: 12px;
|
|
331
|
+
font-weight: 700;
|
|
332
|
+
color: var(--muted);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/* Row title and meta were `text-body-2` / `text-caption`, i.e. Roboto again.
|
|
336
|
+
These take the design's cell type, the same pair every converted table row
|
|
337
|
+
uses. */
|
|
338
|
+
.att-name {
|
|
339
|
+
font-family: var(--font-sans);
|
|
340
|
+
font-size: 13.5px;
|
|
341
|
+
font-weight: 600;
|
|
342
|
+
color: var(--text);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
.att-meta {
|
|
346
|
+
font-family: var(--font-sans);
|
|
347
|
+
font-size: 12px;
|
|
348
|
+
color: var(--muted);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
.att-skeleton {
|
|
352
|
+
border: 1px solid var(--border);
|
|
353
|
+
border-radius: var(--r-inner);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
.att-icon--err {
|
|
357
|
+
color: var(--err);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
.att-icon--info {
|
|
361
|
+
color: var(--info);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
.att-icon--ok {
|
|
365
|
+
color: var(--ok);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
.att-icon--warn {
|
|
369
|
+
color: var(--warn);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
.att-icon--muted {
|
|
373
|
+
color: var(--muted);
|
|
374
|
+
}
|
|
375
|
+
</style>
|