Files
writer-work-flow/apps/web/lib/nav/items.ts
Yaojia Wang a2dcd89881 feat(web): Scope B B1 — 多章工作流链前端 UI(发起/轮询/裁决续跑)
链页 app/projects/[id]/chains(RSC fetchProject)+ ChainPage/ChainStarter/
ChainProgress/ChainAdjudication;lib/chain 纯函数(result 收窄/相位映射/resume 组装)。
复用 useJobPoll 轮询、ConflictCard + decisions.ts 裁决、normalizeConflicts/latestReview、
friendlyError;nav 加 chains 入口。awaiting(interrupt)→ 读该章冲突渲 ConflictCard →
POST .../chains/runs/{job_id}/resume 续跑。gen:api 纳入 chains run/resume。
守 #5(链暂停=等裁决,token/正文不入 job result)。
2026-06-23 19:21:00 +02:00

60 lines
2.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 左导航条目数据 + 激活判定(纯逻辑,供桌面静态侧栏 / 移动抽屉共用UX §5.1/§3.1)。
// 组件只负责渲染;条目与高亮规则在此集中,避免侧栏与抽屉漂移。
export type ActiveNav =
| "write"
| "outline"
| "foreshadow"
| "review"
| "style"
| "codex"
| "rules"
| "skills"
| "toolbox"
| "chains";
export interface NavItem {
href: string;
label: string;
// 项目级入口的激活键(与 activeNav 比对高亮);全局项无 key。
key?: ActiveNav;
}
export const GLOBAL_NAV_ITEMS: readonly NavItem[] = [
{ href: "/", label: "作品库" },
{ href: "/settings/providers", label: "设置" },
];
// 项目内页展开的项目级入口UX §3.1)。
export function projectNavItems(projectId: string): NavItem[] {
return [
{ href: `/projects/${projectId}/write`, label: "写作", key: "write" },
{ href: `/projects/${projectId}/outline`, label: "大纲", key: "outline" },
{
href: `/projects/${projectId}/foreshadow`,
label: "伏笔",
key: "foreshadow",
},
{ href: `/projects/${projectId}/review`, label: "审稿", key: "review" },
{ href: `/projects/${projectId}/chains`, label: "多章链", key: "chains" },
{ href: `/projects/${projectId}/style`, label: "文风", key: "style" },
{ href: `/projects/${projectId}/codex`, label: "设定库", key: "codex" },
{ href: `/projects/${projectId}/toolbox`, label: "工具箱", key: "toolbox" },
{ href: `/projects/${projectId}/rules`, label: "规则", key: "rules" },
{ href: `/projects/${projectId}/skills`, label: "技能库", key: "skills" },
];
}
export interface NavActiveContext {
pathname: string;
activeNav?: ActiveNav;
}
// 全局项按精确路径匹配;项目项按 activeNav 键匹配(或路径相等兜底)。
export function isNavItemActive(item: NavItem, ctx: NavActiveContext): boolean {
if (item.key !== undefined) {
return item.key === ctx.activeNav || ctx.pathname === item.href;
}
return ctx.pathname === item.href;
}