Skip to content

Commit

Permalink
- Align window titles with breadcrumb
Browse files Browse the repository at this point in the history
- Added project breadcrumb
  • Loading branch information
grolu committed Mar 21, 2024
1 parent 6ef5e94 commit 7b0b665
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 41 deletions.
43 changes: 37 additions & 6 deletions frontend/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,36 @@ import {
inject,
toRef,
watch,
computed,
} from 'vue'
import { useTheme } from 'vuetify'
import {
onKeyStroke,
useEventBus,
useColorMode,
useDocumentVisibility,
useTitle,
} from '@vueuse/core'
import { useRoute } from 'vue-router'

import { useConfigStore } from '@/store/config'
import { useLoginStore } from '@/store/login'
import { useLocalStorageStore } from '@/store/localStorage'
import { useShootStore } from '@/store/shoot'
import { useProjectStore } from '@/store/project'

import { useCustomColors } from '@/composables/useCustomColors'

import { last } from '@/lodash'

const theme = useTheme()
const route = useRoute()
const localStorageStore = useLocalStorageStore()
const visibility = useDocumentVisibility()
const configStore = useConfigStore()
const loginStore = useLoginStore()
const shootStore = useShootStore()
const projectStore = useProjectStore()
const logger = inject('logger')

async function setCustomColors () {
Expand All @@ -46,12 +54,6 @@ async function setCustomColors () {
}
setCustomColors()

watch(() => configStore.branding ?? loginStore.branding, branding => {
if (branding.productTitle) {
document.title = branding.documentTitle ?? `${branding.productName} Dashboard`
}
})

const colorScheme = toRef(localStorageStore, 'colorScheme')
const { system } = useColorMode({
storageRef: colorScheme,
Expand All @@ -76,4 +78,33 @@ watch(visibility, (current, previous) => {
shootStore.invokeSubscriptionEventHandler()
}
})

const documentTitle = computed(() => {
let appTitle = process.env.VITE_APP_TITLE
const branding = configStore.branding ?? loginStore.branding
if (branding.productTitle) {
appTitle = branding.documentTitle ?? `${branding.productName} Dashboard`
}

const breadcrumbs = route.meta.breadcrumbs ?? []
const breadcrumbItems = typeof breadcrumbs === 'function'
? breadcrumbs(route, projectStore.projectName)
: breadcrumbs

const projectItem = breadcrumbItems.find(item => item.isProjectItem)
const nameItem = breadcrumbItems.find(item => item.isNameItem)
const pageItem = last(breadcrumbItems.filter(item => !item.isProjectItem && !item.isNameItem))

const locationTitle = [projectItem?.title, nameItem?.title].filter(item => item !== undefined).join('/')
const titleItems = [pageItem?.title, locationTitle].filter(item => item?.length)

if (titleItems.length) {
appTitle = `${titleItems.join(' • ')} | ${appTitle}`
}

return appTitle
})

useTitle(documentTitle)

</script>
5 changes: 4 additions & 1 deletion frontend/src/components/GBreadcrumb.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,17 @@ SPDX-License-Identifier: Apache-2.0
import { computed } from 'vue'
import { useRoute } from 'vue-router'

import { useProjectStore } from '@/store/project'

import { kebabCase } from '@/lodash'

const route = useRoute()
const projectStore = useProjectStore()

const breadcrumbItems = computed(() => {
const breadcrumbs = route.meta?.breadcrumbs ?? []
const items = typeof breadcrumbs === 'function'
? breadcrumbs(route)
? breadcrumbs(route, projectStore.projectName)
: breadcrumbs
return items.map(({ title, href, to, disabled, exact }) => {
const item = {
Expand Down
54 changes: 41 additions & 13 deletions frontend/src/router/breadcrumbs.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,21 @@ import {
pick,
} from '@/lodash'

function projectItem (params, projectName) {
return {
get title () {
return projectName
},
get to () {
return {
name: 'Administration',
params: pick(params, ['namespace']),
}
},
isProjectItem: true,
}
}

export function homeBreadcrumbs () {
return [
{
Expand Down Expand Up @@ -41,56 +56,63 @@ export function settingsBreadcrumbs () {
]
}

export function membersBreadcrumbs () {
export function membersBreadcrumbs ({ params }, projectName) {
return [
projectItem(params, projectName),
{
title: 'Members',
},
]
}

export function administrationBreadcrumbs () {
export function administrationBreadcrumbs ({ params }, projectName) {
return [
projectItem(params, projectName),
{
title: 'Administration',
},
]
}

export function newShootBreadcrumbs () {
export function newShootBreadcrumbs ({ params }, projectName) {
return [
projectItem(params, projectName),
{
title: 'Create Cluster',
},
]
}

export function newShootEditorBreadcrumbs () {
export function newShootEditorBreadcrumbs ({ params }, projectName) {
return [
projectItem(params, projectName),
{
title: 'Create Cluster Editor',
},
]
}

export function terminalBreadcrumbs () {
export function terminalBreadcrumbs ({ params }, projectName) {
return [
projectItem(params, projectName),
{
title: 'Garden Cluster Terminal',
},
]
}

export function shootListBreadcrumbs () {
export function shootListBreadcrumbs ({ params }, projectName) {
return [
projectItem(params, projectName),
{
title: 'Project Clusters',
title: 'Clusters',
},
]
}

export function secretsBreadcrumbs () {
export function secretsBreadcrumbs ({ params }, projectName) {
return [
projectItem(params, projectName),
{
title: 'Secrets',
},
Expand All @@ -105,10 +127,11 @@ export function notFoundBreadcrumbs () {
]
}

export function shootItemBreadcrumbs ({ params }) {
export function shootItemBreadcrumbs ({ params }, projectName) {
return [
projectItem(params, projectName),
{
title: 'Project Clusters',
title: 'Clusters',
get to () {
return {
name: 'ShootList',
Expand All @@ -120,12 +143,14 @@ export function shootItemBreadcrumbs ({ params }) {
get title () {
return get(params, 'name')
},
isNameItem: true,
},
]
}

export function secretItemBreadcrumbs ({ params }) {
export function secretItemBreadcrumbs ({ params }, projectName) {
return [
projectItem(params, projectName),
{
title: 'Secrets',
get to () {
Expand All @@ -139,14 +164,16 @@ export function secretItemBreadcrumbs ({ params }) {
get title () {
return get(params, 'name')
},
isNameItem: true,
},
]
}

export function shootItemTerminalBreadcrumbs ({ params }) {
export function shootItemTerminalBreadcrumbs ({ params }, projectName) {
return [
projectItem(params, projectName),
{
title: 'Project Clusters',
title: 'Clusters',
get to () {
return {
name: 'ShootList',
Expand All @@ -164,6 +191,7 @@ export function shootItemTerminalBreadcrumbs ({ params }) {
params,
}
},
isNameItem: true,
},
{
title: 'Terminal',
Expand Down
14 changes: 2 additions & 12 deletions frontend/src/router/guards.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
// SPDX-License-Identifier: Apache-2.0
//

import { useRoute } from 'vue-router'

import { useAppStore } from '@/store/app'
import { useAuthzStore } from '@/store/authz'
import { useAuthnStore } from '@/store/authn'
Expand Down Expand Up @@ -165,18 +167,6 @@ export function createGlobalBeforeGuards () {
},
ensureUserAuthenticatedForNonPublicRoutes(),
ensureDataLoaded(),
to => {
const titles = []
titles.push(to.meta.title ?? to.name)
if (to.params.name) {
titles.push(to.params.name)
}
if (projectStore.projectName) {
titles.push(projectStore.projectName)
}
titles.push(process.env.VITE_APP_TITLE)
document.title = titles.join(' | ')
},
]
}

Expand Down
9 changes: 0 additions & 9 deletions frontend/src/router/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,6 @@ export function createRoutes () {
namespaced: false,
projectScope: false,
breadcrumbs: newProjectBreadcrumbs,
title: 'New Project',
},
}
}
Expand Down Expand Up @@ -251,7 +250,6 @@ export function createRoutes () {
title: 'Clusters',
icon: 'mdi-hexagon-multiple',
},
title: 'Clusters',
projectScope: false,
breadcrumbs: shootListBreadcrumbs,
},
Expand All @@ -266,7 +264,6 @@ export function createRoutes () {
meta: {
breadcrumbs: newShootBreadcrumbs,
tabs: newShootTabs,
title: 'Create Cluster',
},
}
}
Expand All @@ -279,7 +276,6 @@ export function createRoutes () {
meta: {
breadcrumbs: newShootEditorBreadcrumbs,
tabs: newShootTabs,
title: 'Create Cluster Editor',
},
}
}
Expand All @@ -292,7 +288,6 @@ export function createRoutes () {
meta: {
breadcrumbs: shootItemBreadcrumbs,
tabs: shootItemTabs,
title: 'Cluster Details',
},
}
}
Expand All @@ -305,7 +300,6 @@ export function createRoutes () {
meta: {
breadcrumbs: shootItemBreadcrumbs,
tabs: shootItemTabs,
title: 'Cluster Editor',
},
}
}
Expand All @@ -318,7 +312,6 @@ export function createRoutes () {
meta: {
breadcrumbs: shootItemBreadcrumbs,
tabs: shootItemTabs,
title: 'Hibernation',
},
}
}
Expand All @@ -330,7 +323,6 @@ export function createRoutes () {
component: GShootItemTerminal,
meta: {
breadcrumbs: shootItemTerminalBreadcrumbs,
title: 'Terminal',
},
beforeEnter (to, from) {
if (!authzStore.hasShootTerminalAccess) {
Expand Down Expand Up @@ -414,7 +406,6 @@ export function createRoutes () {
},
},
breadcrumbs: terminalBreadcrumbs,
title: 'Garden Terminal',
},
beforeEnter (to, from) {
if (!authzStore.hasGardenTerminalAccess) {
Expand Down

0 comments on commit 7b0b665

Please sign in to comment.