控制台导航最多两层(侧栏一项 = 一页,页内最多一层页签 / 分段);从列表打开的
记录改成列表页上的右侧抽屉,打开的记录写在 ?open=,刷新、分享、前进后退都能还原,
后退就是关抽屉。标准写在 docs/design/console-ia.md §9,ui-controls.md 引用。
- DetailSheet 加 xl 宽度、标题下操作行;抽屉里再开的 DetailSheet 在同一抽屉里换成子视图(返回 / Esc)
- record-sheet.tsx:useRecordSheet / RecordLink / useOpenRecord / recordPath / taskPath
- 整理记录、订阅、站点(含页签)、下载、日志任务改成抽屉;旧业务任务 / 下载任务 id 在任务抽屉里换算
- 回收站并进文件管理右侧视图(?view=trash);设置左栏只列分区
- 规则组、策略版本、媒体库未识别 / 外部身份、设置实例编辑走 ?open=
- 旧地址 /console/{organize,subscriptions,sites,downloads}/:id、/tasks/:id、/files/trash 跳到列表页抽屉
- 站内链接、铃铛、命令面板、任务时间线改拼新地址;冒烟按 ?open= 检查抽屉
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
88 lines
3.1 KiB
TypeScript
88 lines
3.1 KiB
TypeScript
import type { AttentionSummary, Decision } from "@umt/contracts";
|
|
import { describe, expect, it } from "vitest";
|
|
import { approvalHref, HEALTH_HREF } from "../console/inbox-bell.tsx";
|
|
import { attentionRows } from "./attention-summary.tsx";
|
|
|
|
// 首页 / 运行状态的「需要关注」汇总计数与铃铛跳转(2026-10-06 去掉待处理中心后)。
|
|
|
|
const id = (n: number) => `00000000-0000-4000-8000-${String(n).padStart(12, "0")}`;
|
|
const dec = (n: number, over: Partial<Decision>): Decision =>
|
|
({
|
|
id: id(n),
|
|
kind: "other",
|
|
status: "open",
|
|
severity: "warning",
|
|
title: "t",
|
|
summary: null,
|
|
subjectType: null,
|
|
subjectId: null,
|
|
dedupeKey: `k${n}`,
|
|
evidence: {},
|
|
options: [],
|
|
resolution: null,
|
|
taskId: null,
|
|
agentRunId: null,
|
|
attempts: 0,
|
|
nextReviewAt: null,
|
|
resolvedBy: null,
|
|
resolvedAt: null,
|
|
createdAt: "2026-10-06T00:00:00.000Z",
|
|
updatedAt: "2026-10-06T00:00:00.000Z",
|
|
...over,
|
|
}) as Decision;
|
|
|
|
const empty: AttentionSummary = { organize: 0, approvals: { total: 0, items: [] }, health: { total: 0, items: [] } };
|
|
|
|
describe("需要关注汇总", () => {
|
|
it("只列非零项", () => {
|
|
expect(attentionRows(empty)).toEqual([]);
|
|
expect(attentionRows(undefined)).toEqual([]);
|
|
});
|
|
|
|
it("整理需要处理 / 等你批准 / 系统健康按问题归类,点进去到对应页面", () => {
|
|
const rows = attentionRows({
|
|
organize: 3,
|
|
approvals: {
|
|
total: 1,
|
|
items: [dec(1, { kind: "approval_required", subjectType: "agent_run", subjectId: id(9) })],
|
|
},
|
|
health: {
|
|
total: 3,
|
|
items: [
|
|
dec(2, { kind: "source_unreachable" }),
|
|
dec(3, { kind: "downloader_offline" }),
|
|
dec(4, { kind: "other", dedupeKey: "library_root_offline:x" }),
|
|
],
|
|
},
|
|
});
|
|
expect(rows.map((r) => [r.text, r.to])).toEqual([
|
|
["3 条整理需要处理", "/console/organize?tab=records&attention=1"],
|
|
["1 个操作等你批准", `/console/agent/${id(9)}`],
|
|
["1 个站点不可达", HEALTH_HREF],
|
|
["1 个下载器离线", HEALTH_HREF],
|
|
["1 个媒体库目录离线", HEALTH_HREF],
|
|
]);
|
|
});
|
|
|
|
it("健康问题超过列出的条数时补一行", () => {
|
|
const rows = attentionRows({ ...empty, health: { total: 5, items: [dec(2, { kind: "space_insufficient" })] } });
|
|
expect(rows.map((r) => r.text)).toEqual(["1 个下载盘空间不足", "4 个系统问题"]);
|
|
});
|
|
});
|
|
|
|
describe("铃铛跳转", () => {
|
|
it("智能体会话 / 下载计划 / 下载任务", () => {
|
|
expect(approvalHref({ subjectType: "agent_run", subjectId: id(1), agentRunId: null })).toBe(
|
|
`/console/agent/${id(1)}`,
|
|
);
|
|
expect(approvalHref({ subjectType: "acquisition_plan", subjectId: id(2), agentRunId: null })).toBe(
|
|
`/console/downloads?plan=${id(2)}`,
|
|
);
|
|
expect(approvalHref({ subjectType: "download_task", subjectId: id(3), agentRunId: null })).toBe(
|
|
`/console/downloads?open=${id(3)}`,
|
|
);
|
|
expect(approvalHref({ subjectType: null, subjectId: null, agentRunId: null })).toBe("/console/agent");
|
|
expect(HEALTH_HREF).toBe("/console/status#attention");
|
|
});
|
|
});
|