fix(web): 注入面板保存失败不再清空已加载实体并支持重试

This commit is contained in:
Yaojia Wang
2026-06-29 16:52:43 +02:00
parent ab3f9e17b1
commit 4afbbe0fe7
3 changed files with 166 additions and 40 deletions

View File

@@ -1,7 +1,10 @@
"use client";
import Link from "next/link";
import { RotateCcw, X } from "lucide-react";
import { StatusNote } from "@/components/ui/StatusNote";
import { buttonClass } from "@/lib/ui/variants";
import {
isPinned,
kindLabel,
@@ -61,30 +64,69 @@ export function AssistantContent({ projectId, chapterNo }: ChapterAssistantProps
{injection.loading ? (
<p className="mt-2 text-xs text-ink-soft"></p>
) : injection.error ? (
<p className="mt-2 rounded border border-dashed border-line bg-bg p-3 text-xs text-ink-soft">
{injection.error}
</p>
) : selected.length === 0 ? (
<p className="mt-2 rounded border border-dashed border-line bg-bg p-3 text-xs text-ink-soft">
/
</p>
) : !data ? (
// 首次加载失败data 仍为空 → 满屏错误框 + 重试。
<StatusNote variant="danger" className="mt-2 text-xs" title="注入信息暂不可用">
<p></p>
<button
type="button"
onClick={injection.reload}
className={buttonClass({ variant: "outline", size: "sm", className: "mt-2" })}
>
<RotateCcw className="h-3.5 w-3.5" aria-hidden="true" />
</button>
</StatusNote>
) : (
<ul className="mt-2 space-y-2">
{selected.map((entity) => (
<EntityRow
key={`${entity.kind}:${entity.name}`}
entity={entity}
pinned={isPinned(
{ pinned: data?.pinned, excluded: data?.excluded, recent_n: data?.recent_n },
entity,
)}
disabled={injection.saving}
onTogglePin={injection.togglePin}
onExclude={injection.exclude}
/>
))}
</ul>
<>
{injection.saveError ? (
// 保存失败:悬浮提示,不替换列表;可关闭 + 重试上一次覆盖。
<StatusNote variant="danger" className="mt-2 text-xs" title={injection.saveError}>
<div className="mt-1 flex items-center gap-2">
<button
type="button"
onClick={() => void injection.retrySave()}
disabled={injection.saving}
className={buttonClass({ variant: "outline", size: "sm" })}
>
<RotateCcw className="h-3.5 w-3.5" aria-hidden="true" />
</button>
<button
type="button"
onClick={injection.clearSaveError}
aria-label="关闭保存失败提示"
className={buttonClass({ variant: "ghost", size: "sm" })}
>
<X className="h-3.5 w-3.5" aria-hidden="true" />
</button>
</div>
</StatusNote>
) : null}
{selected.length === 0 ? (
<p className="mt-2 rounded border border-dashed border-line bg-bg p-3 text-xs text-ink-soft">
/
</p>
) : (
<ul className="mt-2 space-y-2">
{selected.map((entity) => (
<EntityRow
key={`${entity.kind}:${entity.name}`}
entity={entity}
pinned={isPinned(
{ pinned: data.pinned, excluded: data.excluded, recent_n: data.recent_n },
entity,
)}
disabled={injection.saving}
onTogglePin={injection.togglePin}
onExclude={injection.exclude}
/>
))}
</ul>
)}
</>
)}
{excluded.length > 0 ? (
@@ -115,7 +157,7 @@ export function AssistantContent({ projectId, chapterNo }: ChapterAssistantProps
</p>
<Link
href={`/projects/${projectId}/review?chapter=${chapterNo}`}
className="mt-2 inline-block rounded border border-cinnabar px-3 py-1.5 text-xs text-cinnabar hover:bg-[var(--color-cinnabar-wash)]"
className={buttonClass({ variant: "outline", size: "sm", className: "mt-2" })}
>
稿
</Link>