refactor(web): simplify organize defaults and restore historical options

This commit is contained in:
root committed 2026-10-13 20:34:30 +08:00
1 parent acf68ee03b
commit c85b139ec4
11 files changed
+661 -439

No files matched your search

@@ -1,81 +0,0 @@
import { useEffect } from "react";
import { filesErrorText } from "~/api/files.ts";
import { useOrganizeSources } from "~/api/organize-sources.ts";
import type { OrganizeSource } from "~/components/organize-wizard/organize-wizard.tsx";
import { Button } from "~/components/ui/button.tsx";
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "~/components/ui/dialog.tsx";
import { matchingOrganizeSources } from "./source-match.ts";
type FileSource = Extract<OrganizeSource, { kind: "files" }>;
/** Wait for profiles even on the first click; ambiguous sources require an explicit choice. */
export function FileSourceSelection({
source,
onSelect,
onClose,
}: {
source: FileSource;
onSelect: (source: FileSource) => void;
onClose: () => void;
}) {
const profiles = useOrganizeSources();
const matches = matchingOrganizeSources(source.items, profiles.data?.items ?? []);
useEffect(() => {
if (!profiles.isSuccess || matches.length > 1) return;
const profile = matches[0];
onSelect(
profile
? { ...source, sourceConfigId: profile.id, defaultAction: profile.action, label: `整理来源 · ${profile.name}` }
: source,
);
}, [profiles.isSuccess, matches, source, onSelect]);
return (
<Dialog open onOpenChange={(open) => !open && onClose()}>
<DialogContent>
<DialogHeader>
<DialogTitle>{profiles.isPending ? "读取整理来源…" : "选择整理来源"}</DialogTitle>
<DialogDescription>整理时沿用所选整理来源的整理方式、目标目录和分类。</DialogDescription>
</DialogHeader>
{profiles.isPending ? (
<p role="status" className="text-caption text-muted-foreground">
匹配整理来源…
</p>
) : profiles.error ? (
<>
<p role="alert" className="text-caption text-destructive">
{filesErrorText(profiles.error, "读取整理来源失败")}
</p>
<Button variant="outline" onClick={() => void profiles.refetch()}>
重试
</Button>
</>
) : matches.length > 1 ? (
<div className="max-h-72 space-y-2 overflow-auto">
{matches.map((profile) => (
<Button
key={profile.id}
variant="outline"
className="h-auto w-full justify-start whitespace-normal py-3 text-left"
onClick={() =>
onSelect({
...source,
sourceConfigId: profile.id,
defaultAction: profile.action,
label: `整理来源 · ${profile.name}`,
})
}
>
{profile.name} · {profile.action === "copy" ? "复制" : "移动"} · {profile.category ?? "自动分类"}
{!profile.enabled ? " · 已停用" : ""}
</Button>
))}
</div>
) : null}
{!profiles.isPending && (profiles.error || matches.length > 1) ? (
<Button variant="outline" onClick={() => onSelect(source)}>
不用整理来源,手动设置
</Button>
) : null}
</DialogContent>
</Dialog>
);
}
@@ -1,6 +1,5 @@
import type { OrganizeSourceView, OrganizeStockResult } from "@umt/contracts";
import { useState } from "react";
import { Link } from "react-router";
import { toast } from "sonner";
import { filesErrorText } from "~/api/files.ts";
import { useOrganizeSources, useOrganizeStock } from "~/api/organize-sources.ts";
@@ -42,12 +41,13 @@ export function SourceSelection({
const sources = useOrganizeSources();
const stock = useOrganizeStock();
const [manual, setManual] = useState(false);
if (manual)
const direct = sources.isSuccess && !sources.data.items.length;
if (manual || direct)
return (
<DirectoryDialog
mode="source"
allowRoot={false}
onClose={() => setManual(false)}
onClose={direct ? onClose : () => setManual(false)}
onSelect={(ref) => onSelect({ kind: "files", items: [ref], label: "手动选择的目录" })}
/>
);
@@ -56,7 +56,7 @@ export function SourceSelection({
<DialogContent>
<DialogHeader>
<DialogTitle>选择整理来源</DialogTitle>
<DialogDescription>扫描来源目录里已有的文件,预览后再整理。扫描不改变自动整理的基线。</DialogDescription>
<DialogDescription>选择来源,扫描已有文件后开始整理。扫描不改变自动整理的基线。</DialogDescription>
</DialogHeader>
<div className="max-h-72 space-y-2 overflow-auto">
{sources.isPending ? <p className="text-caption text-muted-foreground">加载中…</p> : null}
@@ -101,15 +101,6 @@ export function SourceSelection({
<Button variant="outline" disabled={stock.isPending} onClick={() => setManual(true)}>
手动选择目录
</Button>
{sources.isSuccess && !sources.data.items.length ? (
<Link
to="/console/settings#library/sources"
onClick={onClose}
className="text-caption text-muted-foreground underline"
>
新增整理来源
</Link>
) : null}
</DialogContent>
</Dialog>
);