mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2025-04-20 03:13:30 +00:00
Export and import templates
This commit is contained in:
parent
f8caa24bcc
commit
6dbb18df92
@ -22,6 +22,15 @@ class ManageTemplates extends ComfyDialog {
|
|||||||
super();
|
super();
|
||||||
this.element.classList.add("comfy-manage-templates");
|
this.element.classList.add("comfy-manage-templates");
|
||||||
this.templates = this.load();
|
this.templates = this.load();
|
||||||
|
|
||||||
|
this.importInput = $el("input", {
|
||||||
|
type: "file",
|
||||||
|
accept: ".json",
|
||||||
|
multiple: true,
|
||||||
|
style: {display: "none"},
|
||||||
|
parent: document.body,
|
||||||
|
onchange: () => this.importAll(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
createButtons() {
|
createButtons() {
|
||||||
@ -34,6 +43,22 @@ class ManageTemplates extends ComfyDialog {
|
|||||||
onclick: () => this.save(),
|
onclick: () => this.save(),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
btns.unshift(
|
||||||
|
$el("button", {
|
||||||
|
type: "button",
|
||||||
|
textContent: "Export",
|
||||||
|
onclick: () => this.exportAll(),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
btns.unshift(
|
||||||
|
$el("button", {
|
||||||
|
type: "button",
|
||||||
|
textContent: "Import",
|
||||||
|
onclick: () => {
|
||||||
|
this.importInput.click();
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
return btns;
|
return btns;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,6 +94,50 @@ class ManageTemplates extends ComfyDialog {
|
|||||||
localStorage.setItem(id, JSON.stringify(this.templates));
|
localStorage.setItem(id, JSON.stringify(this.templates));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async importAll() {
|
||||||
|
for (const file of this.importInput.files) {
|
||||||
|
if (file.type === "application/json" || file.name.endsWith(".json")) {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = async () => {
|
||||||
|
var importFile = JSON.parse(reader.result);
|
||||||
|
if (importFile && importFile?.templates) {
|
||||||
|
for (const template of importFile.templates) {
|
||||||
|
if (template?.name && template?.data) {
|
||||||
|
this.templates.push(template);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.store();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
await reader.readAsText(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
exportAll() {
|
||||||
|
if (this.templates.length == 0) {
|
||||||
|
alert("No templates to export.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const json = JSON.stringify({templates: this.templates}, null, 2); // convert the data to a JSON string
|
||||||
|
const blob = new Blob([json], {type: "application/json"});
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
const a = $el("a", {
|
||||||
|
href: url,
|
||||||
|
download: "node_templates.json",
|
||||||
|
style: {display: "none"},
|
||||||
|
parent: document.body,
|
||||||
|
});
|
||||||
|
a.click();
|
||||||
|
setTimeout(function () {
|
||||||
|
a.remove();
|
||||||
|
window.URL.revokeObjectURL(url);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
|
||||||
show() {
|
show() {
|
||||||
// Show list of template names + delete button
|
// Show list of template names + delete button
|
||||||
super.show(
|
super.show(
|
||||||
@ -97,6 +166,33 @@ class ManageTemplates extends ComfyDialog {
|
|||||||
}),
|
}),
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
|
$el(
|
||||||
|
"div",
|
||||||
|
{},
|
||||||
|
[
|
||||||
|
$el("button", {
|
||||||
|
textContent: "Export",
|
||||||
|
style: {
|
||||||
|
fontSize: "12px",
|
||||||
|
fontWeight: "normal",
|
||||||
|
},
|
||||||
|
onclick: (e) => {
|
||||||
|
const json = JSON.stringify({templates: [t]}, null, 2); // convert the data to a JSON string
|
||||||
|
const blob = new Blob([json], {type: "application/json"});
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
const a = $el("a", {
|
||||||
|
href: url,
|
||||||
|
download: t.name + ".json",
|
||||||
|
style: {display: "none"},
|
||||||
|
parent: document.body,
|
||||||
|
});
|
||||||
|
a.click();
|
||||||
|
setTimeout(function () {
|
||||||
|
a.remove();
|
||||||
|
window.URL.revokeObjectURL(url);
|
||||||
|
}, 0);
|
||||||
|
},
|
||||||
|
}),
|
||||||
$el("button", {
|
$el("button", {
|
||||||
textContent: "Delete",
|
textContent: "Delete",
|
||||||
style: {
|
style: {
|
||||||
@ -106,10 +202,12 @@ class ManageTemplates extends ComfyDialog {
|
|||||||
},
|
},
|
||||||
onclick: (e) => {
|
onclick: (e) => {
|
||||||
nameInput.value = "";
|
nameInput.value = "";
|
||||||
e.target.style.display = "none";
|
e.target.parentElement.style.display = "none";
|
||||||
e.target.previousElementSibling.style.display = "none";
|
e.target.parentElement.previousElementSibling.style.display = "none";
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
]
|
||||||
|
),
|
||||||
];
|
];
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
@ -164,7 +262,6 @@ app.registerExtension({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (subItems.length) {
|
|
||||||
subItems.push(null, {
|
subItems.push(null, {
|
||||||
content: "Manage",
|
content: "Manage",
|
||||||
callback: () => manage.show(),
|
callback: () => manage.show(),
|
||||||
@ -176,7 +273,6 @@ app.registerExtension({
|
|||||||
options: subItems,
|
options: subItems,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
};
|
};
|
||||||
|
@ -1416,6 +1416,43 @@ export class ComfyApp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadTemplateData(templateData) {
|
||||||
|
if (!templateData?.templates) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const old = localStorage.getItem("litegrapheditor_clipboard");
|
||||||
|
|
||||||
|
var maxY, nodeBottom, node;
|
||||||
|
|
||||||
|
for (const template of templateData.templates) {
|
||||||
|
if (!template?.data) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
localStorage.setItem("litegrapheditor_clipboard", template.data);
|
||||||
|
app.canvas.pasteFromClipboard();
|
||||||
|
|
||||||
|
// Move mouse position down to paste the next template below
|
||||||
|
|
||||||
|
maxY = false;
|
||||||
|
|
||||||
|
for (const i in app.canvas.selected_nodes) {
|
||||||
|
node = app.canvas.selected_nodes[i];
|
||||||
|
|
||||||
|
nodeBottom = node.pos[1] + node.size[1];
|
||||||
|
|
||||||
|
if (maxY === false || nodeBottom > maxY) {
|
||||||
|
maxY = nodeBottom;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
app.canvas.graph_mouse[1] = maxY + 50;
|
||||||
|
}
|
||||||
|
|
||||||
|
localStorage.setItem("litegrapheditor_clipboard", old);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Populates the graph with the specified workflow data
|
* Populates the graph with the specified workflow data
|
||||||
* @param {*} graphData A serialized graph object
|
* @param {*} graphData A serialized graph object
|
||||||
@ -1756,7 +1793,12 @@ export class ComfyApp {
|
|||||||
} else if (file.type === "application/json" || file.name?.endsWith(".json")) {
|
} else if (file.type === "application/json" || file.name?.endsWith(".json")) {
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
reader.onload = () => {
|
reader.onload = () => {
|
||||||
this.loadGraphData(JSON.parse(reader.result));
|
var jsonContent = JSON.parse(reader.result);
|
||||||
|
if (jsonContent?.templates) {
|
||||||
|
this.loadTemplateData(jsonContent);
|
||||||
|
} else {
|
||||||
|
this.loadGraphData(jsonContent);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
reader.readAsText(file);
|
reader.readAsText(file);
|
||||||
} else if (file.name?.endsWith(".latent") || file.name?.endsWith(".safetensors")) {
|
} else if (file.name?.endsWith(".latent") || file.name?.endsWith(".safetensors")) {
|
||||||
|
Loading…
Reference in New Issue
Block a user