Files
UHD_Media_Tool/apps/web/app/components/console/nav.ts
T
rootandClaude Opus 5.5 e5e42b1f0d feat(web): W3-1 shared console routes, nav, api/sse/query-keys and shared components
- routes.ts registers all workspaces under /console (+ detail routes, engine, audit, login)
- api.ts: cookie session first (credentials include, CSRF header), Bearer only with stored key, 401 -> /login
- sse.ts: shared EventSource with ?after=seq catch-up, backoff reconnect, per-type subscribe
- shared components: data-table, filter-bar, detail-sheet, timeline, json-view, confirm-dialog,
  form-field, kv-list, stat-tile, error/loading states; ui tabs and textarea

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-27 20:21:29 +08:00

145 lines
4.1 KiB
TypeScript

import {
Activity,
Bot,
CalendarClock,
Download,
FileStack,
Fingerprint,
Globe,
House,
Inbox,
Library,
type LucideIcon,
Rss,
ScrollText,
Settings,
Tags,
} from "lucide-react";
export type NavItem = { to: string; label: string; icon: LucideIcon; description: string };
export type NavGroup = { title: string; items: NavItem[] };
/** 控制台路由前缀 */
export const CONSOLE_BASE = "/console";
/** 拼控制台路径:consolePath("library", id) → /console/library/<id> */
export function consolePath(...segments: (string | number)[]): string {
const rest = segments.map((s) => encodeURIComponent(String(s))).join("/");
return rest ? `${CONSOLE_BASE}/${rest}` : CONSOLE_BASE;
}
/** 控制台 12 个工作区(任务书 §3.1 第 10 条 / REQ §13.1)+ 引擎面板与审计两个运维页 */
export const NAV_GROUPS: NavGroup[] = [
{
title: "概览",
items: [
{
to: "/console",
label: "首页",
icon: House,
description: "自动化概览、当前工作、需要我处理、缓存与保留、来源健康、最近产出",
},
{
to: "/console/inbox",
label: "待处理中心",
icon: Inbox,
description: "按作品与根因合并的待决定事项,Agent 已先行调查",
},
],
},
{
title: "媒体",
items: [
{ to: "/console/library", label: "媒体库", icon: Library, description: "作品、内容单元、版本目标与实际路径" },
{
to: "/console/identity",
label: "身份与元数据",
icon: Fingerprint,
description: "外部身份映射、待识别池与元数据来源",
},
{
to: "/console/organize",
label: "整理记录",
icon: FileStack,
description: "Copy/Move 入库前后路径与逐文件结果",
},
],
},
{
title: "获取",
items: [
{
to: "/console/subscriptions",
label: "订阅与收录规则",
icon: CalendarClock,
description: "单次收录与持续追踪,版本目标与预算",
},
{
to: "/console/preferences",
label: "偏好标签",
icon: Tags,
description: "软偏好与硬规则,手动取消的偏好不会被自动加回",
},
{
to: "/console/sites",
label: "PT 站点工作台",
icon: Globe,
description: "统一格式浏览、搜索站点资源并关联本地库存",
},
{
to: "/console/sources",
label: "来源 / Feed / 快照",
icon: Rss,
description: "RSS 与站点快照的抓取状态、新鲜度与健康",
},
{
to: "/console/tasks",
label: "下载与任务",
icon: Download,
description: "下载、整理、核验的业务时间线与子任务",
},
],
},
{
title: "助手与系统",
items: [
{
to: "/console/agent",
label: "Agent 会话",
icon: Bot,
description: "用自然语言交代目标,Agent 在授权内执行并汇报",
},
{
to: "/console/settings",
label: "系统设置",
icon: Settings,
description: "下载器与媒体服务器实例、路径映射、API Key、Pi 上游与自动化开关",
},
{
to: "/console/engine",
label: "工作流引擎",
icon: Activity,
description: "持久任务引擎的运行记录、步骤尝试与信号(只读诊断,仅管理员)",
},
{
to: "/console/audit",
label: "审计日志",
icon: ScrollText,
description: "登录、设置、密钥与实例变更的操作留痕",
},
],
},
];
export const NAV_ITEMS = NAV_GROUPS.flatMap((g) => g.items);
/** 按路径找当前导航项(最长前缀匹配) */
export function findNavItem(pathname: string): NavItem | undefined {
return (
NAV_ITEMS.find((i) => i.to === pathname.replace(/\/+$/, "")) ??
NAV_ITEMS.filter((i) => i.to !== CONSOLE_BASE && pathname.startsWith(`${i.to}/`)).sort(
(a, b) => b.to.length - a.to.length,
)[0]
);
}