mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-20 06:44:32 +00:00
## Summary Add node replacement UI to the missing nodes dialog. Users can select and replace deprecated/missing nodes with compatible alternatives directly from the dialog. ## Changes - Classify missing nodes into **Replaceable** (quick fix) and **Install Required** sections - Add select-all checkbox + per-node checkboxes for batch replacement - `useNodeReplacement` composable handles in-place node replacement on the graph: - Simple replacement (configure+copy) for nodes without mapping - Input/output connection remapping for nodes with mapping - Widget value transfer via `old_widget_ids` - Dot-notation input handling for Autogrow/DynamicCombo - Undo/redo support via `changeTracker` (try/finally) - Title and properties preservation - Footer UX: "Skip for Now" button when all nodes are replaceable (cloud + OSS) - Auto-close dialog when all replaceable nodes are replaced and no non-replaceable remain - Settings navigation link from "Don't show again" checkbox - 505-line unit test suite for `useNodeReplacement` ## Review Focus - `useNodeReplacement.ts` — core graph manipulation logic - `MissingNodesContent.vue` — checkbox selection state management - `MissingNodesFooter.vue` — conditional button rendering (cloud vs OSS vs all-replaceable) [screen-capture.webm](https://github.com/user-attachments/assets/7dae891c-926c-4f26-987f-9637c4a2ca16) ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-8604-feat-Node-replacement-UI-2fd6d73d36508148a371dabb8f4115af) by [Unito](https://www.unito.io) --------- Co-authored-by: github-actions <github-actions@github.com>
206 lines
4.0 KiB
JSON
206 lines
4.0 KiB
JSON
{
|
|
"last_node_id": 7,
|
|
"last_link_id": 5,
|
|
"nodes": [
|
|
{
|
|
"id": 1,
|
|
"type": "T2IAdapterLoader",
|
|
"pos": [100, 100],
|
|
"size": [300, 80],
|
|
"flags": {},
|
|
"order": 0,
|
|
"mode": 0,
|
|
"inputs": [],
|
|
"outputs": [
|
|
{
|
|
"name": "CONTROL_NET",
|
|
"type": "CONTROL_NET",
|
|
"links": [],
|
|
"slot_index": 0
|
|
}
|
|
],
|
|
"properties": {
|
|
"Node name for S&R": "T2IAdapterLoader"
|
|
},
|
|
"widgets_values": ["t2iadapter_model.safetensors"]
|
|
},
|
|
{
|
|
"id": 2,
|
|
"type": "CheckpointLoaderSimple",
|
|
"pos": [100, 300],
|
|
"size": [315, 98],
|
|
"flags": {},
|
|
"order": 1,
|
|
"mode": 0,
|
|
"outputs": [
|
|
{
|
|
"name": "MODEL",
|
|
"type": "MODEL",
|
|
"links": [],
|
|
"slot_index": 0
|
|
},
|
|
{
|
|
"name": "CLIP",
|
|
"type": "CLIP",
|
|
"links": [],
|
|
"slot_index": 1
|
|
},
|
|
{
|
|
"name": "VAE",
|
|
"type": "VAE",
|
|
"links": [],
|
|
"slot_index": 2
|
|
}
|
|
],
|
|
"properties": {
|
|
"Node name for S&R": "CheckpointLoaderSimple"
|
|
},
|
|
"widgets_values": ["v1-5-pruned-emaonly-fp16.safetensors"]
|
|
},
|
|
{
|
|
"id": 3,
|
|
"type": "ResizeImagesByLongerEdge",
|
|
"pos": [500, 100],
|
|
"size": [300, 80],
|
|
"flags": {},
|
|
"order": 2,
|
|
"mode": 0,
|
|
"inputs": [
|
|
{
|
|
"name": "images",
|
|
"type": "IMAGE",
|
|
"link": null
|
|
}
|
|
],
|
|
"outputs": [
|
|
{
|
|
"name": "IMAGE",
|
|
"type": "IMAGE",
|
|
"links": [1],
|
|
"slot_index": 0
|
|
}
|
|
],
|
|
"properties": {
|
|
"Node name for S&R": "ResizeImagesByLongerEdge"
|
|
},
|
|
"widgets_values": [1024]
|
|
},
|
|
{
|
|
"id": 4,
|
|
"type": "ImageScaleBy",
|
|
"pos": [500, 280],
|
|
"size": [300, 80],
|
|
"flags": {},
|
|
"order": 3,
|
|
"mode": 0,
|
|
"inputs": [
|
|
{
|
|
"name": "image",
|
|
"type": "IMAGE",
|
|
"link": 1
|
|
}
|
|
],
|
|
"outputs": [
|
|
{
|
|
"name": "IMAGE",
|
|
"type": "IMAGE",
|
|
"links": [2, 3],
|
|
"slot_index": 0
|
|
}
|
|
],
|
|
"properties": {
|
|
"Node name for S&R": "ImageScaleBy"
|
|
},
|
|
"widgets_values": ["lanczos", 1.5]
|
|
},
|
|
{
|
|
"id": 5,
|
|
"type": "ImageBatch",
|
|
"pos": [900, 100],
|
|
"size": [300, 80],
|
|
"flags": {},
|
|
"order": 4,
|
|
"mode": 0,
|
|
"inputs": [
|
|
{
|
|
"name": "image1",
|
|
"type": "IMAGE",
|
|
"link": 2
|
|
},
|
|
{
|
|
"name": "image2",
|
|
"type": "IMAGE",
|
|
"link": null
|
|
}
|
|
],
|
|
"outputs": [
|
|
{
|
|
"name": "IMAGE",
|
|
"type": "IMAGE",
|
|
"links": [4],
|
|
"slot_index": 0
|
|
}
|
|
],
|
|
"properties": {
|
|
"Node name for S&R": "ImageBatch"
|
|
},
|
|
"widgets_values": []
|
|
},
|
|
{
|
|
"id": 6,
|
|
"type": "SaveImage",
|
|
"pos": [900, 300],
|
|
"size": [300, 80],
|
|
"flags": {},
|
|
"order": 5,
|
|
"mode": 0,
|
|
"inputs": [
|
|
{
|
|
"name": "images",
|
|
"type": "IMAGE",
|
|
"link": 3
|
|
}
|
|
],
|
|
"properties": {
|
|
"Node name for S&R": "SaveImage"
|
|
},
|
|
"widgets_values": ["ComfyUI"]
|
|
},
|
|
{
|
|
"id": 7,
|
|
"type": "PreviewImage",
|
|
"pos": [1250, 100],
|
|
"size": [300, 250],
|
|
"flags": {},
|
|
"order": 6,
|
|
"mode": 0,
|
|
"inputs": [
|
|
{
|
|
"name": "images",
|
|
"type": "IMAGE",
|
|
"link": 4
|
|
}
|
|
],
|
|
"properties": {
|
|
"Node name for S&R": "PreviewImage"
|
|
},
|
|
"widgets_values": []
|
|
}
|
|
],
|
|
"links": [
|
|
[1, 3, 0, 4, 0, "IMAGE"],
|
|
[2, 4, 0, 5, 0, "IMAGE"],
|
|
[3, 4, 0, 6, 0, "IMAGE"],
|
|
[4, 5, 0, 7, 0, "IMAGE"]
|
|
],
|
|
"groups": [],
|
|
"config": {},
|
|
"extra": {
|
|
"ds": {
|
|
"scale": 1,
|
|
"offset": [0, 0]
|
|
}
|
|
},
|
|
"version": 0.4
|
|
}
|