优化
This commit is contained in:
@@ -17,6 +17,7 @@ import {
|
||||
getFirstAccessiblePath,
|
||||
getNavigationLeaves,
|
||||
getNavigationParentKeys,
|
||||
getRouteBreadcrumbs,
|
||||
openNavigationParentKeys,
|
||||
} from './clientNavigation.ts'
|
||||
|
||||
@@ -207,6 +208,31 @@ test('returns navigation parent keys from outermost to innermost', () => {
|
||||
assert.deepEqual(getNavigationParentKeys(clientNavigation, '/not-found'), [])
|
||||
})
|
||||
|
||||
test('builds complete breadcrumbs without repeating the current navigation page', () => {
|
||||
assert.deepEqual(getRouteBreadcrumbs('/', '业务总览'), [{ title: '首页' }])
|
||||
assert.deepEqual(getRouteBreadcrumbs('/orders/first-leg', '订单列表'), [
|
||||
{ title: '首页', path: '/' },
|
||||
{ title: '头程物流' },
|
||||
{ title: '订单列表' },
|
||||
])
|
||||
assert.deepEqual(getRouteBreadcrumbs('/orders/first-leg/create', '创建订单'), [
|
||||
{ title: '首页', path: '/' },
|
||||
{ title: '头程物流' },
|
||||
{ title: '订单列表', path: '/orders/first-leg' },
|
||||
{ title: '创建订单' },
|
||||
])
|
||||
assert.deepEqual(getRouteBreadcrumbs('/notifications/NOTICE-001', '消息详情'), [
|
||||
{ title: '首页', path: '/' },
|
||||
{ title: '消息中心' },
|
||||
{ title: '我的消息', path: '/notifications' },
|
||||
{ title: '消息详情' },
|
||||
])
|
||||
assert.deepEqual(getRouteBreadcrumbs('/forbidden', '无权访问'), [
|
||||
{ title: '首页', path: '/' },
|
||||
{ title: '无权访问' },
|
||||
])
|
||||
})
|
||||
|
||||
test('opens the company parent group for a company route', () => {
|
||||
const openedKeys = []
|
||||
|
||||
|
||||
@@ -62,6 +62,41 @@ export function getFirstAccessiblePath(permissions: readonly string[]) {
|
||||
return getNavigationLeaves(filterNavigationByPermissions(clientNavigation, permissions))[0]?.path ?? '/forbidden'
|
||||
}
|
||||
|
||||
export interface ClientBreadcrumbItem {
|
||||
title: string
|
||||
path?: string
|
||||
}
|
||||
|
||||
function findNavigationTrail(
|
||||
nodes: readonly ClientNavigationNode[],
|
||||
path: string,
|
||||
parents: readonly ClientBreadcrumbItem[] = [],
|
||||
): ClientBreadcrumbItem[] | undefined {
|
||||
for (const node of nodes) {
|
||||
if (isNavigationGroup(node)) {
|
||||
const result = findNavigationTrail(node.children, path, [...parents, { title: node.title }])
|
||||
if (result) return result
|
||||
continue
|
||||
}
|
||||
if (node.path === path) return [...parents, { title: node.title, path: node.path }]
|
||||
}
|
||||
}
|
||||
|
||||
export function getRouteBreadcrumbs(path: string, currentTitle: string): ClientBreadcrumbItem[] {
|
||||
const home: ClientBreadcrumbItem = { title: '首页', path: '/' }
|
||||
if (path === '/') return [{ title: '首页' }]
|
||||
|
||||
const leaves = getNavigationLeaves(clientNavigation)
|
||||
.filter((leaf) => leaf.path !== '/' && (path === leaf.path || path.startsWith(`${leaf.path}/`)))
|
||||
.sort((left, right) => right.path.length - left.path.length)
|
||||
const parentLeaf = leaves[0]
|
||||
const trail = parentLeaf ? findNavigationTrail(clientNavigation, parentLeaf.path) ?? [] : []
|
||||
const items = [home, ...trail]
|
||||
if (items.at(-1)?.title !== currentTitle) items.push({ title: currentTitle })
|
||||
if (items.length > 1) delete items.at(-1)!.path
|
||||
return items
|
||||
}
|
||||
|
||||
function findNavigationParentKeys(
|
||||
nodes: readonly ClientNavigationNode[],
|
||||
path: string,
|
||||
|
||||
Reference in New Issue
Block a user