From 65d38c351f5892fd43a2c19f91a20271a168efbd Mon Sep 17 00:00:00 2001 From: HouYunFei <1844025705@qq.com> Date: Wed, 5 Aug 2026 17:12:04 +0800 Subject: [PATCH] feat(ui): optimize prompt card layout and enhance prompt select dialog for improved usability --- CHANGELOG.md | 2 + docs/content/docs/progress/pending-test.mdx | 2 +- web/src/components/prompts/prompt-card.tsx | 32 +++---- .../prompts/prompt-select-dialog.tsx | 88 +++++++++---------- web/src/pages/prompts/index.tsx | 4 +- 5 files changed, 58 insertions(+), 70 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a98591..8ceabb1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ + [优化] Agent 输入区控件随面板宽度在图标与图标加文字之间自适应。 + [修复] Agent Skill 草稿期间保持 MCP 活动画布隔离,支持停止临时生成任务,并禁止并发修改 Skill。 + [修复] Agent 新建或恢复对话时统一同步版本化会话与 MCP 初始化状态,避免多页面竞态误触 `409`、提前发送或任务后残留初始化卡片。 ++ [优化] 提示词中心缩小卡片、每行展示四张,移除“加入我的资产”按钮边框。 ++ [优化] 缩小生图与视频工作台的提示词库弹窗,精简卡片。 ## v0.13.0 - 2026-08-03 diff --git a/docs/content/docs/progress/pending-test.mdx b/docs/content/docs/progress/pending-test.mdx index bbd5363..e454fed 100644 --- a/docs/content/docs/progress/pending-test.mdx +++ b/docs/content/docs/progress/pending-test.mdx @@ -13,7 +13,7 @@ The current release needs manual verification in these areas: - Canvas Agent startup, MCP status, model and permission controls, approvals, version reporting, diagnostics, streaming responses, history consistency, multi-tab isolation, and local Skill management. - Agent header tabs in English and Chinese at different panel widths; labels should collapse to icons and counts before either edge is clipped. - Agent message layout, Markdown, code blocks, attachments, token statistics, progress timelines, command groups, and scroll-follow behavior. -- Prompt Center layout, source synchronization, search, asset insertion, and prompt detail dialogs. +- Prompt Center layout, source synchronization, search, asset insertion, prompt detail dialogs, and compact split-layout prompt pickers in the image and video workbenches. - Settings import/export, Volcengine Ark protocol handling, and WebDAV-related configuration. The Chinese version contains the complete item-by-item acceptance checklist. diff --git a/web/src/components/prompts/prompt-card.tsx b/web/src/components/prompts/prompt-card.tsx index 01937fb..a5220fa 100644 --- a/web/src/components/prompts/prompt-card.tsx +++ b/web/src/components/prompts/prompt-card.tsx @@ -13,6 +13,7 @@ export function PromptCard({ actionIcon = , actionType = "text", extraAction, + compact = false, }: { item: Prompt; onOpen: () => void; @@ -21,41 +22,30 @@ export function PromptCard({ actionIcon?: ReactNode; actionType?: "text" | "primary"; extraAction?: ReactNode; + compact?: boolean; }) { const { i18n, t } = useTranslation(); return ( - {item.coverUrl ? {item.title} : } + } > - -
- - {extraAction} -
+ {!compact ?
{extraAction}
: null}
); } diff --git a/web/src/components/prompts/prompt-select-dialog.tsx b/web/src/components/prompts/prompt-select-dialog.tsx index bfb583b..7559233 100644 --- a/web/src/components/prompts/prompt-select-dialog.tsx +++ b/web/src/components/prompts/prompt-select-dialog.tsx @@ -1,4 +1,4 @@ -import { Check, Search } from "lucide-react"; +import { Search } from "lucide-react"; import { type UIEvent, useEffect, useState } from "react"; import { App, Empty, Input, Modal, Spin, Tag } from "antd"; import { useTranslation } from "react-i18next"; @@ -34,54 +34,50 @@ export function PromptSelectDialog({ open, onOpenChange, onSelect }: { open: boo }; return ( - onOpenChange(false)} footer={null} width={1040} centered> -
event.stopPropagation()}> -
- } value={keyword} onChange={(event) => setKeyword(event.target.value)} placeholder={t("prompts.searchTitle")} /> -
-
-
-
{t("prompts.category")}
-
- {promptCategories.map((category) => ( - setSelectedCategory(category)}> - {category === ALL_PROMPTS_OPTION ? t("common.all") : category} - - ))} -
-
-
-
{t("prompts.tags")}
-
- {promptTags.map((tag) => { - const active = tag === ALL_PROMPTS_OPTION ? selectedTags.length === 0 : selectedTags.includes(tag); - return ( - toggleTag(tag)}> - {tag === ALL_PROMPTS_OPTION ? t("common.all") : tag} - - ); - })} -
-
-
-
event.stopPropagation()}> - {query.isLoading ? ( -
- -
- ) : null} -
- {items.map((item) => ( - selectPrompt(item.prompt)} onCopy={() => selectPrompt(item.prompt)} actionLabel={t("prompts.use")} actionIcon={} actionType="primary" /> + onOpenChange(false)} footer={null} width={880} centered> +
event.stopPropagation()}> + +
+ } value={keyword} onChange={(event) => setKeyword(event.target.value)} placeholder={t("prompts.searchTitle")} /> +
event.stopPropagation()}> + {query.isLoading ? ( +
+ +
+ ) : null} +
+ {items.map((item) => ( + selectPrompt(item.prompt)} onCopy={() => selectPrompt(item.prompt)} compact /> + ))}
- ) : null} -
+ {!query.isLoading && items.length === 0 ? : null} + {query.isFetchingNextPage ? ( +
+ +
+ ) : null} +
+
); diff --git a/web/src/pages/prompts/index.tsx b/web/src/pages/prompts/index.tsx index 5ec3c93..5e0b8f5 100644 --- a/web/src/pages/prompts/index.tsx +++ b/web/src/pages/prompts/index.tsx @@ -65,7 +65,7 @@ export default function PromptsPage() {
} value={titleKeyword} placeholder={t("prompts.search")} onChange={(event) => setTitleKeyword(event.target.value)} /> {query.isLoading ?
: null} - {!query.isLoading ?
} onCopy={(item) => copyText(item.prompt, t("common.promptCopied"))} emptyText={t("prompts.empty")} />
: null} + {!query.isLoading ?
} onCopy={(item) => copyText(item.prompt, t("common.promptCopied"))} emptyText={t("prompts.empty")} />
: null}
{query.isFetchingNextPage ? t("prompts.loading") : query.hasNextPage ? t("prompts.loadMore") : promptItems.length > 0 ? t("prompts.end") : null}
@@ -83,5 +83,5 @@ function PromptFilter({ label, options, selected, onChange }: { label: string; o } function PromptGrid({ items, onOpen, onCopy, renderActions, emptyText }: { items: Prompt[]; onOpen: (item: Prompt) => void; onCopy: (item: Prompt) => void; renderActions: (item: Prompt) => ReactNode; emptyText: string }) { - return
{items.map((item) => onOpen(item)} onCopy={() => onCopy(item)} extraAction={renderActions(item)} />)}
{items.length === 0 ? : null}
; + return
{items.map((item) => onOpen(item)} onCopy={() => onCopy(item)} extraAction={renderActions(item)} />)}
{items.length === 0 ? : null}
; }