@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,32 +1,32 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<v-card width="100%">
|
|
3
|
-
<!--
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
<!-- Submission metadata bar (readonly only) -->
|
|
2
|
+
<v-card class="screen-modal" width="100%">
|
|
3
|
+
<!-- The title row was a `grey-darken-3` v-toolbar with white uppercase
|
|
4
|
+
text: the same hardcoded dark slab on both themes. A `v-card-title` on
|
|
5
|
+
`.screen-modal` is the same row on the card's own surface, so it
|
|
6
|
+
follows the theme - and the actions slot keeps its place on the right. -->
|
|
7
|
+
<v-card-title class="d-flex align-center ga-2">
|
|
8
|
+
<span class="flex-grow-1">{{ definition.title }}</span>
|
|
9
|
+
<slot name="title-actions" />
|
|
10
|
+
</v-card-title>
|
|
11
|
+
|
|
12
|
+
<!-- Submission metadata bar (readonly only). Shown for an actual
|
|
13
|
+
submission (submissionStatus) OR a pure template preview that
|
|
14
|
+
requires payment — a preview has no submission yet, but should
|
|
15
|
+
still tell the admin the form carries a fee. -->
|
|
18
16
|
<div
|
|
19
|
-
v-if="readonly && (submissionStatus)"
|
|
20
|
-
class="px-6 py-2 d-flex align-center ga-4"
|
|
21
|
-
style="background: #f5f5f5; border-bottom: 1px solid #e0e0e0; flex-wrap: wrap"
|
|
17
|
+
v-if="readonly && (submissionStatus || requiresPayment)"
|
|
18
|
+
class="online-form-fill__meta px-6 py-2 d-flex align-center ga-4"
|
|
22
19
|
>
|
|
23
|
-
|
|
20
|
+
<!-- `StatusChip` IS the design's status pill: it maps the WORD to a tone
|
|
21
|
+
through the shared `utils/status.ts`, so "Pending" is the same amber
|
|
22
|
+
here as on a work order, and it carries `--tone-bg` with the ink so
|
|
23
|
+
both halves of the measured pair arrive together. The `v-chip` it
|
|
24
|
+
replaces painted a flat fixed-palette fill under a white label. -->
|
|
25
|
+
<StatusChip
|
|
24
26
|
v-if="submissionStatus"
|
|
25
|
-
:
|
|
26
|
-
variant="flat"
|
|
27
|
-
size="x-small"
|
|
27
|
+
:status="submissionStatus"
|
|
28
28
|
class="text-capitalize"
|
|
29
|
-
|
|
29
|
+
/>
|
|
30
30
|
<span v-if="(initialValues as any).block" class="text-caption text-medium-emphasis">
|
|
31
31
|
Block: <strong>{{ (initialValues as any).block }}</strong>
|
|
32
32
|
</span>
|
|
@@ -37,18 +37,21 @@
|
|
|
37
37
|
Unit: <strong>{{ submissionUnit }}</strong>
|
|
38
38
|
</span>
|
|
39
39
|
<template v-if="requiresPayment">
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
40
|
+
<!-- The payment pair is not a status WORD the shared map knows, so the
|
|
41
|
+
tone is given directly - the same pill, the same measured pair.
|
|
42
|
+
A preview has no submission to be paid/unpaid yet, so it shows
|
|
43
|
+
the configured fee instead of a status that doesn't apply. -->
|
|
44
|
+
<StatusChip
|
|
45
|
+
v-if="!submissionStatus"
|
|
46
|
+
tone="info"
|
|
47
|
+
:label="`Requires Payment: $${paymentAmount}`"
|
|
48
|
+
/>
|
|
49
|
+
<StatusChip
|
|
50
|
+
v-else-if="initialManagementValues?.paymentStatus"
|
|
51
|
+
tone="ok"
|
|
52
|
+
:label="`Payment ${initialManagementValues.paymentStatus}`"
|
|
53
|
+
/>
|
|
54
|
+
<StatusChip v-else tone="warn" label="Payment Not Paid" />
|
|
52
55
|
<span
|
|
53
56
|
v-if="initialManagementValues?.paymentOrderId"
|
|
54
57
|
class="text-caption text-medium-emphasis"
|
|
@@ -58,17 +61,21 @@
|
|
|
58
61
|
|
|
59
62
|
<!-- Scrollable body -->
|
|
60
63
|
<v-card-text
|
|
61
|
-
style="max-height: 76vh
|
|
62
|
-
class="pa-6"
|
|
64
|
+
style="max-height: 76vh"
|
|
65
|
+
class="screen-modal__body pa-6"
|
|
63
66
|
>
|
|
64
|
-
|
|
67
|
+
<!-- `.filter-field` is a DESCENDANT selector (`.filter-field .v-field`),
|
|
68
|
+
so one class on the form gives every input below it the design's
|
|
69
|
+
40px/10px/13.5px geometry. Every `:rules` below is untouched, and no
|
|
70
|
+
field becomes an `AppField` - AppField carries no rules, and Submit
|
|
71
|
+
is gated on `validForm`, which only exists because these rules run. -->
|
|
72
|
+
<v-form v-model="validForm" class="filter-field">
|
|
65
73
|
<template v-for="(block, i) in displayBlocks" :key="i">
|
|
66
74
|
|
|
67
75
|
<!-- ADDRESS BLOCK -->
|
|
68
76
|
<div
|
|
69
77
|
v-if="block.type === 'address'"
|
|
70
|
-
class="mb-4 pa-3"
|
|
71
|
-
style="background: #f5f5f5; border-radius: 6px"
|
|
78
|
+
class="online-form-fill__panel mb-4 pa-3"
|
|
72
79
|
>
|
|
73
80
|
<v-row no-gutters>
|
|
74
81
|
<v-col cols="5">
|
|
@@ -91,7 +98,11 @@
|
|
|
91
98
|
:key="field.key"
|
|
92
99
|
:cols="field.cols || 6"
|
|
93
100
|
>
|
|
94
|
-
|
|
101
|
+
<!-- `required` was never passed, so the design system's own
|
|
102
|
+
asterisk never drew: a field the form REFUSES to submit
|
|
103
|
+
without looked identical to an optional one. The rule below
|
|
104
|
+
is keyed on the same `field.required`. -->
|
|
105
|
+
<InputLabel :title="field.label" :required="!readonly && !!field.required" />
|
|
95
106
|
<v-text-field
|
|
96
107
|
v-if="field.fieldType === 'text'"
|
|
97
108
|
v-model="values[field.key]"
|
|
@@ -137,7 +148,7 @@
|
|
|
137
148
|
|
|
138
149
|
<!-- SINGLE FULL-WIDTH FIELD -->
|
|
139
150
|
<div v-else-if="block.type === 'field'" class="mb-0">
|
|
140
|
-
<InputLabel :title="block.field.label" />
|
|
151
|
+
<InputLabel :title="block.field.label" :required="!readonly && !!block.field.required" />
|
|
141
152
|
<v-text-field
|
|
142
153
|
v-if="block.field.fieldType === 'text'"
|
|
143
154
|
v-model="values[block.field.key]"
|
|
@@ -233,20 +244,50 @@
|
|
|
233
244
|
</div>
|
|
234
245
|
|
|
235
246
|
<!-- PARAGRAPH (terms / info text) -->
|
|
247
|
+
<!-- `color: #333` was a near-black on a dark card: the terms text was
|
|
248
|
+
invisible on the dark theme (measured 1.32:1). `--text` is the
|
|
249
|
+
design's own ink and `--border` the design's own rule. -->
|
|
236
250
|
<p
|
|
237
251
|
v-else-if="block.type === 'paragraph'"
|
|
238
|
-
class="text-body-2 mb-3"
|
|
239
|
-
style="
|
|
240
|
-
line-height: 1.65;
|
|
241
|
-
color: #333;
|
|
242
|
-
text-align: justify;
|
|
243
|
-
border-left: 3px solid #ddd;
|
|
244
|
-
padding-left: 10px;
|
|
245
|
-
"
|
|
252
|
+
class="online-form-fill__para text-body-2 mb-3"
|
|
246
253
|
>
|
|
247
254
|
{{ resolveText(block.text) }}
|
|
248
255
|
</p>
|
|
249
256
|
|
|
257
|
+
<!-- ORDERED LIST -->
|
|
258
|
+
<div v-else-if="block.type === 'ordered-list'" class="mb-3">
|
|
259
|
+
<div
|
|
260
|
+
v-if="block.title"
|
|
261
|
+
class="text-body-2 font-weight-bold mb-1"
|
|
262
|
+
style="text-decoration: underline; text-underline-offset: 3px"
|
|
263
|
+
>{{ block.title }}</div>
|
|
264
|
+
<ol style="padding-left: 22px; margin: 0">
|
|
265
|
+
<li
|
|
266
|
+
v-for="(item, itemIdx) in block.items"
|
|
267
|
+
:key="itemIdx"
|
|
268
|
+
class="text-body-2 mb-1"
|
|
269
|
+
style="line-height: 1.55; color: var(--text)"
|
|
270
|
+
>{{ item }}</li>
|
|
271
|
+
</ol>
|
|
272
|
+
</div>
|
|
273
|
+
|
|
274
|
+
<!-- UNORDERED LIST -->
|
|
275
|
+
<div v-else-if="block.type === 'unordered-list'" class="mb-3">
|
|
276
|
+
<div
|
|
277
|
+
v-if="block.title"
|
|
278
|
+
class="text-body-2 font-weight-bold mb-1"
|
|
279
|
+
style="text-decoration: underline; text-underline-offset: 3px"
|
|
280
|
+
>{{ block.title }}</div>
|
|
281
|
+
<ul style="padding-left: 22px; margin: 0">
|
|
282
|
+
<li
|
|
283
|
+
v-for="(item, itemIdx) in block.items"
|
|
284
|
+
:key="itemIdx"
|
|
285
|
+
class="text-body-2 mb-1"
|
|
286
|
+
style="line-height: 1.55; color: var(--text)"
|
|
287
|
+
>{{ item }}</li>
|
|
288
|
+
</ul>
|
|
289
|
+
</div>
|
|
290
|
+
|
|
250
291
|
<!-- DIVIDER -->
|
|
251
292
|
<v-divider v-else-if="block.type === 'divider'" class="my-4" />
|
|
252
293
|
|
|
@@ -265,6 +306,12 @@
|
|
|
265
306
|
class="mt-3 mb-5"
|
|
266
307
|
>
|
|
267
308
|
<span class="text-caption text-medium-emphasis d-block mb-1">{{ block.label }}</span>
|
|
309
|
+
<!-- DELIBERATELY NOT TOKENISED. `detectSigBackground` reads the
|
|
310
|
+
saved PNG and decides whether its ink is black or white; this
|
|
311
|
+
plate has to match THAT ink, not the current theme. A white
|
|
312
|
+
signature on a `--card` plate is invisible on the light theme,
|
|
313
|
+
and a black one on the dark theme - which is the whole reason
|
|
314
|
+
the detection exists. -->
|
|
268
315
|
<div
|
|
269
316
|
v-if="initialValues[block.key]"
|
|
270
317
|
:style="{
|
|
@@ -283,15 +330,14 @@
|
|
|
283
330
|
</div>
|
|
284
331
|
<div
|
|
285
332
|
v-else
|
|
286
|
-
|
|
333
|
+
class="online-form-fill__sig-blank"
|
|
287
334
|
/>
|
|
288
335
|
</div>
|
|
289
336
|
|
|
290
337
|
<!-- ACKNOWLEDGEMENT -->
|
|
291
338
|
<div
|
|
292
339
|
v-else-if="block.type === 'acknowledgement'"
|
|
293
|
-
class="mb-4 pa-3"
|
|
294
|
-
style="background: #f9f9f9; border-radius: 6px; border: 1px solid #eee"
|
|
340
|
+
class="online-form-fill__panel online-form-fill__panel--bordered mb-4 pa-3"
|
|
295
341
|
>
|
|
296
342
|
<span class="text-body-2 font-weight-medium">{{ resolveText(block.text) }}</span>
|
|
297
343
|
</div>
|
|
@@ -299,10 +345,10 @@
|
|
|
299
345
|
<!-- MANAGEMENT USE -->
|
|
300
346
|
<div
|
|
301
347
|
v-else-if="block.type === 'management-use'"
|
|
302
|
-
class="pa-4 mt-2"
|
|
303
|
-
:
|
|
304
|
-
? '
|
|
305
|
-
: '
|
|
348
|
+
class="online-form-fill__panel pa-4 mt-2"
|
|
349
|
+
:class="approvalMode && selectedAction === 'approved'
|
|
350
|
+
? 'online-form-fill__panel--ok'
|
|
351
|
+
: 'online-form-fill__panel--dim'"
|
|
306
352
|
>
|
|
307
353
|
<v-row no-gutters class="mb-2">
|
|
308
354
|
<span class="text-caption font-weight-bold text-medium-emphasis">
|
|
@@ -326,7 +372,7 @@
|
|
|
326
372
|
/>
|
|
327
373
|
<div
|
|
328
374
|
v-else
|
|
329
|
-
|
|
375
|
+
class="online-form-fill__mgmt-line"
|
|
330
376
|
>{{ managementValues[item] || '' }}</div>
|
|
331
377
|
</div>
|
|
332
378
|
</v-row>
|
|
@@ -344,7 +390,7 @@
|
|
|
344
390
|
<!-- Approval action panel -->
|
|
345
391
|
<div
|
|
346
392
|
v-if="readonly && approvalMode"
|
|
347
|
-
|
|
393
|
+
class="online-form-fill__approve"
|
|
348
394
|
>
|
|
349
395
|
<v-text-field
|
|
350
396
|
v-model="adminRemarks"
|
|
@@ -355,35 +401,35 @@
|
|
|
355
401
|
:error="remarksRequired && adminRemarks.trim().length === 0"
|
|
356
402
|
:error-messages="remarksRequired && adminRemarks.trim().length === 0 ? 'Remarks are required' : ''"
|
|
357
403
|
/>
|
|
358
|
-
|
|
359
|
-
|
|
404
|
+
<!-- The three verdicts keep their colour coding - it is what tells them
|
|
405
|
+
apart - but on the theme's own status colours rather than fixed
|
|
406
|
+
palette entries, so both the tonal and the flat state follow the
|
|
407
|
+
theme. Confirm was a hardcoded `grey-darken-3` fill and is now the
|
|
408
|
+
design's primary button, which is what it is. -->
|
|
409
|
+
<div class="d-flex align-center ga-2 justify-end flex-wrap">
|
|
410
|
+
<v-btn variant="outlined" class="screen-btn-ghost" @click="emit('cancel')">Close</v-btn>
|
|
360
411
|
<v-btn
|
|
361
412
|
:variant="selectedAction === 'resubmission' ? 'flat' : 'tonal'"
|
|
362
|
-
color="
|
|
413
|
+
color="warning"
|
|
363
414
|
class="text-none"
|
|
364
|
-
size="small"
|
|
365
415
|
@click="selectAction('resubmission')"
|
|
366
416
|
>Resubmit</v-btn>
|
|
367
417
|
<v-btn
|
|
368
418
|
:variant="selectedAction === 'rejected' ? 'flat' : 'tonal'"
|
|
369
|
-
color="
|
|
419
|
+
color="error"
|
|
370
420
|
class="text-none"
|
|
371
|
-
size="small"
|
|
372
421
|
@click="selectAction('rejected')"
|
|
373
422
|
>Reject</v-btn>
|
|
374
423
|
<v-btn
|
|
375
424
|
:variant="selectedAction === 'approved' ? 'flat' : 'tonal'"
|
|
376
|
-
color="
|
|
425
|
+
color="success"
|
|
377
426
|
class="text-none"
|
|
378
|
-
size="small"
|
|
379
427
|
@click="selectAction('approved')"
|
|
380
428
|
>Approve</v-btn>
|
|
381
429
|
<v-btn
|
|
382
430
|
v-if="selectedAction"
|
|
383
431
|
variant="flat"
|
|
384
|
-
|
|
385
|
-
class="text-none"
|
|
386
|
-
size="small"
|
|
432
|
+
class="screen-btn-primary"
|
|
387
433
|
:disabled="!canConfirm"
|
|
388
434
|
:loading="updatingStatus"
|
|
389
435
|
@click="confirmStatusUpdate"
|
|
@@ -391,24 +437,25 @@
|
|
|
391
437
|
</div>
|
|
392
438
|
</div>
|
|
393
439
|
|
|
394
|
-
<!--
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
440
|
+
<!-- The design's footer: equal-width buttons, ghost then primary, on a
|
|
441
|
+
bordered strip. Submit was a hardcoded `color="black"` block fill. Its
|
|
442
|
+
`:disabled="!validForm || submitting"` is untouched - the gate is still
|
|
443
|
+
the form's own validity. -->
|
|
444
|
+
<div v-else class="screen-modal__footer">
|
|
445
|
+
<template v-if="readonly">
|
|
446
|
+
<v-btn variant="outlined" class="screen-btn-ghost" @click="emit('cancel')">Close</v-btn>
|
|
447
|
+
</template>
|
|
448
|
+
<template v-else>
|
|
449
|
+
<v-btn variant="outlined" class="screen-btn-ghost" :disabled="submitting" @click="emit('cancel')">Cancel</v-btn>
|
|
450
|
+
<v-btn
|
|
451
|
+
variant="flat"
|
|
452
|
+
class="screen-btn-primary"
|
|
453
|
+
:disabled="!validForm || submitting"
|
|
454
|
+
:loading="submitting"
|
|
455
|
+
@click="submit"
|
|
456
|
+
>Submit</v-btn>
|
|
457
|
+
</template>
|
|
458
|
+
</div>
|
|
412
459
|
</v-card>
|
|
413
460
|
</template>
|
|
414
461
|
<script setup lang="ts">
|
|
@@ -433,6 +480,7 @@ const props = defineProps({
|
|
|
433
480
|
approvalMode: { type: Boolean, default: false },
|
|
434
481
|
initialManagementValues: { type: Object as PropType<Record<string, string>>, default: () => ({}) },
|
|
435
482
|
formType: { type: String, default: "" },
|
|
483
|
+
paymentAmount: { type: Number, default: 0 },
|
|
436
484
|
/** Optional custom submit handler. Receives the collected form values.
|
|
437
485
|
* If omitted the component submits to /api/online-forms automatically. */
|
|
438
486
|
submitFn: {
|
|
@@ -586,25 +634,13 @@ function confirmStatusUpdate() {
|
|
|
586
634
|
|
|
587
635
|
const requiredRule = (v: any) => (v !== null && v !== undefined && v !== "") || "This field is required";
|
|
588
636
|
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
case "resubmission": return "orange";
|
|
594
|
-
case "rejected": return "red";
|
|
595
|
-
default: return "grey";
|
|
596
|
-
}
|
|
597
|
-
});
|
|
598
|
-
|
|
599
|
-
const PAYMENT_REQUIRED_FORM_TYPES = new Set([
|
|
600
|
-
"Application for Electronic Access Card",
|
|
601
|
-
"Application for Booking of BBQ Pit",
|
|
602
|
-
"Application for Moving In/Out & Delivery",
|
|
603
|
-
"Application for Main Entrance RFID Transponder",
|
|
604
|
-
]);
|
|
637
|
+
// The local status -> colour switch this file carried is gone: `StatusChip`
|
|
638
|
+
// maps the word through the shared `utils/status.ts`, which already had
|
|
639
|
+
// approved/pending/rejected and now has resubmission too. One mapping, not a
|
|
640
|
+
// second private copy that could drift from it.
|
|
605
641
|
|
|
606
642
|
const requiresPayment = computed(() => {
|
|
607
|
-
if (
|
|
643
|
+
if (props.paymentAmount <= 0) return false;
|
|
608
644
|
if (props.formType === "Application for Main Entrance RFID Transponder") {
|
|
609
645
|
return !!(props.initialValues.reasonLost || props.initialValues.reasonDamaged);
|
|
610
646
|
}
|
|
@@ -743,3 +779,74 @@ async function submit() {
|
|
|
743
779
|
}
|
|
744
780
|
}
|
|
745
781
|
</script>
|
|
782
|
+
|
|
783
|
+
<style scoped>
|
|
784
|
+
/*
|
|
785
|
+
* Every surface below was a hardcoded near-white hex - `#f5f5f5`, `#f9f9f9`,
|
|
786
|
+
* `#f0f0f0`, `#fafafa` - with THEMED text on top of it. On the dark theme that
|
|
787
|
+
* put the design's near-white ink on a near-white plate: the address strip read
|
|
788
|
+
* 1.05:1, the acknowledgement 1.08:1 and the management panel 1:1, i.e. text
|
|
789
|
+
* that was there and could not be seen. `--bg` is the design's own recessed
|
|
790
|
+
* surface and follows the theme, so the same rows read correctly on both.
|
|
791
|
+
*/
|
|
792
|
+
.online-form-fill__meta {
|
|
793
|
+
flex-wrap: wrap;
|
|
794
|
+
background: var(--bg);
|
|
795
|
+
border-bottom: 1px solid var(--border);
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
.online-form-fill__panel {
|
|
799
|
+
background: var(--bg);
|
|
800
|
+
border-radius: var(--r-inner);
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
.online-form-fill__panel--bordered {
|
|
804
|
+
border: 1px solid var(--border);
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
/* The approved state of the management panel. `--ok-bg` / `--ok` are the
|
|
808
|
+
design's own success pair; it was `#e8f5e9` on `#a5d6a7`, the same greens on
|
|
809
|
+
both themes. */
|
|
810
|
+
.online-form-fill__panel--ok {
|
|
811
|
+
background: var(--ok-bg);
|
|
812
|
+
border: 1px solid var(--ok);
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
.online-form-fill__panel--dim {
|
|
816
|
+
opacity: 0.75;
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
.online-form-fill__para {
|
|
820
|
+
line-height: 1.65;
|
|
821
|
+
color: var(--text);
|
|
822
|
+
text-align: justify;
|
|
823
|
+
border-left: 3px solid var(--border);
|
|
824
|
+
padding-left: 10px;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
/* The ruled line a management entry is written on, and the empty signature
|
|
828
|
+
plate - both were fixed greys. */
|
|
829
|
+
.online-form-fill__mgmt-line {
|
|
830
|
+
border-bottom: 1px solid var(--border);
|
|
831
|
+
min-width: 120px;
|
|
832
|
+
height: 22px;
|
|
833
|
+
font-size: var(--fs-cell);
|
|
834
|
+
padding-top: 2px;
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
.online-form-fill__sig-blank {
|
|
838
|
+
border-bottom: 1px dashed var(--border);
|
|
839
|
+
height: 56px;
|
|
840
|
+
background: var(--bg);
|
|
841
|
+
border-radius: var(--r-inner-sm);
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
.online-form-fill__approve {
|
|
845
|
+
display: flex;
|
|
846
|
+
flex-direction: column;
|
|
847
|
+
gap: 10px;
|
|
848
|
+
padding: 12px 16px;
|
|
849
|
+
background: var(--bg);
|
|
850
|
+
border-top: 1px solid var(--border);
|
|
851
|
+
}
|
|
852
|
+
</style>
|
|
@@ -5,25 +5,25 @@
|
|
|
5
5
|
width="560"
|
|
6
6
|
persistent
|
|
7
7
|
>
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
</v-
|
|
8
|
+
<!-- The title row was a `grey-darken-3` v-toolbar: the same hardcoded grey
|
|
9
|
+
slab on both themes, with white text sitting on it. A `v-card-title` on
|
|
10
|
+
`.screen-modal` is the same row on the card's own surface, so it
|
|
11
|
+
follows the theme. -->
|
|
12
|
+
<v-card class="screen-modal d-flex flex-column">
|
|
13
|
+
<v-card-title class="flex-grow-0">{{ form?.formType }}</v-card-title>
|
|
14
14
|
|
|
15
|
-
<v-card-subtitle class="px-6
|
|
15
|
+
<v-card-subtitle class="screen-hint px-6 pb-0 flex-grow-0">
|
|
16
16
|
Form preview — fields are read-only
|
|
17
17
|
</v-card-subtitle>
|
|
18
18
|
|
|
19
|
-
<v-card-text class="px-6 py-4 flex-grow-1"
|
|
19
|
+
<v-card-text class="screen-modal__body px-6 py-4 flex-grow-1">
|
|
20
20
|
<template v-for="(input, index) in form?.inputs" :key="index">
|
|
21
21
|
<v-text-field
|
|
22
22
|
v-if="input.dataType === 'Text Input'"
|
|
23
23
|
:label="input.label"
|
|
24
24
|
density="comfortable"
|
|
25
25
|
variant="outlined"
|
|
26
|
-
class="mb-1"
|
|
26
|
+
class="filter-field mb-1"
|
|
27
27
|
:hint="input.required ? 'Required' : ''"
|
|
28
28
|
persistent-hint
|
|
29
29
|
readonly
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
density="comfortable"
|
|
35
35
|
variant="outlined"
|
|
36
36
|
rows="3"
|
|
37
|
-
class="mb-1"
|
|
37
|
+
class="filter-field mb-1"
|
|
38
38
|
:hint="input.required ? 'Required' : ''"
|
|
39
39
|
persistent-hint
|
|
40
40
|
readonly
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
type="date"
|
|
46
46
|
density="comfortable"
|
|
47
47
|
variant="outlined"
|
|
48
|
-
class="mb-1"
|
|
48
|
+
class="filter-field mb-1"
|
|
49
49
|
:hint="input.required ? 'Required' : ''"
|
|
50
50
|
persistent-hint
|
|
51
51
|
readonly
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
:items="input.options || []"
|
|
57
57
|
density="comfortable"
|
|
58
58
|
variant="outlined"
|
|
59
|
-
class="mb-1"
|
|
59
|
+
class="filter-field mb-1"
|
|
60
60
|
:hint="input.required ? 'Required' : ''"
|
|
61
61
|
persistent-hint
|
|
62
62
|
readonly
|
|
@@ -65,29 +65,24 @@
|
|
|
65
65
|
v-else-if="input.dataType === 'Checkbox'"
|
|
66
66
|
:label="input.label"
|
|
67
67
|
density="comfortable"
|
|
68
|
-
class="mb-1"
|
|
68
|
+
class="filter-field mb-1"
|
|
69
69
|
readonly
|
|
70
70
|
/>
|
|
71
71
|
</template>
|
|
72
72
|
</v-card-text>
|
|
73
73
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
Close Preview
|
|
87
|
-
</v-btn>
|
|
88
|
-
</v-col>
|
|
89
|
-
</v-row>
|
|
90
|
-
</v-toolbar>
|
|
74
|
+
<!-- The design's modal footer. The Close button was a `color="black"`
|
|
75
|
+
square-cornered block fill - the same black on both themes, and the
|
|
76
|
+
shape of a primary action for what is only a dismiss. -->
|
|
77
|
+
<div class="screen-modal__footer flex-grow-0">
|
|
78
|
+
<v-btn
|
|
79
|
+
variant="outlined"
|
|
80
|
+
class="screen-btn-ghost"
|
|
81
|
+
@click="$emit('update:modelValue', false)"
|
|
82
|
+
>
|
|
83
|
+
Close Preview
|
|
84
|
+
</v-btn>
|
|
85
|
+
</div>
|
|
91
86
|
</v-card>
|
|
92
87
|
</v-dialog>
|
|
93
88
|
</template>
|