Compare commits

...

4 Commits

Author SHA1 Message Date
github-actions
d915ba7e7e [automated] Update test expectations 2026-01-08 01:42:24 +00:00
Jin Yi
e004919712 fix: test code 2026-01-08 10:34:53 +09:00
Jin Yi
d81d5f9ac7 refactor: dialog logic 2026-01-08 10:34:53 +09:00
Jin Yi
f5eb533615 chore: test code 2026-01-08 10:34:53 +09:00
12 changed files with 265 additions and 170 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -64,12 +64,12 @@ import { storeToRefs } from 'pinia'
import { computed, onMounted, toRefs } from 'vue'
import HelpCenterMenuContent from '@/components/helpcenter/HelpCenterMenuContent.vue'
import { useNodeConflictDialog } from '@/composables/useNodeConflictDialog'
import { useSettingStore } from '@/platform/settings/settingStore'
import { useTelemetry } from '@/platform/telemetry'
import { useReleaseStore } from '@/platform/updates/common/releaseStore'
import ReleaseNotificationToast from '@/platform/updates/components/ReleaseNotificationToast.vue'
import WhatsNewPopup from '@/platform/updates/components/WhatsNewPopup.vue'
import { useDialogService } from '@/services/dialogService'
import { useHelpCenterStore } from '@/stores/helpCenterStore'
import { useConflictAcknowledgment } from '@/workbench/extensions/manager/composables/useConflictAcknowledgment'
import { useConflictDetection } from '@/workbench/extensions/manager/composables/useConflictDetection'
@@ -84,7 +84,7 @@ const { shouldShowRedDot: showReleaseRedDot } = storeToRefs(releaseStore)
const conflictDetection = useConflictDetection()
const { showNodeConflictDialog } = useDialogService()
const { show: showNodeConflictDialog } = useNodeConflictDialog()
// Use conflict acknowledgment state from composable - call only once
const { shouldShowRedDot: shouldShowConflictRedDot, markConflictsAsSeen } =

View File

@@ -0,0 +1,29 @@
import MissingNodesContent from '@/components/dialog/content/MissingNodesContent.vue'
import MissingNodesFooter from '@/components/dialog/content/MissingNodesFooter.vue'
import MissingNodesHeader from '@/components/dialog/content/MissingNodesHeader.vue'
import { useDialogService } from '@/services/dialogService'
import { useDialogStore } from '@/stores/dialogStore'
import type { ComponentProps } from 'vue-component-type-helpers'
const DIALOG_KEY = 'global-missing-nodes'
export const useMissingNodesDialog = () => {
const dialogService = useDialogService()
const dialogStore = useDialogStore()
function hide() {
dialogStore.closeDialog({ key: DIALOG_KEY })
}
function show(props: ComponentProps<typeof MissingNodesContent>) {
dialogService.showSmallDialog({
key: DIALOG_KEY,
headerComponent: MissingNodesHeader,
footerComponent: MissingNodesFooter,
component: MissingNodesContent,
props
})
}
return { show, hide }
}

View File

@@ -0,0 +1,48 @@
import NodeConflictDialogContent from '@/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue'
import NodeConflictFooter from '@/workbench/extensions/manager/components/manager/NodeConflictFooter.vue'
import NodeConflictHeader from '@/workbench/extensions/manager/components/manager/NodeConflictHeader.vue'
import { useDialogService } from '@/services/dialogService'
import { useDialogStore } from '@/stores/dialogStore'
import type { DialogComponentProps } from '@/stores/dialogStore'
import type { ConflictDetectionResult } from '@/workbench/extensions/manager/types/conflictDetectionTypes'
const DIALOG_KEY = 'global-node-conflict'
export const useNodeConflictDialog = () => {
const dialogService = useDialogService()
const dialogStore = useDialogStore()
function hide() {
dialogStore.closeDialog({ key: DIALOG_KEY })
}
function show(
options: {
showAfterWhatsNew?: boolean
conflictedPackages?: ConflictDetectionResult[]
dialogComponentProps?: DialogComponentProps
buttonText?: string
onButtonClick?: () => void
} = {}
) {
const { buttonText, onButtonClick, showAfterWhatsNew, conflictedPackages } =
options
return dialogService.showSmallDialog({
key: DIALOG_KEY,
headerComponent: NodeConflictHeader,
footerComponent: NodeConflictFooter,
component: NodeConflictDialogContent,
props: {
showAfterWhatsNew,
conflictedPackages
},
footerProps: {
buttonText,
onButtonClick
}
})
}
return { show, hide }
}

View File

@@ -46,6 +46,7 @@ import {
ComponentWidgetImpl,
DOMWidgetImpl
} from '@/scripts/domWidget'
import { useMissingNodesDialog } from '@/composables/useMissingNodesDialog'
import { useDialogService } from '@/services/dialogService'
import { useSubscription } from '@/platform/cloud/subscription/composables/useSubscription'
import { useExtensionService } from '@/services/extensionService'
@@ -1029,7 +1030,7 @@ export class ComfyApp {
private showMissingNodesError(missingNodeTypes: MissingNodeType[]) {
if (useSettingStore().get('Comfy.Workflow.ShowMissingNodesWarning')) {
useDialogService().showLoadWorkflowWarning({ missingNodeTypes })
useMissingNodesDialog().show({ missingNodeTypes })
}
}

View File

@@ -2,9 +2,6 @@ import { merge } from 'es-toolkit/compat'
import type { Component } from 'vue'
import ApiNodesSignInContent from '@/components/dialog/content/ApiNodesSignInContent.vue'
import MissingNodesContent from '@/components/dialog/content/MissingNodesContent.vue'
import MissingNodesFooter from '@/components/dialog/content/MissingNodesFooter.vue'
import MissingNodesHeader from '@/components/dialog/content/MissingNodesHeader.vue'
import ConfirmationDialogContent from '@/components/dialog/content/ConfirmationDialogContent.vue'
import ErrorDialogContent from '@/components/dialog/content/ErrorDialogContent.vue'
import MissingModelsWarning from '@/components/dialog/content/MissingModelsWarning.vue'
@@ -30,11 +27,7 @@ import ManagerProgressFooter from '@/workbench/extensions/manager/components/Man
import ManagerProgressHeader from '@/workbench/extensions/manager/components/ManagerProgressHeader.vue'
import ManagerDialogContent from '@/workbench/extensions/manager/components/manager/ManagerDialogContent.vue'
import ManagerHeader from '@/workbench/extensions/manager/components/manager/ManagerHeader.vue'
import NodeConflictDialogContent from '@/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue'
import NodeConflictFooter from '@/workbench/extensions/manager/components/manager/NodeConflictFooter.vue'
import NodeConflictHeader from '@/workbench/extensions/manager/components/manager/NodeConflictHeader.vue'
import type { ConflictDetectionResult } from '@/workbench/extensions/manager/types/conflictDetectionTypes'
import type { ComponentAttrs } from 'vue-component-type-helpers'
import type { ComponentAttrs, ComponentProps } from 'vue-component-type-helpers'
export type ConfirmationDialogType =
| 'default'
@@ -47,32 +40,6 @@ export type ConfirmationDialogType =
export const useDialogService = () => {
const dialogStore = useDialogStore()
function showLoadWorkflowWarning(
props: ComponentAttrs<typeof MissingNodesContent>
) {
dialogStore.showDialog({
key: 'global-missing-nodes',
headerComponent: MissingNodesHeader,
footerComponent: MissingNodesFooter,
component: MissingNodesContent,
dialogComponentProps: {
closable: true,
pt: {
root: { class: 'bg-base-background border-border-default' },
header: { class: '!p-0 !m-0' },
content: { class: '!p-0 overflow-y-hidden' },
footer: { class: '!p-0' },
pcCloseButton: {
root: {
class: '!w-7 !h-7 !border-none !outline-none !p-2 !m-1.5'
}
}
}
},
props
})
}
function showMissingModelsWarning(
props: ComponentAttrs<typeof MissingModelsWarning>
) {
@@ -450,6 +417,44 @@ export const useDialogService = () => {
}
}
function showSmallDialog<T extends Component>(options: {
key: string
component: T
headerComponent?: Component
footerComponent?: Component
props?: ComponentProps<T>
footerProps?: Record<string, unknown>
dialogComponentProps?: DialogComponentProps
}) {
const smallDialogDefaultProps: DialogComponentProps = {
closable: true,
pt: {
root: { class: 'bg-base-background border-border-default' },
header: { class: '!p-0 !m-0' },
content: { class: '!p-0 overflow-y-hidden' },
footer: { class: '!p-0' },
pcCloseButton: {
root: {
class: '!w-7 !h-7 !border-none !outline-none !p-2 !m-1.5'
}
}
}
}
return dialogStore.showDialog({
key: options.key,
component: options.component,
headerComponent: options.headerComponent,
footerComponent: options.footerComponent,
props: options.props,
footerProps: options.footerProps,
dialogComponentProps: merge(
smallDialogDefaultProps,
options.dialogComponentProps || {}
)
})
}
function showLayoutDialog(options: {
key: string
component: Component
@@ -482,54 +487,6 @@ export const useDialogService = () => {
})
}
function showNodeConflictDialog(
options: {
showAfterWhatsNew?: boolean
conflictedPackages?: ConflictDetectionResult[]
dialogComponentProps?: DialogComponentProps
buttonText?: string
onButtonClick?: () => void
} = {}
) {
const {
dialogComponentProps,
buttonText,
onButtonClick,
showAfterWhatsNew,
conflictedPackages
} = options
return dialogStore.showDialog({
key: 'global-node-conflict',
headerComponent: NodeConflictHeader,
footerComponent: NodeConflictFooter,
component: NodeConflictDialogContent,
dialogComponentProps: {
closable: true,
pt: {
header: { class: '!p-0 !m-0' },
content: { class: '!p-0 overflow-y-hidden' },
footer: { class: '!p-0' },
pcCloseButton: {
root: {
class:
'!w-7 !h-7 !border-none !outline-none !p-2 !m-1.5 bg-dialog-surface text-white'
}
}
},
...dialogComponentProps
},
props: {
showAfterWhatsNew,
conflictedPackages
},
footerProps: {
buttonText,
onButtonClick
}
})
}
async function showSubscriptionRequiredDialog() {
if (!isCloud || !window.__CONFIG__?.subscription_required) {
return
@@ -542,7 +499,6 @@ export const useDialogService = () => {
}
return {
showLoadWorkflowWarning,
showMissingModelsWarning,
showSettingsDialog,
showAboutDialog,
@@ -560,7 +516,7 @@ export const useDialogService = () => {
confirm,
toggleManagerDialog,
toggleManagerProgressDialog,
showLayoutDialog,
showNodeConflictDialog
showSmallDialog,
showLayoutDialog
}
}

View File

@@ -215,12 +215,19 @@ export const useDialogStore = defineStore('dialog', () => {
F extends Component = Component
>(options: ShowDialogOptions<H, B, F>) {
const dialogKey = options.key || genDialogKey()
let dialog = dialogStack.value.find((d) => d.key === dialogKey)
const existingIndex = dialogStack.value.findIndex(
(d) => d.key === dialogKey
)
let dialog =
existingIndex !== -1 ? dialogStack.value[existingIndex] : undefined
if (dialog) {
dialog.visible = true
riseDialog(dialog)
if (!dialog.visible) {
dialogStack.value.splice(existingIndex, 1)
dialog = createDialog({ ...options, key: dialogKey })
} else {
dialog.visible = true
riseDialog(dialog)
}
} else {
dialog = createDialog({ ...options, key: dialogKey })
}

View File

@@ -185,18 +185,25 @@ describe('NodeConflictDialogContent', () => {
const wrapper = createWrapper()
// Import Failed Extensions section should show 1 package
const importFailedSection = wrapper.findAll(
'.w-full.flex.flex-col.bg-base-background'
)[0]
expect(importFailedSection.text()).toContain('1')
expect(importFailedSection.text()).toContain('Import Failed Extensions')
const sections = wrapper.findAll('.bg-secondary-background')
expect(sections.length).toBeGreaterThan(0)
const importFailedSection = sections.find((section) =>
section.text().includes('Import Failed Extensions')
)
expect(importFailedSection).toBeDefined()
expect(importFailedSection!.text()).toContain('1')
expect(importFailedSection!.text()).toContain('Import Failed Extensions')
// Conflicts section should show 3 conflicts (excluding import_failed)
const conflictsSection = wrapper.findAll(
'.w-full.flex.flex-col.bg-base-background'
)[1]
expect(conflictsSection.text()).toContain('3')
expect(conflictsSection.text()).toContain('Conflicts')
const conflictsSection = sections.find(
(section) =>
section.text().includes('Conflicts') &&
!section.text().includes('Import Failed')
)
expect(conflictsSection).toBeDefined()
expect(conflictsSection!.text()).toContain('3')
expect(conflictsSection!.text()).toContain('Conflicts')
})
})
@@ -208,10 +215,14 @@ describe('NodeConflictDialogContent', () => {
it('should toggle import failed panel', async () => {
const wrapper = createWrapper()
// Find import failed panel header (first one)
const importFailedHeader = wrapper.find(
// Find import failed panel header - look for the one containing "Import Failed Extensions"
const headers = wrapper.findAll(
'[data-testid="conflict-dialog-panel-toggle"]'
)
const importFailedHeader = headers.find((header) =>
header.text().includes('Import Failed Extensions')
)
expect(importFailedHeader).toBeDefined()
// Initially collapsed
expect(
@@ -219,7 +230,7 @@ describe('NodeConflictDialogContent', () => {
).toBe(false)
// Click to expand import failed panel
await importFailedHeader.trigger('click')
await importFailedHeader!.trigger('click')
// Should be expanded now and show package name
const expandedContent = wrapper.find(
@@ -236,34 +247,46 @@ describe('NodeConflictDialogContent', () => {
it('should toggle conflicts panel', async () => {
const wrapper = createWrapper()
// Find conflicts panel header (second one)
const conflictsHeader = wrapper.findAll(
// Find conflicts panel header - look for the one containing "Conflicts"
const headers = wrapper.findAll(
'[data-testid="conflict-dialog-panel-toggle"]'
)[1]
)
const conflictsHeader = headers.find(
(header) =>
header.text().includes('Conflicts') &&
!header.text().includes('Import Failed')
)
expect(conflictsHeader).toBeDefined()
// Click to expand conflicts panel
await conflictsHeader.trigger('click')
await conflictsHeader!.trigger('click')
// Should be expanded now
const conflictItems = wrapper.findAll('.conflict-list-item')
expect(conflictItems.length).toBeGreaterThan(0)
// Should be expanded now - look for the expanded content
const expandedPanels = wrapper.findAll(
'[data-testid="conflict-dialog-panel-expanded"]'
)
expect(expandedPanels.length).toBeGreaterThan(0)
})
it('should toggle extensions panel', async () => {
const wrapper = createWrapper()
// Find extensions panel header (third one)
const extensionsHeader = wrapper.findAll(
// Find extensions panel header - look for the one containing "Extensions at Risk"
const headers = wrapper.findAll(
'[data-testid="conflict-dialog-panel-toggle"]'
)[2]
)
const extensionsHeader = headers.find((header) =>
header.text().includes('Extensions at Risk')
)
expect(extensionsHeader).toBeDefined()
// Click to expand extensions panel
await extensionsHeader.trigger('click')
await extensionsHeader!.trigger('click')
// Should be expanded now and show all package names
const expandedContent = wrapper.findAll(
const expandedContent = wrapper.find(
'[data-testid="conflict-dialog-panel-expanded"]'
)[0]
)
expect(expandedContent.exists()).toBe(true)
expect(expandedContent.text()).toContain('Test Package 1')
expect(expandedContent.text()).toContain('Test Package 2')
@@ -273,18 +296,27 @@ describe('NodeConflictDialogContent', () => {
it('should collapse other panels when opening one', async () => {
const wrapper = createWrapper()
const importFailedHeader = wrapper.findAll(
const headers = wrapper.findAll(
'[data-testid="conflict-dialog-panel-toggle"]'
)[0]
const conflictsHeader = wrapper.findAll(
'[data-testid="conflict-dialog-panel-toggle"]'
)[1]
const extensionsHeader = wrapper.findAll(
'[data-testid="conflict-dialog-panel-toggle"]'
)[2]
)
const importFailedHeader = headers.find((header) =>
header.text().includes('Import Failed Extensions')
)
const conflictsHeader = headers.find(
(header) =>
header.text().includes('Conflicts') &&
!header.text().includes('Import Failed')
)
const extensionsHeader = headers.find((header) =>
header.text().includes('Extensions at Risk')
)
expect(importFailedHeader).toBeDefined()
expect(conflictsHeader).toBeDefined()
expect(extensionsHeader).toBeDefined()
// Open import failed panel first
await importFailedHeader.trigger('click')
await importFailedHeader!.trigger('click')
// Verify import failed panel is open
expect((wrapper.vm as any).importFailedExpanded).toBe(true)
@@ -292,7 +324,7 @@ describe('NodeConflictDialogContent', () => {
expect((wrapper.vm as any).extensionsExpanded).toBe(false)
// Open conflicts panel
await conflictsHeader.trigger('click')
await conflictsHeader!.trigger('click')
// Verify conflicts panel is open and others are closed
expect((wrapper.vm as any).importFailedExpanded).toBe(false)
@@ -300,7 +332,7 @@ describe('NodeConflictDialogContent', () => {
expect((wrapper.vm as any).extensionsExpanded).toBe(false)
// Open extensions panel
await extensionsHeader.trigger('click')
await extensionsHeader!.trigger('click')
// Verify extensions panel is open and others are closed
expect((wrapper.vm as any).importFailedExpanded).toBe(false)
@@ -317,28 +349,50 @@ describe('NodeConflictDialogContent', () => {
it('should display individual conflict details excluding import_failed', async () => {
const wrapper = createWrapper()
// Expand conflicts panel (second header)
const conflictsHeader = wrapper.findAll(
// Expand conflicts panel - find the one containing "Conflicts"
const headers = wrapper.findAll(
'[data-testid="conflict-dialog-panel-toggle"]'
)[1]
await conflictsHeader.trigger('click')
)
const conflictsHeader = headers.find(
(header) =>
header.text().includes('Conflicts') &&
!header.text().includes('Import Failed')
)
expect(conflictsHeader).toBeDefined()
await conflictsHeader!.trigger('click')
// Should display conflict messages (excluding import_failed)
const conflictItems = wrapper.findAll('.conflict-list-item')
expect(conflictItems).toHaveLength(3) // 2 from Package1 + 1 from Package2
// Look for the expanded panel content that contains conflict items
const expandedPanel = wrapper.find(
'[data-testid="conflict-dialog-panel-expanded"]'
)
expect(expandedPanel.exists()).toBe(true)
// Check that it contains the expected conflict details
const conflictElements = expandedPanel.findAll('.flex.h-6')
expect(conflictElements).toHaveLength(3) // 2 from Package1 + 1 from Package2
})
it('should display import failed packages separately', async () => {
const wrapper = createWrapper()
// Expand import failed panel (first header)
const importFailedHeader = wrapper.findAll(
// Expand import failed panel - find the one containing "Import Failed Extensions"
const headers = wrapper.findAll(
'[data-testid="conflict-dialog-panel-toggle"]'
)[0]
await importFailedHeader.trigger('click')
)
const importFailedHeader = headers.find((header) =>
header.text().includes('Import Failed Extensions')
)
expect(importFailedHeader).toBeDefined()
await importFailedHeader!.trigger('click')
// Should display only import failed package
const importFailedItems = wrapper.findAll('.conflict-list-item')
const expandedPanel = wrapper.find(
'[data-testid="conflict-dialog-panel-expanded"]'
)
expect(expandedPanel.exists()).toBe(true)
const importFailedItems = expandedPanel.findAll('.flex.h-6')
expect(importFailedItems).toHaveLength(1)
expect(importFailedItems[0].text()).toContain('Test Package 3')
})
@@ -346,16 +400,24 @@ describe('NodeConflictDialogContent', () => {
it('should display all package names in extensions list', async () => {
const wrapper = createWrapper()
// Expand extensions panel (third header)
const extensionsHeader = wrapper.findAll(
// Expand extensions panel - find the one containing "Extensions at Risk"
const headers = wrapper.findAll(
'[data-testid="conflict-dialog-panel-toggle"]'
)[2]
await extensionsHeader.trigger('click')
)
const extensionsHeader = headers.find((header) =>
header.text().includes('Extensions at Risk')
)
expect(extensionsHeader).toBeDefined()
await extensionsHeader!.trigger('click')
// Should display all package names
expect(wrapper.text()).toContain('Test Package 1')
expect(wrapper.text()).toContain('Test Package 2')
expect(wrapper.text()).toContain('Test Package 3')
const expandedPanel = wrapper.find(
'[data-testid="conflict-dialog-panel-expanded"]'
)
expect(expandedPanel.exists()).toBe(true)
expect(expandedPanel.text()).toContain('Test Package 1')
expect(expandedPanel.text()).toContain('Test Package 2')
expect(expandedPanel.text()).toContain('Test Package 3')
})
})

View File

@@ -14,7 +14,7 @@
<!-- Import Failed List Wrapper -->
<div
v-if="importFailedConflicts.length > 0"
class="flex min-h-8 w-full flex-col rounded-lg bg-base-background"
class="flex min-h-8 w-full flex-col rounded-lg bg-secondary-background"
>
<div
data-testid="conflict-dialog-panel-toggle"
@@ -50,7 +50,7 @@
<div
v-for="(packageName, i) in importFailedConflicts"
:key="i"
class="conflict-list-item flex h-6 shrink-0 items-center justify-between px-4"
class="hover:bg-alpha-azure-600-30 flex h-6 flex-shrink-0 items-center justify-between px-4"
>
<span class="text-xs text-muted">
{{ packageName }}
@@ -62,7 +62,7 @@
<!-- Conflict List Wrapper -->
<div
v-if="allConflictDetails.length > 0"
class="flex min-h-8 w-full flex-col rounded-lg bg-base-background"
class="flex min-h-8 w-full flex-col rounded-lg bg-secondary-background"
>
<div
data-testid="conflict-dialog-panel-toggle"
@@ -98,7 +98,7 @@
<div
v-for="(conflict, i) in allConflictDetails"
:key="i"
class="conflict-list-item flex h-6 shrink-0 items-center justify-between px-4"
class="hover:bg-alpha-azure-600-30 flex h-6 flex-shrink-0 items-center justify-between px-4"
>
<span class="text-xs text-muted">{{
getConflictMessage(conflict, t)
@@ -110,7 +110,7 @@
<!-- Extension List Wrapper -->
<div
v-if="conflictData.length > 0"
class="flex min-h-8 w-full flex-col rounded-lg bg-base-background"
class="flex min-h-8 w-full flex-col rounded-lg bg-secondary-background"
>
<div
data-testid="conflict-dialog-panel-toggle"
@@ -146,7 +146,7 @@
<div
v-for="conflictResult in conflictData"
:key="conflictResult.package_id"
class="conflict-list-item flex h-6 shrink-0 items-center justify-between px-4"
class="hover:bg-alpha-azure-600-30 flex h-6 flex-shrink-0 items-center justify-between px-4"
>
<span class="text-xs text-muted">
{{ conflictResult.package_name }}
@@ -236,8 +236,3 @@ const toggleExtensionsPanel = () => {
importFailedExpanded.value = false
}
</script>
<style scoped>
.conflict-list-item:hover {
background-color: rgb(0 122 255 / 0.2);
}
</style>

View File

@@ -1,10 +1,8 @@
<template>
<div class="flex h-12 w-full items-center justify-between pl-6">
<div class="flex w-full items-center justify-between p-4">
<div class="flex items-center gap-2">
<!-- Warning Icon -->
<i class="pi pi-exclamation-triangle text-lg"></i>
<!-- Title -->
<p class="text-base font-bold">
<i class="icon-[lucide--triangle-alert] text-gold-600"></i>
<p class="m-0 text-sm">
{{ $t('manager.conflicts.title') }}
</p>
</div>

View File

@@ -34,7 +34,7 @@ import ToggleSwitch from 'primevue/toggleswitch'
import { computed, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { useDialogService } from '@/services/dialogService'
import { useNodeConflictDialog } from '@/composables/useNodeConflictDialog'
import type { components } from '@/types/comfyRegistryTypes'
import { useConflictAcknowledgment } from '@/workbench/extensions/manager/composables/useConflictAcknowledgment'
import { useComfyManagerStore } from '@/workbench/extensions/manager/stores/comfyManagerStore'
@@ -51,7 +51,7 @@ const { t } = useI18n()
const { isPackEnabled, enablePack, disablePack, installedPacks } =
useComfyManagerStore()
const { getConflictsForPackageByID } = useConflictDetectionStore()
const { showNodeConflictDialog } = useDialogService()
const { show: showNodeConflictDialog } = useNodeConflictDialog()
const { acknowledgmentState, markConflictsAsSeen } = useConflictAcknowledgment()
const isLoading = ref(false)

View File

@@ -20,12 +20,12 @@
<script setup lang="ts">
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
import DotSpinner from '@/components/common/DotSpinner.vue'
import Button from '@/components/ui/button/Button.vue'
import type { ButtonVariants } from '@/components/ui/button/button.variants'
import { useDialogService } from '@/services/dialogService'
import { useNodeConflictDialog } from '@/composables/useNodeConflictDialog'
import { t } from '@/i18n'
import type { components } from '@/types/comfyRegistryTypes'
import { useConflictDetection } from '@/workbench/extensions/manager/composables/useConflictDetection'
import { useComfyManagerStore } from '@/workbench/extensions/manager/stores/comfyManagerStore'
@@ -54,8 +54,7 @@ const {
}>()
const managerStore = useComfyManagerStore()
const { showNodeConflictDialog } = useDialogService()
const { t } = useI18n()
const { show: showNodeConflictDialog } = useNodeConflictDialog()
// Check if any of the packs are currently being installed
const isInstalling = computed(() => {