V13-FE-011: finalize search list layout slice

This commit is contained in:
2026-08-09 02:57:26 +09:00
parent 9efd202e76
commit 6422cb2b13
984 changed files with 120811 additions and 1498 deletions
@@ -0,0 +1,52 @@
export interface NavigationRouteLike {
path: string
meta?: Record<string, unknown>
}
export interface NavigationEntry {
screenId: string
path: string
module: string
section: string
title: string
order: number
favoriteAllowed: boolean
internalOnly: boolean
}
export interface NavigationSection {
module: string
entries: NavigationEntry[]
}
function toEntry(route: NavigationRouteLike): NavigationEntry | null {
const meta = route.meta
if (!meta || typeof meta.screenId !== 'string' || typeof meta.module !== 'string') return null
if (meta.module === 'Home') return null
return {
screenId: meta.screenId,
path: route.path,
module: meta.module,
section: typeof meta.section === 'string' ? meta.section : meta.module,
title: typeof meta.title === 'string' ? meta.title : route.path,
order: typeof meta.order === 'number' ? meta.order : 0,
favoriteAllowed: meta.favoriteAllowed !== false,
internalOnly: meta.internalOnly === true
}
}
/** router.getRoutes()의 flat route 목록에서 즐겨찾기/검색/사이드바가 공유하는 단일 카탈로그를 파생한다. */
export function buildNavigationEntries(routes: readonly NavigationRouteLike[]): NavigationEntry[] {
const entries = routes.map(toEntry).filter((entry): entry is NavigationEntry => entry !== null)
return entries.sort((a, b) => a.module.localeCompare(b.module) || a.order - b.order)
}
export function groupByModule(entries: readonly NavigationEntry[]): NavigationSection[] {
const byModule = new Map<string, NavigationEntry[]>()
for (const entry of entries) {
const list = byModule.get(entry.module) ?? []
list.push(entry)
byModule.set(entry.module, list)
}
return [...byModule.entries()].map(([module, list]) => ({ module, entries: [...list].sort((a, b) => a.order - b.order) }))
}