diff --git a/src/components/skills/SkillsPage.tsx b/src/components/skills/SkillsPage.tsx index 73865513f..adb100e42 100644 --- a/src/components/skills/SkillsPage.tsx +++ b/src/components/skills/SkillsPage.tsx @@ -43,6 +43,7 @@ export const SkillsPage = forwardRef( const { t } = useTranslation(); const [repoManagerOpen, setRepoManagerOpen] = useState(false); const [searchQuery, setSearchQuery] = useState(""); + const [filterRepo, setFilterRepo] = useState("all"); const [filterStatus, setFilterStatus] = useState< "all" | "installed" | "uninstalled" >("all"); @@ -80,12 +81,25 @@ export const SkillsPage = forwardRef( type DiscoverableSkillItem = DiscoverableSkill & { installed: boolean }; + // 从可发现技能中提取所有仓库选项 + const repoOptions = useMemo(() => { + if (!discoverableSkills) return []; + const repoSet = new Set(); + discoverableSkills.forEach((s) => { + if (s.repoOwner && s.repoName) { + repoSet.add(`${s.repoOwner}/${s.repoName}`); + } + }); + return Array.from(repoSet).sort(); + }, [discoverableSkills]); + // 为发现列表补齐 installed 状态,供 SkillCard 使用 const skills: DiscoverableSkillItem[] = useMemo(() => { if (!discoverableSkills) return []; return discoverableSkills.map((d) => { + // 同时处理 / 和 \ 路径分隔符(兼容 Windows 和 Unix) const installName = - d.directory.split("/").pop()?.toLowerCase() || + d.directory.split(/[/\\]/).pop()?.toLowerCase() || d.directory.toLowerCase(); // 使用 directory + repoOwner + repoName 组合判断是否已安装 const key = `${installName}:${d.repoOwner.toLowerCase()}:${d.repoName.toLowerCase()}`; @@ -179,12 +193,21 @@ export const SkillsPage = forwardRef( // 过滤技能列表 const filteredSkills = useMemo(() => { - const byStatus = skills.filter((skill) => { + // 按仓库筛选 + const byRepo = skills.filter((skill) => { + if (filterRepo === "all") return true; + const skillRepo = `${skill.repoOwner}/${skill.repoName}`; + return skillRepo === filterRepo; + }); + + // 按安装状态筛选 + const byStatus = byRepo.filter((skill) => { if (filterStatus === "installed") return skill.installed; if (filterStatus === "uninstalled") return !skill.installed; return true; }); + // 按搜索关键词筛选 if (!searchQuery.trim()) return byStatus; const query = searchQuery.toLowerCase(); @@ -199,7 +222,7 @@ export const SkillsPage = forwardRef( directory.includes(query) ); }); - }, [skills, searchQuery, filterStatus]); + }, [skills, searchQuery, filterRepo, filterStatus]); return (
@@ -228,7 +251,7 @@ export const SkillsPage = forwardRef(
) : ( <> - {/* 搜索框 */} + {/* 搜索框和筛选器 */}
@@ -240,7 +263,39 @@ export const SkillsPage = forwardRef( className="pl-9 pr-3" />
-
+ {/* 仓库筛选 */} +
+ +
+ {/* 安装状态筛选 */} +