style(knowledge): 实体改回纯展示(不可点击),chip 精致化

按需求去掉点击筛选,实体为静态彩色 chip:色点 + 名称 + 胶囊型类型标签。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
AdministratorandClaude Opus 4.8 committed 2026-06-09 20:34:59 +08:00
1 parent f6af9379b7
commit 1ce15fbb15
15 files changed
+596 -38

No files matched your search

@@ -68,6 +68,7 @@ import type { ValidateSkillUploadResponse } from "@/core/skills/api";
import {
useDeleteCustomSkill,
useDuplicateSkill,
useGenerateMissingSkillNameZh,
useInstallSkillUpload,
useReconcileCustomSkills,
useSetSkillFeatured,
@@ -155,6 +156,7 @@ function SkillSettingsList({ onClose }: { onClose?: () => void }) {
const [page, setPage] = useState(1);
const [viewMode, setViewMode] = useViewMode("skill");
const reconcileMutation = useReconcileCustomSkills();
const fillNamesMutation = useGenerateMissingSkillNameZh();
// Name + tag filtering is resolved server-side via the /api/skills query.
const { skills, isLoading, error } = useSkills({ search, tagIds, sort });
@@ -232,6 +234,23 @@ function SkillSettingsList({ onClose }: { onClose?: () => void }) {
[orderedSkills, page],
);
const handleFillNames = async () => {
try {
const result = await fillNamesMutation.mutateAsync();
const okCount = result.generated.length;
const failCount = result.failed.length;
if (okCount === 0 && failCount === 0) {
toast.info("所有技能均已配置中文名称");
} else if (failCount === 0) {
toast.success(`已为 ${okCount} 个技能补充中文名称`);
} else {
toast.warning(`已补充 ${okCount} 个,${failCount} 个生成失败,可稍后重试或手动填写`);
}
} catch (err) {
toast.error(err instanceof Error ? err.message : String(err));
}
};
const handleRescan = async () => {
try {
const result = await reconcileMutation.mutateAsync();
@@ -322,6 +341,23 @@ function SkillSettingsList({ onClose }: { onClose?: () => void }) {
? t.settings.skills.rescanSkillsRunning
: t.settings.skills.rescanSkills}
</Button>
<Button
size="sm"
variant="outline"
onClick={() => void handleFillNames()}
disabled={
fillNamesMutation.isPending ||
env.NEXT_PUBLIC_STATIC_WEBSITE_ONLY === "true"
}
title="为所有尚未配置中文名称的技能自动生成中文名"
>
{fillNamesMutation.isPending ? (
<Loader2 className="size-4 animate-spin" />
) : (
<SparklesIcon className="size-4" />
)}
{fillNamesMutation.isPending ? "补充中…" : "一键补充中文名"}
</Button>
<Button
size="sm"
variant="outline"
@@ -550,8 +586,13 @@ export function SkillRow({
const badgeGroup = (
<div className="flex flex-wrap items-center gap-2">
<span className={cn(isCard && "truncate font-medium")}>
{desensitize(skill.name)}
{skill.name_zh?.trim() ? skill.name_zh : desensitize(skill.name)}
</span>
{skill.name_zh?.trim() && (
<span className="text-muted-foreground truncate text-xs font-normal">
{desensitize(skill.name)}
</span>
)}
{isBuiltin && (
<Badge variant="secondary" className="text-xs">
{t.settings.skills.badgeBuiltin}