refactor: simplify PackInstallButton isInstalling state management

- Remove isInstalling prop from PackInstallButton component
- Use internal computed property with comfyManagerStore.isPackInstalling()
- Remove redundant isInstalling computations from parent components
- Fix test mocks for useConflictDetection and es-toolkit/compat
- Clean up unused imports and inject dependencies

This centralizes the installation state management in the store,
reducing code duplication and complexity across components.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Jin Yi
2025-08-27 23:00:42 +09:00
parent a5153cd4b9
commit 267e07e26d
8 changed files with 23 additions and 51 deletions

View File

@@ -36,7 +36,6 @@
size="md"
:disabled="!!error || missingNodePacks.length === 0"
:is-loading="isLoading"
:is-installing="isInstalling"
:node-packs="missingNodePacks"
:label="
isLoading
@@ -59,11 +58,9 @@ import PackInstallButton from '@/components/dialog/content/manager/button/PackIn
import { useMissingNodes } from '@/composables/nodePack/useMissingNodes'
import { useComfyManagerService } from '@/services/comfyManagerService'
import { useDialogService } from '@/services/dialogService'
import { useComfyManagerStore } from '@/stores/comfyManagerStore'
import type { MissingNodeType } from '@/types/comfy'
import { ManagerTab } from '@/types/comfyManagerTypes'
const props = defineProps<{
missingNodeTypes: MissingNodeType[]
}>()
@@ -72,17 +69,8 @@ const props = defineProps<{
const { missingNodePacks, isLoading, error, missingCoreNodes } =
useMissingNodes()
const comfyManagerStore = useComfyManagerStore()
const isLegacyManager = ref(false)
// Check if any of the missing packs are currently being installed
const isInstalling = computed(() => {
if (!missingNodePacks.value?.length) return false
return missingNodePacks.value.some((pack) =>
comfyManagerStore.isPackInstalling(pack.id)
)
})
const uniqueNodes = computed(() => {
const seenTypes = new Set()
return props.missingNodeTypes

View File

@@ -11,10 +11,14 @@ import { useComfyManagerStore } from '@/stores/comfyManagerStore'
import PackEnableToggle from './PackEnableToggle.vue'
// Mock debounce to execute immediately
vi.mock('es-toolkit/compat', () => ({
debounce: <T extends (...args: any[]) => any>(fn: T) => fn
}))
// Mock debounce and memoize to execute immediately
vi.mock('es-toolkit/compat', async (importOriginal) => {
const actual = (await importOriginal()) as any
return {
...actual,
debounce: <T extends (...args: any[]) => any>(fn: T) => fn
}
})
const mockNodePack = {
id: 'test-pack',

View File

@@ -47,7 +47,6 @@ type NodePack = components['schemas']['Node']
const {
nodePacks,
isLoading = false,
isInstalling = false,
label = 'Install',
size = 'sm',
hasConflict,
@@ -55,7 +54,6 @@ const {
} = defineProps<{
nodePacks: NodePack[]
isLoading?: boolean
isInstalling?: boolean
label?: string
size?: ButtonSize
hasConflict?: boolean
@@ -65,6 +63,12 @@ const {
const managerStore = useComfyManagerStore()
const { showNodeConflictDialog } = useDialogService()
// Check if any of the packs are currently being installed
const isInstalling = computed(() => {
if (!nodePacks?.length) return false
return nodePacks.some((pack) => managerStore.isPackInstalling(pack.id))
})
const createPayload = (installItem: NodePack) => {
if (!installItem.id) {
throw new Error('Node ID is required for installation')
@@ -107,14 +111,12 @@ const installAllPacks = async () => {
buttonText: t('manager.conflicts.installAnyway'),
onButtonClick: async () => {
// Proceed with installation
// isInstalling.value = true
await performInstallation(nodePacks)
}
})
return
}
// No conflicts or conflicts acknowledged - proceed with installation
// isInstalling.value = true
await performInstallation(nodePacks)
}
@@ -124,7 +126,7 @@ const performInstallation = async (packs: NodePack[]) => {
}
const computedLabel = computed(() =>
isInstalling
isInstalling.value
? t('g.installing')
: label ??
(nodePacks.length > 1 ? t('manager.installSelected') : t('g.install'))

View File

@@ -26,7 +26,6 @@
v-else
v-bind="$attrs"
size="md"
:is-installing="isInstalling"
:node-packs="nodePacks"
:has-conflict="hasConflict"
/>
@@ -42,7 +41,7 @@
</template>
<script setup lang="ts">
import { computed, inject, ref, watch } from 'vue'
import { inject, ref, watch } from 'vue'
import NoResultsPlaceholder from '@/components/common/NoResultsPlaceholder.vue'
import PackInstallButton from '@/components/dialog/content/manager/button/PackInstallButton.vue'
@@ -73,10 +72,4 @@ watch(
},
{ immediate: true }
)
// Check if any of the packs are currently being installed
const isInstalling = computed(() => {
if (!nodePacks?.length) return false
return nodePacks.some((pack) => managerStore.isPackInstalling(pack.id))
})
</script>

View File

@@ -24,7 +24,6 @@
v-else
v-bind="$attrs"
size="md"
:is-installing="isInstalling"
:node-packs="nodePacks"
/>
</template>
@@ -77,12 +76,6 @@ watch(
{ immediate: true }
)
// Check if any of the packs are currently being installed
const isInstalling = computed(() => {
if (!nodePacks?.length) return false
return nodePacks.some((pack) => managerStore.isPackInstalling(pack.id))
})
const getPackNodes = async (pack: components['schemas']['Node']) => {
if (!pack.latest_version?.version) return []
const nodeDefs = await getNodeDefs.call({

View File

@@ -22,7 +22,6 @@
<template v-if="!isInstalled">
<PackInstallButton
:node-packs="[nodePack]"
:is-installing="isInstalling"
:has-conflict="uninstalledPackConflict.hasConflict"
:conflict-info="uninstalledPackConflict.conflicts"
/>
@@ -39,7 +38,7 @@
</template>
<script setup lang="ts">
import { computed, inject } from 'vue'
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
import PackEnableToggle from '@/components/dialog/content/manager/button/PackEnableToggle.vue'
@@ -48,7 +47,6 @@ import { useConflictDetection } from '@/composables/useConflictDetection'
import { useImportFailedDetection } from '@/composables/useImportFailedDetection'
import { useComfyManagerStore } from '@/stores/comfyManagerStore'
import { useConflictDetectionStore } from '@/stores/conflictDetectionStore'
import { IsInstallingKey } from '@/types/comfyManagerTypes'
import type { components } from '@/types/comfyRegistryTypes'
const { nodePack } = defineProps<{
@@ -57,7 +55,6 @@ const { nodePack } = defineProps<{
const { isPackInstalled } = useComfyManagerStore()
const isInstalled = computed(() => isPackInstalled(nodePack?.id))
const isInstalling = inject(IsInstallingKey)
const { n, t } = useI18n()

View File

@@ -29,7 +29,6 @@
<PackInstallButton
v-if="isMissingTab && missingNodePacks.length > 0"
:disabled="isLoading || !!error"
:is-installing="isInstalling"
:node-packs="missingNodePacks"
:label="$t('manager.installAllMissingNodes')"
/>
@@ -73,7 +72,6 @@ import PackUpdateButton from '@/components/dialog/content/manager/button/PackUpd
import SearchFilterDropdown from '@/components/dialog/content/manager/registrySearchBar/SearchFilterDropdown.vue'
import { useMissingNodes } from '@/composables/nodePack/useMissingNodes'
import { useUpdateAvailableNodes } from '@/composables/nodePack/useUpdateAvailableNodes'
import { useComfyManagerStore } from '@/stores/comfyManagerStore'
import {
type SearchOption,
SortableAlgoliaField
@@ -104,15 +102,6 @@ const { t } = useI18n()
// Get missing node packs from workflow with loading and error states
const { missingNodePacks, isLoading, error } = useMissingNodes()
const comfyManagerStore = useComfyManagerStore()
// Check if any of the missing packs are currently being installed
const isInstalling = computed(() => {
if (!missingNodePacks.value?.length) return false
return missingNodePacks.value.some((pack) =>
comfyManagerStore.isPackInstalling(pack.id)
)
})
// Use the composable to get update available nodes
const { hasUpdateAvailable, updateAvailableNodePacks } =
useUpdateAvailableNodes()

View File

@@ -21,6 +21,12 @@ vi.mock('@/stores/dialogStore')
vi.mock('@/stores/settingStore')
vi.mock('@/stores/commandStore')
vi.mock('@/services/comfyManagerService')
vi.mock('@/composables/useConflictDetection', () => ({
useConflictDetection: vi.fn(() => ({
conflictedPackages: { value: [] },
performConflictDetection: vi.fn().mockResolvedValue(undefined)
}))
}))
// Mock useEventListener to capture the event handler
let reconnectHandler: (() => void) | null = null