Fix Subflow edit box and color change

This commit is contained in:
GogoVega 2025-01-12 14:06:21 +01:00
parent 1e8f840993
commit 37aacd3e84
No known key found for this signature in database
GPG Key ID: E1E048B63AC5AC2B
4 changed files with 97 additions and 81 deletions

View File

@ -490,6 +490,13 @@ RED.history = (function() {
} }
} }
}); });
} else if (i === "color" && ev.node.type === "subflow") {
// Handle the Subflow definition color change
RED.utils.clearNodeColorCache();
const subflowDef = RED.nodes.getType("subflow:" + ev.node.id);
if (subflowDef) {
subflowDef.color = ev.changes[i] || "#DDAA99";
}
} }
if (i === "credentials" && ev.changes[i]) { if (i === "credentials" && ev.changes[i]) {
// Reset - Only want to keep the changes // Reset - Only want to keep the changes
@ -556,6 +563,10 @@ RED.history = (function() {
if (node) { if (node) {
node.changed = n.changed; node.changed = n.changed;
node.dirty = true; node.dirty = true;
if (ev.changes && ev.changes.hasOwnProperty('color')) {
node._colorChanged = true;
}
} }
}); });
} }

View File

@ -295,8 +295,8 @@ RED.editor = (function() {
* Called when the node's properties have changed. * Called when the node's properties have changed.
* Marks the node as dirty and needing a size check. * Marks the node as dirty and needing a size check.
* Removes any links to non-existant outputs. * Removes any links to non-existant outputs.
* @param node - the node that has been updated * @param {object} node - the node that has been updated
* @param outputMap - (optional) a map of old->new port numbers if wires should be moved * @param {object} [outputMap] - (optional) a map of old->new port numbers if wires should be moved
* @returns {array} the links that were removed due to this update * @returns {array} the links that were removed due to this update
*/ */
function updateNodeProperties(node, outputMap) { function updateNodeProperties(node, outputMap) {
@ -1778,11 +1778,13 @@ RED.editor = (function() {
function showEditSubflowDialog(subflow, defaultTab) { function showEditSubflowDialog(subflow, defaultTab) {
if (buildingEditDialog) { return } if (buildingEditDialog) { return }
buildingEditDialog = true; buildingEditDialog = true;
var editing_node = subflow;
var activeEditPanes = [];
editStack.push(subflow); editStack.push(subflow);
RED.view.state(RED.state.EDITING); RED.view.state(RED.state.EDITING);
var trayOptions = {
let editingNode = subflow;
let activeEditPanes = [];
const trayOptions = {
title: getEditStackTitle(), title: getEditStackTitle(),
buttons: [ buttons: [
{ {
@ -1797,38 +1799,31 @@ RED.editor = (function() {
class: "primary", class: "primary",
text: RED._("common.label.done"), text: RED._("common.label.done"),
click: function () { click: function () {
var i; const wasDirty = RED.nodes.dirty();
var editState = { const editState = {
changes: {}, changes: {},
changed: false, changed: false,
outputMap: null outputMap: null
} };
var wasDirty = RED.nodes.dirty();
// Search for changes in edit boxes (panes)
// NOTE: no `oneditsave` for Subflow def
activeEditPanes.forEach(function (pane) { activeEditPanes.forEach(function (pane) {
if (pane.apply) { if (pane.apply) {
pane.apply.call(pane, editState); pane.apply.call(pane, editState);
} }
}) });
var newName = $("#subflow-input-name").val(); // Search for env changes (not handled in properties pane)
const oldEnv = editingNode.env;
const newEnv = RED.subflow.exportSubflowTemplateEnv($("#node-input-env-container").editableList("items"));
if (newName != editing_node.name) { if (newEnv && newEnv.length > 0) {
editState.changes['name'] = editing_node.name; newEnv.forEach(function (prop) {
editing_node.name = newName;
editState.changed = true;
}
var old_env = editing_node.env;
var new_env = RED.subflow.exportSubflowTemplateEnv($("#node-input-env-container").editableList("items"));
if (new_env && new_env.length > 0) {
new_env.forEach(function(prop) {
if (prop.type === "cred") { if (prop.type === "cred") {
editing_node.credentials = editing_node.credentials || {_:{}}; editingNode.credentials = editingNode.credentials || { _: {} };
editing_node.credentials[prop.name] = prop.value; editingNode.credentials[prop.name] = prop.value;
editing_node.credentials['has_'+prop.name] = (prop.value !== ""); editingNode.credentials['has_' + prop.name] = (prop.value !== "");
if (prop.value !== '__PWRD__') { if (prop.value !== '__PWRD__') {
editState.changed = true; editState.changed = true;
} }
@ -1837,37 +1832,43 @@ RED.editor = (function() {
}); });
} }
if (!isSameObj(old_env, new_env)) { if (!isSameObj(oldEnv, newEnv)) {
editState.changes.env = editing_node.env; editState.changes.env = oldEnv;
editing_node.env = new_env; editingNode.env = newEnv;
editState.changed = true; editState.changed = true;
} }
if (editState.changed) { if (editState.changed) {
var wasChanged = editing_node.changed; const wasChanged = editingNode.changed;
editing_node.changed = true; const subflowInstances = [];
validateNode(editing_node);
var subflowInstances = []; // Marks the Subflow has changed and validate it
editingNode.changed = true;
validateNode(editingNode);
// Update each Subflow instances
RED.nodes.eachNode(function (n) { RED.nodes.eachNode(function (n) {
if (n.type == "subflow:"+editing_node.id) { if (n.type == "subflow:" + editingNode.id) {
subflowInstances.push({ subflowInstances.push({
id: n.id, id: n.id,
changed: n.changed changed: n.changed
}) });
n._def.color = editing_node.color;
if (editState.changes.hasOwnProperty("color")) {
// Redraw the node color
n._colorChanged = true;
}
n.changed = true; n.changed = true;
n.dirty = true; n.dirty = true;
updateNodeProperties(n); updateNodeProperties(n);
validateNode(n); validateNode(n);
} }
}); });
RED.events.emit("subflows:change",editing_node);
RED.nodes.dirty(true); const historyEvent = {
var historyEvent = {
t: 'edit', t: 'edit',
node:editing_node, node: editingNode,
changes: editState.changes, changes: editState.changes,
dirty: wasDirty, dirty: wasDirty,
changed: wasChanged, changed: wasChanged,
@ -1876,9 +1877,12 @@ RED.editor = (function() {
} }
}; };
RED.events.emit("subflows:change", editingNode);
RED.history.push(historyEvent); RED.history.push(historyEvent);
RED.nodes.dirty(true);
} }
editing_node.dirty = true;
editingNode.dirty = true;
RED.tray.close(); RED.tray.close();
} }
} }
@ -1886,39 +1890,35 @@ RED.editor = (function() {
resize: function (dimensions) { resize: function (dimensions) {
$(".red-ui-tray-content").height(dimensions.height - 50); $(".red-ui-tray-content").height(dimensions.height - 50);
var form = $(".red-ui-tray-content form").height(dimensions.height - 50 - 40); const form = $(".red-ui-tray-content form").height(dimensions.height - 50 - 40);
var size = {width:form.width(),height:form.height()}; const size = { width: form.width(), height: form.height() };
activeEditPanes.forEach(function (pane) { activeEditPanes.forEach(function (pane) {
if (pane.resize) { if (pane.resize) {
pane.resize.call(pane, size); pane.resize.call(pane, size);
} }
}) });
}, },
open: function (tray, done) { open: function (tray, done) {
var trayFooter = tray.find(".red-ui-tray-footer"); const trayBody = tray.find('.red-ui-tray-body');
var trayFooterLeft = $("<div/>", { const trayFooter = tray.find(".red-ui-tray-footer");
class: "red-ui-tray-footer-left"
}).appendTo(trayFooter)
var trayBody = tray.find('.red-ui-tray-body');
trayBody.parent().css('overflow', 'hidden'); trayBody.parent().css('overflow', 'hidden');
const trayFooterLeft = $("<div/>", { class: "red-ui-tray-footer-left" }).appendTo(trayFooter);
$('<span style="margin-left: 10px"><i class="fa fa-info-circle"></i> <i id="red-ui-editor-subflow-user-count"></i></span>').appendTo(trayFooterLeft); $('<span style="margin-left: 10px"><i class="fa fa-info-circle"></i> <i id="red-ui-editor-subflow-user-count"></i></span>').appendTo(trayFooterLeft);
if (editing_node) { if (editingNode) {
RED.sidebar.info.refresh(editing_node); RED.sidebar.info.refresh(editingNode);
} }
var nodeEditPanes = [ const nodeEditPanes = [
'editor-tab-properties', 'editor-tab-properties',
'editor-tab-subflow-module', 'editor-tab-subflow-module',
'editor-tab-description', 'editor-tab-description',
'editor-tab-appearance' 'editor-tab-appearance'
]; ];
prepareEditDialog(trayBody, nodeEditPanes, subflow, subflow._def, "subflow-input", defaultTab, function (_activeEditPanes) {
prepareEditDialog(trayBody, nodeEditPanes, subflow, subflow._def, "node-input", defaultTab, function(_activeEditPanes) {
activeEditPanes = _activeEditPanes; activeEditPanes = _activeEditPanes;
$("#subflow-input-name").val(subflow.name);
RED.text.bidi.prepareInput($("#subflow-input-name"));
trayBody.i18n(); trayBody.i18n();
trayFooter.i18n(); trayFooter.i18n();
buildingEditDialog = false; buildingEditDialog = false;
@ -1929,19 +1929,22 @@ RED.editor = (function() {
if (RED.view.state() != RED.state.IMPORT_DRAGGING) { if (RED.view.state() != RED.state.IMPORT_DRAGGING) {
RED.view.state(RED.state.DEFAULT); RED.view.state(RED.state.DEFAULT);
} }
RED.sidebar.info.refresh(editing_node);
RED.sidebar.info.refresh(editingNode);
RED.workspaces.refresh(); RED.workspaces.refresh();
activeEditPanes.forEach(function (pane) { activeEditPanes.forEach(function (pane) {
if (pane.close) { if (pane.close) {
pane.close.call(pane); pane.close.call(pane);
} }
}) });
editStack.pop(); editStack.pop();
editing_node = null; // TODO: useless?
editingNode = null;
}, },
show: function() { show: function () {}
}
} }
RED.tray.show(trayOptions); RED.tray.show(trayOptions);
} }

View File

@ -26,6 +26,8 @@
if (node._def.category === "config" && nodeType !== "group") { if (node._def.category === "config" && nodeType !== "group") {
this.inputClass = "node-config-input"; this.inputClass = "node-config-input";
formStyle = "node-config-dialog-edit-form"; formStyle = "node-config-dialog-edit-form";
} else if (node.type === "subflow") {
this.inputClass = "subflow-input";
} }
RED.editor.buildEditForm(container,formStyle,nodeType,i18nNamespace,node); RED.editor.buildEditForm(container,formStyle,nodeType,i18nNamespace,node);
}, },

View File

@ -562,7 +562,7 @@ RED.palette = (function() {
} }
} }
paletteNode.css("backgroundColor", sf.color); paletteNode.css("backgroundColor", RED.utils.getNodeColor("subflow", sf._def));
} }
function refreshFilter() { function refreshFilter() {