195 lines
8.1 KiB
JavaScript
195 lines
8.1 KiB
JavaScript
import { app } from "../../scripts/app.js"
|
|
import { api } from "../../scripts/api.js"
|
|
|
|
let EXTENSION_NAME, MESSAGE_ROUTE, chainCallback, fetchSend;
|
|
(async () => {
|
|
const constants = await fetch('/dadosConstants').then(response => response.json());
|
|
EXTENSION_NAME = constants.EXTENSION_NAME;
|
|
MESSAGE_ROUTE = constants.MESSAGE_ROUTE;
|
|
|
|
({chainCallback, fetchSend} =
|
|
await import(`/extensions/${EXTENSION_NAME}/common/js/utils.js`));
|
|
})().catch(error => console.error("Failed to load utilities:", error));
|
|
|
|
app.registerExtension({
|
|
name: "DN_CSVMultiDropDownNode",
|
|
async beforeRegisterNodeDef(nodeType, nodeData, app) {
|
|
if (nodeData.name !== "DN_CSVMultiDropDownNode") return;
|
|
|
|
chainCallback(nodeType.prototype, "onNodeCreated", function() {
|
|
this.properties = this.properties || {};
|
|
this.properties.csvText = this.properties.csvText || "";
|
|
this.properties.removeDuplicates = this.properties.removeDuplicates || "false";
|
|
this.dropdownWidgets = {};
|
|
|
|
if (this.outputs) {
|
|
for (let i = this.outputs.length - 1; i >= 0; i--) {
|
|
const output = this.outputs[i];
|
|
if (output.name !== "combined_selections") {
|
|
this.removeOutput(i);
|
|
}
|
|
}
|
|
}
|
|
|
|
const computed = this.computeSize();
|
|
this.size[0] = Math.max(this.size[0], computed[0]);
|
|
this.size[1] = computed[1];
|
|
this.setDirtyCanvas(true, true);
|
|
|
|
const csvWidget = this.widgets.find(w => w.name === "csv_text");
|
|
if (csvWidget && csvWidget.element) {
|
|
/* csvWidget.element.addEventListener('focus', () => {
|
|
console.log("csv_text focused", this.id);
|
|
}); */
|
|
csvWidget.element.addEventListener('blur', () => {
|
|
this.resetDropdowns();
|
|
this.properties.csvText = csvWidget.value;
|
|
this.parseCSVToDropdowns(csvWidget.value);
|
|
});
|
|
|
|
this.addWidget("button", "load_csv", "Load CSV", () => {
|
|
const input = document.createElement('input');
|
|
input.type = 'file';
|
|
input.accept = '.csv';
|
|
input.onchange = async (e) => {
|
|
const file = e.target.files[0];
|
|
if (file) {
|
|
const content = await file.text();
|
|
this.properties.csvText = content;
|
|
csvWidget.value = content;
|
|
this.resetDropdowns();
|
|
this.parseCSVToDropdowns(content);
|
|
}
|
|
};
|
|
input.click();
|
|
}, {});
|
|
}
|
|
|
|
this.updateBackend = async function() {
|
|
if (!this.id || this.id === -1) return;
|
|
const payload = {};
|
|
for (const [id, widget] of Object.entries(this.dropdownWidgets)) {
|
|
let value = widget.value;
|
|
payload[id] = value;
|
|
if (value === "random") {
|
|
payload[id + "_entries"] = widget.options.values.filter(v => v !== "random");
|
|
}
|
|
}
|
|
await fetchSend(MESSAGE_ROUTE, this.id, "update_selections", payload);
|
|
};
|
|
|
|
this.resetDropdowns = function() {
|
|
for (const id in this.dropdownWidgets) {
|
|
const widget = this.dropdownWidgets[id];
|
|
const index = this.widgets.indexOf(widget);
|
|
if (index !== -1) {
|
|
this.widgets.splice(index, 1);
|
|
}
|
|
}
|
|
this.dropdownWidgets = {};
|
|
|
|
if (this.outputs) {
|
|
for (let i = this.outputs.length - 1; i >= 0; i--) {
|
|
const output = this.outputs[i];
|
|
if (output.name !== "combined_selections") {
|
|
this.removeOutput(i);
|
|
}
|
|
}
|
|
}
|
|
|
|
this.setDirtyCanvas(true, true);
|
|
};
|
|
|
|
this.parseCSVToDropdowns = function(csvText) {
|
|
if (!csvText) return;
|
|
const rows = csvText.split(/\r?\n/).filter(r => r.trim() !== "");
|
|
|
|
const newDropdownWidgets = {};
|
|
|
|
for (const row of rows) {
|
|
let parts = row.split(",");
|
|
let id, options;
|
|
|
|
if (parts.length === 2 && parts[1].includes('"')) {
|
|
id = parts[0].replace(/^"|"$/g, "").trim();
|
|
options = parts[1].replace(/^"|"$/g, "").split(",").map(o => o.trim().replace(/^"|"$/g, ''));
|
|
} else if (parts.length > 1) {
|
|
id = parts[0].trim();
|
|
options = parts.slice(1).map(o => o.trim().replace(/^"|"$/g, ''));
|
|
} else {
|
|
continue;
|
|
}
|
|
|
|
if (this.properties.removeDuplicates === "true") {
|
|
options = [...new Set(options)];
|
|
}
|
|
if (options.length > 1) options.push("random");
|
|
|
|
let widget = this.dropdownWidgets[id];
|
|
if (!widget) {
|
|
const initialValue = (this.properties[id] !== undefined && options.includes(this.properties[id]))
|
|
? this.properties[id]
|
|
: options[0];
|
|
widget = this.addWidget("combo", id, initialValue, async (value) => {
|
|
this.properties[id] = value;
|
|
await this.updateBackend();
|
|
return value;
|
|
}, { values: options });
|
|
|
|
const existingOutput = this.outputs?.find(output => output.name === id);
|
|
if (!existingOutput) {
|
|
this.addOutput(id, "STRING");
|
|
}
|
|
} else {
|
|
widget.options.values = options;
|
|
if (widget.value && options.includes(widget.value)) {
|
|
widget.value = widget.value;
|
|
} else {
|
|
widget.value = options[0];
|
|
}
|
|
}
|
|
newDropdownWidgets[id] = widget;
|
|
}
|
|
|
|
this.dropdownWidgets = newDropdownWidgets;
|
|
this.setDirtyCanvas(true, true);
|
|
this.updateBackend().catch(() => {/* silent error */});
|
|
};
|
|
|
|
if (this.properties.csvText) {
|
|
setTimeout(() => this.parseCSVToDropdowns(this.properties.csvText), 50);
|
|
}
|
|
});
|
|
|
|
chainCallback(nodeType.prototype, "onConfigure", function(o) {
|
|
if (this.properties.csvText) {
|
|
this.parseCSVToDropdowns(this.properties.csvText);
|
|
}
|
|
});
|
|
|
|
return nodeType;
|
|
},
|
|
|
|
setup(app) {
|
|
const originalOnNodeRemoved = app.graph.onNodeRemoved;
|
|
app.graph.onNodeRemoved = function(node) {
|
|
if (node.type === "DN_CSVMultiDropDownNode") {
|
|
fetchSend(MESSAGE_ROUTE, node.id, "remove_selection");
|
|
}
|
|
originalOnNodeRemoved?.apply(this, arguments);
|
|
};
|
|
api.addEventListener('reconnected', () => {
|
|
// Find all DN_CSVMultiDropDownNode instances and send their selections
|
|
for (const node of app.graph._nodes) {
|
|
if (node.type === "DN_CSVMultiDropDownNode" && node.updateBackend) {
|
|
console.log("API reconnected - sending selections to backend");
|
|
setTimeout(() => {
|
|
node.updateBackend().catch(() => {/* silent error */});
|
|
}, 100);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
})
|
|
|