summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorChristopher Ng <chrng8@gmail.com>2023-10-26 10:30:22 -0700
committerChristopher Ng <chrng8@gmail.com>2023-10-26 10:30:22 -0700
commit3b402559accc91931d79847ec60dcead512d4461 (patch)
treebbb161aeb4a8520ad4f5fcedb448b5d8ce989b90 /core
parent4c8256c15bd9ffa84e60ad5df68cf1b18f3acac3 (diff)
downloadnextcloud-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.vue140
-rw-r--r--core/src/views/UserMenu.vue12
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,