refactor(frontend): unify list and create pages with compact topbar layout
Move resource list and guide page titles into the shared topbar, introduce ListPageLayout for tighter spacing, and align knowledge edit with the prompt editor chrome. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -33,10 +33,9 @@ import {
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import { DataList } from "@/components/ui/data-list";
|
||||
import {
|
||||
PageTopbar,
|
||||
TopbarPortal,
|
||||
} from "@/components/layout/topbar-portal";
|
||||
import { PageHeader } from "@/components/ui/page-header";
|
||||
ListPageLayout,
|
||||
ListPageSection,
|
||||
} from "@/components/layout/list-page-layout";
|
||||
import { FilterPills } from "@/components/ui/filter-pills";
|
||||
import { SearchInput } from "@/components/ui/search-input";
|
||||
import { ListToolbar } from "@/components/ui/list-toolbar";
|
||||
@@ -538,9 +537,10 @@ export function AssistantPage(props: AssistantPageProps) {
|
||||
}
|
||||
|
||||
// 删除助手
|
||||
async function handleDelete(id: string) {
|
||||
async function handleDelete(assistant: AssistantListItem) {
|
||||
if (!window.confirm(`确认删除助手“${assistant.name}”?`)) return;
|
||||
try {
|
||||
await assistantsApi.remove(id);
|
||||
await assistantsApi.remove(assistant.id);
|
||||
await loadAssistants();
|
||||
} catch (error) {
|
||||
setListError(error instanceof Error ? error.message : "删除失败");
|
||||
@@ -997,23 +997,17 @@ export function AssistantPage(props: AssistantPageProps) {
|
||||
|
||||
if (view === "list") {
|
||||
return (
|
||||
<div className="mx-auto flex w-full max-w-[1440px] flex-col gap-8">
|
||||
<PageHeader
|
||||
title="助手列表"
|
||||
description="管理已有的视频助手,支持提示词、工作流、Dify 和 FastGPT 类型。"
|
||||
action={
|
||||
<Button
|
||||
size="lg"
|
||||
className="w-full gap-2 sm:w-auto"
|
||||
onClick={startCreate}
|
||||
>
|
||||
<Plus size={16} />
|
||||
创建助手
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
|
||||
<section className="rounded-2xl border border-hairline bg-card p-6 shadow-sm">
|
||||
<ListPageLayout
|
||||
title="助手列表"
|
||||
description="管理已有的视频助手,支持提示词、工作流、Dify 和 FastGPT 类型。"
|
||||
action={
|
||||
<Button className="w-full shrink-0 gap-2 sm:w-auto" onClick={startCreate}>
|
||||
<Plus size={16} />
|
||||
创建助手
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
<ListPageSection>
|
||||
<ListToolbar
|
||||
filters={
|
||||
<FilterPills
|
||||
@@ -1039,6 +1033,7 @@ export function AssistantPage(props: AssistantPageProps) {
|
||||
loadingText="正在加载助手列表…"
|
||||
error={listError}
|
||||
onRetry={() => void loadAssistants()}
|
||||
onRowClick={handleEdit}
|
||||
empty={{
|
||||
title: listItems.length === 0 ? "暂无助手" : "未找到匹配的助手",
|
||||
description:
|
||||
@@ -1116,12 +1111,19 @@ export function AssistantPage(props: AssistantPageProps) {
|
||||
align: "right",
|
||||
cellClassName: "flex justify-end gap-2",
|
||||
cell: (assistant) => (
|
||||
<>
|
||||
<div
|
||||
className="flex justify-end gap-2"
|
||||
onClick={(event) => event.stopPropagation()}
|
||||
onPointerDown={(event) => event.stopPropagation()}
|
||||
>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="gap-1.5 border-hairline-strong text-xs text-muted-foreground hover:text-foreground"
|
||||
onClick={() => handleEdit(assistant)}
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
handleEdit(assistant);
|
||||
}}
|
||||
>
|
||||
<Pencil size={14} />
|
||||
编辑
|
||||
@@ -1134,6 +1136,7 @@ export function AssistantPage(props: AssistantPageProps) {
|
||||
size="icon-sm"
|
||||
className="border-hairline-strong text-muted-foreground hover:text-foreground"
|
||||
aria-label={`${assistant.name} 更多操作`}
|
||||
onClick={(event) => event.stopPropagation()}
|
||||
>
|
||||
<MoreHorizontal size={15} />
|
||||
</Button>
|
||||
@@ -1154,7 +1157,10 @@ export function AssistantPage(props: AssistantPageProps) {
|
||||
className="rounded-lg"
|
||||
onSelect={(event) => {
|
||||
event.preventDefault();
|
||||
void handleDelete(assistant.id);
|
||||
window.setTimeout(
|
||||
() => void handleDelete(assistant),
|
||||
0,
|
||||
);
|
||||
}}
|
||||
>
|
||||
<Trash2 size={14} />
|
||||
@@ -1162,59 +1168,52 @@ export function AssistantPage(props: AssistantPageProps) {
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</section>
|
||||
</div>
|
||||
</ListPageSection>
|
||||
</ListPageLayout>
|
||||
);
|
||||
}
|
||||
|
||||
if (view === "choose") {
|
||||
return (
|
||||
<>
|
||||
<TopbarPortal>
|
||||
<PageTopbar
|
||||
title="创建助手"
|
||||
action={
|
||||
<Button
|
||||
variant="outline"
|
||||
className="gap-2 border-hairline-strong text-muted-foreground hover:text-foreground"
|
||||
onClick={() => router.push("/assistants")}
|
||||
>
|
||||
<ChevronLeft size={16} />
|
||||
返回列表
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
</TopbarPortal>
|
||||
<ListPageLayout
|
||||
title="创建助手"
|
||||
className="max-w-[1180px]"
|
||||
description="先为助手取个名字,再选择构建方式。确认后将立即创建助手并进入编辑页。"
|
||||
action={
|
||||
<Button
|
||||
variant="outline"
|
||||
className="w-full shrink-0 gap-2 border-hairline-strong text-muted-foreground hover:text-foreground sm:w-auto"
|
||||
onClick={() => router.push("/assistants")}
|
||||
>
|
||||
<ChevronLeft size={16} />
|
||||
返回列表
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
<ListPageSection>
|
||||
<label className="block">
|
||||
<div className="mb-2 text-sm font-medium text-foreground">
|
||||
助手名称
|
||||
</div>
|
||||
<Input
|
||||
value={draftName}
|
||||
autoFocus
|
||||
onChange={(event) => setDraftName(event.target.value)}
|
||||
placeholder="请输入助手名称"
|
||||
className="border-hairline-strong bg-background text-foreground placeholder:text-muted-soft"
|
||||
/>
|
||||
</label>
|
||||
</ListPageSection>
|
||||
|
||||
<div className="mx-auto flex w-full max-w-[1180px] flex-col gap-8">
|
||||
<p className="max-w-2xl text-[15px] leading-7 text-muted-foreground">
|
||||
先为助手取个名字,再选择构建方式。确认后将立即创建助手并进入编辑页。
|
||||
</p>
|
||||
<section className="flex flex-col gap-3">
|
||||
<div className="text-sm font-medium text-foreground">构建方式</div>
|
||||
|
||||
<section className="rounded-2xl border border-hairline bg-card p-6 shadow-sm">
|
||||
<label className="block">
|
||||
<div className="mb-2 text-sm font-medium text-foreground">
|
||||
助手名称
|
||||
</div>
|
||||
<Input
|
||||
value={draftName}
|
||||
autoFocus
|
||||
onChange={(event) => setDraftName(event.target.value)}
|
||||
placeholder="请输入助手名称"
|
||||
className="border-hairline-strong bg-background text-foreground placeholder:text-muted-soft"
|
||||
/>
|
||||
</label>
|
||||
</section>
|
||||
|
||||
<section className="flex flex-col gap-4">
|
||||
<div className="text-sm font-medium text-foreground">构建方式</div>
|
||||
|
||||
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
|
||||
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
|
||||
{assistantTypeOptions.map((option) => {
|
||||
const selected = draftType === option.type;
|
||||
|
||||
@@ -1264,21 +1263,19 @@ export function AssistantPage(props: AssistantPageProps) {
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div className="flex items-center justify-end gap-3">
|
||||
{createError && (
|
||||
<span className="text-xs text-destructive">{createError}</span>
|
||||
)}
|
||||
<Button
|
||||
variant="outline"
|
||||
size="lg"
|
||||
className="border-hairline-strong text-muted-foreground hover:text-foreground"
|
||||
disabled={creating}
|
||||
onClick={() => router.push("/assistants")}
|
||||
>
|
||||
取消
|
||||
</Button>
|
||||
<div className="flex items-center justify-end gap-3">
|
||||
{createError && (
|
||||
<span className="text-xs text-destructive">{createError}</span>
|
||||
)}
|
||||
<Button
|
||||
variant="outline"
|
||||
className="border-hairline-strong text-muted-foreground hover:text-foreground"
|
||||
disabled={creating}
|
||||
onClick={() => router.push("/assistants")}
|
||||
>
|
||||
取消
|
||||
</Button>
|
||||
<Button
|
||||
size="lg"
|
||||
className="gap-2"
|
||||
disabled={!draftName.trim() || !draftType || creating}
|
||||
onClick={() => void confirmType()}
|
||||
@@ -1290,9 +1287,8 @@ export function AssistantPage(props: AssistantPageProps) {
|
||||
)}
|
||||
创建助手
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
</ListPageLayout>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user