mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Merge changes by reimporting changed node config
This commit is contained in:
parent
5ca0c066e2
commit
7970c9dbe5
@ -16,6 +16,289 @@
|
|||||||
RED.history = (function() {
|
RED.history = (function() {
|
||||||
var undo_history = [];
|
var undo_history = [];
|
||||||
|
|
||||||
|
function undoEvent(ev) {
|
||||||
|
var i;
|
||||||
|
var len;
|
||||||
|
var node;
|
||||||
|
var subflow;
|
||||||
|
var modifiedTabs = {};
|
||||||
|
if (ev) {
|
||||||
|
if (ev.t == 'multi') {
|
||||||
|
len = ev.events.length;
|
||||||
|
for (i=len-1;i>=0;i--) {
|
||||||
|
undoEvent(ev.events[i]);
|
||||||
|
}
|
||||||
|
} else if (ev.t == 'replace') {
|
||||||
|
RED.nodes.clear();
|
||||||
|
var imported = RED.nodes.import(ev.config);
|
||||||
|
imported[0].forEach(function(n) {
|
||||||
|
if (ev.changed[n.id]) {
|
||||||
|
n.changed = true;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
RED.nodes.version(ev.rev);
|
||||||
|
} else if (ev.t == 'add') {
|
||||||
|
if (ev.nodes) {
|
||||||
|
for (i=0;i<ev.nodes.length;i++) {
|
||||||
|
node = RED.nodes.node(ev.nodes[i]);
|
||||||
|
if (node.z) {
|
||||||
|
modifiedTabs[node.z] = true;
|
||||||
|
}
|
||||||
|
RED.nodes.remove(ev.nodes[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ev.links) {
|
||||||
|
for (i=0;i<ev.links.length;i++) {
|
||||||
|
RED.nodes.removeLink(ev.links[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ev.workspaces) {
|
||||||
|
for (i=0;i<ev.workspaces.length;i++) {
|
||||||
|
RED.nodes.removeWorkspace(ev.workspaces[i].id);
|
||||||
|
RED.workspaces.remove(ev.workspaces[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ev.subflows) {
|
||||||
|
for (i=0;i<ev.subflows.length;i++) {
|
||||||
|
RED.nodes.removeSubflow(ev.subflows[i]);
|
||||||
|
RED.workspaces.remove(ev.subflows[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ev.subflow) {
|
||||||
|
if (ev.subflow.instances) {
|
||||||
|
ev.subflow.instances.forEach(function(n) {
|
||||||
|
var node = RED.nodes.node(n.id);
|
||||||
|
if (node) {
|
||||||
|
node.changed = n.changed;
|
||||||
|
node.dirty = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (ev.subflow.hasOwnProperty('changed')) {
|
||||||
|
subflow = RED.nodes.subflow(ev.subflow.id);
|
||||||
|
if (subflow) {
|
||||||
|
subflow.changed = ev.subflow.changed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ev.removedLinks) {
|
||||||
|
for (i=0;i<ev.removedLinks.length;i++) {
|
||||||
|
RED.nodes.addLink(ev.removedLinks[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (ev.t == "delete") {
|
||||||
|
if (ev.workspaces) {
|
||||||
|
for (i=0;i<ev.workspaces.length;i++) {
|
||||||
|
RED.nodes.addWorkspace(ev.workspaces[i]);
|
||||||
|
RED.workspaces.add(ev.workspaces[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ev.subflow && ev.subflow.subflow) {
|
||||||
|
RED.nodes.addSubflow(ev.subflow.subflow);
|
||||||
|
}
|
||||||
|
if (ev.subflowInputs && ev.subflowInputs.length > 0) {
|
||||||
|
subflow = RED.nodes.subflow(ev.subflowInputs[0].z);
|
||||||
|
subflow.in.push(ev.subflowInputs[0]);
|
||||||
|
subflow.in[0].dirty = true;
|
||||||
|
}
|
||||||
|
if (ev.subflowOutputs && ev.subflowOutputs.length > 0) {
|
||||||
|
subflow = RED.nodes.subflow(ev.subflowOutputs[0].z);
|
||||||
|
ev.subflowOutputs.sort(function(a,b) { return a.i-b.i});
|
||||||
|
for (i=0;i<ev.subflowOutputs.length;i++) {
|
||||||
|
var output = ev.subflowOutputs[i];
|
||||||
|
subflow.out.splice(output.i,0,output);
|
||||||
|
for (var j=output.i+1;j<subflow.out.length;j++) {
|
||||||
|
subflow.out[j].i++;
|
||||||
|
subflow.out[j].dirty = true;
|
||||||
|
}
|
||||||
|
RED.nodes.eachLink(function(l) {
|
||||||
|
if (l.source.type == "subflow:"+subflow.id) {
|
||||||
|
if (l.sourcePort >= output.i) {
|
||||||
|
l.sourcePort++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ev.subflow && ev.subflow.hasOwnProperty('instances')) {
|
||||||
|
ev.subflow.instances.forEach(function(n) {
|
||||||
|
var node = RED.nodes.node(n.id);
|
||||||
|
if (node) {
|
||||||
|
node.changed = n.changed;
|
||||||
|
node.dirty = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (subflow) {
|
||||||
|
RED.nodes.filterNodes({type:"subflow:"+subflow.id}).forEach(function(n) {
|
||||||
|
n.inputs = subflow.in.length;
|
||||||
|
n.outputs = subflow.out.length;
|
||||||
|
while (n.outputs > n.ports.length) {
|
||||||
|
n.ports.push(n.ports.length);
|
||||||
|
}
|
||||||
|
n.resize = true;
|
||||||
|
n.dirty = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (ev.nodes) {
|
||||||
|
for (i=0;i<ev.nodes.length;i++) {
|
||||||
|
RED.nodes.add(ev.nodes[i]);
|
||||||
|
modifiedTabs[ev.nodes[i].z] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ev.links) {
|
||||||
|
for (i=0;i<ev.links.length;i++) {
|
||||||
|
RED.nodes.addLink(ev.links[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ev.changes) {
|
||||||
|
for (i in ev.changes) {
|
||||||
|
if (ev.changes.hasOwnProperty(i)) {
|
||||||
|
node = RED.nodes.node(i);
|
||||||
|
if (node) {
|
||||||
|
for (var d in ev.changes[i]) {
|
||||||
|
if (ev.changes[i].hasOwnProperty(d)) {
|
||||||
|
node[d] = ev.changes[i][d];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node.dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} else if (ev.t == "move") {
|
||||||
|
for (i=0;i<ev.nodes.length;i++) {
|
||||||
|
var n = ev.nodes[i];
|
||||||
|
n.n.x = n.ox;
|
||||||
|
n.n.y = n.oy;
|
||||||
|
n.n.dirty = true;
|
||||||
|
n.n.changed = n.changed;
|
||||||
|
}
|
||||||
|
// A move could have caused a link splice
|
||||||
|
if (ev.links) {
|
||||||
|
for (i=0;i<ev.links.length;i++) {
|
||||||
|
RED.nodes.removeLink(ev.links[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ev.removedLinks) {
|
||||||
|
for (i=0;i<ev.removedLinks.length;i++) {
|
||||||
|
RED.nodes.addLink(ev.removedLinks[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (ev.t == "edit") {
|
||||||
|
for (i in ev.changes) {
|
||||||
|
if (ev.changes.hasOwnProperty(i)) {
|
||||||
|
if (ev.node._def.defaults[i].type) {
|
||||||
|
// This is a config node property
|
||||||
|
var currentConfigNode = RED.nodes.node(ev.node[i]);
|
||||||
|
if (currentConfigNode) {
|
||||||
|
currentConfigNode.users.splice(currentConfigNode.users.indexOf(ev.node),1);
|
||||||
|
}
|
||||||
|
var newConfigNode = RED.nodes.node(ev.changes[i]);
|
||||||
|
if (newConfigNode) {
|
||||||
|
newConfigNode.users.push(ev.node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ev.node[i] = ev.changes[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ev.subflow) {
|
||||||
|
if (ev.subflow.hasOwnProperty('inputCount')) {
|
||||||
|
if (ev.node.in.length > ev.subflow.inputCount) {
|
||||||
|
ev.node.in.splice(ev.subflow.inputCount);
|
||||||
|
} else if (ev.subflow.inputs.length > 0) {
|
||||||
|
ev.node.in = ev.node.in.concat(ev.subflow.inputs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ev.subflow.hasOwnProperty('outputCount')) {
|
||||||
|
if (ev.node.out.length > ev.subflow.outputCount) {
|
||||||
|
ev.node.out.splice(ev.subflow.outputCount);
|
||||||
|
} else if (ev.subflow.outputs.length > 0) {
|
||||||
|
ev.node.out = ev.node.out.concat(ev.subflow.outputs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ev.subflow.hasOwnProperty('instances')) {
|
||||||
|
ev.subflow.instances.forEach(function(n) {
|
||||||
|
var node = RED.nodes.node(n.id);
|
||||||
|
if (node) {
|
||||||
|
node.changed = n.changed;
|
||||||
|
node.dirty = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
RED.nodes.filterNodes({type:"subflow:"+ev.node.id}).forEach(function(n) {
|
||||||
|
n.inputs = ev.node.in.length;
|
||||||
|
n.outputs = ev.node.out.length;
|
||||||
|
RED.editor.updateNodeProperties(n);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
var outputMap;
|
||||||
|
if (ev.outputMap) {
|
||||||
|
outputMap = {};
|
||||||
|
for (var port in ev.outputMap) {
|
||||||
|
if (ev.outputMap.hasOwnProperty(port) && ev.outputMap[port] !== -1) {
|
||||||
|
outputMap[ev.outputMap[port]] = port;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RED.editor.updateNodeProperties(ev.node,outputMap);
|
||||||
|
RED.editor.validateNode(ev.node);
|
||||||
|
}
|
||||||
|
if (ev.links) {
|
||||||
|
for (i=0;i<ev.links.length;i++) {
|
||||||
|
RED.nodes.addLink(ev.links[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ev.node.dirty = true;
|
||||||
|
ev.node.changed = ev.changed;
|
||||||
|
} else if (ev.t == "createSubflow") {
|
||||||
|
if (ev.nodes) {
|
||||||
|
RED.nodes.filterNodes({z:ev.subflow.subflow.id}).forEach(function(n) {
|
||||||
|
n.z = ev.activeWorkspace;
|
||||||
|
n.dirty = true;
|
||||||
|
});
|
||||||
|
for (i=0;i<ev.nodes.length;i++) {
|
||||||
|
RED.nodes.remove(ev.nodes[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ev.links) {
|
||||||
|
for (i=0;i<ev.links.length;i++) {
|
||||||
|
RED.nodes.removeLink(ev.links[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RED.nodes.removeSubflow(ev.subflow.subflow);
|
||||||
|
RED.workspaces.remove(ev.subflow.subflow);
|
||||||
|
|
||||||
|
if (ev.removedLinks) {
|
||||||
|
for (i=0;i<ev.removedLinks.length;i++) {
|
||||||
|
RED.nodes.addLink(ev.removedLinks[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (ev.t == "reorder") {
|
||||||
|
if (ev.order) {
|
||||||
|
RED.workspaces.order(ev.order);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Object.keys(modifiedTabs).forEach(function(id) {
|
||||||
|
var subflow = RED.nodes.subflow(id);
|
||||||
|
if (subflow) {
|
||||||
|
RED.editor.validateNode(subflow);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
RED.nodes.dirty(ev.dirty);
|
||||||
|
RED.view.redraw(true);
|
||||||
|
RED.palette.refresh();
|
||||||
|
RED.workspaces.refresh();
|
||||||
|
RED.sidebar.config.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
//TODO: this function is a placeholder until there is a 'save' event that can be listened to
|
//TODO: this function is a placeholder until there is a 'save' event that can be listened to
|
||||||
markAllDirty: function() {
|
markAllDirty: function() {
|
||||||
@ -34,269 +317,7 @@ RED.history = (function() {
|
|||||||
},
|
},
|
||||||
pop: function() {
|
pop: function() {
|
||||||
var ev = undo_history.pop();
|
var ev = undo_history.pop();
|
||||||
var i;
|
undoEvent(ev);
|
||||||
var node;
|
|
||||||
var subflow;
|
|
||||||
var modifiedTabs = {};
|
|
||||||
if (ev) {
|
|
||||||
if (ev.t == 'add') {
|
|
||||||
if (ev.nodes) {
|
|
||||||
for (i=0;i<ev.nodes.length;i++) {
|
|
||||||
node = RED.nodes.node(ev.nodes[i]);
|
|
||||||
if (node.z) {
|
|
||||||
modifiedTabs[node.z] = true;
|
|
||||||
}
|
|
||||||
RED.nodes.remove(ev.nodes[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ev.links) {
|
|
||||||
for (i=0;i<ev.links.length;i++) {
|
|
||||||
RED.nodes.removeLink(ev.links[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ev.workspaces) {
|
|
||||||
for (i=0;i<ev.workspaces.length;i++) {
|
|
||||||
RED.nodes.removeWorkspace(ev.workspaces[i].id);
|
|
||||||
RED.workspaces.remove(ev.workspaces[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ev.subflows) {
|
|
||||||
for (i=0;i<ev.subflows.length;i++) {
|
|
||||||
RED.nodes.removeSubflow(ev.subflows[i]);
|
|
||||||
RED.workspaces.remove(ev.subflows[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ev.subflow) {
|
|
||||||
if (ev.subflow.instances) {
|
|
||||||
ev.subflow.instances.forEach(function(n) {
|
|
||||||
var node = RED.nodes.node(n.id);
|
|
||||||
if (node) {
|
|
||||||
node.changed = n.changed;
|
|
||||||
node.dirty = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (ev.subflow.hasOwnProperty('changed')) {
|
|
||||||
subflow = RED.nodes.subflow(ev.subflow.id);
|
|
||||||
if (subflow) {
|
|
||||||
subflow.changed = ev.subflow.changed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ev.removedLinks) {
|
|
||||||
for (i=0;i<ev.removedLinks.length;i++) {
|
|
||||||
RED.nodes.addLink(ev.removedLinks[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (ev.t == "delete") {
|
|
||||||
if (ev.workspaces) {
|
|
||||||
for (i=0;i<ev.workspaces.length;i++) {
|
|
||||||
RED.nodes.addWorkspace(ev.workspaces[i]);
|
|
||||||
RED.workspaces.add(ev.workspaces[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ev.subflow && ev.subflow.subflow) {
|
|
||||||
RED.nodes.addSubflow(ev.subflow.subflow);
|
|
||||||
}
|
|
||||||
if (ev.subflowInputs && ev.subflowInputs.length > 0) {
|
|
||||||
subflow = RED.nodes.subflow(ev.subflowInputs[0].z);
|
|
||||||
subflow.in.push(ev.subflowInputs[0]);
|
|
||||||
subflow.in[0].dirty = true;
|
|
||||||
}
|
|
||||||
if (ev.subflowOutputs && ev.subflowOutputs.length > 0) {
|
|
||||||
subflow = RED.nodes.subflow(ev.subflowOutputs[0].z);
|
|
||||||
ev.subflowOutputs.sort(function(a,b) { return a.i-b.i});
|
|
||||||
for (i=0;i<ev.subflowOutputs.length;i++) {
|
|
||||||
var output = ev.subflowOutputs[i];
|
|
||||||
subflow.out.splice(output.i,0,output);
|
|
||||||
for (var j=output.i+1;j<subflow.out.length;j++) {
|
|
||||||
subflow.out[j].i++;
|
|
||||||
subflow.out[j].dirty = true;
|
|
||||||
}
|
|
||||||
RED.nodes.eachLink(function(l) {
|
|
||||||
if (l.source.type == "subflow:"+subflow.id) {
|
|
||||||
if (l.sourcePort >= output.i) {
|
|
||||||
l.sourcePort++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ev.subflow && ev.subflow.hasOwnProperty('instances')) {
|
|
||||||
ev.subflow.instances.forEach(function(n) {
|
|
||||||
var node = RED.nodes.node(n.id);
|
|
||||||
if (node) {
|
|
||||||
node.changed = n.changed;
|
|
||||||
node.dirty = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (subflow) {
|
|
||||||
RED.nodes.filterNodes({type:"subflow:"+subflow.id}).forEach(function(n) {
|
|
||||||
n.inputs = subflow.in.length;
|
|
||||||
n.outputs = subflow.out.length;
|
|
||||||
while (n.outputs > n.ports.length) {
|
|
||||||
n.ports.push(n.ports.length);
|
|
||||||
}
|
|
||||||
n.resize = true;
|
|
||||||
n.dirty = true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (ev.nodes) {
|
|
||||||
for (i=0;i<ev.nodes.length;i++) {
|
|
||||||
RED.nodes.add(ev.nodes[i]);
|
|
||||||
modifiedTabs[ev.nodes[i].z] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ev.links) {
|
|
||||||
for (i=0;i<ev.links.length;i++) {
|
|
||||||
RED.nodes.addLink(ev.links[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ev.changes) {
|
|
||||||
for (i in ev.changes) {
|
|
||||||
if (ev.changes.hasOwnProperty(i)) {
|
|
||||||
node = RED.nodes.node(i);
|
|
||||||
if (node) {
|
|
||||||
for (var d in ev.changes[i]) {
|
|
||||||
if (ev.changes[i].hasOwnProperty(d)) {
|
|
||||||
node[d] = ev.changes[i][d];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
node.dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
} else if (ev.t == "move") {
|
|
||||||
for (i=0;i<ev.nodes.length;i++) {
|
|
||||||
var n = ev.nodes[i];
|
|
||||||
n.n.x = n.ox;
|
|
||||||
n.n.y = n.oy;
|
|
||||||
n.n.dirty = true;
|
|
||||||
n.n.changed = n.changed;
|
|
||||||
}
|
|
||||||
// A move could have caused a link splice
|
|
||||||
if (ev.links) {
|
|
||||||
for (i=0;i<ev.links.length;i++) {
|
|
||||||
RED.nodes.removeLink(ev.links[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ev.removedLinks) {
|
|
||||||
for (i=0;i<ev.removedLinks.length;i++) {
|
|
||||||
RED.nodes.addLink(ev.removedLinks[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (ev.t == "edit") {
|
|
||||||
for (i in ev.changes) {
|
|
||||||
if (ev.changes.hasOwnProperty(i)) {
|
|
||||||
if (ev.node._def.defaults[i].type) {
|
|
||||||
// This is a config node property
|
|
||||||
var currentConfigNode = RED.nodes.node(ev.node[i]);
|
|
||||||
if (currentConfigNode) {
|
|
||||||
currentConfigNode.users.splice(currentConfigNode.users.indexOf(ev.node),1);
|
|
||||||
}
|
|
||||||
var newConfigNode = RED.nodes.node(ev.changes[i]);
|
|
||||||
if (newConfigNode) {
|
|
||||||
newConfigNode.users.push(ev.node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ev.node[i] = ev.changes[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ev.subflow) {
|
|
||||||
if (ev.subflow.hasOwnProperty('inputCount')) {
|
|
||||||
if (ev.node.in.length > ev.subflow.inputCount) {
|
|
||||||
ev.node.in.splice(ev.subflow.inputCount);
|
|
||||||
} else if (ev.subflow.inputs.length > 0) {
|
|
||||||
ev.node.in = ev.node.in.concat(ev.subflow.inputs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ev.subflow.hasOwnProperty('outputCount')) {
|
|
||||||
if (ev.node.out.length > ev.subflow.outputCount) {
|
|
||||||
ev.node.out.splice(ev.subflow.outputCount);
|
|
||||||
} else if (ev.subflow.outputs.length > 0) {
|
|
||||||
ev.node.out = ev.node.out.concat(ev.subflow.outputs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ev.subflow.hasOwnProperty('instances')) {
|
|
||||||
ev.subflow.instances.forEach(function(n) {
|
|
||||||
var node = RED.nodes.node(n.id);
|
|
||||||
if (node) {
|
|
||||||
node.changed = n.changed;
|
|
||||||
node.dirty = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
RED.nodes.filterNodes({type:"subflow:"+ev.node.id}).forEach(function(n) {
|
|
||||||
n.inputs = ev.node.in.length;
|
|
||||||
n.outputs = ev.node.out.length;
|
|
||||||
RED.editor.updateNodeProperties(n);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
var outputMap;
|
|
||||||
if (ev.outputMap) {
|
|
||||||
outputMap = {};
|
|
||||||
for (var port in ev.outputMap) {
|
|
||||||
if (ev.outputMap.hasOwnProperty(port) && ev.outputMap[port] !== -1) {
|
|
||||||
outputMap[ev.outputMap[port]] = port;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RED.editor.updateNodeProperties(ev.node,outputMap);
|
|
||||||
RED.editor.validateNode(ev.node);
|
|
||||||
}
|
|
||||||
if (ev.links) {
|
|
||||||
for (i=0;i<ev.links.length;i++) {
|
|
||||||
RED.nodes.addLink(ev.links[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ev.node.dirty = true;
|
|
||||||
ev.node.changed = ev.changed;
|
|
||||||
} else if (ev.t == "createSubflow") {
|
|
||||||
if (ev.nodes) {
|
|
||||||
RED.nodes.filterNodes({z:ev.subflow.subflow.id}).forEach(function(n) {
|
|
||||||
n.z = ev.activeWorkspace;
|
|
||||||
n.dirty = true;
|
|
||||||
});
|
|
||||||
for (i=0;i<ev.nodes.length;i++) {
|
|
||||||
RED.nodes.remove(ev.nodes[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ev.links) {
|
|
||||||
for (i=0;i<ev.links.length;i++) {
|
|
||||||
RED.nodes.removeLink(ev.links[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RED.nodes.removeSubflow(ev.subflow.subflow);
|
|
||||||
RED.workspaces.remove(ev.subflow.subflow);
|
|
||||||
|
|
||||||
if (ev.removedLinks) {
|
|
||||||
for (i=0;i<ev.removedLinks.length;i++) {
|
|
||||||
RED.nodes.addLink(ev.removedLinks[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (ev.t == "reorder") {
|
|
||||||
if (ev.order) {
|
|
||||||
RED.workspaces.order(ev.order);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Object.keys(modifiedTabs).forEach(function(id) {
|
|
||||||
var subflow = RED.nodes.subflow(id);
|
|
||||||
if (subflow) {
|
|
||||||
RED.editor.validateNode(subflow);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
RED.nodes.dirty(ev.dirty);
|
|
||||||
RED.view.redraw(true);
|
|
||||||
RED.palette.refresh();
|
|
||||||
RED.workspaces.refresh();
|
|
||||||
RED.sidebar.config.refresh();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
peek: function() {
|
peek: function() {
|
||||||
return undo_history[undo_history.length-1];
|
return undo_history[undo_history.length-1];
|
||||||
|
@ -701,17 +701,19 @@ RED.nodes = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var activeWorkspace = RED.workspaces.active();
|
var activeWorkspace = RED.workspaces.active();
|
||||||
|
//TODO: check the z of the subflow instance and check _that_ if it exists
|
||||||
var activeSubflow = getSubflow(activeWorkspace);
|
var activeSubflow = getSubflow(activeWorkspace);
|
||||||
if (activeSubflow) {
|
for (i=0;i<newNodes.length;i++) {
|
||||||
for (i=0;i<newNodes.length;i++) {
|
var m = /^subflow:(.+)$/.exec(newNodes[i].type);
|
||||||
var m = /^subflow:(.+)$/.exec(newNodes[i].type);
|
if (m) {
|
||||||
if (m) {
|
var subflowId = m[1];
|
||||||
var subflowId = m[1];
|
var parent = getSubflow(newNodes[i].z || activeWorkspace);
|
||||||
|
if (parent) {
|
||||||
var err;
|
var err;
|
||||||
if (subflowId === activeSubflow.id) {
|
if (subflowId === parent.id) {
|
||||||
err = new Error(RED._("notification.errors.cannotAddSubflowToItself"));
|
err = new Error(RED._("notification.errors.cannotAddSubflowToItself"));
|
||||||
}
|
}
|
||||||
if (subflowContains(m[1],activeSubflow.id)) {
|
if (subflowContains(subflowId,parent.id)) {
|
||||||
err = new Error(RED._("notification.errors.cannotAddCircularReference"));
|
err = new Error(RED._("notification.errors.cannotAddCircularReference"));
|
||||||
}
|
}
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -1144,6 +1146,38 @@ RED.nodes = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clear() {
|
||||||
|
nodes = [];
|
||||||
|
links = [];
|
||||||
|
configNodes = {};
|
||||||
|
workspacesOrder = [];
|
||||||
|
var subflowIds = Object.keys(subflows);
|
||||||
|
subflowIds.forEach(function(id) {
|
||||||
|
RED.subflow.removeSubflow(id)
|
||||||
|
});
|
||||||
|
var workspaceIds = Object.keys(workspaces);
|
||||||
|
workspaceIds.forEach(function(id) {
|
||||||
|
RED.workspaces.remove(workspaces[id]);
|
||||||
|
});
|
||||||
|
defaultWorkspace = null;
|
||||||
|
|
||||||
|
RED.nodes.dirty(true);
|
||||||
|
RED.view.redraw(true);
|
||||||
|
RED.palette.refresh();
|
||||||
|
RED.workspaces.refresh();
|
||||||
|
RED.sidebar.config.refresh();
|
||||||
|
|
||||||
|
// var node_defs = {};
|
||||||
|
// var nodes = [];
|
||||||
|
// var configNodes = {};
|
||||||
|
// var links = [];
|
||||||
|
// var defaultWorkspace;
|
||||||
|
// var workspaces = {};
|
||||||
|
// var workspacesOrder =[];
|
||||||
|
// var subflows = {};
|
||||||
|
// var loadedFlowVersion = null;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
registry:registry,
|
registry:registry,
|
||||||
setNodeList: registry.setNodeList,
|
setNodeList: registry.setNodeList,
|
||||||
@ -1160,6 +1194,7 @@ RED.nodes = (function() {
|
|||||||
|
|
||||||
add: addNode,
|
add: addNode,
|
||||||
remove: removeNode,
|
remove: removeNode,
|
||||||
|
clear: clear,
|
||||||
|
|
||||||
addLink: addLink,
|
addLink: addLink,
|
||||||
removeLink: removeLink,
|
removeLink: removeLink,
|
||||||
|
@ -105,6 +105,9 @@ RED.tabs = (function() {
|
|||||||
if (typeof link === "string") {
|
if (typeof link === "string") {
|
||||||
link = ul.find("a[href='#"+link+"']");
|
link = ul.find("a[href='#"+link+"']");
|
||||||
}
|
}
|
||||||
|
if (link.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!link.parent().hasClass("active")) {
|
if (!link.parent().hasClass("active")) {
|
||||||
ul.children().removeClass("active");
|
ul.children().removeClass("active");
|
||||||
ul.children().css({"transition": "width 100ms"});
|
ul.children().css({"transition": "width 100ms"});
|
||||||
|
@ -119,6 +119,8 @@ RED.deploy = (function() {
|
|||||||
text: RED._("deploy.confirm.button.merge"),
|
text: RED._("deploy.confirm.button.merge"),
|
||||||
class: "primary disabled",
|
class: "primary disabled",
|
||||||
click: function() {
|
click: function() {
|
||||||
|
RED.diff.mergeDiff(currentDiff);
|
||||||
|
$( this ).dialog( "close" );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -156,7 +158,7 @@ RED.deploy = (function() {
|
|||||||
|
|
||||||
var now = Date.now();
|
var now = Date.now();
|
||||||
RED.diff.getRemoteDiff(function(diff) {
|
RED.diff.getRemoteDiff(function(diff) {
|
||||||
var ellapsed = Math.max(2000 - (Date.now()-now), 0);
|
var ellapsed = Math.max(1000 - (Date.now()-now), 0);
|
||||||
currentDiff = diff;
|
currentDiff = diff;
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
$("#node-dialog-confirm-deploy-conflict-checking").hide();
|
$("#node-dialog-confirm-deploy-conflict-checking").hide();
|
||||||
@ -239,25 +241,6 @@ RED.deploy = (function() {
|
|||||||
$( "#node-dialog-confirm-deploy-conflict" ).show();
|
$( "#node-dialog-confirm-deploy-conflict" ).show();
|
||||||
$( "#node-dialog-confirm-deploy-type" ).val("conflict");
|
$( "#node-dialog-confirm-deploy-type" ).val("conflict");
|
||||||
$( "#node-dialog-confirm-deploy" ).dialog( "open" );
|
$( "#node-dialog-confirm-deploy" ).dialog( "open" );
|
||||||
|
|
||||||
// $("#node-dialog-confirm-deploy-review").append($('<img src="red/images/spin.svg" style="background: rgba(255,255,255,0.8); margin-top: -16px; margin-left: -8px; height:16px; position: absolute; "/>'));
|
|
||||||
// $("#node-dialog-confirm-deploy-review .ui-button-text").css("opacity",0.4);
|
|
||||||
// $("#node-dialog-confirm-deploy-review").attr("disabled",true).addClass("disabled");
|
|
||||||
// $.ajax({
|
|
||||||
// headers: {
|
|
||||||
// "Accept":"application/json",
|
|
||||||
// },
|
|
||||||
// cache: false,
|
|
||||||
// url: 'flows',
|
|
||||||
// success: function(nodes) {
|
|
||||||
// var newNodes = nodes.flows;
|
|
||||||
// var newRevision = nodes.rev;
|
|
||||||
// generateDiff(currentNodes,newNodes);
|
|
||||||
// $("#node-dialog-confirm-deploy-review").attr("disabled",false).removeClass("disabled");
|
|
||||||
// $("#node-dialog-confirm-deploy-review img").remove();
|
|
||||||
// $("#node-dialog-confirm-deploy-review .ui-button-text").css("opacity",1);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function save(skipValidation,force) {
|
function save(skipValidation,force) {
|
||||||
|
@ -4,10 +4,10 @@ RED.diff = (function() {
|
|||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
|
|
||||||
RED.actions.add("core:show-current-diff",showLocalDiff);
|
// RED.actions.add("core:show-current-diff",showLocalDiff);
|
||||||
RED.actions.add("core:show-remote-diff",showRemoteDiff);
|
RED.actions.add("core:show-remote-diff",showRemoteDiff);
|
||||||
|
|
||||||
RED.keyboard.add("*","ctrl-shift-l","core:show-current-diff");
|
// RED.keyboard.add("*","ctrl-shift-l","core:show-current-diff");
|
||||||
RED.keyboard.add("*","ctrl-shift-r","core:show-remote-diff");
|
RED.keyboard.add("*","ctrl-shift-r","core:show-remote-diff");
|
||||||
|
|
||||||
|
|
||||||
@ -74,6 +74,8 @@ RED.diff = (function() {
|
|||||||
var remoteDiff = object.remoteDiff;
|
var remoteDiff = object.remoteDiff;
|
||||||
var tab = object.tab.n;
|
var tab = object.tab.n;
|
||||||
var def = object.def;
|
var def = object.def;
|
||||||
|
var conflicts = currentDiff.conflicts;
|
||||||
|
|
||||||
var tabDiv = $('<div>',{class:"node-diff-tab"}).appendTo(container);
|
var tabDiv = $('<div>',{class:"node-diff-tab"}).appendTo(container);
|
||||||
tabDiv.addClass('collapsed');
|
tabDiv.addClass('collapsed');
|
||||||
var titleRow = $('<div>',{class:"node-diff-tab-title"}).appendTo(tabDiv);
|
var titleRow = $('<div>',{class:"node-diff-tab-title"}).appendTo(tabDiv);
|
||||||
@ -132,6 +134,7 @@ RED.diff = (function() {
|
|||||||
var originalNodeDiv = $("<div>",{class:"node-diff-node-entry-cell"}).appendTo(row);
|
var originalNodeDiv = $("<div>",{class:"node-diff-node-entry-cell"}).appendTo(row);
|
||||||
var localNodeDiv = $("<div>",{class:"node-diff-node-entry-cell node-diff-node-local"}).appendTo(row);
|
var localNodeDiv = $("<div>",{class:"node-diff-node-entry-cell node-diff-node-local"}).appendTo(row);
|
||||||
var localChanged = false;
|
var localChanged = false;
|
||||||
|
var remoteChanged = false;
|
||||||
|
|
||||||
if (!localDiff.newConfig.all[tab.id]) {
|
if (!localDiff.newConfig.all[tab.id]) {
|
||||||
localNodeDiv.addClass("node-diff-empty");
|
localNodeDiv.addClass("node-diff-empty");
|
||||||
@ -153,11 +156,16 @@ RED.diff = (function() {
|
|||||||
remoteNodeDiv = $("<div>",{class:"node-diff-node-entry-cell node-diff-node-remote"}).appendTo(row);
|
remoteNodeDiv = $("<div>",{class:"node-diff-node-entry-cell node-diff-node-remote"}).appendTo(row);
|
||||||
if (!remoteDiff.newConfig.all[tab.id]) {
|
if (!remoteDiff.newConfig.all[tab.id]) {
|
||||||
remoteNodeDiv.addClass("node-diff-empty");
|
remoteNodeDiv.addClass("node-diff-empty");
|
||||||
|
if (remoteDiff.deleted[tab.id]) {
|
||||||
|
remoteChanged = true;
|
||||||
|
}
|
||||||
} else if (remoteDiff.added[tab.id]) {
|
} else if (remoteDiff.added[tab.id]) {
|
||||||
remoteNodeDiv.addClass("node-diff-node-added");
|
remoteNodeDiv.addClass("node-diff-node-added");
|
||||||
|
remoteChanged = true;
|
||||||
$('<span class="node-diff-status"><i class="fa fa-plus-square"></i> added</span>').appendTo(remoteNodeDiv);
|
$('<span class="node-diff-status"><i class="fa fa-plus-square"></i> added</span>').appendTo(remoteNodeDiv);
|
||||||
} else if (remoteDiff.changed[tab.id]) {
|
} else if (remoteDiff.changed[tab.id]) {
|
||||||
remoteNodeDiv.addClass("node-diff-node-changed");
|
remoteNodeDiv.addClass("node-diff-node-changed");
|
||||||
|
remoteChanged = true;
|
||||||
$('<span class="node-diff-status"><i class="fa fa-square"></i> changed</span>').appendTo(remoteNodeDiv);
|
$('<span class="node-diff-status"><i class="fa fa-square"></i> changed</span>').appendTo(remoteNodeDiv);
|
||||||
} else {
|
} else {
|
||||||
remoteNodeDiv.addClass("node-diff-node-unchanged");
|
remoteNodeDiv.addClass("node-diff-node-unchanged");
|
||||||
@ -172,9 +180,9 @@ RED.diff = (function() {
|
|||||||
$(this).parent().toggleClass('collapsed');
|
$(this).parent().toggleClass('collapsed');
|
||||||
});
|
});
|
||||||
|
|
||||||
createNodePropertiesTable(def,tab,localTabNode,remoteTabNode,object.conflicts).appendTo(div);
|
createNodePropertiesTable(def,tab,localTabNode,remoteTabNode,conflicts).appendTo(div);
|
||||||
selectState = "";
|
selectState = "";
|
||||||
if (object.conflicts[tab.id]) {
|
if (conflicts[tab.id]) {
|
||||||
flowStats.conflicts++;
|
flowStats.conflicts++;
|
||||||
|
|
||||||
if (!localNodeDiv.hasClass("node-diff-empty")) {
|
if (!localNodeDiv.hasClass("node-diff-empty")) {
|
||||||
@ -185,14 +193,10 @@ RED.diff = (function() {
|
|||||||
}
|
}
|
||||||
div.addClass("node-diff-node-entry-conflict");
|
div.addClass("node-diff-node-entry-conflict");
|
||||||
} else {
|
} else {
|
||||||
if (!localChanged) {
|
selectState = currentDiff.resolutions[tab.id];
|
||||||
selectState = "remote";
|
|
||||||
} else {
|
|
||||||
selectState = "local";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// Tab properties row
|
||||||
createNodeConflictRadioBoxes(tab,div,localNodeDiv,remoteNodeDiv,true,!object.conflicts[tab.id],selectState);
|
createNodeConflictRadioBoxes(tab,div,localNodeDiv,remoteNodeDiv,true,!conflicts[tab.id],selectState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// var stats = $('<span>',{class:"node-diff-tab-stats"}).appendTo(titleRow);
|
// var stats = $('<span>',{class:"node-diff-tab-stats"}).appendTo(titleRow);
|
||||||
@ -201,14 +205,14 @@ RED.diff = (function() {
|
|||||||
var seen = {};
|
var seen = {};
|
||||||
object.tab.nodes.forEach(function(node) {
|
object.tab.nodes.forEach(function(node) {
|
||||||
seen[node.id] = true;
|
seen[node.id] = true;
|
||||||
createNodeDiffRow(node,flowStats,localDiff,remoteDiff,object.conflicts[node.id]).appendTo(nodesDiv)
|
createNodeDiffRow(node,flowStats).appendTo(nodesDiv)
|
||||||
});
|
});
|
||||||
if (object.newTab) {
|
if (object.newTab) {
|
||||||
localNodeCount = object.newTab.nodes.length;
|
localNodeCount = object.newTab.nodes.length;
|
||||||
object.newTab.nodes.forEach(function(node) {
|
object.newTab.nodes.forEach(function(node) {
|
||||||
if (!seen[node.id]) {
|
if (!seen[node.id]) {
|
||||||
seen[node.id] = true;
|
seen[node.id] = true;
|
||||||
createNodeDiffRow(node,flowStats,localDiff,remoteDiff,object.conflicts[node.id]).appendTo(nodesDiv)
|
createNodeDiffRow(node,flowStats).appendTo(nodesDiv)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -216,7 +220,7 @@ RED.diff = (function() {
|
|||||||
remoteNodeCount = object.remoteTab.nodes.length;
|
remoteNodeCount = object.remoteTab.nodes.length;
|
||||||
object.remoteTab.nodes.forEach(function(node) {
|
object.remoteTab.nodes.forEach(function(node) {
|
||||||
if (!seen[node.id]) {
|
if (!seen[node.id]) {
|
||||||
createNodeDiffRow(node,flowStats,localDiff,remoteDiff,object.conflicts[node.id]).appendTo(nodesDiv)
|
createNodeDiffRow(node,flowStats).appendTo(nodesDiv)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -304,12 +308,16 @@ RED.diff = (function() {
|
|||||||
} else {
|
} else {
|
||||||
remoteCell.addClass("node-diff-empty");
|
remoteCell.addClass("node-diff-empty");
|
||||||
}
|
}
|
||||||
|
selectState = "";
|
||||||
if (flowStats.conflicts > 0) {
|
if (flowStats.conflicts > 0) {
|
||||||
titleRow.addClass("node-diff-node-entry-conflict");
|
titleRow.addClass("node-diff-node-entry-conflict");
|
||||||
|
} else {
|
||||||
|
selectState = currentDiff.resolutions[tab.id];
|
||||||
}
|
}
|
||||||
if (tab.id) {
|
if (tab.id) {
|
||||||
selectState = "";
|
var hide = !(flowStats.conflicts > 0 &&(localDiff.deleted[tab.id] || remoteDiff.deleted[tab.id]));
|
||||||
createNodeConflictRadioBoxes(tab,titleRow,localCell,remoteCell, false, !(flowStats.conflicts > 0 &&(localDiff.deleted[tab.id] || remoteDiff.deleted[tab.id])),selectState);
|
// Tab parent row
|
||||||
|
createNodeConflictRadioBoxes(tab,titleRow,localCell,remoteCell, false, hide, selectState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,7 +391,11 @@ RED.diff = (function() {
|
|||||||
$('<span>',{class:"node-diff-node-label"}).html(nodeLabel).appendTo(contentDiv);
|
$('<span>',{class:"node-diff-node-label"}).html(nodeLabel).appendTo(contentDiv);
|
||||||
return nodeTitleDiv;
|
return nodeTitleDiv;
|
||||||
}
|
}
|
||||||
function createNodeDiffRow(node,stats,localDiff,remoteDiff,conflicted) {
|
function createNodeDiffRow(node,stats) {
|
||||||
|
var localDiff = currentDiff.localDiff;
|
||||||
|
var remoteDiff = currentDiff.remoteDiff;
|
||||||
|
var conflicted = currentDiff.conflicts[node.id];
|
||||||
|
|
||||||
var hasChanges = false; // exists in original and local/remote but with changes
|
var hasChanges = false; // exists in original and local/remote but with changes
|
||||||
var unChanged = true; // existing in original,local,remote unchanged
|
var unChanged = true; // existing in original,local,remote unchanged
|
||||||
var localChanged = false;
|
var localChanged = false;
|
||||||
@ -450,6 +462,7 @@ RED.diff = (function() {
|
|||||||
remoteNodeDiv.addClass("node-diff-node-unchanged");
|
remoteNodeDiv.addClass("node-diff-node-unchanged");
|
||||||
$('<span class="node-diff-status"><i class="fa fa-square-o"></i> unchanged</span>').appendTo(remoteNodeDiv);
|
$('<span class="node-diff-status"><i class="fa fa-square-o"></i> unchanged</span>').appendTo(remoteNodeDiv);
|
||||||
}
|
}
|
||||||
|
div.addClass("node-diff-node-unchanged");
|
||||||
} else if (localDiff.added[node.id]) {
|
} else if (localDiff.added[node.id]) {
|
||||||
localNodeDiv.addClass("node-diff-node-added");
|
localNodeDiv.addClass("node-diff-node-added");
|
||||||
if (remoteNodeDiv) {
|
if (remoteNodeDiv) {
|
||||||
@ -569,12 +582,9 @@ RED.diff = (function() {
|
|||||||
}
|
}
|
||||||
div.addClass("node-diff-node-entry-conflict");
|
div.addClass("node-diff-node-entry-conflict");
|
||||||
} else {
|
} else {
|
||||||
if (!localChanged) {
|
selectState = currentDiff.resolutions[node.id];
|
||||||
selectState = "remote";
|
|
||||||
} else {
|
|
||||||
selectState = "local";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// Node row
|
||||||
createNodeConflictRadioBoxes(node,div,localNodeDiv,remoteNodeDiv,false,!conflicted,selectState);
|
createNodeConflictRadioBoxes(node,div,localNodeDiv,remoteNodeDiv,false,!conflicted,selectState);
|
||||||
row.click(function(evt) {
|
row.click(function(evt) {
|
||||||
$(this).parent().toggleClass('collapsed');
|
$(this).parent().toggleClass('collapsed');
|
||||||
@ -840,17 +850,14 @@ RED.diff = (function() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
function refreshConflictHeader() {
|
function refreshConflictHeader() {
|
||||||
currentDiff.resolutions = {};
|
|
||||||
var resolutionCount = 0;
|
var resolutionCount = 0;
|
||||||
$(".node-diff-selectbox>input:checked").each(function() {
|
$(".node-diff-selectbox>input:checked").each(function() {
|
||||||
if (currentDiff.conflicts[$(this).data('node-id')]) {
|
if (currentDiff.conflicts[$(this).data('node-id')]) {
|
||||||
resolutionCount++;
|
resolutionCount++;
|
||||||
}
|
}
|
||||||
currentDiff.resolutions[$(this).data('node-id')] = $(this).val();
|
currentDiff.resolutions[$(this).data('node-id')] = $(this).val();
|
||||||
// console.log($(this).data('node-id'),$(this).val())
|
|
||||||
})
|
})
|
||||||
var conflictCount = Object.keys(currentDiff.conflicts).length;
|
var conflictCount = Object.keys(currentDiff.conflicts).length;
|
||||||
// console.log(resolutionCount,"of",conflictCount,"conflicts resolve");
|
|
||||||
if (conflictCount - resolutionCount === 0) {
|
if (conflictCount - resolutionCount === 0) {
|
||||||
$("#node-diff-toolbar-resolved-conflicts").html('<span class="node-diff-node-added"><span class="node-diff-status"><i class="fa fa-check"></i></span></span> '+RED._("diff.unresolvedCount",{count:conflictCount - resolutionCount}));
|
$("#node-diff-toolbar-resolved-conflicts").html('<span class="node-diff-node-added"><span class="node-diff-status"><i class="fa fa-check"></i></span></span> '+RED._("diff.unresolvedCount",{count:conflictCount - resolutionCount}));
|
||||||
} else {
|
} else {
|
||||||
@ -873,30 +880,23 @@ RED.diff = (function() {
|
|||||||
var remoteFlow = nodes.flows;
|
var remoteFlow = nodes.flows;
|
||||||
var localDiff = generateDiff(originalFlow,localFlow);
|
var localDiff = generateDiff(originalFlow,localFlow);
|
||||||
var remoteDiff = generateDiff(originalFlow,remoteFlow);
|
var remoteDiff = generateDiff(originalFlow,remoteFlow);
|
||||||
var conflicts = identifyConflicts(localDiff,remoteDiff);
|
remoteDiff.rev = nodes.rev;
|
||||||
console.log(localDiff.moved);
|
callback(resolveDiffs(localDiff,remoteDiff))
|
||||||
console.log(remoteDiff.moved);
|
|
||||||
|
|
||||||
callback({
|
|
||||||
localDiff:localDiff,
|
|
||||||
remoteDiff:remoteDiff,
|
|
||||||
conflicts: conflicts
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
function showLocalDiff() {
|
// function showLocalDiff() {
|
||||||
var nns = RED.nodes.createCompleteNodeSet();
|
// var nns = RED.nodes.createCompleteNodeSet();
|
||||||
var originalFlow = RED.nodes.originalFlow();
|
// var originalFlow = RED.nodes.originalFlow();
|
||||||
var diff = generateDiff(originalFlow,nns);
|
// var diff = generateDiff(originalFlow,nns);
|
||||||
showDiff(diff);
|
// showDiff(diff);
|
||||||
}
|
// }
|
||||||
function showRemoteDiff(diff) {
|
function showRemoteDiff(diff) {
|
||||||
if (diff === undefined) {
|
if (diff === undefined) {
|
||||||
getRemoteDiff(showRemoteDiff);
|
getRemoteDiff(showRemoteDiff);
|
||||||
} else {
|
} else {
|
||||||
showDiff(diff.localDiff,diff.remoteDiff,diff.conflicts);
|
showDiff(diff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function parseNodes(nodeList) {
|
function parseNodes(nodeList) {
|
||||||
@ -971,11 +971,18 @@ RED.diff = (function() {
|
|||||||
moved: moved
|
moved: moved
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function identifyConflicts(localDiff,remoteDiff) {
|
function resolveDiffs(localDiff,remoteDiff) {
|
||||||
var seen = {};
|
|
||||||
var conflicted = {};
|
var conflicted = {};
|
||||||
var id,node;
|
var resolutions = {};
|
||||||
|
|
||||||
|
var diff = {
|
||||||
|
localDiff: localDiff,
|
||||||
|
remoteDiff: remoteDiff,
|
||||||
|
conflicts: conflicted,
|
||||||
|
resolutions: resolutions
|
||||||
|
}
|
||||||
|
var seen = {};
|
||||||
|
var id,node;
|
||||||
for (id in localDiff.currentConfig.all) {
|
for (id in localDiff.currentConfig.all) {
|
||||||
if (localDiff.currentConfig.all.hasOwnProperty(id)) {
|
if (localDiff.currentConfig.all.hasOwnProperty(id)) {
|
||||||
seen[id] = true;
|
seen[id] = true;
|
||||||
@ -990,6 +997,13 @@ RED.diff = (function() {
|
|||||||
conflicted[id] = true;
|
conflicted[id] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!conflicted[id]) {
|
||||||
|
if (remoteDiff.added[id]||remoteDiff.changed[id]||remoteDiff.deleted[id]) {
|
||||||
|
resolutions[id] = 'remote';
|
||||||
|
} else {
|
||||||
|
resolutions[id] = 'local';
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (id in localDiff.added) {
|
for (id in localDiff.added) {
|
||||||
@ -998,6 +1012,8 @@ RED.diff = (function() {
|
|||||||
if (remoteDiff.deleted[node.z]) {
|
if (remoteDiff.deleted[node.z]) {
|
||||||
conflicted[id] = true;
|
conflicted[id] = true;
|
||||||
// conflicted[node.z] = true;
|
// conflicted[node.z] = true;
|
||||||
|
} else {
|
||||||
|
resolutions[id] = 'local';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1007,13 +1023,20 @@ RED.diff = (function() {
|
|||||||
if (localDiff.deleted[node.z]) {
|
if (localDiff.deleted[node.z]) {
|
||||||
conflicted[id] = true;
|
conflicted[id] = true;
|
||||||
// conflicted[node.z] = true;
|
// conflicted[node.z] = true;
|
||||||
|
} else {
|
||||||
|
resolutions[id] = 'remote';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// console.log(diff.resolutions);
|
||||||
// console.log(conflicted);
|
// console.log(conflicted);
|
||||||
return conflicted;
|
return diff;
|
||||||
}
|
}
|
||||||
function showDiff(localDiff,remoteDiff,conflicts) {
|
function showDiff(diff) {
|
||||||
|
var localDiff = diff.localDiff;
|
||||||
|
var remoteDiff = diff.remoteDiff;
|
||||||
|
var conflicts = diff.conflicts;
|
||||||
|
currentDiff = diff;
|
||||||
var list = $("#node-dialog-view-diff-diff");
|
var list = $("#node-dialog-view-diff-diff");
|
||||||
list.editableList('empty');
|
list.editableList('empty');
|
||||||
|
|
||||||
@ -1027,12 +1050,6 @@ RED.diff = (function() {
|
|||||||
} else {
|
} else {
|
||||||
$("#node-diff-view-diff-merge").hide();
|
$("#node-diff-view-diff-merge").hide();
|
||||||
}
|
}
|
||||||
currentDiff = {
|
|
||||||
localDiff: localDiff,
|
|
||||||
remoteDiff: remoteDiff,
|
|
||||||
conflicts: conflicts,
|
|
||||||
resolutions: {}
|
|
||||||
}
|
|
||||||
refreshConflictHeader();
|
refreshConflictHeader();
|
||||||
|
|
||||||
$("#node-dialog-view-diff-headers").empty();
|
$("#node-dialog-view-diff-headers").empty();
|
||||||
@ -1044,7 +1061,6 @@ RED.diff = (function() {
|
|||||||
conflicts = conflicts || {};
|
conflicts = conflicts || {};
|
||||||
|
|
||||||
var el = {
|
var el = {
|
||||||
conflicts: conflicts,
|
|
||||||
diff: localDiff,
|
diff: localDiff,
|
||||||
def: {
|
def: {
|
||||||
category: 'config',
|
category: 'config',
|
||||||
@ -1080,7 +1096,6 @@ RED.diff = (function() {
|
|||||||
currentConfig.tabOrder.forEach(function(tabId) {
|
currentConfig.tabOrder.forEach(function(tabId) {
|
||||||
var tab = currentConfig.tabs[tabId];
|
var tab = currentConfig.tabs[tabId];
|
||||||
var el = {
|
var el = {
|
||||||
conflicts: conflicts,
|
|
||||||
diff: localDiff,
|
diff: localDiff,
|
||||||
def: {},
|
def: {},
|
||||||
tab:tab
|
tab:tab
|
||||||
@ -1100,7 +1115,6 @@ RED.diff = (function() {
|
|||||||
seenTabs[tabId] = true;
|
seenTabs[tabId] = true;
|
||||||
var tab = newConfig.tabs[tabId];
|
var tab = newConfig.tabs[tabId];
|
||||||
var el = {
|
var el = {
|
||||||
conflicts: conflicts,
|
|
||||||
diff: localDiff,
|
diff: localDiff,
|
||||||
def: {},
|
def: {},
|
||||||
tab:tab,
|
tab:tab,
|
||||||
@ -1118,7 +1132,6 @@ RED.diff = (function() {
|
|||||||
var tab = remoteDiff.newConfig.tabs[tabId];
|
var tab = remoteDiff.newConfig.tabs[tabId];
|
||||||
// TODO how to recognise this is a remotely added flow
|
// TODO how to recognise this is a remotely added flow
|
||||||
var el = {
|
var el = {
|
||||||
conflicts: conflicts,
|
|
||||||
diff: localDiff,
|
diff: localDiff,
|
||||||
remoteDiff: remoteDiff,
|
remoteDiff: remoteDiff,
|
||||||
def: {},
|
def: {},
|
||||||
@ -1134,7 +1147,6 @@ RED.diff = (function() {
|
|||||||
if (currentConfig.subflows.hasOwnProperty(subflowId)) {
|
if (currentConfig.subflows.hasOwnProperty(subflowId)) {
|
||||||
seenTabs[subflowId] = true;
|
seenTabs[subflowId] = true;
|
||||||
el = {
|
el = {
|
||||||
conflicts: conflicts,
|
|
||||||
diff: localDiff,
|
diff: localDiff,
|
||||||
def: {
|
def: {
|
||||||
defaults:{},
|
defaults:{},
|
||||||
@ -1158,7 +1170,6 @@ RED.diff = (function() {
|
|||||||
if (newConfig.subflows.hasOwnProperty(subflowId) && !seenTabs[subflowId]) {
|
if (newConfig.subflows.hasOwnProperty(subflowId) && !seenTabs[subflowId]) {
|
||||||
seenTabs[subflowId] = true;
|
seenTabs[subflowId] = true;
|
||||||
el = {
|
el = {
|
||||||
conflicts: conflicts,
|
|
||||||
diff: localDiff,
|
diff: localDiff,
|
||||||
def: {
|
def: {
|
||||||
defaults:{},
|
defaults:{},
|
||||||
@ -1178,9 +1189,7 @@ RED.diff = (function() {
|
|||||||
if (remoteDiff !== undefined) {
|
if (remoteDiff !== undefined) {
|
||||||
for (subflowId in remoteDiff.newConfig.subflows) {
|
for (subflowId in remoteDiff.newConfig.subflows) {
|
||||||
if (remoteDiff.newConfig.subflows.hasOwnProperty(subflowId) && !seenTabs[subflowId]) {
|
if (remoteDiff.newConfig.subflows.hasOwnProperty(subflowId) && !seenTabs[subflowId]) {
|
||||||
// TODO how to recognise this is a remotely added flow
|
|
||||||
el = {
|
el = {
|
||||||
conflicts: conflicts,
|
|
||||||
diff: localDiff,
|
diff: localDiff,
|
||||||
remoteDiff: remoteDiff,
|
remoteDiff: remoteDiff,
|
||||||
def: {
|
def: {
|
||||||
@ -1205,109 +1214,77 @@ RED.diff = (function() {
|
|||||||
}
|
}
|
||||||
function mergeDiff(diff) {
|
function mergeDiff(diff) {
|
||||||
var currentConfig = diff.localDiff.currentConfig;
|
var currentConfig = diff.localDiff.currentConfig;
|
||||||
|
|
||||||
var localDiff = diff.localDiff;
|
var localDiff = diff.localDiff;
|
||||||
var remoteDiff = diff.remoteDiff;
|
var remoteDiff = diff.remoteDiff;
|
||||||
var conflicts = diff.conflicts;
|
var conflicts = diff.conflicts;
|
||||||
var resolutions = diff.resolutions;
|
var resolutions = diff.resolutions;
|
||||||
|
|
||||||
var toAdd = [];
|
|
||||||
var toRemove = [];
|
|
||||||
var toMerge = [];
|
|
||||||
var toMove = [];
|
|
||||||
|
|
||||||
var id;
|
var id;
|
||||||
for (id in remoteDiff.added) {
|
|
||||||
if (remoteDiff.added.hasOwnProperty(id) && !localDiff.added.hasOwnProperty(id)) {
|
for (id in conflicts) {
|
||||||
toAdd.push(remoteDiff.newConfig.all[id]);
|
if (conflicts.hasOwnProperty(id)) {
|
||||||
|
if (!resolutions.hasOwnProperty(id)) {
|
||||||
|
console.log(diff);
|
||||||
|
throw new Error("No resolution for conflict on node",id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (id in currentConfig.all) {
|
|
||||||
if (currentConfig.all.hasOwnProperty(id)) {
|
var newConfig = [];
|
||||||
var node = currentConfig.all[id];
|
var node;
|
||||||
|
var nodeChangedStates = {};
|
||||||
|
var localChangedStates = {};
|
||||||
|
for (id in localDiff.newConfig.all) {
|
||||||
|
if (localDiff.newConfig.all.hasOwnProperty(id)) {
|
||||||
|
node = RED.nodes.node(id);
|
||||||
if (resolutions[id] === 'local') {
|
if (resolutions[id] === 'local') {
|
||||||
// use local - nothing to change then
|
if (node) {
|
||||||
} else {
|
nodeChangedStates[id] = node.changed;
|
||||||
if (remoteDiff.deleted[id]) {
|
|
||||||
toRemove.push(id);
|
|
||||||
} else if (remoteDiff.moved[id]) {
|
|
||||||
toRemove.push(id);
|
|
||||||
toAdd.push(remoteDiff.newConfig.all[id]);
|
|
||||||
} else if (remoteDiff.changed[id]) {
|
|
||||||
if (localDiff.deleted[id]) {
|
|
||||||
toAdd.push(remoteDiff.newConfig.all[id]);
|
|
||||||
} else {
|
|
||||||
if (node.type !== 'tab' && node.type !== 'subflow') {
|
|
||||||
toRemove.push(id);
|
|
||||||
toAdd.push(remoteDiff.newConfig.all[id]);
|
|
||||||
} else {
|
|
||||||
toMerge.push(remoteDiff.newConfig.all[id]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
newConfig.push(localDiff.newConfig.all[id]);
|
||||||
|
} else if (resolutions[id] === 'remote') {
|
||||||
|
if (!remoteDiff.deleted[id] && remoteDiff.newConfig.all.hasOwnProperty(id)) {
|
||||||
|
if (node) {
|
||||||
|
nodeChangedStates[id] = node.changed;
|
||||||
|
}
|
||||||
|
localChangedStates[id] = true;
|
||||||
|
newConfig.push(remoteDiff.newConfig.all[id]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log("Unresolved",id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log("adding",toAdd);
|
for (id in remoteDiff.added) {
|
||||||
console.log("deleting",toRemove);
|
if (remoteDiff.added.hasOwnProperty(id)) {
|
||||||
console.log("replacing",toMerge);
|
node = RED.nodes.node(id);
|
||||||
console.log("moving",toMove);
|
if (node) {
|
||||||
|
nodeChangedStates[id] = node.changed;
|
||||||
var removed = [];
|
}
|
||||||
toRemove.forEach(function(id) {
|
if (!localDiff.added.hasOwnProperty(id)) {
|
||||||
var node = currentConfig.all[id];
|
localChangedStates[id] = true;
|
||||||
if (node.type === 'tab') {
|
newConfig.push(remoteDiff.newConfig.all[id]);
|
||||||
console.log("removing tab",id);
|
|
||||||
RED.workspaces.remove(node);
|
|
||||||
removed.push(RED.nodes.removeWorkspace(id));
|
|
||||||
} else if (node.type === 'subflow') {
|
|
||||||
console.log("removing subflow",id);
|
|
||||||
removed.push(RED.subflow.removeSubflow(id));
|
|
||||||
} else {
|
|
||||||
console.log("removing node",id);
|
|
||||||
var r = RED.nodes.remove(id);
|
|
||||||
if (r.links.length > 0 || r.nodes.length > 0) {
|
|
||||||
removed.push(r);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
// Need to refresh the view so when we add back nodes with the same id,
|
var historyEvent = {
|
||||||
// they get properly initialised in the view.
|
t:"replace",
|
||||||
RED.view.redraw(true);
|
config: RED.nodes.createCompleteNodeSet(),
|
||||||
|
changed: nodeChangedStates,
|
||||||
|
dirty: RED.nodes.dirty(),
|
||||||
|
rev: RED.nodes.version()
|
||||||
|
}
|
||||||
|
|
||||||
var imported = RED.nodes.import(toAdd);
|
RED.history.push(historyEvent);
|
||||||
|
|
||||||
|
RED.nodes.clear();
|
||||||
// toMove.forEach(function(newNode) {
|
var imported = RED.nodes.import(newConfig);
|
||||||
// var currentNode;
|
imported[0].forEach(function(n) {
|
||||||
// currentNode = RED.nodes.node(newNode.id);
|
if (nodeChangedStates[n.id] || localChangedStates[n.id]) {
|
||||||
// currentNode.z = newNode.z;
|
n.changed = true;
|
||||||
// });
|
|
||||||
toMerge.forEach(function(newNode) {
|
|
||||||
var currentNode;
|
|
||||||
console.log("merging node",newNode.id);
|
|
||||||
if (newNode.type !== 'tab' && newNode.type !== 'subflow') {
|
|
||||||
currentNode = RED.nodes.node(newNode.id);
|
|
||||||
var def = RED.nodes.getType(currentNode.type);
|
|
||||||
if (currentNode.hasOwnProperty('x')) {
|
|
||||||
currentNode.x = newNode.x;
|
|
||||||
currentNode.y = newNode.y;
|
|
||||||
}
|
|
||||||
for (var d in def.defaults) {
|
|
||||||
if (def.defaults.hasOwnProperty(d)) {
|
|
||||||
currentNode[d] = newNode[d];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var removedLinks = RED.editor.updateNodeProperties(currentNode);
|
|
||||||
if (removedLinks.length > 0) {
|
|
||||||
removed.push({links:removedLinks});
|
|
||||||
}
|
|
||||||
} else if (newNode.type === 'tab') {
|
|
||||||
currentNode = RED.nodes.workspace(newNode.id);
|
|
||||||
currentNode.label = newNode.label;
|
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
|
RED.nodes.version(remoteDiff.rev);
|
||||||
|
|
||||||
RED.view.redraw(true);
|
RED.view.redraw(true);
|
||||||
RED.palette.refresh();
|
RED.palette.refresh();
|
||||||
@ -1318,6 +1295,7 @@ RED.diff = (function() {
|
|||||||
return {
|
return {
|
||||||
init: init,
|
init: init,
|
||||||
getRemoteDiff: getRemoteDiff,
|
getRemoteDiff: getRemoteDiff,
|
||||||
showRemoteDiff: showRemoteDiff
|
showRemoteDiff: showRemoteDiff,
|
||||||
|
mergeDiff: mergeDiff
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user