From f97cf77e757e488df641f035ccea19575cf2b7d9 Mon Sep 17 00:00:00 2001 From: Jin Yi Date: Wed, 12 Nov 2025 19:03:09 +0900 Subject: [PATCH] Add cloud-specific missing nodes warning dialog (#6659) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Implements a cloud-specific dialog to warn users when loading workflows with unsupported custom nodes in Comfy Cloud. The new dialog follows the visual style of the node conflict dialog and provides appropriate messaging and actions. ## Changes - Add `CloudMissingNodesHeader`, `CloudMissingNodesContent`, and `CloudMissingNodesFooter` components - Add `showCloudLoadWorkflowWarning` to dialogService - Update app.ts to show cloud dialog when in cloud environment - Add `cloud.missingNodes` translations ## Screenshots The dialog displays: - Warning icon and title - Description of the issue - List of missing nodes - "Learn more" link and "Ok, got it" button ## Test plan 1. Load a workflow with custom nodes in cloud environment 2. Verify cloud-specific dialog appears with appropriate styling 3. Verify "Learn more" button opens cloud documentation 4. Verify "Ok, got it" button closes dialog ## Notes - Two unused i18n keys (`cloud.missingNodes.cannotRun` and `cloud.missingNodes.missingNodes`) are included for future PR that will add breadcrumb warning icons and run button disable functionality 스크린샷 2025-11-12 오후 4 33 38 🤖 Generated with [Claude Code](https://claude.com/claude-code) ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-6659-Add-cloud-specific-missing-nodes-warning-dialog-2a96d73d36508161ae55fe157f55cd17) by [Unito](https://www.unito.io) --------- Co-authored-by: Claude --- .../content/CloudMissingNodesContent.vue | 70 +++++++++++++++++++ .../content/CloudMissingNodesFooter.vue | 37 ++++++++++ .../content/CloudMissingNodesHeader.vue | 10 +++ src/locales/en/main.json | 12 ++++ src/scripts/app.ts | 6 +- src/services/dialogService.ts | 30 ++++++++ 6 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 src/components/dialog/content/CloudMissingNodesContent.vue create mode 100644 src/components/dialog/content/CloudMissingNodesFooter.vue create mode 100644 src/components/dialog/content/CloudMissingNodesHeader.vue diff --git a/src/components/dialog/content/CloudMissingNodesContent.vue b/src/components/dialog/content/CloudMissingNodesContent.vue new file mode 100644 index 000000000..108bfd0e3 --- /dev/null +++ b/src/components/dialog/content/CloudMissingNodesContent.vue @@ -0,0 +1,70 @@ + + + diff --git a/src/components/dialog/content/CloudMissingNodesFooter.vue b/src/components/dialog/content/CloudMissingNodesFooter.vue new file mode 100644 index 000000000..ee00cf54b --- /dev/null +++ b/src/components/dialog/content/CloudMissingNodesFooter.vue @@ -0,0 +1,37 @@ + + + diff --git a/src/components/dialog/content/CloudMissingNodesHeader.vue b/src/components/dialog/content/CloudMissingNodesHeader.vue new file mode 100644 index 000000000..21055ac56 --- /dev/null +++ b/src/components/dialog/content/CloudMissingNodesHeader.vue @@ -0,0 +1,10 @@ + diff --git a/src/locales/en/main.json b/src/locales/en/main.json index c49a73548..5a297bf23 100644 --- a/src/locales/en/main.json +++ b/src/locales/en/main.json @@ -2049,6 +2049,18 @@ "vueNodesBanner": { "message": "Nodes just got a new look and feel", "tryItOut": "Try it out" + }, + "cloud": { + "missingNodes": { + "title": "These nodes aren't available on Comfy Cloud yet", + "description": "This workflow uses custom nodes that aren't supported in the Cloud version yet.", + "priorityMessage": "We've automatically flagged these nodes so we can prioritize adding them.", + "missingNodes": "Missing Nodes", + "replacementInstruction": "In the meantime, replace these nodes (highlighted red on the canvas) with supported ones if possible, or try a different workflow.", + "learnMore": "Learn more", + "gotIt": "Ok, got it", + "cannotRun": "Workflow contains unsupported nodes (highlighted red). Remove these to run the workflow. " + } } } diff --git a/src/scripts/app.ts b/src/scripts/app.ts index d26698c62..0390bd157 100644 --- a/src/scripts/app.ts +++ b/src/scripts/app.ts @@ -1001,7 +1001,11 @@ export class ComfyApp { private showMissingNodesError(missingNodeTypes: MissingNodeType[]) { if (useSettingStore().get('Comfy.Workflow.ShowMissingNodesWarning')) { - useDialogService().showLoadWorkflowWarning({ missingNodeTypes }) + if (isCloud) { + useDialogService().showCloudLoadWorkflowWarning({ missingNodeTypes }) + } else { + useDialogService().showLoadWorkflowWarning({ missingNodeTypes }) + } } } diff --git a/src/services/dialogService.ts b/src/services/dialogService.ts index db4202ae7..c31905280 100644 --- a/src/services/dialogService.ts +++ b/src/services/dialogService.ts @@ -2,6 +2,9 @@ import { merge } from 'es-toolkit/compat' import type { Component } from 'vue' import ApiNodesSignInContent from '@/components/dialog/content/ApiNodesSignInContent.vue' +import CloudMissingNodesContent from '@/components/dialog/content/CloudMissingNodesContent.vue' +import CloudMissingNodesFooter from '@/components/dialog/content/CloudMissingNodesFooter.vue' +import CloudMissingNodesHeader from '@/components/dialog/content/CloudMissingNodesHeader.vue' import ConfirmationDialogContent from '@/components/dialog/content/ConfirmationDialogContent.vue' import ErrorDialogContent from '@/components/dialog/content/ErrorDialogContent.vue' import LoadWorkflowWarning from '@/components/dialog/content/LoadWorkflowWarning.vue' @@ -32,6 +35,7 @@ import NodeConflictDialogContent from '@/workbench/extensions/manager/components 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 { ComponentProps } from 'vue-component-type-helpers' export type ConfirmationDialogType = | 'default' @@ -53,6 +57,31 @@ export const useDialogService = () => { }) } + function showCloudLoadWorkflowWarning( + props: ComponentProps + ) { + dialogStore.showDialog({ + key: 'global-cloud-missing-nodes', + headerComponent: CloudMissingNodesHeader, + footerComponent: CloudMissingNodesFooter, + component: CloudMissingNodesContent, + 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' + } + } + } + }, + props + }) + } + function showMissingModelsWarning( props: InstanceType['$props'] ) { @@ -520,6 +549,7 @@ export const useDialogService = () => { return { showLoadWorkflowWarning, + showCloudLoadWorkflowWarning, showMissingModelsWarning, showSettingsDialog, showAboutDialog,