diff options
author | Christopher Ng <chrng8@gmail.com> | 2023-10-26 10:30:22 -0700 |
---|---|---|
committer | Christopher Ng <chrng8@gmail.com> | 2023-10-26 10:30:22 -0700 |
commit | 3b402559accc91931d79847ec60dcead512d4461 (patch) | |
tree | bbb161aeb4a8520ad4f5fcedb448b5d8ce989b90 /core | |
parent | 4c8256c15bd9ffa84e60ad5df68cf1b18f3acac3 (diff) | |
download | nextcloud-server-3b402559accc91931d79847ec60dcead512d4461.tar.gz nextcloud-server-3b402559accc91931d79847ec60dcead512d4461.zip |
enh(a11y): Add separate profile entry
Signed-off-by: Christopher Ng <chrng8@gmail.com>
Diffstat (limited to 'core')
-rw-r--r-- | core/src/components/UserMenu/ProfileUserMenuEntry.vue | 140 | ||||
-rw-r--r-- | core/src/views/UserMenu.vue | 12 |
2 files changed, 150 insertions, 2 deletions
diff --git a/core/src/components/UserMenu/ProfileUserMenuEntry.vue b/core/src/components/UserMenu/ProfileUserMenuEntry.vue new file mode 100644 index 00000000000..61357f09ac6 --- /dev/null +++ b/core/src/components/UserMenu/ProfileUserMenuEntry.vue @@ -0,0 +1,140 @@ +<!-- + - @copyright 2023 Christopher Ng <chrng8@gmail.com> + - + - @author Christopher Ng <chrng8@gmail.com> + - + - @license AGPL-3.0-or-later + - + - This program is free software: you can redistribute it and/or modify + - it under the terms of the GNU Affero General Public License as + - published by the Free Software Foundation, either version 3 of the + - License, or (at your option) any later version. + - + - This program is distributed in the hope that it will be useful, + - but WITHOUT ANY WARRANTY; without even the implied warranty of + - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + - GNU Affero General Public License for more details. + - + - You should have received a copy of the GNU Affero General Public License + - along with this program. If not, see <http://www.gnu.org/licenses/>. + - +--> + +<template> + <li :id="id" + class="menu-entry"> + <component :is="profileEnabled ? 'a' : 'span'" + class="menu-entry__wrapper" + :class="{ + active, + 'menu-entry__wrapper--link': profileEnabled, + }" + :href="profileEnabled ? href : undefined" + @click.exact="handleClick"> + <span class="menu-entry__content"> + <span class="menu-entry__displayname">{{ displayName }}</span> + <NcLoadingIcon v-if="loading" :size="18" /> + </span> + <span v-if="profileEnabled">{{ name }}</span> + </component> + </li> +</template> + +<script> +import { loadState } from '@nextcloud/initial-state' +import { getCurrentUser } from '@nextcloud/auth' +import { subscribe, unsubscribe } from '@nextcloud/event-bus' + +import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js' + +const { profileEnabled } = loadState('user_status', 'profileEnabled', false) + +export default { + name: 'ProfileUserMenuEntry', + + components: { + NcLoadingIcon, + }, + + props: { + id: { + type: String, + required: true, + }, + name: { + type: String, + required: true, + }, + href: { + type: String, + required: true, + }, + active: { + type: Boolean, + required: true, + }, + }, + + data() { + return { + profileEnabled, + displayName: getCurrentUser().displayName, + loading: false, + } + }, + + mounted() { + subscribe('settings:profile-enabled:updated', this.handleProfileEnabledUpdate) + subscribe('settings:display-name:updated', this.handleDisplayNameUpdate) + }, + + beforeDestroy() { + unsubscribe('settings:profile-enabled:updated', this.handleProfileEnabledUpdate) + unsubscribe('settings:display-name:updated', this.handleDisplayNameUpdate) + }, + + methods: { + handleClick() { + if (this.profileEnabled) { + this.loading = true + } + }, + + handleProfileEnabledUpdate(profileEnabled) { + this.profileEnabled = profileEnabled + }, + + handleDisplayNameUpdate(displayName) { + this.displayName = displayName + }, + }, +} +</script> + +<style lang="scss" scoped> +.menu-entry { + &__wrapper { + box-sizing: border-box; + display: inline-flex; + flex-direction: column; + align-items: flex-start !important; + padding: 10px 12px 5px 12px !important; + height: var(--header-menu-item-height); + color: var(--color-text-maxcontrast); + + &--link { + height: calc(var(--header-menu-item-height) * 1.5) !important; + color: var(--color-main-text); + } + } + + &__content { + display: inline-flex; + gap: 0 10px; + } + + &__displayname { + font-weight: bold; + } +} +</style> diff --git a/core/src/views/UserMenu.vue b/core/src/views/UserMenu.vue index 8940e31c3c2..7c03a11cf3d 100644 --- a/core/src/views/UserMenu.vue +++ b/core/src/views/UserMenu.vue @@ -35,7 +35,11 @@ :preloaded-user-status="userStatus" /> </template> <ul> - <UserMenuEntry v-for="entry in settingsNavEntries" + <ProfileUserMenuEntry :id="profileEntry.id" + :name="profileEntry.name" + :href="profileEntry.href" + :active="profileEntry.active" /> + <UserMenuEntry v-for="entry in otherEntries" :id="entry.id" :key="entry.id" :name="entry.name" @@ -58,6 +62,7 @@ import NcAvatar from '@nextcloud/vue/dist/Components/NcAvatar.js' import NcHeaderMenu from '@nextcloud/vue/dist/Components/NcHeaderMenu.js' import { getAllStatusOptions } from '../../../apps/user_status/src/services/statusOptionsService.js' +import ProfileUserMenuEntry from '../components/UserMenu/ProfileUserMenuEntry.vue' import UserMenuEntry from '../components/UserMenu/UserMenuEntry.vue' import logger from '../logger.js' @@ -77,6 +82,7 @@ import logger from '../logger.js' /** @type {SettingNavEntry[]} */ const settingsNavEntries = loadState('core', 'settingsNavEntries', []) +const { profile: profileEntry, ...otherEntries } = settingsNavEntries const translateStatus = (status) => { const statusMap = Object.fromEntries( @@ -95,12 +101,14 @@ export default { components: { NcAvatar, NcHeaderMenu, + ProfileUserMenuEntry, UserMenuEntry, }, data() { return { - settingsNavEntries, + profileEntry, + otherEntries, displayName: getCurrentUser()?.displayName, userId: getCurrentUser()?.uid, isLoadingUserStatus: true, |