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.
This commit is contained in:
Jason
2026-04-05 19:23:42 +08:00
parent e3179ad9e4
commit b7e99014c9
4 changed files with 51 additions and 0 deletions
@@ -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<string, SkillUpdateInfo> = {};
@@ -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")}
</Button>
{skillUpdates && skillUpdates.length > 0 && (
<Button
type="button"
variant="outline"
size="sm"
className="h-7 text-xs gap-1"
onClick={handleUpdateAll}
disabled={isUpdatingAll || updateSkillMutation.isPending}
>
{isUpdatingAll ? (
<Loader2 size={12} className="animate-spin" />
) : (
<RefreshCw size={12} />
)}
{isUpdatingAll
? t("skills.updatingAll")
: t("skills.updateAll", { count: skillUpdates.length })}
</Button>
)}
</div>
<div className="flex-1 overflow-y-auto overflow-x-hidden pb-24">
+3
View File
@@ -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)",
+3
View File
@@ -1582,6 +1582,9 @@
"checkingUpdates": "確認中...",
"noUpdates": "すべてのスキルは最新です",
"updatesFound": "{{count}} 個のスキルに更新があります",
"updateAll": "すべて更新 ({{count}})",
"updatingAll": "更新中...",
"updateAllSuccess": "{{count}} 個のスキルを更新しました",
"error": {
"skillNotFound": "スキルが見つかりません: {{directory}}",
"missingRepoInfo": "リポジトリ情報(owner または name)が不足しています",
+3
View File
@@ -1582,6 +1582,9 @@
"checkingUpdates": "检查中...",
"noUpdates": "所有技能已是最新版本",
"updatesFound": "发现 {{count}} 个技能有可用更新",
"updateAll": "全部更新 ({{count}})",
"updatingAll": "更新中...",
"updateAllSuccess": "已成功更新 {{count}} 个技能",
"error": {
"skillNotFound": "技能不存在:{{directory}}",
"missingRepoInfo": "缺少仓库信息(owner 或 name",