Add reroute migration toast (#3286)

Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
Chenlei Hu
2025-03-30 21:48:10 -04:00
committed by GitHub
parent 7e76665a22
commit 58dec5ea42
15 changed files with 90 additions and 22 deletions

View File

@@ -32,7 +32,7 @@ test.describe('Keybindings', () => {
})
await comfyPage.executeCommand('TestCommand')
await expect(comfyPage.page.locator('.p-toast')).toBeVisible()
expect(await comfyPage.getToastErrorCount()).toBe(1)
})
test('Should handle async command errors', async ({ comfyPage }) => {
@@ -45,6 +45,6 @@ test.describe('Keybindings', () => {
})
await comfyPage.executeCommand('TestCommand')
await expect(comfyPage.page.locator('.p-toast')).toBeVisible()
expect(await comfyPage.getToastErrorCount()).toBe(1)
})
})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -0,0 +1,46 @@
<template>
<Toast group="reroute-migration">
<template #message>
<div class="flex flex-col items-start flex-auto">
<div class="font-medium text-lg my-4">
{{ t('toastMessages.migrateToLitegraphReroute') }}
</div>
<Button
class="self-end"
size="small"
:label="t('g.migrate')"
severity="warn"
@click="migrateToLitegraphReroute"
/>
</div>
</template>
</Toast>
</template>
<script setup lang="ts">
import { useToast } from 'primevue'
import Button from 'primevue/button'
import Toast from 'primevue/toast'
import { useI18n } from 'vue-i18n'
import type { WorkflowJSON04 } from '@/schemas/comfyWorkflowSchema'
import { app } from '@/scripts/app'
import { useWorkflowStore } from '@/stores/workflowStore'
import { migrateLegacyRerouteNodes } from '@/utils/migration/migrateReroute'
const { t } = useI18n()
const toast = useToast()
const workflowStore = useWorkflowStore()
const migrateToLitegraphReroute = () => {
const workflowJSON = app.serializeGraph() as unknown as WorkflowJSON04
const migratedWorkflowJSON = migrateLegacyRerouteNodes(workflowJSON)
app.loadGraphData(
migratedWorkflowJSON,
false,
false,
workflowStore.activeWorkflow
)
toast.removeGroup('reroute-migration')
}
</script>

View File

@@ -104,7 +104,8 @@
"interrupted": "Interrupted",
"enabling": "Enabling",
"disabling": "Disabling",
"updating": "Updating"
"updating": "Updating",
"migrate": "Migrate"
},
"manager": {
"title": "Custom Nodes Manager",
@@ -1024,6 +1025,7 @@
"errorSaveSetting": "Error saving setting {id}: {err}",
"errorCopyImage": "Error copying image: {error}",
"noTemplatesToExport": "No templates to export",
"failedToFetchLogs": "Failed to fetch server logs"
"failedToFetchLogs": "Failed to fetch server logs",
"migrateToLitegraphReroute": "Reroute nodes will be removed in future versions. Click to migrate to litegraph-native reroute."
}
}

View File

@@ -181,6 +181,7 @@
"loadWorkflow": "Cargar flujo de trabajo",
"loading": "Cargando",
"logs": "Registros",
"migrate": "Migrar",
"missing": "Faltante",
"name": "Nombre",
"newFolder": "Nueva carpeta",
@@ -1000,6 +1001,7 @@
"fileLoadError": "No se puede encontrar el flujo de trabajo en {fileName}",
"fileUploadFailed": "Error al subir el archivo",
"interrupted": "La ejecución ha sido interrumpida",
"migrateToLitegraphReroute": "Los nodos de reroute se eliminarán en futuras versiones. Haz clic para migrar a reroute nativo de litegraph.",
"no3dScene": "No hay escena 3D para aplicar textura",
"no3dSceneToExport": "No hay escena 3D para exportar",
"noTemplatesToExport": "No hay plantillas para exportar",

View File

@@ -181,6 +181,7 @@
"loadWorkflow": "Charger le flux de travail",
"loading": "Chargement",
"logs": "Journaux",
"migrate": "Migrer",
"missing": "Manquant",
"name": "Nom",
"newFolder": "Nouveau dossier",
@@ -1000,6 +1001,7 @@
"fileLoadError": "Impossible de trouver le flux de travail dans {fileName}",
"fileUploadFailed": "Échec du téléchargement du fichier",
"interrupted": "L'exécution a été interrompue",
"migrateToLitegraphReroute": "Les nœuds de reroute seront supprimés dans les futures versions. Cliquez pour migrer vers le reroute natif de litegraph.",
"no3dScene": "Aucune scène 3D pour appliquer la texture",
"no3dSceneToExport": "Aucune scène 3D à exporter",
"noTemplatesToExport": "Aucun modèle à exporter",

View File

@@ -181,6 +181,7 @@
"loadWorkflow": "ワークフローを読み込む",
"loading": "読み込み中",
"logs": "ログ",
"migrate": "移行する",
"missing": "不足している",
"name": "名前",
"newFolder": "新しいフォルダー",
@@ -1000,6 +1001,7 @@
"fileLoadError": "{fileName}でワークフローが見つかりません",
"fileUploadFailed": "ファイルのアップロードに失敗しました",
"interrupted": "実行が中断されました",
"migrateToLitegraphReroute": "将来のバージョンではRerouteードが削除されます。litegraph-native rerouteに移行するにはクリックしてください。",
"no3dScene": "テクスチャを適用する3Dシーンがありません",
"no3dSceneToExport": "エクスポートする3Dシーンがありません",
"noTemplatesToExport": "エクスポートするテンプレートがありません",

View File

@@ -181,6 +181,7 @@
"loadWorkflow": "워크플로 로드",
"loading": "로딩 중",
"logs": "로그",
"migrate": "마이그레이트",
"missing": "누락됨",
"name": "이름",
"newFolder": "새 폴더",
@@ -1000,6 +1001,7 @@
"fileLoadError": "{fileName}에서 워크플로우를 찾을 수 없습니다",
"fileUploadFailed": "파일 업로드에 실패했습니다",
"interrupted": "실행이 중단되었습니다",
"migrateToLitegraphReroute": "미래 버전에서는 Reroute 노드가 제거됩니다. litegraph-native reroute로 마이그레이트하려면 클릭하세요.",
"no3dScene": "텍스처를 적용할 3D 장면이 없습니다",
"no3dSceneToExport": "내보낼 3D 장면이 없습니다",
"noTemplatesToExport": "내보낼 템플릿이 없습니다",

View File

@@ -181,6 +181,7 @@
"loadWorkflow": "Загрузить рабочий процесс",
"loading": "Загрузка",
"logs": "Логи",
"migrate": "Мигрировать",
"missing": "Отсутствует",
"name": "Имя",
"newFolder": "Новая папка",
@@ -1000,6 +1001,7 @@
"fileLoadError": "Не удалось найти рабочий процесс в {fileName}",
"fileUploadFailed": "Не удалось загрузить файл",
"interrupted": "Выполнение было прервано",
"migrateToLitegraphReroute": "Узлы перенаправления будут удалены в будущих версиях. Нажмите, чтобы перейти на litegraph-native reroute.",
"no3dScene": "Нет 3D сцены для применения текстуры",
"no3dSceneToExport": "Нет 3D сцены для экспорта",
"noTemplatesToExport": "Нет шаблонов для экспорта",

View File

@@ -181,6 +181,7 @@
"loadWorkflow": "加载工作流",
"loading": "加载中",
"logs": "日志",
"migrate": "迁移",
"missing": "缺失",
"name": "名称",
"newFolder": "新文件夹",
@@ -1000,6 +1001,7 @@
"fileLoadError": "无法在 {fileName} 中找到工作流",
"fileUploadFailed": "文件上传失败",
"interrupted": "执行已被中断",
"migrateToLitegraphReroute": "将来的版本中将删除重定向节点。点击以迁移到litegraph-native重定向。",
"no3dScene": "没有3D场景可以应用纹理",
"no3dSceneToExport": "没有3D场景可以导出",
"noTemplatesToExport": "没有模板可以导出",

View File

@@ -47,7 +47,7 @@ import { ExtensionManager } from '@/types/extensionTypes'
import { ColorAdjustOptions, adjustColor } from '@/utils/colorUtil'
import { graphToPrompt } from '@/utils/executionUtil'
import { executeWidgetsCallback, isImageNode } from '@/utils/litegraphUtil'
import { migrateLegacyRerouteNodes } from '@/utils/migration/migrateReroute'
import { findLegacyRerouteNodes } from '@/utils/migration/migrateReroute'
import { deserialiseAndCreate } from '@/utils/vintageClipboard'
import { type ComfyApi, PromptExecutionError, api } from './api'
@@ -945,7 +945,11 @@ export class ComfyApp {
clean: boolean = true,
restore_view: boolean = true,
workflow: string | null | ComfyWorkflow = null,
{ showMissingNodesDialog = true, showMissingModelsDialog = true } = {}
{
showMissingNodesDialog = true,
showMissingModelsDialog = true,
checkForRerouteMigration = true
} = {}
) {
if (clean !== false) {
this.clean()
@@ -972,11 +976,16 @@ export class ComfyApp {
graphData = validatedGraphData ?? graphData
}
// Migrate legacy reroute nodes to the new format
if (graphData.version === 0.4) {
graphData = migrateLegacyRerouteNodes(graphData)
if (
checkForRerouteMigration &&
graphData.version === 0.4 &&
findLegacyRerouteNodes(graphData).length
) {
useToastStore().add({
group: 'reroute-migration',
severity: 'warn'
})
}
useWorkflowService().beforeLoadNewGraph()
const missingNodeTypes: MissingNodeType[] = []

View File

@@ -135,7 +135,8 @@ export class ChangeTracker {
try {
await this.app.loadGraphData(prevState, false, false, this.workflow, {
showMissingModelsDialog: false,
showMissingNodesDialog: false
showMissingNodesDialog: false,
checkForRerouteMigration: false
})
this.activeState = prevState
this.updateModified()

View File

@@ -3,10 +3,7 @@ import type { SerialisableGraph, Vector2 } from '@comfyorg/litegraph'
import { toRaw } from 'vue'
import { t } from '@/i18n'
import {
ComfyWorkflowJSON,
WorkflowJSON04
} from '@/schemas/comfyWorkflowSchema'
import { ComfyWorkflowJSON } from '@/schemas/comfyWorkflowSchema'
import { app } from '@/scripts/app'
import { blankGraph, defaultGraph } from '@/scripts/defaultGraph'
import { downloadBlob } from '@/scripts/utils'
@@ -15,7 +12,6 @@ import { useToastStore } from '@/stores/toastStore'
import { ComfyWorkflow, useWorkflowStore } from '@/stores/workflowStore'
import { useWorkspaceStore } from '@/stores/workspaceStore'
import { appendJsonExt } from '@/utils/formatUtil'
import { migrateLegacyRerouteNodes } from '@/utils/migration/migrateReroute'
import { useDialogService } from './dialogService'
@@ -167,7 +163,8 @@ export const useWorkflowService = () => {
workflow,
{
showMissingModelsDialog: loadFromRemote,
showMissingNodesDialog: loadFromRemote
showMissingNodesDialog: loadFromRemote,
checkForRerouteMigration: loadFromRemote
}
)
}
@@ -328,10 +325,7 @@ export const useWorkflowService = () => {
) => {
const loadedWorkflow = await workflow.load()
const data = loadedWorkflow.initialState
const workflowJSON =
data.version === 0.4
? migrateLegacyRerouteNodes(data as WorkflowJSON04)
: data
const workflowJSON = data
const old = localStorage.getItem('litegrapheditor_clipboard')
// unknown conversion: ComfyWorkflowJSON is stricter than LiteGraph's
// serialisation schema.

View File

@@ -20,7 +20,9 @@ type LinkExtension = {
/**
* Identifies all legacy Reroute nodes in a workflow
*/
function findLegacyRerouteNodes(workflow: WorkflowJSON04): RerouteNode[] {
export function findLegacyRerouteNodes(
workflow: WorkflowJSON04
): RerouteNode[] {
return workflow.nodes.filter(
(node) => node.type === 'Reroute'
) as RerouteNode[]

View File

@@ -14,6 +14,7 @@
</div>
<GlobalToast />
<RerouteMigrationToast />
<UnloadWindowConfirmDialog v-if="!isElectron()" />
<BrowserTabTitle />
<MenuHamburger />
@@ -31,6 +32,7 @@ import MenuHamburger from '@/components/MenuHamburger.vue'
import UnloadWindowConfirmDialog from '@/components/dialog/UnloadWindowConfirmDialog.vue'
import GraphCanvas from '@/components/graph/GraphCanvas.vue'
import GlobalToast from '@/components/toast/GlobalToast.vue'
import RerouteMigrationToast from '@/components/toast/RerouteMigrationToast.vue'
import TopMenubar from '@/components/topbar/TopMenubar.vue'
import { useCoreCommands } from '@/composables/useCoreCommands'
import { useErrorHandling } from '@/composables/useErrorHandling'