From b7e99014c99858523597121505cb1a83fcdb3e91 Mon Sep 17 00:00:00 2001 From: Jason Date: Sun, 5 Apr 2026 19:23:42 +0800 Subject: [PATCH] feat: add "Update All" button for batch skill updates Show an "Update All (N)" button next to "Check Updates" when updates are available. Sequentially updates each skill and reports results. --- src/components/skills/UnifiedSkillsPanel.tsx | 42 ++++++++++++++++++++ src/i18n/locales/en.json | 3 ++ src/i18n/locales/ja.json | 3 ++ src/i18n/locales/zh.json | 3 ++ 4 files changed, 51 insertions(+) diff --git a/src/components/skills/UnifiedSkillsPanel.tsx b/src/components/skills/UnifiedSkillsPanel.tsx index 3a361d52..4e11f288 100644 --- a/src/components/skills/UnifiedSkillsPanel.tsx +++ b/src/components/skills/UnifiedSkillsPanel.tsx @@ -100,6 +100,7 @@ const UnifiedSkillsPanel = React.forwardRef< isFetching: isCheckingUpdates, } = useCheckSkillUpdates(); const updateSkillMutation = useUpdateSkill(); + const [isUpdatingAll, setIsUpdatingAll] = useState(false); const updatesMap = useMemo(() => { const map: Record = {}; @@ -245,6 +246,28 @@ const UnifiedSkillsPanel = React.forwardRef< } }; + const handleUpdateAll = async () => { + if (!skillUpdates || skillUpdates.length === 0) return; + setIsUpdatingAll(true); + let successCount = 0; + for (const update of skillUpdates) { + try { + await updateSkillMutation.mutateAsync(update.id); + successCount++; + } catch (error) { + toast.error(t("skills.updateFailed"), { + description: `${update.name}: ${String(error)}`, + }); + } + } + setIsUpdatingAll(false); + if (successCount > 0) { + toast.success(t("skills.updateAllSuccess", { count: successCount }), { + closeButton: true, + }); + } + }; + const handleOpenRestoreFromBackup = async () => { setRestoreDialogOpen(true); try { @@ -338,6 +361,25 @@ const UnifiedSkillsPanel = React.forwardRef< ? t("skills.checkingUpdates") : t("skills.checkUpdates")} + {skillUpdates && skillUpdates.length > 0 && ( + + )}
diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index 16102e20..663634e5 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -1582,6 +1582,9 @@ "checkingUpdates": "Checking...", "noUpdates": "All skills are up to date", "updatesFound": "{{count}} skill(s) have updates available", + "updateAll": "Update All ({{count}})", + "updatingAll": "Updating...", + "updateAllSuccess": "Successfully updated {{count}} skill(s)", "error": { "skillNotFound": "Skill not found: {{directory}}", "missingRepoInfo": "Missing repository info (owner or name)", diff --git a/src/i18n/locales/ja.json b/src/i18n/locales/ja.json index 0010b348..0a432b88 100644 --- a/src/i18n/locales/ja.json +++ b/src/i18n/locales/ja.json @@ -1582,6 +1582,9 @@ "checkingUpdates": "確認中...", "noUpdates": "すべてのスキルは最新です", "updatesFound": "{{count}} 個のスキルに更新があります", + "updateAll": "すべて更新 ({{count}})", + "updatingAll": "更新中...", + "updateAllSuccess": "{{count}} 個のスキルを更新しました", "error": { "skillNotFound": "スキルが見つかりません: {{directory}}", "missingRepoInfo": "リポジトリ情報(owner または name)が不足しています", diff --git a/src/i18n/locales/zh.json b/src/i18n/locales/zh.json index 04658c58..dd2715b3 100644 --- a/src/i18n/locales/zh.json +++ b/src/i18n/locales/zh.json @@ -1582,6 +1582,9 @@ "checkingUpdates": "检查中...", "noUpdates": "所有技能已是最新版本", "updatesFound": "发现 {{count}} 个技能有可用更新", + "updateAll": "全部更新 ({{count}})", + "updatingAll": "更新中...", + "updateAllSuccess": "已成功更新 {{count}} 个技能", "error": { "skillNotFound": "技能不存在:{{directory}}", "missingRepoInfo": "缺少仓库信息(owner 或 name)",