fix: route logo to configured landing page
Use the default landing-page resolver for logo navigation while keeping the Overview menu as an explicit overview link.
This commit is contained in:
parent
34d67823cb
commit
150940291c
|
|
@ -4,16 +4,17 @@
|
|||
aria-label="main navigation"
|
||||
class="navbar d-print-none"
|
||||
>
|
||||
<RouterLink
|
||||
:to="{ name: 'home' }"
|
||||
<a
|
||||
href="/"
|
||||
class="logo-link"
|
||||
:aria-label="$t('navigation.home')"
|
||||
@click.prevent="openLandingPage"
|
||||
>
|
||||
<Logo
|
||||
width="164"
|
||||
height="48"
|
||||
/>
|
||||
</RouterLink>
|
||||
</a>
|
||||
|
||||
<MenuButton class="menu-button" />
|
||||
|
||||
|
|
@ -129,7 +130,7 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import { PERMISSIONS as Permissions } from '@/constants/permissions'
|
||||
|
|
@ -147,6 +148,7 @@ import OpenQuickActions from '@/components/misc/OpenQuickActions.vue'
|
|||
|
||||
import { getProjectTitle } from '@/helpers/getProjectTitle'
|
||||
import { isEditorContentEmpty } from '@/helpers/editorContentEmpty'
|
||||
import { getDefaultPageRoute } from '@/helpers/getDefaultPageRoute'
|
||||
|
||||
import { useBaseStore } from '@/stores/base'
|
||||
import { useConfigStore } from '@/stores/config'
|
||||
|
|
@ -165,6 +167,7 @@ const menuActive = computed(() => baseStore.menuActive)
|
|||
|
||||
// Standalone pages (no project) surface their route's title in the header.
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const { t } = useI18n()
|
||||
const pageTitle = computed(() => {
|
||||
const title = route.meta.title as string | undefined
|
||||
|
|
@ -177,6 +180,10 @@ const configStore = useConfigStore()
|
|||
const imprintUrl = computed(() => configStore.legal.imprintUrl)
|
||||
const privacyPolicyUrl = computed(() => configStore.legal.privacyPolicyUrl)
|
||||
const adminPanelEnabled = computed(() => configStore.isProFeatureEnabled(PRO_FEATURE.ADMIN_PANEL))
|
||||
|
||||
async function openLandingPage() {
|
||||
await router.push(await getDefaultPageRoute() ?? {name: 'home'})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
|||
|
|
@ -5,16 +5,17 @@
|
|||
:style="{'--sidebar-width': sidebarWidth}"
|
||||
>
|
||||
<nav class="menu top-menu">
|
||||
<RouterLink
|
||||
:to="{name: 'home'}"
|
||||
<a
|
||||
href="/"
|
||||
class="logo"
|
||||
:aria-label="$t('navigation.home')"
|
||||
@click.prevent="openLandingPage"
|
||||
>
|
||||
<Logo
|
||||
width="164"
|
||||
height="48"
|
||||
/>
|
||||
</RouterLink>
|
||||
</a>
|
||||
<menu class="menu-list other-menu-items">
|
||||
<li>
|
||||
<RouterLink
|
||||
|
|
@ -134,6 +135,7 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import {computed} from 'vue'
|
||||
import {useRouter} from 'vue-router'
|
||||
|
||||
import PoweredByLink from '@/components/home/PoweredByLink.vue'
|
||||
import Logo from '@/components/home/Logo.vue'
|
||||
|
|
@ -146,10 +148,12 @@ import {PRO_FEATURE} from '@/constants/proFeatures'
|
|||
import ProjectsNavigation from '@/components/home/ProjectsNavigation.vue'
|
||||
import type {IProject} from '@/modelTypes/IProject'
|
||||
import {useSidebarResize} from '@/composables/useSidebarResize'
|
||||
import {getDefaultPageRoute} from '@/helpers/getDefaultPageRoute'
|
||||
|
||||
const baseStore = useBaseStore()
|
||||
const projectStore = useProjectStore()
|
||||
const configStore = useConfigStore()
|
||||
const router = useRouter()
|
||||
|
||||
const timeTrackingEnabled = computed(() => configStore.isProFeatureEnabled(PRO_FEATURE.TIME_TRACKING))
|
||||
|
||||
|
|
@ -159,6 +163,10 @@ const {sidebarWidth, isResizing, startResize, isMobile} = useSidebarResize()
|
|||
const projects = computed(() => projectStore.notArchivedRootProjects as IProject[])
|
||||
const favoriteProjects = computed(() => projectStore.favoriteProjects as IProject[])
|
||||
const savedFilterProjects = computed(() => projectStore.savedFilterProjects as IProject[])
|
||||
|
||||
async function openLandingPage() {
|
||||
await router.push(await getDefaultPageRoute() ?? {name: 'home'})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
|||
|
|
@ -70,6 +70,9 @@ test.describe('Default Landing Page', () => {
|
|||
await page.locator('nav.menu.top-menu a').filter({hasText: 'Overview'}).click()
|
||||
await page.waitForLoadState('networkidle')
|
||||
await expect(page).toHaveURL('/')
|
||||
|
||||
await page.locator('.logo-link').click()
|
||||
await page.waitForURL(`**/projects/${project.id}/**`)
|
||||
})
|
||||
|
||||
test('falls back to overview when default project does not exist', async ({page, apiContext}) => {
|
||||
|
|
@ -107,7 +110,7 @@ test.describe('Default Landing Page', () => {
|
|||
await page.waitForURL(`**/projects/${project.id}/${views[0].id}`)
|
||||
})
|
||||
|
||||
test('does not redirect on in-app navigation to home', async ({page, apiContext}) => {
|
||||
test('redirects to default page when clicking the logo', async ({page, apiContext}) => {
|
||||
const user = (await UserFactory.create(1, {
|
||||
frontend_settings: JSON.stringify({defaultPage: 'upcoming'}),
|
||||
}))[0]
|
||||
|
|
@ -121,7 +124,6 @@ test.describe('Default Landing Page', () => {
|
|||
await page.waitForLoadState('networkidle')
|
||||
|
||||
await page.locator('.logo-link').click()
|
||||
await page.waitForLoadState('networkidle')
|
||||
await expect(page).toHaveURL('/')
|
||||
await page.waitForURL('**/tasks/by/upcoming**')
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -3,14 +3,21 @@ import {TaskFactory} from '../../factories/task'
|
|||
import {ProjectFactory} from '../../factories/project'
|
||||
import {createProjects} from './prepareProjects'
|
||||
|
||||
interface ProjectWithViews {
|
||||
id: number
|
||||
title: string
|
||||
views: Array<{id: number}>
|
||||
}
|
||||
|
||||
test.describe('Projects', () => {
|
||||
test.use({
|
||||
// Use authenticated page for all tests
|
||||
})
|
||||
|
||||
let projects: any[]
|
||||
let projects: ProjectWithViews[]
|
||||
|
||||
test.beforeEach(async ({authenticatedPage}) => {
|
||||
test.beforeEach(async ({authenticatedPage: page}) => {
|
||||
void page
|
||||
projects = await createProjects()
|
||||
})
|
||||
|
||||
|
|
@ -72,7 +79,7 @@ test.describe('Projects', () => {
|
|||
await expect(page.locator('.project-title')).toContainText(newProjectName)
|
||||
await expect(page.locator('.project-title')).not.toContainText(projects[0].title)
|
||||
await expect(page.locator('.menu-container .menu-list').getByRole('listitem').filter({hasText: newProjectName})).toBeVisible()
|
||||
await page.locator('.logo-link').click()
|
||||
await page.locator('nav.menu.top-menu a').filter({hasText: 'Overview'}).click()
|
||||
await page.waitForLoadState('networkidle')
|
||||
await expect(page.locator('.project-grid')).toContainText(newProjectName)
|
||||
await expect(page.locator('.project-grid')).not.toContainText(projects[0].title)
|
||||
|
|
|
|||
Loading…
Reference in New Issue