feat(web): regroup console nav into 7 groups, split downloads/plans/tasks, add legacy redirects

- Sidebar: 概览/资源/订阅/下载/整理/Agent/系统, 18 items (+ 定时任务); single
  active item via findNavItem; 待处理 badge; collapsed rail groups; mobile drawer
  shares NAV_GROUPS.
- New pages: /downloads (queue + cache watermark header), /downloads/plans,
  /downloads/:id, /tasks (business tasks only) + /tasks/:id detail, /rules.
- Legacy links: ?tab= on tasks/subscriptions/sources redirect via clientLoader;
  /tasks/:downloadId falls back to /downloads/:id.
- List filters in URL query; settingsPath() helper for settings deep links.
- Copy per glossary (待处理, 收录策略, 引擎面板, 文件管理, 版本目标).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-09-28 02:46:47 +08:00
1 parent 5843527317
commit 909cd2ad49
31 files changed
+1247 -609

No files matched your search

+4 -4
View File
@@ -648,7 +648,7 @@ export function DeleteDialog({
const reason = filesErrorReason(e);
setErr(
reason === "permanent_disabled"
? "系统设置未开启永久删除(files.allowPermanentDelete)"
? "设置里未开启永久删除(files.allowPermanentDelete)"
: reason === "approval_required"
? "用 API Key 删除,每次都需要审批"
: filesErrorText(e),
@@ -701,7 +701,7 @@ export function DeleteDialog({
{c.downloads.map((d) => (
<p key={d.taskId}>
下载任务{" "}
<Link className="underline hover:text-foreground" to={`/console/tasks/${d.taskId}`}>
<Link className="underline hover:text-foreground" to={`/console/downloads/${d.taskId}`}>
{d.taskId.slice(0, 8)}
</Link>{" "}
· {d.status} · H&R{" "}
@@ -774,7 +774,7 @@ export function DeleteDialog({
<span>
永久删除
<span className="block text-meta text-muted-foreground">
{isAdmin ? "不可恢复。需要在系统设置里开启。" : "仅管理员会话可用。"}
{isAdmin ? "不可恢复。需要在设置里开启。" : "仅管理员会话可用。"}
</span>
</span>
</label>
@@ -858,7 +858,7 @@ export function CopyPathDialog({ root, entry, onClose }: { root: FileRoot; entry
</li>
))}
</ul>
<p className="text-meta text-muted-foreground">下载器与媒体服务器看到的路径按“系统设置 → 路径映射”换算。</p>
<p className="text-meta text-muted-foreground">下载器与媒体服务器看到的路径按“设置 → 路径映射”换算。</p>
</DialogContent>
</Dialog>
);
@@ -132,7 +132,7 @@ export function FileDetail({
{
label: "任务",
value: (
<Link className="underline underline-offset-2" to={`/console/tasks/${e.download.taskId}`}>
<Link className="underline underline-offset-2" to={`/console/downloads/${e.download.taskId}`}>
{downloadLabel(e.download.status).label}
</Link>
),
+1 -1
View File
@@ -66,7 +66,7 @@ export function EntryStatus({ e, compact = false }: { e: FileEntry; compact?: bo
<StatusBadge tone={v.tone}>{v.label}</StatusBadge>
{!compact && e.download ? (
<Link
to={`/console/tasks/${e.download.taskId}`}
to={`/console/downloads/${e.download.taskId}`}
onClick={(ev) => ev.stopPropagation()}
className="truncate text-meta text-muted-foreground underline-offset-2 hover:text-foreground hover:underline"
>
@@ -385,7 +385,7 @@ export function OrganizeWizard({
</div>
</section>
<section className="space-y-1 rounded-xl border border-border px-3 py-2.5 text-caption text-muted-foreground">
<p>命名:按系统设置的命名模板;已绑定的作品/季沿用原目录。</p>
<p>命名:按设置里的命名模板;已绑定的作品/季沿用原目录。</p>
<p>目标已存在:不覆盖,作为冲突进入待处理。</p>
</section>
</div>