feat(web): split plan page from tasks (FE-6)

- Nav overview group: 首页 / 任务 / 计划 / Agent 会话; tasks page drops the plan tab
- /console/tasks?tab=plan[&job=] redirects to /console/schedules[?job=]
- Plan page: 自动任务 compact grouped list (switch, interval preset/custom, last result,
  countdown, failure reason, run now/skip/run records) and Agent 巡检 cards (goal,
  allowlist, budget, upstream/model, trigger, cost per run, recent sessions); split stats
- Home plan band: two counts linking to #auto / #checks
- Docs: console-ia §7.4a, glossary, schedules runbook; smoke routes

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-09-29 17:13:54 +08:00
1 parent c3aaf901ad
commit baf2d6ea04
22 files changed
+1030 -417

No files matched your search

+7 -7
View File
@@ -19,22 +19,21 @@ describe("控制台导航", () => {
it("IA-3:5 组,按定稿清单逐项列出,路径唯一且都在 /console 下", () => {
expect(NAV_GROUPS.map((g) => g.title)).toEqual(["概览", "资源", "订阅", "整理", "系统"]);
expect(NAV_GROUPS.map((g) => g.items.map((i) => i.label))).toEqual([
["首页", "任务", "Agent 会话"],
["首页", "任务", "计划", "Agent 会话"],
["站点", "RSS 订阅"],
["订阅", "规则"],
["下载面板", "整理记录", "文件管理", "媒体概览"],
["设置", "审计", "运行状态"],
]);
// 定稿文字写"共 12 项",逐项清单实际是 14 项;以清单为准
expect(NAV_ITEMS).toHaveLength(14);
// IA-3 逐项清单 14 项 + FE-6 计划页
expect(NAV_ITEMS).toHaveLength(15);
expect(new Set(NAV_ITEMS.map((i) => i.to)).size).toBe(NAV_ITEMS.length);
expect(NAV_ITEMS.every((i) => i.to.startsWith("/console"))).toBe(true);
});
it("取消的入口不在侧栏:待处理走顶栏收件箱,引擎面板 / 定时任务 / 身份并入别处", () => {
it("取消的入口不在侧栏:待处理走顶栏收件箱,引擎面板 / 身份并入别处", () => {
const paths = NAV_ITEMS.map((i) => i.to);
for (const p of ["/console/inbox", "/console/engine", "/console/schedules", "/console/identity"])
expect(paths).not.toContain(p);
for (const p of ["/console/inbox", "/console/engine", "/console/identity"]) expect(paths).not.toContain(p);
expect(pageTitle("/console/inbox")).toBe("待处理");
});
@@ -47,6 +46,7 @@ describe("控制台导航", () => {
expect(findNavItem("/console/")?.label).toBe("首页");
expect(findNavItem("/console/library/abc")?.label).toBe("媒体概览");
expect(findNavItem("/console/tasks/r1")?.label).toBe("任务");
expect(findNavItem("/console/schedules")?.label).toBe("计划");
expect(findNavItem("/console/downloads")?.label).toBe("下载面板");
expect(findNavItem("/console/downloads/plans")?.label).toBe("下载面板");
expect(findNavItem("/console/downloads/abc")?.label).toBe("下载面板");
@@ -83,7 +83,7 @@ describe("旧链接重定向", () => {
it("不相关的 query 不跳转", () => {
expect(legacyRedirect("/console/tasks", "?kind=submitDownload")).toBeNull();
expect(legacyRedirect("/console/tasks", "?tab=plan&job=trash.purge")).toBeNull();
expect(legacyRedirect("/console/schedules", "?job=trash.purge")).toBeNull();
expect(legacyRedirect("/console/tasks", "?tab=failed")).toBeNull();
expect(legacyRedirect("/console/library", "?filter=unidentified")).toBeNull();
expect(legacyRedirect("/console/subscriptions", "")).toBeNull();