chore(web): 合并 U / V / W 后的收尾——剩余「入库」文案、设置新分区深链、冒烟锚点
Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
This commit is contained in:
1 parent
ee3ebcb25c
commit
f397687a5f
11 files changed
+31
-36
No files matched your search
@@ -110,7 +110,7 @@ const TASK_STATUS_TEXT: Record<string, string> = {
|
||||
|
||||
const TASK_KIND_LABEL: Partial<Record<TaskKind, string>> = {
|
||||
submitDownload: "提交下载",
|
||||
verifyAndImport: "核验入库",
|
||||
verifyAndImport: "核验整理",
|
||||
evaluateAcquisition: "评估候选",
|
||||
cleanupDownloadCache: "清理缓存",
|
||||
resolveDecision: "处理待处理事项",
|
||||
|
||||
@@ -88,7 +88,7 @@ describe("控制台导航", () => {
|
||||
});
|
||||
|
||||
it("settingsPath 只认新分区名", () => {
|
||||
expect(settingsPath("automation", "cache")).toBe("/console/settings#automation/cache");
|
||||
expect(settingsPath("downloaders", "cache")).toBe("/console/settings#downloaders/cache");
|
||||
expect(settingsPath("agent")).toBe("/console/settings#agent");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -51,7 +51,7 @@ export const NAV_GROUPS: NavGroup[] = [
|
||||
to: "/console",
|
||||
label: "首页",
|
||||
icon: House,
|
||||
description: "在忙什么、要我处理什么、最近入库了什么",
|
||||
description: "在忙什么、要我处理什么、最近整理了什么",
|
||||
},
|
||||
{
|
||||
to: "/console/agent",
|
||||
@@ -139,15 +139,18 @@ export const NAV_ITEMS = NAV_GROUPS.flatMap((g) => g.items);
|
||||
|
||||
/** 设置页深链(IA-2):`/console/settings#分区[/节]`。调用方只认新分区名 */
|
||||
export type SettingsSection =
|
||||
| "automation"
|
||||
| "sites"
|
||||
| "downloaders"
|
||||
| "library"
|
||||
| "media-servers"
|
||||
| "sites"
|
||||
| "metadata"
|
||||
| "acquire"
|
||||
| "library"
|
||||
| "organize"
|
||||
| "agent"
|
||||
| "api-keys"
|
||||
| "account";
|
||||
| "system"
|
||||
| "cache"
|
||||
| "account"
|
||||
| "interface";
|
||||
export function settingsPath(section: SettingsSection, anchor?: string): string {
|
||||
return `${CONSOLE_BASE}/settings#${section}${anchor ? `/${anchor}` : ""}`;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ export const TASK_KIND_LABEL: Record<TaskKind, string> = {
|
||||
resolveObservation: "识别资源",
|
||||
evaluateAcquisition: "评估候选",
|
||||
submitDownload: "提交下载",
|
||||
verifyAndImport: "核验入库",
|
||||
verifyAndImport: "核验整理",
|
||||
refreshMetadata: "刷新元数据",
|
||||
reconcileLibrary: "文件核对",
|
||||
cleanupDownloadCache: "清理缓存",
|
||||
@@ -246,7 +246,7 @@ export function BusinessTasks() {
|
||||
empty={{
|
||||
icon: ListTodo,
|
||||
title: f.active ? "没有符合筛选的任务" : "还没有业务任务",
|
||||
description: f.active ? undefined : "提交下载、核验入库、清理缓存、对账等后台任务会出现在这里。",
|
||||
description: f.active ? undefined : "提交下载、核验整理、清理缓存、对账等后台任务会出现在这里。",
|
||||
}}
|
||||
/>
|
||||
<DetailSheet
|
||||
|
||||
@@ -106,7 +106,7 @@ export function CacheVolumes() {
|
||||
<h2 className="text-label font-semibold tracking-[0.18em] text-muted-foreground uppercase">下载盘</h2>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<Button asChild variant="ghost" size="sm">
|
||||
<Link to={settingsPath("automation", "cache")}>
|
||||
<Link to={settingsPath("downloaders", "cache")}>
|
||||
<SlidersHorizontal />
|
||||
调整阈值
|
||||
</Link>
|
||||
|
||||
@@ -20,7 +20,7 @@ import { cn, formatBytes, formatDateTime } from "~/lib/utils.ts";
|
||||
|
||||
// 运行状态页「存储」节(FIX-5):GET /system/health 的存储告警 + GET /system/storage 明细(库体积与预算、表 top 10、
|
||||
// 缓存用量、图片 / 备份 / 会话与证据、DATA_DIR 分目录、各清理任务),手动清理调 POST /system/storage/cleanup/{target}。
|
||||
// 预算与保留期在「设置 → 自动化 → 存储与保留」改,见 docs/runbook/storage.md。
|
||||
// 预算与保留期在「设置 → 系统 → 存储预算 / 数据保留」改,见 docs/runbook/storage.md。
|
||||
|
||||
const LEVEL: Record<HealthLevel, { label: string; tone: StatusTone }> = {
|
||||
ok: { label: "正常", tone: "success" },
|
||||
|
||||
@@ -36,7 +36,7 @@ export const WORKFLOW_LABEL: Record<string, string> = {
|
||||
resolveObservation: "识别资源",
|
||||
evaluateAcquisition: "评估候选",
|
||||
submitDownload: "提交下载",
|
||||
verifyAndImport: "核验入库",
|
||||
verifyAndImport: "核验整理",
|
||||
scrapeMedia: "刮削",
|
||||
refreshMetadata: "刷新元数据",
|
||||
reconcileLibrary: "文件核对",
|
||||
|
||||
@@ -36,7 +36,7 @@ import { qk } from "~/lib/query-keys.ts";
|
||||
import { useSse } from "~/lib/sse.ts";
|
||||
import { cn } from "~/lib/utils.ts";
|
||||
|
||||
// 首页概览:自动化、存储与下载器状态,以及当前工作、要我处理的汇总计数(整理需要处理 / 等你批准 / 系统健康)和最近入库。
|
||||
// 首页概览:自动化、存储与下载器状态,以及当前工作、要我处理的汇总计数(整理需要处理 / 等你批准 / 系统健康)和最近整理。
|
||||
|
||||
/** 首页关心的事件:任意一个到达就(节流)刷新聚合 */
|
||||
const DASHBOARD_EVENTS = [
|
||||
@@ -102,7 +102,7 @@ function Row({ children }: { children: ReactNode }) {
|
||||
return <li className="flex min-w-0 items-center justify-between gap-3 py-1.5 text-sm">{children}</li>;
|
||||
}
|
||||
|
||||
/** 非零项拼一句:[[3, "个下载"], [0, "个入库中"]] → "3 个下载" */
|
||||
/** 非零项拼一句:[[3, "个下载"], [0, "个整理中"]] → "3 个下载" */
|
||||
function nonZero(parts: [number, string][]): string {
|
||||
return parts
|
||||
.filter(([n]) => n > 0)
|
||||
@@ -157,7 +157,7 @@ function StatusLine({ d }: { d: Dashboard }) {
|
||||
) : a.readOnlyReconcile ? (
|
||||
<>
|
||||
只读模式:不会自动下载和整理。
|
||||
<Link to={settingsPath("automation", "advanced")} className="underline underline-offset-4">
|
||||
<Link to={settingsPath("system", "readonly")} className="underline underline-offset-4">
|
||||
去设置关闭
|
||||
</Link>
|
||||
</>
|
||||
@@ -211,7 +211,7 @@ function Busy({ w }: { w: Dashboard["currentWork"] }) {
|
||||
const agents = w.agentRuns.slice(0, 2);
|
||||
const summary = nonZero([
|
||||
[w.downloading, "个下载中"],
|
||||
[w.importing, "个入库中"],
|
||||
[w.importing, "个整理中"],
|
||||
[w.stalled, "个没有进展"],
|
||||
[w.paused, "个已暂停"],
|
||||
]);
|
||||
@@ -275,14 +275,14 @@ function NeedsMe() {
|
||||
);
|
||||
}
|
||||
|
||||
// ─── 最近入库了什么:成功 / 部分成功的整理 ───
|
||||
// ─── 最近整理了什么:成功 / 部分成功的整理 ───
|
||||
function RecentImports({ d }: { d: Dashboard }) {
|
||||
const rows = d.recentOutput.filter((r) => r.status === "succeeded" || r.status === "partial").slice(0, 6);
|
||||
const today = d.automation.today.filesImported;
|
||||
return (
|
||||
<Section title="最近入库" icon={LibraryIcon} to={consolePath("organize")}>
|
||||
<Section title="最近整理" icon={LibraryIcon} to={consolePath("organize")}>
|
||||
{rows.length === 0 ? (
|
||||
<EmptyState plain icon={LibraryIcon} title="最近没有新入库的作品" className="py-6" />
|
||||
<EmptyState plain icon={LibraryIcon} title="最近没有新整理的作品" className="py-6" />
|
||||
) : (
|
||||
<ul className="divide-y divide-border/60">
|
||||
{rows.map((r) => (
|
||||
@@ -294,7 +294,7 @@ function RecentImports({ d }: { d: Dashboard }) {
|
||||
<span className="block truncate">{r.title ?? r.targetPath?.split("/").pop() ?? "未关联作品"}</span>
|
||||
{r.status === "partial" ? (
|
||||
<span className="block text-meta text-warning">
|
||||
{r.counts.succeeded}/{r.counts.total} 个文件入库
|
||||
{r.counts.succeeded}/{r.counts.total} 个文件已整理
|
||||
</span>
|
||||
) : null}
|
||||
</Link>
|
||||
@@ -303,7 +303,7 @@ function RecentImports({ d }: { d: Dashboard }) {
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
{today ? <p className="mt-auto pt-3 text-meta text-muted-foreground">今天入库 {today} 个文件</p> : null}
|
||||
{today ? <p className="mt-auto pt-3 text-meta text-muted-foreground">今天整理 {today} 个文件</p> : null}
|
||||
</Section>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ const OP_KIND: Record<AssetOperation["kind"], string> = {
|
||||
delete_source: "删除源文件",
|
||||
delete_target: "删除目标文件",
|
||||
verify: "校验",
|
||||
register: "登记入库",
|
||||
register: "登记",
|
||||
qb_pause: "暂停下载",
|
||||
qb_resume: "恢复下载",
|
||||
qb_remove: "移除下载",
|
||||
|
||||
@@ -75,9 +75,11 @@ const STATIC_ROUTES = [
|
||||
"/console/settings#media-servers",
|
||||
"/console/settings#metadata",
|
||||
"/console/settings#agent",
|
||||
"/console/settings#api-keys",
|
||||
"/console/settings#acquire",
|
||||
"/console/settings#organize",
|
||||
"/console/settings#system",
|
||||
"/console/settings#cache",
|
||||
"/console/settings#interface",
|
||||
"/console/settings#automation/advanced",
|
||||
"/console/settings#account",
|
||||
];
|
||||
|
||||
@@ -128,7 +130,7 @@ const REDIRECT_ROUTES = [
|
||||
{ from: "/console/identity?tab=external", to: "/console/library?view=identities" },
|
||||
// 设置旧页签 ?tab= → 分区 hash(IA-2)
|
||||
{ from: "/console/settings?tab=pi", to: "/console/settings#agent" },
|
||||
{ from: "/console/settings?tab=storage", to: "/console/settings#automation/cache" },
|
||||
{ from: "/console/settings?tab=storage", to: "/console/settings#downloaders/cache" },
|
||||
{ from: "/console/settings?tab=path-mappings", to: "/console/settings#downloaders" },
|
||||
{ from: "/console/settings?tab=site-credentials", to: "/console/settings#sites" },
|
||||
];
|
||||
|
||||
@@ -59,16 +59,6 @@ const TERM_PENDING = new Set([
|
||||
"apps/web/app/components/agent/mock.ts",
|
||||
"apps/web/app/components/agent/quick-goals.ts",
|
||||
"apps/web/app/api/agent.ts",
|
||||
"apps/web/app/api/tasks.ts",
|
||||
"apps/web/app/components/console/nav.ts",
|
||||
"apps/web/app/components/downloads/business-tasks.tsx",
|
||||
"apps/web/app/components/settings/automation.tsx",
|
||||
"apps/web/app/components/settings/instances.tsx",
|
||||
"apps/web/app/components/settings/library.tsx",
|
||||
"apps/web/app/components/settings/organize-sources.tsx",
|
||||
"apps/web/app/components/tasks/labels.ts",
|
||||
"apps/web/app/routes/console/home.tsx",
|
||||
"apps/web/app/routes/console/tasks.$id.tsx",
|
||||
"apps/server/src/modules/agent/report.ts",
|
||||
]);
|
||||
let termScope = true;
|
||||
|
||||
Reference in new issue
Block a user