@7365admin1/layer-common 3.2.7 → 3.2.8-staging.200
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 +241 -79
- 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,43 +1,87 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
2
|
+
<!--
|
|
3
|
+
PHASE 2 - THE 58px TOP BAR.
|
|
4
|
+
|
|
5
|
+
Same bar, same hamburger, same theme toggle, same profile menu with the
|
|
6
|
+
same two actions. What changes is its height (the design's 58px), the
|
|
7
|
+
breadcrumb it now carries, and the shape of the menu it opens.
|
|
8
|
+
|
|
9
|
+
The breadcrumb READS state that is already in the page - the site the
|
|
10
|
+
application has loaded and the route the router is on. It fetches nothing
|
|
11
|
+
and navigates nowhere; it is a label.
|
|
12
|
+
-->
|
|
13
|
+
<v-app-bar
|
|
14
|
+
:height="58"
|
|
15
|
+
flat
|
|
16
|
+
scroll-behavior="elevate"
|
|
17
|
+
scroll-threshold="200"
|
|
18
|
+
class="app-topbar-shell"
|
|
19
|
+
>
|
|
3
20
|
<v-app-bar-nav-icon v-if="!props.hideNavIcon" @click="drawer = !drawer"></v-app-bar-nav-icon>
|
|
4
21
|
|
|
22
|
+
<div class="app-topbar-shell__crumb">
|
|
23
|
+
<span v-if="siteName" class="app-topbar-shell__site">{{ siteName }}</span>
|
|
24
|
+
<span v-if="siteName && moduleName" class="app-topbar-shell__sep">/</span>
|
|
25
|
+
<span class="app-topbar-shell__module">{{ moduleName }}</span>
|
|
26
|
+
</div>
|
|
27
|
+
|
|
5
28
|
<template #append>
|
|
6
|
-
|
|
29
|
+
<!--
|
|
30
|
+
The icon now says which theme you would GET, and the choice is
|
|
31
|
+
remembered - see `composables/useThemePreference.ts`. Same button, same
|
|
32
|
+
place, same one click.
|
|
33
|
+
-->
|
|
34
|
+
<!-- The design's 36px bordered icon button. Same one click, same icon. -->
|
|
35
|
+
<v-btn
|
|
36
|
+
:icon="current === 'dark' ? 'mdi-weather-sunny' : 'mdi-weather-night'"
|
|
37
|
+
:aria-label="current === 'dark' ? 'Switch to light theme' : 'Switch to dark theme'"
|
|
38
|
+
variant="text"
|
|
39
|
+
size="36"
|
|
40
|
+
class="app-topbar-shell__icon-btn ms-2"
|
|
41
|
+
@click="toggleTheme"
|
|
42
|
+
/>
|
|
7
43
|
|
|
8
44
|
<v-menu offset="10px" :close-on-content-click="false">
|
|
9
45
|
<template #activator="{ props }">
|
|
10
|
-
<v-btn fab variant="text" icon v-bind="props" class="
|
|
46
|
+
<v-btn fab variant="text" icon v-bind="props" class="ms-2 me-1">
|
|
11
47
|
<AvatarMain :image-src="currentUser?.profile" :name="name" />
|
|
12
48
|
</v-btn>
|
|
13
49
|
</template>
|
|
14
50
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
<
|
|
24
|
-
{{ name }}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
51
|
+
<!--
|
|
52
|
+
240px, 14px radius and the design's menu shadow. The two actions and
|
|
53
|
+
the condition on the first are exactly as they were.
|
|
54
|
+
-->
|
|
55
|
+
<v-card :width="240" elevation="0" class="app-profile-menu">
|
|
56
|
+
<div class="app-profile-menu__head">
|
|
57
|
+
<AvatarMain :image-src="currentUser?.profile" :name="name" />
|
|
58
|
+
|
|
59
|
+
<div class="app-profile-menu__who">
|
|
60
|
+
<div class="app-profile-menu__name">{{ name }}</div>
|
|
61
|
+
<div v-if="siteName" class="app-profile-menu__site">{{ siteName }}</div>
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
|
|
65
|
+
<div class="app-profile-menu__rows">
|
|
66
|
+
<button
|
|
67
|
+
v-if="APP_NAME.toLowerCase() !== 'account'"
|
|
68
|
+
type="button"
|
|
69
|
+
class="app-profile-menu__row"
|
|
70
|
+
@click="redirect(APP_ACCOUNT, 'home')"
|
|
71
|
+
>
|
|
72
|
+
<v-icon icon="mdi-account-cog-outline" size="18" />
|
|
73
|
+
Manage Account
|
|
74
|
+
</button>
|
|
75
|
+
|
|
76
|
+
<button
|
|
77
|
+
type="button"
|
|
78
|
+
class="app-profile-menu__row app-profile-menu__row--danger"
|
|
79
|
+
@click="logout()"
|
|
80
|
+
>
|
|
81
|
+
<v-icon icon="mdi-logout" size="18" />
|
|
82
|
+
Logout
|
|
83
|
+
</button>
|
|
84
|
+
</div>
|
|
41
85
|
</v-card>
|
|
42
86
|
</v-menu>
|
|
43
87
|
</template>
|
|
@@ -45,7 +89,7 @@
|
|
|
45
89
|
</template>
|
|
46
90
|
|
|
47
91
|
<script setup lang="ts">
|
|
48
|
-
import {
|
|
92
|
+
import { moduleNameFromRoute } from "../../utils/breadcrumb";
|
|
49
93
|
|
|
50
94
|
const props = defineProps({
|
|
51
95
|
hideNavIcon: {
|
|
@@ -64,14 +108,49 @@ const { redirect } = useUtils();
|
|
|
64
108
|
|
|
65
109
|
const { APP_ACCOUNT, APP_MAIN, APP_NAME } = useRuntimeConfig().public;
|
|
66
110
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
111
|
+
/**
|
|
112
|
+
* This used to be `theme.global.name.value = ...` and nothing else, so the
|
|
113
|
+
* choice was gone on the next reload - and, because these are eleven separate
|
|
114
|
+
* applications, gone again on every hop between them. The composable writes the
|
|
115
|
+
* layer's shared `theme` cookie, and `plugins/vuetify.ts` boots on it.
|
|
116
|
+
*/
|
|
117
|
+
const { current, toggleTheme } = useThemePreference();
|
|
72
118
|
|
|
73
119
|
const { currentUser } = useLocalAuth();
|
|
74
120
|
|
|
121
|
+
/**
|
|
122
|
+
* THE BREADCRUMB: `Site name / Current module`.
|
|
123
|
+
*
|
|
124
|
+
* Both halves are read from what the page already holds - the shared `site`
|
|
125
|
+
* state the applications populate, and the router's own current route. NO
|
|
126
|
+
* request is made from this component; if the site has not been loaded on a
|
|
127
|
+
* given screen the site half is simply omitted and the module stands alone.
|
|
128
|
+
*/
|
|
129
|
+
const { site } = useSite();
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* The shared `site` state is only populated by the screens that load a site
|
|
133
|
+
* document, so on most screens - the dashboard included - the bar had no name
|
|
134
|
+
* to print. `SwitchContext` mirrors the label it is ALREADY showing in the
|
|
135
|
+
* rail into this state, so the bar falls back to the very name the user can
|
|
136
|
+
* see two inches to the left. Still no request from this component.
|
|
137
|
+
*/
|
|
138
|
+
const shellSiteName = useState<string>("shell-context-site-name", () => "");
|
|
139
|
+
|
|
140
|
+
const siteName = computed(() =>
|
|
141
|
+
String(site.value?.name || shellSiteName.value || "").trim()
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
const route = useRoute();
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* The page's name comes off the route name, which the applications build from
|
|
148
|
+
* their own folder structure: `org-site-work-orders` is Work Orders. The rule
|
|
149
|
+
* itself lives in `utils/breadcrumb.ts`, where it is unit-tested against every
|
|
150
|
+
* route shape the eleven applications actually have.
|
|
151
|
+
*/
|
|
152
|
+
const moduleName = computed(() => moduleNameFromRoute(route));
|
|
153
|
+
|
|
75
154
|
const profile = computed(() => {
|
|
76
155
|
return `/api/public/${currentUser.value?.profile}`;
|
|
77
156
|
});
|
|
@@ -95,8 +174,11 @@ const name = computed(() => {
|
|
|
95
174
|
|
|
96
175
|
if(full) return full;
|
|
97
176
|
|
|
177
|
+
/* A member invited by email has no name stored yet, which left the avatar's
|
|
178
|
+
initials empty and the circle blank. The address is what the product shows
|
|
179
|
+
that member everywhere else, so it stands in here too. */
|
|
98
180
|
const alternative = user?.name?.trim();
|
|
99
|
-
return alternative || ""
|
|
181
|
+
return alternative || user?.email?.trim() || ""
|
|
100
182
|
|
|
101
183
|
})
|
|
102
184
|
|
|
@@ -105,6 +187,151 @@ const { getNameInitials } = useUtils();
|
|
|
105
187
|
</script>
|
|
106
188
|
|
|
107
189
|
<style scoped>
|
|
190
|
+
/* ---------------------------------------------------------------- */
|
|
191
|
+
/* The top bar. */
|
|
192
|
+
/* ---------------------------------------------------------------- */
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* The design's bar is 58px INCLUDING its rule. A real `border-bottom` is added
|
|
196
|
+
* to the 58px Vuetify lays out, so the bar measures 59 and every page below it
|
|
197
|
+
* starts a pixel low; an inset shadow draws the same 1px line inside the 58.
|
|
198
|
+
*/
|
|
199
|
+
.app-topbar-shell,
|
|
200
|
+
.app-profile-menu {
|
|
201
|
+
/* The shell is the first surface to wear the design's typeface - see the
|
|
202
|
+
note in NavigationDrawer.vue. */
|
|
203
|
+
font-family: var(--font-sans);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
.app-topbar-shell {
|
|
207
|
+
box-shadow: inset 0 -1px 0 var(--border);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.app-topbar-shell__crumb {
|
|
211
|
+
flex: 1 1 auto;
|
|
212
|
+
min-width: 0;
|
|
213
|
+
display: flex;
|
|
214
|
+
align-items: center;
|
|
215
|
+
gap: 6px;
|
|
216
|
+
font-size: var(--fs-breadcrumb);
|
|
217
|
+
/* Truncates rather than wraps: two lines would break a 58px bar, and the
|
|
218
|
+
site name is the half worth losing first. */
|
|
219
|
+
overflow: hidden;
|
|
220
|
+
white-space: nowrap;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
.app-topbar-shell__site,
|
|
224
|
+
.app-topbar-shell__sep {
|
|
225
|
+
color: var(--muted);
|
|
226
|
+
overflow: hidden;
|
|
227
|
+
text-overflow: ellipsis;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
.app-topbar-shell__module {
|
|
231
|
+
color: var(--text);
|
|
232
|
+
font-weight: 700;
|
|
233
|
+
flex: 0 0 auto;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* THE TOP-BAR AVATAR is the design's accent-soft circle with accent-text
|
|
238
|
+
* initials, and only this one. `AvatarMain` gives every person a colour of
|
|
239
|
+
* their own from their name, which is right in a list of people - it is how
|
|
240
|
+
* you tell two rows apart - and wrong for the one avatar that is always the
|
|
241
|
+
* same person. `!important` because that per-person colour arrives as an
|
|
242
|
+
* inline style, and the rule is confined to the bar and its own menu.
|
|
243
|
+
*/
|
|
244
|
+
.app-topbar-shell :deep(.v-avatar),
|
|
245
|
+
.app-profile-menu :deep(.v-avatar) {
|
|
246
|
+
background-color: var(--accent-soft) !important;
|
|
247
|
+
/* The initials' colour arrives inline as well, and in dark mode it is the
|
|
248
|
+
per-person colour ON a blue wash: 1.26:1, invisible. */
|
|
249
|
+
color: var(--accent-text) !important;
|
|
250
|
+
font-weight: 800;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/* 36px, 1px border, 10px radius - the design's icon button. */
|
|
254
|
+
.app-topbar-shell__icon-btn {
|
|
255
|
+
border: 1px solid var(--border);
|
|
256
|
+
border-radius: var(--r-inner);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/* ---------------------------------------------------------------- */
|
|
260
|
+
/* The 240px profile menu. */
|
|
261
|
+
/* ---------------------------------------------------------------- */
|
|
262
|
+
|
|
263
|
+
.app-profile-menu {
|
|
264
|
+
border-radius: var(--r-menu);
|
|
265
|
+
box-shadow: var(--shadow-menu);
|
|
266
|
+
border: 1px solid var(--border);
|
|
267
|
+
overflow: hidden;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
.app-profile-menu__head {
|
|
271
|
+
display: flex;
|
|
272
|
+
align-items: center;
|
|
273
|
+
gap: 10px;
|
|
274
|
+
padding: 14px;
|
|
275
|
+
border-bottom: 1px solid var(--border);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.app-profile-menu__who {
|
|
279
|
+
min-width: 0;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
.app-profile-menu__name {
|
|
283
|
+
font-size: 13.5px;
|
|
284
|
+
font-weight: 800;
|
|
285
|
+
line-height: 1.3;
|
|
286
|
+
color: var(--text);
|
|
287
|
+
overflow: hidden;
|
|
288
|
+
white-space: nowrap;
|
|
289
|
+
text-overflow: ellipsis;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
.app-profile-menu__site {
|
|
293
|
+
font-size: 11.5px;
|
|
294
|
+
font-weight: 600;
|
|
295
|
+
line-height: 1.3;
|
|
296
|
+
color: var(--muted);
|
|
297
|
+
overflow: hidden;
|
|
298
|
+
white-space: nowrap;
|
|
299
|
+
text-overflow: ellipsis;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
.app-profile-menu__rows {
|
|
303
|
+
padding: 6px;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.app-profile-menu__row {
|
|
307
|
+
width: 100%;
|
|
308
|
+
display: flex;
|
|
309
|
+
align-items: center;
|
|
310
|
+
gap: 10px;
|
|
311
|
+
padding: 9px 10px;
|
|
312
|
+
border-radius: var(--r-inner-sm);
|
|
313
|
+
font-size: var(--fs-btn);
|
|
314
|
+
font-weight: var(--fw-btn);
|
|
315
|
+
color: var(--text2);
|
|
316
|
+
text-align: start;
|
|
317
|
+
cursor: pointer;
|
|
318
|
+
background: transparent;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
.app-profile-menu__row:hover {
|
|
322
|
+
background: var(--hover);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/* Logout is the design's red row: the colour lives on the label, and the
|
|
326
|
+
soft error background is what the hover paints. */
|
|
327
|
+
.app-profile-menu__row--danger {
|
|
328
|
+
color: var(--err);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
.app-profile-menu__row--danger:hover {
|
|
332
|
+
background: var(--err-bg);
|
|
333
|
+
}
|
|
334
|
+
|
|
108
335
|
.APP_NAME {
|
|
109
336
|
display: inline-block;
|
|
110
337
|
word-wrap: break-word;
|