mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-09 23:20:04 +00:00
[Manager] Add update all button functionality
- Add PackUpdateButton component for bulk updates - Add useUpdateAvailableNodes composable to track available updates - Integrate update all button in RegistrySearchBar - Add localization strings for update functionality - Add comprehensive tests for update functionality - Add loading state to PackActionButton
This commit is contained in:
@@ -34,6 +34,7 @@
|
||||
:suggestions="suggestions"
|
||||
:is-missing-tab="isMissingTab"
|
||||
:sort-options="sortOptions"
|
||||
:is-update-available-tab="isUpdateAvailableTab"
|
||||
/>
|
||||
<div class="flex-1 overflow-auto">
|
||||
<div
|
||||
|
||||
@@ -28,6 +28,7 @@ import Button from 'primevue/button'
|
||||
|
||||
const {
|
||||
label,
|
||||
loading = false,
|
||||
loadingMessage,
|
||||
fullWidth = false,
|
||||
variant = 'default'
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
<template>
|
||||
<PackActionButton
|
||||
v-bind="$attrs"
|
||||
variant="black"
|
||||
:label="$t('manager.updateAll')"
|
||||
:loading="isUpdating"
|
||||
:loading-message="$t('g.updating')"
|
||||
@action="updateAllPacks"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
|
||||
import PackActionButton from '@/components/dialog/content/manager/button/PackActionButton.vue'
|
||||
import { useComfyManagerStore } from '@/stores/comfyManagerStore'
|
||||
import type { components } from '@/types/comfyRegistryTypes'
|
||||
|
||||
type NodePack = components['schemas']['Node']
|
||||
|
||||
const { nodePacks } = defineProps<{
|
||||
nodePacks: NodePack[]
|
||||
}>()
|
||||
|
||||
const isUpdating = ref<boolean>(false)
|
||||
|
||||
const managerStore = useComfyManagerStore()
|
||||
|
||||
const createPayload = (updateItem: NodePack) => {
|
||||
return {
|
||||
id: updateItem.id!,
|
||||
version: updateItem.latest_version!.version!
|
||||
}
|
||||
}
|
||||
|
||||
const updatePack = async (item: NodePack) => {
|
||||
if (!item.id || !item.latest_version?.version) {
|
||||
console.warn('Pack missing required id or version:', item)
|
||||
return
|
||||
}
|
||||
await managerStore.updatePack.call(createPayload(item))
|
||||
}
|
||||
|
||||
const updateAllPacks = async () => {
|
||||
if (!nodePacks?.length) {
|
||||
console.warn('No packs provided for update')
|
||||
return
|
||||
}
|
||||
|
||||
isUpdating.value = true
|
||||
|
||||
const updatablePacks = nodePacks.filter((pack) =>
|
||||
managerStore.isPackInstalled(pack.id)
|
||||
)
|
||||
|
||||
if (!updatablePacks.length) {
|
||||
console.info('No installed packs available for update')
|
||||
isUpdating.value = false
|
||||
return
|
||||
}
|
||||
|
||||
console.info(`Starting update of ${updatablePacks.length} packs`)
|
||||
|
||||
try {
|
||||
await Promise.all(updatablePacks.map(updatePack))
|
||||
managerStore.updatePack.clear()
|
||||
console.info('All packs updated successfully')
|
||||
} catch (error) {
|
||||
console.error('Pack update failed:', error)
|
||||
console.error(
|
||||
'Failed packs info:',
|
||||
updatablePacks.map((p) => p.id)
|
||||
)
|
||||
} finally {
|
||||
isUpdating.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -33,6 +33,10 @@
|
||||
:node-packs="missingNodePacks"
|
||||
:label="$t('manager.installAllMissingNodes')"
|
||||
/>
|
||||
<PackUpdateButton
|
||||
v-if="isUpdateAvailableTab && hasUpdateAvailable"
|
||||
:node-packs="updateAvailableNodePacks"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex mt-3 text-sm">
|
||||
<div class="flex gap-6 ml-1">
|
||||
@@ -65,8 +69,10 @@ import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import PackInstallButton from '@/components/dialog/content/manager/button/PackInstallButton.vue'
|
||||
import PackUpdateButton from '@/components/dialog/content/manager/button/PackUpdateButton.vue'
|
||||
import SearchFilterDropdown from '@/components/dialog/content/manager/registrySearchBar/SearchFilterDropdown.vue'
|
||||
import { useMissingNodes } from '@/composables/nodePack/useMissingNodes'
|
||||
import { useUpdateAvailableNodes } from '@/composables/nodePack/useUpdateAvailableNodes'
|
||||
import {
|
||||
type SearchOption,
|
||||
SortableAlgoliaField
|
||||
@@ -83,6 +89,7 @@ const { searchResults, sortOptions } = defineProps<{
|
||||
suggestions?: QuerySuggestion[]
|
||||
sortOptions?: SortableField[]
|
||||
isMissingTab?: boolean
|
||||
isUpdateAvailableTab?: boolean
|
||||
}>()
|
||||
|
||||
const searchQuery = defineModel<string>('searchQuery')
|
||||
@@ -96,6 +103,10 @@ const { t } = useI18n()
|
||||
// Get missing node packs from workflow with loading and error states
|
||||
const { missingNodePacks, isLoading, error } = useMissingNodes()
|
||||
|
||||
// Use the composable to get update available nodes
|
||||
const { hasUpdateAvailable, updateAvailableNodePacks } =
|
||||
useUpdateAvailableNodes()
|
||||
|
||||
const hasResults = computed(
|
||||
() => searchQuery.value?.trim() && searchResults?.length
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user