diff --git a/browser_tests/fixtures/selectors.ts b/browser_tests/fixtures/selectors.ts index b777008d24b..ffc9af5f044 100644 --- a/browser_tests/fixtures/selectors.ts +++ b/browser_tests/fixtures/selectors.ts @@ -27,7 +27,6 @@ export const TestIds = { settingsContainer: 'settings-container', settingsTabAbout: 'settings-tab-about', confirm: 'confirm-dialog', - missingNodes: 'missing-nodes-warning', about: 'about-panel', whatsNewSection: 'whats-new-section' }, diff --git a/browser_tests/tests/dialog.spec.ts b/browser_tests/tests/dialog.spec.ts index 93af2ea673a..88ef01e3c46 100644 --- a/browser_tests/tests/dialog.spec.ts +++ b/browser_tests/tests/dialog.spec.ts @@ -4,71 +4,11 @@ import { expect } from '@playwright/test' import type { Keybinding } from '../../src/platform/keybindings/types' import { comfyPageFixture as test } from '../fixtures/ComfyPage' import { DefaultGraphPositions } from '../fixtures/constants/defaultGraphPositions' -import { TestIds } from '../fixtures/selectors' test.beforeEach(async ({ comfyPage }) => { await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) -test.describe('Load workflow warning', { tag: '@ui' }, () => { - test('Should display a warning when loading a workflow with missing nodes', async ({ - comfyPage - }) => { - await comfyPage.workflow.loadWorkflow('missing/missing_nodes') - - const missingNodesWarning = comfyPage.page.getByTestId( - TestIds.dialogs.missingNodes - ) - await expect(missingNodesWarning).toBeVisible() - }) - - test('Should display a warning when loading a workflow with missing nodes in subgraphs', async ({ - comfyPage - }) => { - await comfyPage.workflow.loadWorkflow('missing/missing_nodes_in_subgraph') - - const missingNodesWarning = comfyPage.page.getByTestId( - TestIds.dialogs.missingNodes - ) - await expect(missingNodesWarning).toBeVisible() - - // Verify the missing node text includes subgraph context - const warningText = await missingNodesWarning.textContent() - expect(warningText).toContain('MISSING_NODE_TYPE_IN_SUBGRAPH') - expect(warningText).toContain('in subgraph') - }) -}) - -test('Does not report warning on undo/redo', async ({ comfyPage }) => { - await comfyPage.settings.setSetting('Comfy.NodeSearchBoxImpl', 'v1 (legacy)') - const missingNodesWarning = comfyPage.page.getByTestId( - TestIds.dialogs.missingNodes - ) - - await comfyPage.workflow.loadWorkflow('missing/missing_nodes') - await expect(missingNodesWarning).toBeVisible() - await comfyPage.page.keyboard.press('Escape') - await expect(missingNodesWarning).not.toBeVisible() - - // Wait for any async operations to complete after dialog closes - await comfyPage.nextFrame() - - // Make a change to the graph - await comfyPage.canvasOps.doubleClick() - await comfyPage.searchBox.fillAndSelectFirstNode('KSampler') - - // Undo and redo the change - await comfyPage.keyboard.undo() - await expect(async () => { - await expect(missingNodesWarning).not.toBeVisible() - }).toPass({ timeout: 5000 }) - - await comfyPage.keyboard.redo() - await expect(async () => { - await expect(missingNodesWarning).not.toBeVisible() - }).toPass({ timeout: 5000 }) -}) - test.describe('Execution error', () => { test.beforeEach(async ({ comfyPage }) => { await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top') diff --git a/browser_tests/tests/nodeDisplay.spec.ts b/browser_tests/tests/nodeDisplay.spec.ts index 061419838ef..8206c00bc8f 100644 --- a/browser_tests/tests/nodeDisplay.spec.ts +++ b/browser_tests/tests/nodeDisplay.spec.ts @@ -73,10 +73,6 @@ test.describe('Optional input', { tag: ['@screenshot', '@node'] }, () => { await expect(comfyPage.canvas).toHaveScreenshot('simple_slider.png') }) test('unknown converted widget', async ({ comfyPage }) => { - await comfyPage.settings.setSetting( - 'Comfy.Workflow.ShowMissingNodesWarning', - false - ) await comfyPage.workflow.loadWorkflow( 'missing/missing_nodes_converted_widget' ) diff --git a/browser_tests/tests/primitiveNode.spec.ts b/browser_tests/tests/primitiveNode.spec.ts index aa0e029e030..98b37e97bc3 100644 --- a/browser_tests/tests/primitiveNode.spec.ts +++ b/browser_tests/tests/primitiveNode.spec.ts @@ -57,15 +57,4 @@ test.describe('Primitive Node', { tag: ['@screenshot', '@node'] }, () => { 'static_primitive_connected.png' ) }) - - test('Report missing nodes when connect to missing node', async ({ - comfyPage - }) => { - await comfyPage.workflow.loadWorkflow( - 'primitive/primitive_node_connect_missing_node' - ) - // Wait for the element with the .comfy-missing-nodes selector to be visible - const missingNodesWarning = comfyPage.page.locator('.comfy-missing-nodes') - await expect(missingNodesWarning).toBeVisible() - }) }) diff --git a/src/components/dialog/content/MissingCoreNodesMessage.test.ts b/src/components/dialog/content/MissingCoreNodesMessage.test.ts deleted file mode 100644 index afcb90996e4..00000000000 --- a/src/components/dialog/content/MissingCoreNodesMessage.test.ts +++ /dev/null @@ -1,199 +0,0 @@ -import { mount } from '@vue/test-utils' -import PrimeVue from 'primevue/config' -import Message from 'primevue/message' -import { beforeEach, describe, expect, it, vi } from 'vitest' -import { nextTick } from 'vue' - -import MissingCoreNodesMessage from '@/components/dialog/content/MissingCoreNodesMessage.vue' -import type { LGraphNode } from '@/lib/litegraph/src/litegraph' -import { useSystemStatsStore } from '@/stores/systemStatsStore' - -// Mock the stores -vi.mock('@/stores/systemStatsStore', () => ({ - useSystemStatsStore: vi.fn() -})) - -const createMockNode = (type: string, version?: string): LGraphNode => - // @ts-expect-error - Creating a partial mock of LGraphNode for testing purposes. - // We only need specific properties for our tests, not the full LGraphNode interface. - ({ - type, - properties: { cnr_id: 'comfy-core', ver: version }, - id: 1, - title: type, - pos: [0, 0], - size: [100, 100], - flags: {}, - graph: null, - mode: 0, - inputs: [], - outputs: [] - }) - -describe('MissingCoreNodesMessage', () => { - const mockSystemStatsStore = { - systemStats: null as { system?: { comfyui_version?: string } } | null, - refetchSystemStats: vi.fn() - } - - beforeEach(() => { - vi.clearAllMocks() - // Reset the mock store state - mockSystemStatsStore.systemStats = null - mockSystemStatsStore.refetchSystemStats = vi.fn() - // @ts-expect-error - Mocking the return value of useSystemStatsStore for testing. - // The actual store has more properties, but we only need these for our tests. - useSystemStatsStore.mockReturnValue(mockSystemStatsStore) - }) - - const mountComponent = (props = {}) => { - return mount(MissingCoreNodesMessage, { - global: { - plugins: [PrimeVue], - components: { Message }, - mocks: { - $t: (key: string, params?: { version?: string }) => { - const translations: Record = { - 'loadWorkflowWarning.outdatedVersion': `Some nodes require a newer version of ComfyUI (current: ${params?.version}). Please update to use all nodes.`, - 'loadWorkflowWarning.outdatedVersionGeneric': - 'Some nodes require a newer version of ComfyUI. Please update to use all nodes.', - 'loadWorkflowWarning.coreNodesFromVersion': `Requires ComfyUI ${params?.version}:` - } - return translations[key] || key - } - } - }, - props: { - missingCoreNodes: {}, - ...props - } - }) - } - - it('does not render when there are no missing core nodes', () => { - const wrapper = mountComponent() - expect(wrapper.findComponent(Message).exists()).toBe(false) - }) - - it('renders message when there are missing core nodes', async () => { - const missingCoreNodes = { - '1.2.0': [createMockNode('TestNode', '1.2.0')] - } - - const wrapper = mountComponent({ missingCoreNodes }) - await nextTick() - - expect(wrapper.findComponent(Message).exists()).toBe(true) - }) - - it('displays current ComfyUI version when available', async () => { - // Set systemStats directly (store auto-fetches with useAsyncState) - mockSystemStatsStore.systemStats = { - system: { comfyui_version: '1.0.0' } - } - - const missingCoreNodes = { - '1.2.0': [createMockNode('TestNode', '1.2.0')] - } - - const wrapper = mountComponent({ missingCoreNodes }) - - // Wait for component to render - await nextTick() - - // No need to check if fetchSystemStats was called since useAsyncState auto-fetches - expect(wrapper.text()).toContain( - 'Some nodes require a newer version of ComfyUI (current: 1.0.0)' - ) - }) - - it('displays generic message when version is unavailable', async () => { - // No systemStats set - version unavailable - mockSystemStatsStore.systemStats = null - - const missingCoreNodes = { - '1.2.0': [createMockNode('TestNode', '1.2.0')] - } - - const wrapper = mountComponent({ missingCoreNodes }) - - // Wait for the async operations to complete - await nextTick() - await new Promise((resolve) => setTimeout(resolve, 0)) - await nextTick() - - expect(wrapper.text()).toContain( - 'Some nodes require a newer version of ComfyUI. Please update to use all nodes.' - ) - }) - - it('groups nodes by version and displays them', async () => { - const missingCoreNodes = { - '1.2.0': [ - createMockNode('NodeA', '1.2.0'), - createMockNode('NodeB', '1.2.0') - ], - '1.3.0': [createMockNode('NodeC', '1.3.0')] - } - - const wrapper = mountComponent({ missingCoreNodes }) - await nextTick() - - const text = wrapper.text() - expect(text).toContain('Requires ComfyUI 1.3.0:') - expect(text).toContain('NodeC') - expect(text).toContain('Requires ComfyUI 1.2.0:') - expect(text).toContain('NodeA, NodeB') - }) - - it('sorts versions in descending order', async () => { - const missingCoreNodes = { - '1.1.0': [createMockNode('Node1', '1.1.0')], - '1.3.0': [createMockNode('Node3', '1.3.0')], - '1.2.0': [createMockNode('Node2', '1.2.0')] - } - - const wrapper = mountComponent({ missingCoreNodes }) - await nextTick() - - const text = wrapper.text() - const version13Index = text.indexOf('1.3.0') - const version12Index = text.indexOf('1.2.0') - const version11Index = text.indexOf('1.1.0') - - expect(version13Index).toBeLessThan(version12Index) - expect(version12Index).toBeLessThan(version11Index) - }) - - it('removes duplicate node names within the same version', async () => { - const missingCoreNodes = { - '1.2.0': [ - createMockNode('DuplicateNode', '1.2.0'), - createMockNode('DuplicateNode', '1.2.0'), - createMockNode('UniqueNode', '1.2.0') - ] - } - - const wrapper = mountComponent({ missingCoreNodes }) - await nextTick() - - const text = wrapper.text() - // Should only appear once in the sorted list - expect(text).toContain('DuplicateNode, UniqueNode') - // Count occurrences of 'DuplicateNode' - should be only 1 - const matches = text.match(/DuplicateNode/g) || [] - expect(matches.length).toBe(1) - }) - - it('handles nodes with missing version info', async () => { - const missingCoreNodes = { - '': [createMockNode('NoVersionNode')] - } - - const wrapper = mountComponent({ missingCoreNodes }) - await nextTick() - - expect(wrapper.text()).toContain('Requires ComfyUI unknown:') - expect(wrapper.text()).toContain('NoVersionNode') - }) -}) diff --git a/src/components/dialog/content/MissingCoreNodesMessage.vue b/src/components/dialog/content/MissingCoreNodesMessage.vue deleted file mode 100644 index 14f2d76786c..00000000000 --- a/src/components/dialog/content/MissingCoreNodesMessage.vue +++ /dev/null @@ -1,83 +0,0 @@ - - - diff --git a/src/components/dialog/content/MissingNodesContent.vue b/src/components/dialog/content/MissingNodesContent.vue deleted file mode 100644 index c5a4f17990b..00000000000 --- a/src/components/dialog/content/MissingNodesContent.vue +++ /dev/null @@ -1,360 +0,0 @@ - - - diff --git a/src/components/dialog/content/MissingNodesFooter.vue b/src/components/dialog/content/MissingNodesFooter.vue deleted file mode 100644 index d9a144e3d05..00000000000 --- a/src/components/dialog/content/MissingNodesFooter.vue +++ /dev/null @@ -1,199 +0,0 @@ - - - diff --git a/src/components/dialog/content/MissingNodesHeader.vue b/src/components/dialog/content/MissingNodesHeader.vue deleted file mode 100644 index 1e150c3d3cf..00000000000 --- a/src/components/dialog/content/MissingNodesHeader.vue +++ /dev/null @@ -1,18 +0,0 @@ - - - diff --git a/src/composables/useMissingNodesDialog.ts b/src/composables/useMissingNodesDialog.ts deleted file mode 100644 index 83b7f156feb..00000000000 --- a/src/composables/useMissingNodesDialog.ts +++ /dev/null @@ -1,30 +0,0 @@ -import type { ComponentAttrs } from 'vue-component-type-helpers' - -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' - -const DIALOG_KEY = 'global-missing-nodes' - -export function useMissingNodesDialog() { - const { showSmallLayoutDialog } = useDialogService() - const dialogStore = useDialogStore() - - function hide() { - dialogStore.closeDialog({ key: DIALOG_KEY }) - } - - function show(props: ComponentAttrs) { - showSmallLayoutDialog({ - key: DIALOG_KEY, - headerComponent: MissingNodesHeader, - footerComponent: MissingNodesFooter, - component: MissingNodesContent, - props - }) - } - - return { show, hide } -} diff --git a/src/locales/ar/settings.json b/src/locales/ar/settings.json index fad3c2c76eb..13d76c1994e 100644 --- a/src/locales/ar/settings.json +++ b/src/locales/ar/settings.json @@ -454,9 +454,6 @@ "Comfy_Workflow_ShowMissingModelsWarning": { "name": "عرض تحذير النماذج المفقودة" }, - "Comfy_Workflow_ShowMissingNodesWarning": { - "name": "عرض تحذير العقد المفقودة" - }, "Comfy_Workflow_SortNodeIdOnSave": { "name": "ترتيب معرفات العقد عند حفظ سير العمل" }, diff --git a/src/locales/en/settings.json b/src/locales/en/settings.json index 7d11e30c8d7..81943a68f9d 100644 --- a/src/locales/en/settings.json +++ b/src/locales/en/settings.json @@ -454,9 +454,6 @@ "Comfy_Workflow_ShowMissingModelsWarning": { "name": "Show missing models warning" }, - "Comfy_Workflow_ShowMissingNodesWarning": { - "name": "Show missing nodes warning" - }, "Comfy_Workflow_SortNodeIdOnSave": { "name": "Sort node IDs when saving workflow" }, diff --git a/src/locales/es/settings.json b/src/locales/es/settings.json index 70ac882c7c0..f74d3b6aae0 100644 --- a/src/locales/es/settings.json +++ b/src/locales/es/settings.json @@ -454,9 +454,6 @@ "Comfy_Workflow_ShowMissingModelsWarning": { "name": "Mostrar advertencia de modelos faltantes" }, - "Comfy_Workflow_ShowMissingNodesWarning": { - "name": "Mostrar advertencia de nodos faltantes" - }, "Comfy_Workflow_SortNodeIdOnSave": { "name": "Ordenar IDs de nodos al guardar el flujo de trabajo" }, diff --git a/src/locales/fa/settings.json b/src/locales/fa/settings.json index de17434bb63..fc41792a38a 100644 --- a/src/locales/fa/settings.json +++ b/src/locales/fa/settings.json @@ -454,9 +454,6 @@ "Comfy_Workflow_ShowMissingModelsWarning": { "name": "نمایش هشدار مدل‌های مفقود" }, - "Comfy_Workflow_ShowMissingNodesWarning": { - "name": "نمایش هشدار نودهای مفقود" - }, "Comfy_Workflow_SortNodeIdOnSave": { "name": "مرتب‌سازی شناسه نودها هنگام ذخیره ورک‌فلو" }, diff --git a/src/locales/fr/settings.json b/src/locales/fr/settings.json index 3487c7caeb2..136bfe6f0f5 100644 --- a/src/locales/fr/settings.json +++ b/src/locales/fr/settings.json @@ -454,9 +454,6 @@ "Comfy_Workflow_ShowMissingModelsWarning": { "name": "Afficher l'avertissement des modèles manquants" }, - "Comfy_Workflow_ShowMissingNodesWarning": { - "name": "Afficher l'avertissement des nœuds manquants" - }, "Comfy_Workflow_SortNodeIdOnSave": { "name": "Trier les ID de nœuds lors de l'enregistrement du flux de travail" }, diff --git a/src/locales/ja/settings.json b/src/locales/ja/settings.json index 30501cae9a1..315ce86413a 100644 --- a/src/locales/ja/settings.json +++ b/src/locales/ja/settings.json @@ -454,9 +454,6 @@ "Comfy_Workflow_ShowMissingModelsWarning": { "name": "欠落しているモデルの警告を表示" }, - "Comfy_Workflow_ShowMissingNodesWarning": { - "name": "欠落しているノードの警告を表示" - }, "Comfy_Workflow_SortNodeIdOnSave": { "name": "ワークフローを保存する際にノードIDをソート" }, diff --git a/src/locales/ko/settings.json b/src/locales/ko/settings.json index 2a3a81a1914..eb995c8a66f 100644 --- a/src/locales/ko/settings.json +++ b/src/locales/ko/settings.json @@ -454,9 +454,6 @@ "Comfy_Workflow_ShowMissingModelsWarning": { "name": "누락된 모델 경고 표시" }, - "Comfy_Workflow_ShowMissingNodesWarning": { - "name": "누락된 노드 경고 표시" - }, "Comfy_Workflow_SortNodeIdOnSave": { "name": "워크플로 저장 시 노드 ID 정렬" }, diff --git a/src/locales/pt-BR/settings.json b/src/locales/pt-BR/settings.json index dd8f0488ea1..b10af3de880 100644 --- a/src/locales/pt-BR/settings.json +++ b/src/locales/pt-BR/settings.json @@ -454,9 +454,6 @@ "Comfy_Workflow_ShowMissingModelsWarning": { "name": "Mostrar aviso de modelos ausentes" }, - "Comfy_Workflow_ShowMissingNodesWarning": { - "name": "Mostrar aviso de nós ausentes" - }, "Comfy_Workflow_SortNodeIdOnSave": { "name": "Ordenar IDs dos nós ao salvar fluxo de trabalho" }, diff --git a/src/locales/ru/settings.json b/src/locales/ru/settings.json index 0dadacdf043..3cc180954e5 100644 --- a/src/locales/ru/settings.json +++ b/src/locales/ru/settings.json @@ -454,9 +454,6 @@ "Comfy_Workflow_ShowMissingModelsWarning": { "name": "Показать предупреждение об отсутствующих моделях" }, - "Comfy_Workflow_ShowMissingNodesWarning": { - "name": "Показать предупреждение об отсутствующих нодах" - }, "Comfy_Workflow_SortNodeIdOnSave": { "name": "Сортировать ID нод при сохранении рабочего процесса" }, diff --git a/src/locales/tr/settings.json b/src/locales/tr/settings.json index dfeb76140b9..d05bd622299 100644 --- a/src/locales/tr/settings.json +++ b/src/locales/tr/settings.json @@ -454,9 +454,6 @@ "Comfy_Workflow_ShowMissingModelsWarning": { "name": "Eksik model uyarısını göster" }, - "Comfy_Workflow_ShowMissingNodesWarning": { - "name": "Eksik düğüm uyarısını göster" - }, "Comfy_Workflow_SortNodeIdOnSave": { "name": "İş akışını kaydederken düğüm kimliklerini sırala" }, diff --git a/src/locales/zh-TW/settings.json b/src/locales/zh-TW/settings.json index 4549aba9a61..a048475c731 100644 --- a/src/locales/zh-TW/settings.json +++ b/src/locales/zh-TW/settings.json @@ -454,9 +454,6 @@ "Comfy_Workflow_ShowMissingModelsWarning": { "name": "顯示缺少模型警告" }, - "Comfy_Workflow_ShowMissingNodesWarning": { - "name": "顯示缺少節點警告" - }, "Comfy_Workflow_SortNodeIdOnSave": { "name": "儲存工作流程時排序節點 ID" }, diff --git a/src/locales/zh/settings.json b/src/locales/zh/settings.json index 49ea81a9404..a259400995e 100644 --- a/src/locales/zh/settings.json +++ b/src/locales/zh/settings.json @@ -454,9 +454,6 @@ "Comfy_Workflow_ShowMissingModelsWarning": { "name": "显示缺失模型警告" }, - "Comfy_Workflow_ShowMissingNodesWarning": { - "name": "显示缺失节点警告" - }, "Comfy_Workflow_SortNodeIdOnSave": { "name": "保存节点ID到工作流" }, diff --git a/src/platform/settings/constants/coreSettings.ts b/src/platform/settings/constants/coreSettings.ts index b65c52a3d2f..ea1a7f7c210 100644 --- a/src/platform/settings/constants/coreSettings.ts +++ b/src/platform/settings/constants/coreSettings.ts @@ -280,12 +280,6 @@ export const CORE_SETTINGS: SettingParams[] = [ step: 0.01 } }, - { - id: 'Comfy.Workflow.ShowMissingNodesWarning', - name: 'Show missing nodes warning', - type: 'boolean', - defaultValue: true - }, { id: 'Comfy.Workflow.ShowMissingModelsWarning', name: 'Show missing models warning', diff --git a/src/platform/workflow/core/services/workflowService.test.ts b/src/platform/workflow/core/services/workflowService.test.ts index 9a9df0cb3ac..bef0d5bbe6a 100644 --- a/src/platform/workflow/core/services/workflowService.test.ts +++ b/src/platform/workflow/core/services/workflowService.test.ts @@ -13,6 +13,7 @@ import type { ComfyWorkflow } from '@/platform/workflow/management/stores/workfl import { useWorkflowStore } from '@/platform/workflow/management/stores/workflowStore' import { useWorkflowService } from '@/platform/workflow/core/services/workflowService' import { app } from '@/scripts/app' +import { useExecutionErrorStore } from '@/stores/executionErrorStore' import { useAppMode } from '@/composables/useAppMode' import type { AppMode } from '@/composables/useAppMode' import type { ComfyWorkflowJSON } from '@/platform/workflow/validation/schemas/workflowSchema' @@ -56,16 +57,9 @@ function makeWorkflowData( } } -const { mockShowMissingNodes, mockShowMissingModels, mockConfirm } = vi.hoisted( - () => ({ - mockShowMissingNodes: vi.fn(), - mockShowMissingModels: vi.fn(), - mockConfirm: vi.fn() - }) -) - -vi.mock('@/composables/useMissingNodesDialog', () => ({ - useMissingNodesDialog: () => ({ show: mockShowMissingNodes, hide: vi.fn() }) +const { mockShowMissingModels, mockConfirm } = vi.hoisted(() => ({ + mockShowMissingModels: vi.fn(), + mockConfirm: vi.fn() })) vi.mock('@/composables/useMissingModelsDialog', () => ({ @@ -156,7 +150,6 @@ function createWorkflow( function enableWarningSettings() { vi.spyOn(useSettingStore(), 'get').mockImplementation( (key: string): boolean => { - if (key === 'Comfy.Workflow.ShowMissingNodesWarning') return true if (key === 'Comfy.Workflow.ShowMissingModelsWarning') return true return false } @@ -178,19 +171,21 @@ describe('useWorkflowService', () => { const workflow = createWorkflow(null) useWorkflowService().showPendingWarnings(workflow) - expect(mockShowMissingNodes).not.toHaveBeenCalled() + const errorStore = useExecutionErrorStore() + expect(errorStore.surfaceMissingNodes).not.toHaveBeenCalled() expect(mockShowMissingModels).not.toHaveBeenCalled() }) - it('should show missing nodes dialog and clear warnings', () => { + it('should surface missing nodes and clear warnings', () => { const missingNodeTypes = ['CustomNode1', 'CustomNode2'] const workflow = createWorkflow({ missingNodeTypes }) useWorkflowService().showPendingWarnings(workflow) - expect(mockShowMissingNodes).toHaveBeenCalledWith({ + const errorStore = useExecutionErrorStore() + expect(errorStore.surfaceMissingNodes).toHaveBeenCalledWith( missingNodeTypes - }) + ) expect(workflow.pendingWarnings).toBeNull() }) @@ -203,7 +198,7 @@ describe('useWorkflowService', () => { expect(workflow.pendingWarnings).toBeNull() }) - it('should not show dialogs when settings are disabled', () => { + it('should not show models dialog when settings are disabled', () => { vi.spyOn(useSettingStore(), 'get').mockReturnValue(false) const workflow = createWorkflow({ @@ -213,7 +208,10 @@ describe('useWorkflowService', () => { useWorkflowService().showPendingWarnings(workflow) - expect(mockShowMissingNodes).not.toHaveBeenCalled() + const errorStore = useExecutionErrorStore() + expect(errorStore.surfaceMissingNodes).toHaveBeenCalledWith([ + 'CustomNode1' + ]) expect(mockShowMissingModels).not.toHaveBeenCalled() expect(workflow.pendingWarnings).toBeNull() }) @@ -227,7 +225,8 @@ describe('useWorkflowService', () => { service.showPendingWarnings(workflow) service.showPendingWarnings(workflow) - expect(mockShowMissingNodes).toHaveBeenCalledTimes(1) + const errorStore = useExecutionErrorStore() + expect(errorStore.surfaceMissingNodes).toHaveBeenCalledTimes(1) }) }) @@ -250,7 +249,8 @@ describe('useWorkflowService', () => { { loadable: true } ) - expect(mockShowMissingNodes).not.toHaveBeenCalled() + const errorStore = useExecutionErrorStore() + expect(errorStore.surfaceMissingNodes).not.toHaveBeenCalled() await useWorkflowService().openWorkflow(workflow) @@ -261,9 +261,9 @@ describe('useWorkflowService', () => { workflow, expect.objectContaining({ deferWarnings: true }) ) - expect(mockShowMissingNodes).toHaveBeenCalledWith({ - missingNodeTypes: ['CustomNode1'] - }) + expect(errorStore.surfaceMissingNodes).toHaveBeenCalledWith([ + 'CustomNode1' + ]) expect(workflow.pendingWarnings).toBeNull() }) @@ -278,20 +278,21 @@ describe('useWorkflowService', () => { ) const service = useWorkflowService() + const errorStore = useExecutionErrorStore() await service.openWorkflow(workflow1) - expect(mockShowMissingNodes).toHaveBeenCalledTimes(1) - expect(mockShowMissingNodes).toHaveBeenCalledWith({ - missingNodeTypes: ['MissingNodeA'] - }) + expect(errorStore.surfaceMissingNodes).toHaveBeenCalledTimes(1) + expect(errorStore.surfaceMissingNodes).toHaveBeenCalledWith([ + 'MissingNodeA' + ]) expect(workflow1.pendingWarnings).toBeNull() expect(workflow2.pendingWarnings).not.toBeNull() await service.openWorkflow(workflow2) - expect(mockShowMissingNodes).toHaveBeenCalledTimes(2) - expect(mockShowMissingNodes).toHaveBeenLastCalledWith({ - missingNodeTypes: ['MissingNodeB'] - }) + expect(errorStore.surfaceMissingNodes).toHaveBeenCalledTimes(2) + expect(errorStore.surfaceMissingNodes).toHaveBeenLastCalledWith([ + 'MissingNodeB' + ]) expect(workflow2.pendingWarnings).toBeNull() }) @@ -302,12 +303,13 @@ describe('useWorkflowService', () => { ) const service = useWorkflowService() + const errorStore = useExecutionErrorStore() await service.openWorkflow(workflow, { force: true }) - expect(mockShowMissingNodes).toHaveBeenCalledTimes(1) + expect(errorStore.surfaceMissingNodes).toHaveBeenCalledTimes(1) await service.openWorkflow(workflow, { force: true }) - expect(mockShowMissingNodes).toHaveBeenCalledTimes(1) + expect(errorStore.surfaceMissingNodes).toHaveBeenCalledTimes(1) }) }) diff --git a/src/platform/workflow/core/services/workflowService.ts b/src/platform/workflow/core/services/workflowService.ts index 72d59d2bc3c..d87989881cc 100644 --- a/src/platform/workflow/core/services/workflowService.ts +++ b/src/platform/workflow/core/services/workflowService.ts @@ -17,7 +17,6 @@ import { useWorkflowThumbnail } from '@/renderer/core/thumbnail/useWorkflowThumb import { app } from '@/scripts/app' import { blankGraph, defaultGraph } from '@/scripts/defaultGraph' import { useMissingModelsDialog } from '@/composables/useMissingModelsDialog' -import { useMissingNodesDialog } from '@/composables/useMissingNodesDialog' import { useDialogService } from '@/services/dialogService' import { useAppMode } from '@/composables/useAppMode' import type { AppMode } from '@/composables/useAppMode' @@ -41,7 +40,6 @@ export const useWorkflowService = () => { const toastStore = useToastStore() const dialogService = useDialogService() const missingModelsDialog = useMissingModelsDialog() - const missingNodesDialog = useMissingNodesDialog() const workflowThumbnail = useWorkflowThumbnail() const domWidgetStore = useDomWidgetStore() const executionErrorStore = useExecutionErrorStore() @@ -540,11 +538,6 @@ export const useWorkflowService = () => { wf.pendingWarnings = null if (missingNodeTypes?.length) { - // Remove modal once Node Replacement is implemented in TabErrors. - if (settingStore.get('Comfy.Workflow.ShowMissingNodesWarning')) { - missingNodesDialog.show({ missingNodeTypes }) - } - executionErrorStore.surfaceMissingNodes(missingNodeTypes) } diff --git a/src/schemas/apiSchema.ts b/src/schemas/apiSchema.ts index fb530f54f50..34a8174f9c7 100644 --- a/src/schemas/apiSchema.ts +++ b/src/schemas/apiSchema.ts @@ -298,7 +298,6 @@ const zSettings = z.object({ 'Comfy.ConfirmClear': z.boolean(), 'Comfy.DevMode': z.boolean(), 'Comfy.UI.TabBarLayout': z.enum(['Default', 'Legacy']), - 'Comfy.Workflow.ShowMissingNodesWarning': z.boolean(), 'Comfy.Workflow.ShowMissingModelsWarning': z.boolean(), 'Comfy.Workflow.WarnBlueprintOverwrite': z.boolean(), 'Comfy.DisableFloatRounding': z.boolean(), diff --git a/src/scripts/app.ts b/src/scripts/app.ts index b3119fc388c..e2ec6b60850 100644 --- a/src/scripts/app.ts +++ b/src/scripts/app.ts @@ -55,7 +55,6 @@ import { DOMWidgetImpl } from '@/scripts/domWidget' import { useDialogService } from '@/services/dialogService' -import { useMissingNodesDialog } from '@/composables/useMissingNodesDialog' import { useExtensionService } from '@/services/extensionService' import { useLitegraphService } from '@/services/litegraphService' import { useSubgraphService } from '@/services/subgraphService' @@ -1093,11 +1092,6 @@ export class ComfyApp { } private showMissingNodesError(missingNodeTypes: MissingNodeType[]) { - // Remove modal once Node Replacement is implemented in TabErrors. - if (useSettingStore().get('Comfy.Workflow.ShowMissingNodesWarning')) { - useMissingNodesDialog().show({ missingNodeTypes }) - } - const executionErrorStore = useExecutionErrorStore() executionErrorStore.surfaceMissingNodes(missingNodeTypes) }