@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,159 +1,164 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
HID READER MANAGEMENT - the readers on this site's doors.
|
|
3
|
+
|
|
4
|
+
Was a bespoke screen: an above-card toolbar, a raw `v-table` and about
|
|
5
|
+
twenty-five hardcoded hexes. Those hexes are why this screen had no dark
|
|
6
|
+
theme - `#111827` on the dark card measures **1.06:1**, and `#475467` 2.17:1.
|
|
7
|
+
|
|
8
|
+
It is the design's standard table screen, so it is drawn with the shared one:
|
|
9
|
+
`TableMain` supplies the page heading, the card, the in-card toolbar, the
|
|
10
|
+
uppercase header row, the 49px rows and the pager. Every column, action,
|
|
11
|
+
dialog and handler is the same - the table's own `filteredReaders` still
|
|
12
|
+
feeds it, the overflow menu still opens the same five dialogs.
|
|
13
|
+
|
|
14
|
+
The handoff draws no HID table, so it states no column proportions for it -
|
|
15
|
+
the table takes the shared automatic layout every other `TableMain` caller
|
|
16
|
+
uses, and scrolls inside the card at 360/768 the way the other wide tables
|
|
17
|
+
do. See `readerHeaders` for why the screen's own fixed percentages were
|
|
18
|
+
measured and dropped rather than carried over.
|
|
19
|
+
-->
|
|
1
20
|
<template>
|
|
2
21
|
<section class="hid-reader-management">
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
class="
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
<
|
|
71
|
-
<
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
<v-list-item title="View" @click="openView(reader)" />
|
|
90
|
-
<v-list-item title="Sync HID Reader" @click="openSyncConfirm(reader)" />
|
|
91
|
-
<v-list-item title="Test Connection" @click="openTestConfirm(reader)" />
|
|
92
|
-
<v-list-item title="Edit" @click="openEdit(reader)" />
|
|
93
|
-
<v-list-item title="Delete" class="text-error" @click="openDeleteConfirm(reader)" />
|
|
94
|
-
</v-list>
|
|
95
|
-
</v-menu>
|
|
96
|
-
</td>
|
|
97
|
-
</tr>
|
|
98
|
-
</tbody>
|
|
99
|
-
</v-table>
|
|
100
|
-
|
|
101
|
-
<div v-if="!filteredReaders.length" class="empty-state">
|
|
102
|
-
No HID devices added yet.
|
|
103
|
-
</div>
|
|
104
|
-
</v-card>
|
|
22
|
+
<TableMain
|
|
23
|
+
title="HID Readers"
|
|
24
|
+
:headers="readerHeaders"
|
|
25
|
+
:items="filteredReaders"
|
|
26
|
+
:loading="loading"
|
|
27
|
+
:items-per-page="-1"
|
|
28
|
+
:page-range="readerRange"
|
|
29
|
+
show-header
|
|
30
|
+
@refresh="loadReaders"
|
|
31
|
+
>
|
|
32
|
+
<template #actions>
|
|
33
|
+
<AppButton icon="mdi-plus" @click="openAdd">Add HID Reader</AppButton>
|
|
34
|
+
</template>
|
|
35
|
+
|
|
36
|
+
<!-- The design puts filters on their own full-width row under the
|
|
37
|
+
toolbar, which is what `extension` is. -->
|
|
38
|
+
<template #extension>
|
|
39
|
+
<div class="app-filter-row hid-reader-filters">
|
|
40
|
+
<AppField v-model="search" search placeholder="Search" />
|
|
41
|
+
<AppSelect
|
|
42
|
+
v-model="status"
|
|
43
|
+
:items="statusOptions"
|
|
44
|
+
placeholder="Status"
|
|
45
|
+
clearable
|
|
46
|
+
/>
|
|
47
|
+
</div>
|
|
48
|
+
</template>
|
|
49
|
+
|
|
50
|
+
<template #[`item.name`]="{ item }">
|
|
51
|
+
<span class="app-cell--strong">{{ item.name || "N/A" }}</span>
|
|
52
|
+
</template>
|
|
53
|
+
|
|
54
|
+
<template #[`item.location`]="{ item }">
|
|
55
|
+
<span class="app-cell--muted">{{ item.location || "N/A" }}</span>
|
|
56
|
+
</template>
|
|
57
|
+
|
|
58
|
+
<template #[`item.deviceId`]="{ item }">
|
|
59
|
+
<span class="app-cell--muted">{{ item.deviceId || "N/A" }}</span>
|
|
60
|
+
</template>
|
|
61
|
+
|
|
62
|
+
<!-- The shared chip, so "Active" is the same green here as on a work
|
|
63
|
+
order. `utils/status.ts` is the mapping; this screen's own
|
|
64
|
+
`getStatusClass` was a fourth private copy of it. -->
|
|
65
|
+
<template #[`item.status`]="{ item }">
|
|
66
|
+
<StatusChip
|
|
67
|
+
:status="resolveReaderStatus(item)"
|
|
68
|
+
:label="formatReaderStatus(resolveReaderStatus(item))"
|
|
69
|
+
/>
|
|
70
|
+
</template>
|
|
71
|
+
|
|
72
|
+
<template #[`item.lastSyncAt`]="{ item }">
|
|
73
|
+
<span class="app-cell--num">{{ formatDate(item.lastSyncAt) }}</span>
|
|
74
|
+
</template>
|
|
75
|
+
|
|
76
|
+
<template #[`item.lastSyncMessage`]="{ item }">
|
|
77
|
+
<span class="app-cell--muted" :title="item.lastSyncMessage || 'N/A'">
|
|
78
|
+
{{ item.lastSyncMessage || "N/A" }}
|
|
79
|
+
</span>
|
|
80
|
+
</template>
|
|
81
|
+
|
|
82
|
+
<template #[`item.action-table`]="{ item }">
|
|
83
|
+
<v-menu>
|
|
84
|
+
<template #activator="{ props: menuProps }">
|
|
85
|
+
<AppButton v-bind="menuProps" variant="row" icon="mdi-dots-vertical" />
|
|
86
|
+
</template>
|
|
87
|
+
|
|
88
|
+
<v-list density="compact" min-width="180">
|
|
89
|
+
<v-list-item title="View" @click="openView(item)" />
|
|
90
|
+
<v-list-item title="Sync HID Reader" @click="openSyncConfirm(item)" />
|
|
91
|
+
<v-list-item title="Test Connection" @click="openTestConfirm(item)" />
|
|
92
|
+
<v-list-item title="Edit" @click="openEdit(item)" />
|
|
93
|
+
<v-list-item title="Delete" class="text-error" @click="openDeleteConfirm(item)" />
|
|
94
|
+
</v-list>
|
|
95
|
+
</v-menu>
|
|
96
|
+
</template>
|
|
97
|
+
|
|
98
|
+
<!-- The screen's own sentence, kept: the shared empty state says "No data
|
|
99
|
+
available", which is less useful on a screen whose whole point is
|
|
100
|
+
that no device has been added yet. -->
|
|
101
|
+
<template #no-data>
|
|
102
|
+
<div class="table-card__empty">
|
|
103
|
+
<v-icon icon="mdi-card-account-details-outline" size="32" />
|
|
104
|
+
<span>No HID devices added yet.</span>
|
|
105
|
+
</div>
|
|
106
|
+
</template>
|
|
107
|
+
</TableMain>
|
|
105
108
|
|
|
106
109
|
<HidReaderForm
|
|
107
110
|
v-model="formDialog"
|
|
108
111
|
:mode="selectedReader ? 'edit' : 'add'"
|
|
109
112
|
:reader="selectedReader"
|
|
110
113
|
:loading="saving"
|
|
114
|
+
:site="site"
|
|
111
115
|
@submit="saveReader"
|
|
112
116
|
/>
|
|
113
117
|
|
|
114
118
|
<v-dialog v-model="viewDialog" max-width="390">
|
|
115
119
|
<v-card rounded="lg">
|
|
116
|
-
<v-card-title class="
|
|
120
|
+
<v-card-title class="screen-card-title">{{ selectedReader?.name || "HID Reader" }}</v-card-title>
|
|
117
121
|
<v-card-text>
|
|
118
122
|
<div class="detail-grid">
|
|
119
123
|
<span>HID reader name</span><strong>{{ selectedReader?.name || "N/A" }}</strong>
|
|
120
124
|
<span>Device ID</span><strong>{{ selectedReader?.deviceId || "N/A" }}</strong>
|
|
121
125
|
<span>Location</span><strong>{{ selectedReader?.location || "N/A" }}</strong>
|
|
126
|
+
<span>HID Portal</span><strong>{{ selectedReader?.portalName || selectedReader?.portalId || "N/A" }}</strong>
|
|
122
127
|
<span>Monitor Path</span><strong>{{ selectedReader?.monitorPath || "N/A" }}</strong>
|
|
123
128
|
<span>Status</span><strong>{{ formatReaderStatus(resolveReaderStatus(selectedReader)) }}</strong>
|
|
124
129
|
<span>Username</span><strong>{{ selectedReader?.username || "N/A" }}</strong>
|
|
125
130
|
</div>
|
|
126
131
|
|
|
127
132
|
<div class="dialog-actions-inline">
|
|
128
|
-
<
|
|
129
|
-
<
|
|
133
|
+
<AppButton variant="ghost" @click="openTestConfirm(selectedReader)">Test Connection</AppButton>
|
|
134
|
+
<AppButton variant="ghost" @click="openSyncConfirm(selectedReader)">Sync Reader</AppButton>
|
|
130
135
|
</div>
|
|
131
136
|
</v-card-text>
|
|
132
137
|
<v-card-actions>
|
|
133
138
|
<v-spacer />
|
|
134
|
-
<
|
|
139
|
+
<AppButton variant="ghost" @click="viewDialog = false">Close</AppButton>
|
|
135
140
|
</v-card-actions>
|
|
136
141
|
</v-card>
|
|
137
142
|
</v-dialog>
|
|
138
143
|
|
|
139
144
|
<v-dialog v-model="confirmDialog" max-width="390" persistent>
|
|
140
145
|
<v-card rounded="lg" class="reader-action-dialog">
|
|
141
|
-
<v-card-title class="
|
|
146
|
+
<v-card-title class="screen-card-title">{{ confirmTitle }}</v-card-title>
|
|
142
147
|
|
|
143
148
|
<v-card-text v-if="pendingAction === 'test'" class="reader-action-content">
|
|
144
|
-
<v-icon icon="mdi-database-sync-outline"
|
|
149
|
+
<v-icon icon="mdi-database-sync-outline" class="dialog-mark" size="48" />
|
|
145
150
|
<h3>Test Device Connection</h3>
|
|
146
151
|
<p>You are about to test the connection for {{ selectedReader?.name || "this HID Reader" }}.</p>
|
|
147
152
|
</v-card-text>
|
|
148
153
|
|
|
149
154
|
<v-card-text v-else-if="pendingAction === 'sync' && actionStage === 'confirm'" class="reader-action-content">
|
|
150
|
-
<v-icon icon="mdi-database-sync-outline"
|
|
155
|
+
<v-icon icon="mdi-database-sync-outline" class="dialog-mark" size="48" />
|
|
151
156
|
<h3>Sync Data</h3>
|
|
152
157
|
<p>You're about to sync data with {{ selectedReader?.name || "this HID Reader" }}.</p>
|
|
153
158
|
</v-card-text>
|
|
154
159
|
|
|
155
160
|
<v-card-text v-else-if="pendingAction === 'sync' && actionStage === 'review'" class="reader-action-content reader-sync-review">
|
|
156
|
-
<v-icon icon="mdi-database-sync-outline"
|
|
161
|
+
<v-icon icon="mdi-database-sync-outline" class="dialog-mark" size="48" />
|
|
157
162
|
<h3>Ready to Synchronize</h3>
|
|
158
163
|
<div class="sync-summary-list">
|
|
159
164
|
<div>
|
|
@@ -181,7 +186,7 @@
|
|
|
181
186
|
</v-card-text>
|
|
182
187
|
|
|
183
188
|
<v-card-text v-else-if="pendingAction === 'sync' && actionStage === 'loading'" class="reader-action-content">
|
|
184
|
-
<v-progress-circular indeterminate
|
|
189
|
+
<v-progress-circular indeterminate class="dialog-spinner" size="42" width="5" />
|
|
185
190
|
<h3>Sync Data to {{ selectedReader?.name || "HID Reader" }}...</h3>
|
|
186
191
|
</v-card-text>
|
|
187
192
|
|
|
@@ -207,7 +212,7 @@
|
|
|
207
212
|
|
|
208
213
|
<v-dialog v-model="resultDialog" max-width="390">
|
|
209
214
|
<v-card rounded="lg">
|
|
210
|
-
<v-card-title v-if="resultReaderName" class="
|
|
215
|
+
<v-card-title v-if="resultReaderName" class="screen-card-title">{{ resultReaderName }}</v-card-title>
|
|
211
216
|
<v-card-text class="result-content" :class="{ 'result-with-stats': resultStats }">
|
|
212
217
|
<v-icon :icon="resultSuccess ? 'mdi-check-circle' : 'mdi-alert-circle'" :color="resultSuccess ? 'success' : 'warning'" size="42" />
|
|
213
218
|
<h3>{{ resultTitle }}</h3>
|
|
@@ -257,7 +262,7 @@ const {
|
|
|
257
262
|
|
|
258
263
|
const readers = ref<Record<string, any>[]>([]);
|
|
259
264
|
const search = ref("");
|
|
260
|
-
const status = ref("
|
|
265
|
+
const status = ref("");
|
|
261
266
|
const loading = ref(false);
|
|
262
267
|
const saving = ref(false);
|
|
263
268
|
const actionLoading = ref(false);
|
|
@@ -281,7 +286,42 @@ const syncPreviewStats = ref({
|
|
|
281
286
|
});
|
|
282
287
|
const resultStats = ref<typeof syncPreviewStats.value | null>(null);
|
|
283
288
|
|
|
284
|
-
const statusOptions = [
|
|
289
|
+
const statusOptions = [
|
|
290
|
+
{ title: "Active", value: "active" },
|
|
291
|
+
{ title: "Inactive", value: "inactive" },
|
|
292
|
+
{ title: "Offline", value: "offline" },
|
|
293
|
+
];
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* The columns. NO `weight`, on purpose.
|
|
297
|
+
*
|
|
298
|
+
* The old CSS pinned them at 19/14/15/12/15/20/5 % with `table-layout: fixed`,
|
|
299
|
+
* and `TableMain`'s `weight` would say exactly that - but it was measured and
|
|
300
|
+
* it is worse than the automatic layout, in two ways the design cares about:
|
|
301
|
+
*
|
|
302
|
+
* * at 360 the six percentages resolve against a ~330px card, so every cell
|
|
303
|
+
* truncates to "Mai...", the headers overlap and the status chip is cut in
|
|
304
|
+
* half. The old fixed grid only worked because it also carried
|
|
305
|
+
* `min-width: 920px`, which is the automatic layout's behaviour anyway.
|
|
306
|
+
* * a 5% action column is ~29px of content once the shared 20px cell padding
|
|
307
|
+
* is taken out, so the 30px row button overflows by half a pixel and the
|
|
308
|
+
* fixed-layout ellipsis rule paints a "..." beside every button.
|
|
309
|
+
*
|
|
310
|
+
* The handoff states `fr` proportions for the tables it draws (Feedbacks,
|
|
311
|
+
* Units, Pass & Key) and draws no HID table at all, so there is no design
|
|
312
|
+
* number to honour here. Automatic is what the other 39 `TableMain` callers
|
|
313
|
+
* use. `sortable: false` keeps the previous behaviour: the raw `v-table` never
|
|
314
|
+
* sorted.
|
|
315
|
+
*/
|
|
316
|
+
const readerHeaders = [
|
|
317
|
+
{ title: "Name", value: "name", sortable: false },
|
|
318
|
+
{ title: "Location", value: "location", sortable: false },
|
|
319
|
+
{ title: "Device ID", value: "deviceId", sortable: false },
|
|
320
|
+
{ title: "Status", value: "status", sortable: false },
|
|
321
|
+
{ title: "Last sync at", value: "lastSyncAt", sortable: false },
|
|
322
|
+
{ title: "Last sync message", value: "lastSyncMessage", sortable: false },
|
|
323
|
+
{ title: "", value: "action-table", sortable: false },
|
|
324
|
+
];
|
|
285
325
|
|
|
286
326
|
const filteredReaders = computed(() => {
|
|
287
327
|
const query = search.value.trim().toLowerCase();
|
|
@@ -294,12 +334,21 @@ const filteredReaders = computed(() => {
|
|
|
294
334
|
resolveReaderStatus(reader),
|
|
295
335
|
].some((value) => String(value ?? "").toLowerCase().includes(query));
|
|
296
336
|
|
|
297
|
-
const matchesStatus = status.value
|
|
337
|
+
const matchesStatus = !status.value || resolveReaderStatus(reader) === status.value;
|
|
298
338
|
|
|
299
339
|
return matchesSearch && matchesStatus;
|
|
300
340
|
});
|
|
301
341
|
});
|
|
302
342
|
|
|
343
|
+
/**
|
|
344
|
+
* The design's `1-6 of 6` count on the toolbar row. This screen loads every
|
|
345
|
+
* reader in one call and has never paged, so the range is simply what is on
|
|
346
|
+
* screen - stated rather than left as `TableMain`'s `-- - -- of --` placeholder.
|
|
347
|
+
*/
|
|
348
|
+
const readerRange = computed(() =>
|
|
349
|
+
filteredReaders.value.length ? `1 - ${filteredReaders.value.length} of ${filteredReaders.value.length}` : "0 of 0"
|
|
350
|
+
);
|
|
351
|
+
|
|
303
352
|
const confirmTitle = computed(() => {
|
|
304
353
|
if (pendingAction.value === "sync" && actionStage.value === "loading") return "Test Connection...";
|
|
305
354
|
if (pendingAction.value === "sync") return "Sync Data";
|
|
@@ -915,13 +964,6 @@ function formatDate(value?: string) {
|
|
|
915
964
|
return Number.isNaN(date.getTime()) ? "N/A" : date.toLocaleString();
|
|
916
965
|
}
|
|
917
966
|
|
|
918
|
-
function getStatusClass(value?: string) {
|
|
919
|
-
if (value === "active") return "status-success";
|
|
920
|
-
if (value === "inactive") return "status-warning";
|
|
921
|
-
if (value === "deleted") return "status-error";
|
|
922
|
-
return "status-muted";
|
|
923
|
-
}
|
|
924
|
-
|
|
925
967
|
function resolveReaderStatus(reader?: Record<string, any> | null) {
|
|
926
968
|
if (!reader) return "";
|
|
927
969
|
if (reader.lastSyncStatus === "failed" && reader.status === "active") return "offline";
|
|
@@ -942,208 +984,49 @@ function formatReaderStatus(value?: string) {
|
|
|
942
984
|
}
|
|
943
985
|
</script>
|
|
944
986
|
|
|
987
|
+
|
|
945
988
|
<style scoped>
|
|
989
|
+
/*
|
|
990
|
+
WHAT IS LEFT AFTER THE CARD AND TABLE MOVED TO `TableMain`.
|
|
991
|
+
|
|
992
|
+
The toolbar, the card, the `reader-table` grid, the seven column widths, the
|
|
993
|
+
header band, the row height, the hover, the empty state and the four
|
|
994
|
+
`status-*` chip palettes are all gone - they were a private copy of the shared
|
|
995
|
+
table, drawn in about twenty-five literal hexes. What remains is the two
|
|
996
|
+
dialogs, and every colour in them is now a token, so the dark theme reaches
|
|
997
|
+
them for the first time.
|
|
998
|
+
*/
|
|
946
999
|
.hid-reader-management {
|
|
947
1000
|
padding: 24px 0;
|
|
948
1001
|
width: 100%;
|
|
949
1002
|
min-width: 0;
|
|
950
1003
|
}
|
|
951
1004
|
|
|
952
|
-
.
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
margin-bottom: 16px;
|
|
958
|
-
}
|
|
959
|
-
|
|
960
|
-
.toolbar-spacer {
|
|
961
|
-
flex: 1;
|
|
962
|
-
}
|
|
963
|
-
|
|
964
|
-
.add-button {
|
|
965
|
-
min-width: 170px;
|
|
966
|
-
background: #e4e4e4;
|
|
967
|
-
color: #0a2638;
|
|
1005
|
+
.hid-reader-filters {
|
|
1006
|
+
/* The filter row sits INSIDE the card's extension, so it needs the card's
|
|
1007
|
+
own side padding rather than the row's default bottom margin. */
|
|
1008
|
+
margin: 0;
|
|
1009
|
+
padding: 10px 14px;
|
|
968
1010
|
}
|
|
969
1011
|
|
|
970
|
-
.
|
|
1012
|
+
.hid-reader-filters :deep(.app-field) {
|
|
971
1013
|
max-width: 240px;
|
|
972
1014
|
}
|
|
973
1015
|
|
|
974
|
-
.
|
|
1016
|
+
.hid-reader-filters :deep(.app-select) {
|
|
975
1017
|
max-width: 160px;
|
|
976
1018
|
}
|
|
977
1019
|
|
|
978
|
-
.table-card {
|
|
979
|
-
min-height: 430px;
|
|
980
|
-
overflow-x: auto;
|
|
981
|
-
overflow-y: hidden;
|
|
982
|
-
}
|
|
983
|
-
|
|
984
|
-
.reader-table :deep(table) {
|
|
985
|
-
table-layout: fixed;
|
|
986
|
-
width: 100%;
|
|
987
|
-
min-width: 920px;
|
|
988
|
-
border-collapse: separate;
|
|
989
|
-
border-spacing: 0;
|
|
990
|
-
}
|
|
991
|
-
|
|
992
|
-
.reader-table :deep(th) {
|
|
993
|
-
height: 44px;
|
|
994
|
-
background: #f8fafc;
|
|
995
|
-
color: #344054;
|
|
996
|
-
font-size: 12px;
|
|
997
|
-
font-weight: 700;
|
|
998
|
-
letter-spacing: 0;
|
|
999
|
-
text-transform: none;
|
|
1000
|
-
border-bottom: 1px solid #e7ebef;
|
|
1001
|
-
}
|
|
1002
|
-
|
|
1003
|
-
.reader-table :deep(td) {
|
|
1004
|
-
height: 64px;
|
|
1005
|
-
color: #1f2937;
|
|
1006
|
-
font-size: 13px;
|
|
1007
|
-
border-bottom: 1px solid #edf0f3;
|
|
1008
|
-
vertical-align: middle;
|
|
1009
|
-
}
|
|
1010
|
-
|
|
1011
|
-
.reader-table :deep(tbody tr) {
|
|
1012
|
-
transition: background-color 0.15s ease;
|
|
1013
|
-
}
|
|
1014
|
-
|
|
1015
|
-
.reader-table :deep(tbody tr:hover) {
|
|
1016
|
-
background: #fbfcfe;
|
|
1017
|
-
}
|
|
1018
|
-
|
|
1019
|
-
.reader-table :deep(th),
|
|
1020
|
-
.reader-table :deep(td) {
|
|
1021
|
-
padding: 0 14px !important;
|
|
1022
|
-
white-space: nowrap;
|
|
1023
|
-
}
|
|
1024
|
-
|
|
1025
|
-
.name-column,
|
|
1026
|
-
.name-cell {
|
|
1027
|
-
width: 19%;
|
|
1028
|
-
}
|
|
1029
|
-
|
|
1030
|
-
.location-column,
|
|
1031
|
-
.location-cell {
|
|
1032
|
-
width: 14%;
|
|
1033
|
-
}
|
|
1034
|
-
|
|
1035
|
-
.device-column,
|
|
1036
|
-
.device-cell {
|
|
1037
|
-
width: 15%;
|
|
1038
|
-
}
|
|
1039
|
-
|
|
1040
|
-
.status-column,
|
|
1041
|
-
.status-cell {
|
|
1042
|
-
width: 12%;
|
|
1043
|
-
}
|
|
1044
|
-
|
|
1045
|
-
.sync-at-column,
|
|
1046
|
-
.sync-at-cell {
|
|
1047
|
-
width: 15%;
|
|
1048
|
-
}
|
|
1049
|
-
|
|
1050
|
-
.message-column,
|
|
1051
|
-
.message-cell {
|
|
1052
|
-
width: 20%;
|
|
1053
|
-
min-width: 0;
|
|
1054
|
-
}
|
|
1055
|
-
|
|
1056
|
-
.action-column,
|
|
1057
|
-
.action-cell {
|
|
1058
|
-
width: 5%;
|
|
1059
|
-
text-align: right;
|
|
1060
|
-
}
|
|
1061
|
-
|
|
1062
|
-
.cell-strong {
|
|
1063
|
-
display: block;
|
|
1064
|
-
overflow: hidden;
|
|
1065
|
-
color: #111827;
|
|
1066
|
-
font-weight: 600;
|
|
1067
|
-
text-overflow: ellipsis;
|
|
1068
|
-
}
|
|
1069
|
-
|
|
1070
|
-
.location-cell,
|
|
1071
|
-
.device-cell,
|
|
1072
|
-
.sync-at-cell {
|
|
1073
|
-
overflow: hidden;
|
|
1074
|
-
color: #475467;
|
|
1075
|
-
text-overflow: ellipsis;
|
|
1076
|
-
}
|
|
1077
|
-
|
|
1078
|
-
.message-text {
|
|
1079
|
-
display: block;
|
|
1080
|
-
max-width: 100%;
|
|
1081
|
-
overflow: hidden;
|
|
1082
|
-
color: #475467;
|
|
1083
|
-
line-height: 1.35;
|
|
1084
|
-
text-overflow: ellipsis;
|
|
1085
|
-
}
|
|
1086
|
-
|
|
1087
|
-
.action-menu-button {
|
|
1088
|
-
color: #344054;
|
|
1089
|
-
}
|
|
1090
|
-
|
|
1091
|
-
.table-refresh {
|
|
1092
|
-
display: flex;
|
|
1093
|
-
justify-content: flex-start;
|
|
1094
|
-
padding: 10px 14px;
|
|
1095
|
-
border-bottom: 1px solid #e7ebef;
|
|
1096
|
-
background: #ffffff;
|
|
1097
|
-
}
|
|
1098
|
-
|
|
1099
|
-
.empty-state {
|
|
1100
|
-
min-height: 280px;
|
|
1101
|
-
display: grid;
|
|
1102
|
-
place-items: center;
|
|
1103
|
-
color: #687382;
|
|
1104
|
-
font-size: 13px;
|
|
1105
|
-
}
|
|
1106
|
-
|
|
1107
|
-
.status-chip {
|
|
1108
|
-
min-width: 86px;
|
|
1109
|
-
justify-content: center;
|
|
1110
|
-
font-weight: 600;
|
|
1111
|
-
}
|
|
1112
|
-
|
|
1113
|
-
.status-success {
|
|
1114
|
-
background: #dff7e7 !important;
|
|
1115
|
-
color: #1b7f3a !important;
|
|
1116
|
-
}
|
|
1117
|
-
|
|
1118
|
-
.status-warning {
|
|
1119
|
-
background: #fff0cc !important;
|
|
1120
|
-
color: #9a6700 !important;
|
|
1121
|
-
}
|
|
1122
|
-
|
|
1123
|
-
.status-error {
|
|
1124
|
-
background: #fde2e1 !important;
|
|
1125
|
-
color: #b42318 !important;
|
|
1126
|
-
}
|
|
1127
|
-
|
|
1128
|
-
.status-muted {
|
|
1129
|
-
background: #e9edf2 !important;
|
|
1130
|
-
color: #475467 !important;
|
|
1131
|
-
}
|
|
1132
|
-
|
|
1133
|
-
.small-title {
|
|
1134
|
-
font-size: 14px;
|
|
1135
|
-
font-weight: 700;
|
|
1136
|
-
}
|
|
1137
|
-
|
|
1138
1020
|
.detail-grid {
|
|
1139
1021
|
display: grid;
|
|
1140
1022
|
grid-template-columns: 1fr 1fr;
|
|
1141
1023
|
gap: 8px 16px;
|
|
1142
1024
|
font-size: 13px;
|
|
1025
|
+
color: var(--text);
|
|
1143
1026
|
}
|
|
1144
1027
|
|
|
1145
1028
|
.detail-grid span {
|
|
1146
|
-
color:
|
|
1029
|
+
color: var(--muted);
|
|
1147
1030
|
}
|
|
1148
1031
|
|
|
1149
1032
|
.dialog-actions-inline {
|
|
@@ -1168,7 +1051,7 @@ function formatReaderStatus(value?: string) {
|
|
|
1168
1051
|
|
|
1169
1052
|
.reader-action-content h3 {
|
|
1170
1053
|
margin: 4px 0 0;
|
|
1171
|
-
color:
|
|
1054
|
+
color: var(--text);
|
|
1172
1055
|
font-size: 15px;
|
|
1173
1056
|
font-weight: 700;
|
|
1174
1057
|
line-height: 1.3;
|
|
@@ -1176,11 +1059,21 @@ function formatReaderStatus(value?: string) {
|
|
|
1176
1059
|
|
|
1177
1060
|
.reader-action-content p {
|
|
1178
1061
|
margin: 0;
|
|
1179
|
-
color:
|
|
1062
|
+
color: var(--muted);
|
|
1180
1063
|
font-size: 13px;
|
|
1181
1064
|
line-height: 1.45;
|
|
1182
1065
|
}
|
|
1183
1066
|
|
|
1067
|
+
/* Was `color="#1976d2"` and `color="#8a8f98"` on the elements themselves - the
|
|
1068
|
+
same blue and the same grey on both themes. */
|
|
1069
|
+
.dialog-mark {
|
|
1070
|
+
color: var(--accent);
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
.dialog-spinner {
|
|
1074
|
+
color: var(--muted);
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1184
1077
|
.reader-sync-review {
|
|
1185
1078
|
justify-items: stretch;
|
|
1186
1079
|
text-align: left;
|
|
@@ -1204,24 +1097,32 @@ function formatReaderStatus(value?: string) {
|
|
|
1204
1097
|
align-items: center;
|
|
1205
1098
|
justify-content: space-between;
|
|
1206
1099
|
gap: 16px;
|
|
1207
|
-
color:
|
|
1100
|
+
color: var(--muted);
|
|
1208
1101
|
font-size: 13px;
|
|
1209
1102
|
}
|
|
1210
1103
|
|
|
1211
1104
|
.sync-summary-list strong {
|
|
1212
|
-
color:
|
|
1105
|
+
color: var(--text);
|
|
1213
1106
|
font-weight: 700;
|
|
1214
1107
|
}
|
|
1215
1108
|
|
|
1109
|
+
/* The split footer bar. The handoff does not draw one, so the SHAPE is the
|
|
1110
|
+
screen's own; only the colours change - `#062d42` was a fixed navy that sat
|
|
1111
|
+
on the dark card unchanged. */
|
|
1216
1112
|
.action-cancel,
|
|
1217
1113
|
.action-submit {
|
|
1218
1114
|
flex: 1;
|
|
1219
1115
|
border-radius: 0;
|
|
1220
1116
|
}
|
|
1221
1117
|
|
|
1118
|
+
.action-cancel {
|
|
1119
|
+
background: var(--card);
|
|
1120
|
+
color: var(--text2);
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1222
1123
|
.action-submit {
|
|
1223
|
-
background:
|
|
1224
|
-
color:
|
|
1124
|
+
background: var(--accent-strong);
|
|
1125
|
+
color: var(--on-accent-strong);
|
|
1225
1126
|
}
|
|
1226
1127
|
|
|
1227
1128
|
.result-content {
|
|
@@ -1245,24 +1146,11 @@ function formatReaderStatus(value?: string) {
|
|
|
1245
1146
|
}
|
|
1246
1147
|
|
|
1247
1148
|
@media (max-width: 960px) {
|
|
1248
|
-
.
|
|
1249
|
-
|
|
1250
|
-
}
|
|
1251
|
-
|
|
1252
|
-
.toolbar-spacer {
|
|
1253
|
-
display: none;
|
|
1254
|
-
}
|
|
1255
|
-
|
|
1256
|
-
.add-button,
|
|
1257
|
-
.search-input,
|
|
1258
|
-
.status-input {
|
|
1149
|
+
.hid-reader-filters :deep(.app-field),
|
|
1150
|
+
.hid-reader-filters :deep(.app-select) {
|
|
1259
1151
|
max-width: none;
|
|
1260
1152
|
width: 100%;
|
|
1261
1153
|
}
|
|
1262
|
-
|
|
1263
|
-
.table-card {
|
|
1264
|
-
min-height: 360px;
|
|
1265
|
-
}
|
|
1266
1154
|
}
|
|
1267
1155
|
|
|
1268
1156
|
@media (max-width: 600px) {
|
|
@@ -1274,7 +1162,7 @@ function formatReaderStatus(value?: string) {
|
|
|
1274
1162
|
grid-template-columns: 1fr;
|
|
1275
1163
|
}
|
|
1276
1164
|
|
|
1277
|
-
.dialog-actions-inline .
|
|
1165
|
+
.dialog-actions-inline .app-btn {
|
|
1278
1166
|
width: 100%;
|
|
1279
1167
|
}
|
|
1280
1168
|
|