feat: improve multi-package selection handling (#5116)

* feat: improve multi-package selection handling

- Check each package individually for conflicts in install dialog
- Show only packages with actual conflicts in warning dialog
- Hide action buttons for mixed installed/uninstalled selections
- Display dynamic status based on selected packages priority
- Deduplicate conflict information across multiple packages
- Fix PackIcon blur background opacity

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

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: extract multi-package logic into reusable composables

- Create usePackageSelection composable for installation state management
- Create usePackageStatus composable for status priority logic
- Refactor InfoPanelMultiItem to use new composables
- Reduce component complexity by separating business logic
- Improve code reusability across components

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

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: directory modified

* test: add comprehensive tests for multi-package selection composables

- Add tests for usePacksSelection composable
  - Test installation status filtering
  - Test selection state determination (all/none/mixed)
  - Test dynamic status changes

- Add tests for usePacksStatus composable
  - Test import failure detection
  - Test status priority handling
  - Test integration with conflict detection store

- Fix existing test mocking issues
  - Update es-toolkit/compat mock to use async import
  - Add Pinia setup for store-dependent tests
  - Update vue-i18n mock to preserve all exports

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Jin Yi
2025-08-28 00:00:09 +09:00
committed by GitHub
parent 267e07e26d
commit 91e462dae8
10 changed files with 978 additions and 34 deletions

View File

@@ -27,6 +27,7 @@ import { computed } from 'vue'
import IconTextButton from '@/components/button/IconTextButton.vue'
import DotSpinner from '@/components/common/DotSpinner.vue'
import { useConflictDetection } from '@/composables/useConflictDetection'
import { t } from '@/i18n'
import { useDialogService } from '@/services/dialogService'
import { useComfyManagerStore } from '@/stores/comfyManagerStore'
@@ -96,15 +97,20 @@ const installAllPacks = async () => {
if (!nodePacks?.length) return
if (hasConflict && conflictInfo) {
const conflictedPackages: ConflictDetectionResult[] = nodePacks.map(
(pack) => ({
package_id: pack.id || '',
package_name: pack.name || '',
has_conflict: true,
conflicts: conflictInfo || [],
is_compatible: false
// Check each package individually for conflicts
const { checkNodeCompatibility } = useConflictDetection()
const conflictedPackages: ConflictDetectionResult[] = nodePacks
.map((pack) => {
const compatibilityCheck = checkNodeCompatibility(pack)
return {
package_id: pack.id || '',
package_name: pack.name || '',
has_conflict: compatibilityCheck.hasConflict,
conflicts: compatibilityCheck.conflicts,
is_compatible: !compatibilityCheck.hasConflict
}
})
)
.filter((result) => result.has_conflict) // Only show packages with conflicts
showNodeConflictDialog({
conflictedPackages,