Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 35 additions & 69 deletions packages/web-runtime/src/components/Topbar/UserMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@
<nav :aria-label="$gettext('Account menu')">
<oc-button
id="_userMenuButton"
ref="menuButton"
v-oc-tooltip="$gettext('My Account')"
appearance="raw"
no-hover
:aria-label="$gettext('My Account')"
>
<user-avatar
v-if="onPremisesSamAccountName"
v-if="user?.onPremisesSamAccountName"
class="oc-topbar-avatar oc-topbar-personal-avatar inline-flex justify-center items-center"
:user-id="user.id"
:user-name="user.displayName"
Expand All @@ -28,7 +27,6 @@
/>
</oc-button>
<oc-drop
ref="menu"
:title="$gettext('Account')"
drop-id="account-info-container"
toggle="#_userMenuButton"
Expand All @@ -38,7 +36,7 @@
class="overflow-hidden"
>
<oc-list class="user-menu-list">
<template v-if="!onPremisesSamAccountName">
<template v-if="!user?.onPremisesSamAccountName">
<li class="flex items-center">
<oc-button
id="oc-topbar-account-manage"
Expand Down Expand Up @@ -75,7 +73,7 @@
<span :class="{ 'py-1': !user.mail }">
<span class="block" v-text="user.displayName" />
<span v-if="user.mail" class="text-sm" v-text="user.mail" />
<quota-information v-if="quotaEnabled" :quota="quota" class="text-sm mt-1" />
<quota-information v-if="quota" :quota="quota" class="text-sm mt-1" />
</span>
</li>
<li class="flex items-center">
Expand All @@ -95,7 +93,7 @@
id="oc-topbar-account-logout"
appearance="raw"
justify-content="left"
@click="logout"
@click="authService.logoutUser()"
>
<oc-icon name="logout-box-r" fill-type="line" />
<span v-text="$gettext('Log out')" />
Expand Down Expand Up @@ -146,9 +144,9 @@
</nav>
</template>

<script lang="ts">
<script setup lang="ts">
import { storeToRefs } from 'pinia'
import { ComponentPublicInstance, computed, defineComponent, unref } from 'vue'
import { computed, unref } from 'vue'
import {
routeToContextQuery,
useAuthService,
Expand All @@ -159,74 +157,42 @@ import {
useThemeStore,
useUserStore
} from '@opencloud-eu/web-pkg'
import { OcDrop } from '@opencloud-eu/design-system/components'
import QuotaInformation from '../Account/QuotaInformation.vue'

export default defineComponent({
components: { UserAvatar, QuotaInformation },
setup() {
const route = useRoute()
const userStore = useUserStore()
const themeStore = useThemeStore()
const spacesStore = useSpacesStore()
const authService = useAuthService()
const authStore = useAuthStore()
const route = useRoute()
const userStore = useUserStore()
const themeStore = useThemeStore()
const spacesStore = useSpacesStore()
const authService = useAuthService()
const authStore = useAuthStore()

const { user } = storeToRefs(userStore)
const { user } = storeToRefs(userStore)

const accountPageRoute = computed(() => ({
name: authStore.userContextReady ? 'account-information' : 'account-preferences',
query: routeToContextQuery(unref(route))
}))

const loginLink = computed(() => {
return {
name: 'login',
query: { redirectUrl: unref(route).fullPath }
}
})
const logout = () => {
authService.logoutUser()
}
const accountPageRoute = computed(() => ({
name: authStore.userContextReady ? 'account-information' : 'account-preferences',
query: {
...routeToContextQuery(unref(route)),
...(!authStore.userContextReady &&
authStore.publicLinkContextReady && { contextRouteName: 'files-public-link' })
}
}))

const imprintUrl = computed(() => themeStore.currentTheme.urls.imprint)
const privacyUrl = computed(() => themeStore.currentTheme.urls.privacy)
const accessibilityUrl = computed(() => themeStore.currentTheme.urls.accessibility)
const loginLink = computed(() => {
return {
name: 'login',
query: { redirectUrl: unref(route).fullPath }
}
})

const showFooter = computed(() => {
return !!(unref(imprintUrl) || unref(privacyUrl) || unref(accessibilityUrl))
})
const imprintUrl = computed(() => themeStore.currentTheme.urls.imprint)
const privacyUrl = computed(() => themeStore.currentTheme.urls.privacy)
const accessibilityUrl = computed(() => themeStore.currentTheme.urls.accessibility)

const quota = computed(() => {
return spacesStore.personalSpace?.spaceQuota
})
const showFooter = computed(() => {
return !!(unref(imprintUrl) || unref(privacyUrl) || unref(accessibilityUrl))
})

return {
user,
loginLink,
imprintUrl,
privacyUrl,
accessibilityUrl,
showFooter,
quota,
logout,
accountPageRoute
}
},
computed: {
onPremisesSamAccountName() {
return this.user?.onPremisesSamAccountName
},
quotaEnabled() {
return !!this.quota
}
},
mounted() {
;(this.$refs.menu as InstanceType<typeof OcDrop>)?.tippy?.setProps({
onHidden: () => (this.$refs.menuButton as ComponentPublicInstance).$el.focus(),
onShown: () =>
(this.$refs.menu as ComponentPublicInstance).$el.querySelector('a:first-of-type').focus()
})
}
const quota = computed(() => {
return spacesStore.personalSpace?.spaceQuota
})
</script>
38 changes: 27 additions & 11 deletions packages/web-runtime/tests/unit/components/Topbar/UserMenu.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ import UserMenu from '../../../../src/components/Topbar/UserMenu.vue'
import {
defaultComponentMocks,
defaultPlugins,
defaultStubs,
mount,
RouteLocation
RouteLocation,
shallowMount
} from '@opencloud-eu/web-test-helpers'
import { mock } from 'vitest-mock-extended'
import { SpaceResource } from '@opencloud-eu/web-client'
import { Quota } from '@opencloud-eu/web-client/graph/generated'
import { WebThemeType } from '@opencloud-eu/web-pkg'
import { OcButton } from '@opencloud-eu/design-system/components'

const totalQuota = 1000
const basicQuota = 300
Expand Down Expand Up @@ -123,6 +123,23 @@ describe('User Menu component', () => {
expect(output).toContain('https://accessibility.url')
})
})
describe('account settings route', () => {
it('should link to account-information when user is logged in', () => {
const wrapper = getMountedWrapper({}, email)
const button = wrapper.findComponent<typeof OcButton>('#oc-topbar-account-manage')

expect((button.props('to') as RouteLocation).name).toEqual('account-information')
})
it('should link to account-preferences when user is not logged in', () => {
const wrapper = getMountedWrapper({}, noEmail, true)
const button = wrapper.findComponent<typeof OcButton>('#oc-topbar-account-manage')

expect((button.props('to') as RouteLocation).name).toEqual('account-preferences')
expect((button.props('to') as RouteLocation).query.contextRouteName).toEqual(
'files-public-link'
)
})
})
})

const getMountedWrapper = (
Expand All @@ -137,7 +154,7 @@ const getMountedWrapper = (
})
}

return mount(UserMenu, {
return shallowMount(UserMenu, {
global: {
provide: mocks,
renderStubDefaultSlot: true,
Expand Down Expand Up @@ -171,18 +188,17 @@ const getMountedWrapper = (
driveType: 'personal'
})
]
},
authState: {
userContextReady: !noUser,
publicLinkContextReady: noUser
}
}
})
],
stubs: {
...defaultStubs,
'oc-button': true,
'oc-drop': true,
'oc-list': true,
'avatar-image': true,
'oc-icon': true,
'oc-progress': true
OcAvatar: false,
UserAvatar: false
},
mocks
}
Expand Down
Loading