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() {
|
||||
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 {
|
||||
//TODO: this function is a placeholder until there is a 'save' event that can be listened to
|
||||
markAllDirty: function() {
|
||||
@ -34,269 +317,7 @@ RED.history = (function() {
|
||||
},
|
||||
pop: function() {
|
||||
var ev = undo_history.pop();
|
||||
var i;
|
||||
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();
|
||||
}
|
||||
undoEvent(ev);
|
||||
},
|
||||
peek: function() {
|
||||
return undo_history[undo_history.length-1];
|
||||
|
@ -701,17 +701,19 @@ RED.nodes = (function() {
|
||||
}
|
||||
|
||||
var activeWorkspace = RED.workspaces.active();
|
||||
//TODO: check the z of the subflow instance and check _that_ if it exists
|
||||
var activeSubflow = getSubflow(activeWorkspace);
|
||||
if (activeSubflow) {
|
||||
for (i=0;i<newNodes.length;i++) {
|
||||
var m = /^subflow:(.+)$/.exec(newNodes[i].type);
|
||||
if (m) {
|
||||
var subflowId = m[1];
|
||||
for (i=0;i<newNodes.length;i++) {
|
||||
var m = /^subflow:(.+)$/.exec(newNodes[i].type);
|
||||
if (m) {
|
||||
var subflowId = m[1];
|
||||
var parent = getSubflow(newNodes[i].z || activeWorkspace);
|
||||
if (parent) {
|
||||
var err;
|
||||
if (subflowId === activeSubflow.id) {
|
||||
if (subflowId === parent.id) {
|
||||
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"));
|
||||
}
|
||||
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 {
|
||||
registry:registry,
|
||||
setNodeList: registry.setNodeList,
|
||||
@ -1160,6 +1194,7 @@ RED.nodes = (function() {
|
||||
|
||||
add: addNode,
|
||||
remove: removeNode,
|
||||
clear: clear,
|
||||
|
||||
addLink: addLink,
|
||||
removeLink: removeLink,
|
||||
|
@ -105,6 +105,9 @@ RED.tabs = (function() {
|
||||
if (typeof link === "string") {
|
||||
link = ul.find("a[href='#"+link+"']");
|
||||
}
|
||||
if (link.length === 0) {
|
||||
return;
|
||||
}
|
||||
if (!link.parent().hasClass("active")) {
|
||||
ul.children().removeClass("active");
|
||||
ul.children().css({"transition": "width 100ms"});
|
||||
|
@ -119,6 +119,8 @@ RED.deploy = (function() {
|
||||
text: RED._("deploy.confirm.button.merge"),
|
||||
class: "primary disabled",
|
||||
click: function() {
|
||||
RED.diff.mergeDiff(currentDiff);
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -156,7 +158,7 @@ RED.deploy = (function() {
|
||||
|
||||
var now = Date.now();
|
||||
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;
|
||||
setTimeout(function() {
|
||||
$("#node-dialog-confirm-deploy-conflict-checking").hide();
|
||||
@ -239,25 +241,6 @@ RED.deploy = (function() {
|
||||
$( "#node-dialog-confirm-deploy-conflict" ).show();
|
||||
$( "#node-dialog-confirm-deploy-type" ).val("conflict");
|
||||
$( "#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) {
|
||||
|
@ -4,10 +4,10 @@ RED.diff = (function() {
|
||||
|
||||
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.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");
|
||||
|
||||
|
||||
@ -74,6 +74,8 @@ RED.diff = (function() {
|
||||
var remoteDiff = object.remoteDiff;
|
||||
var tab = object.tab.n;
|
||||
var def = object.def;
|
||||
var conflicts = currentDiff.conflicts;
|
||||
|
||||
var tabDiv = $('<div>',{class:"node-diff-tab"}).appendTo(container);
|
||||
tabDiv.addClass('collapsed');
|
||||
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 localNodeDiv = $("<div>",{class:"node-diff-node-entry-cell node-diff-node-local"}).appendTo(row);
|
||||
var localChanged = false;
|
||||
var remoteChanged = false;
|
||||
|
||||
if (!localDiff.newConfig.all[tab.id]) {
|
||||
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);
|
||||
if (!remoteDiff.newConfig.all[tab.id]) {
|
||||
remoteNodeDiv.addClass("node-diff-empty");
|
||||
if (remoteDiff.deleted[tab.id]) {
|
||||
remoteChanged = true;
|
||||
}
|
||||
} else if (remoteDiff.added[tab.id]) {
|
||||
remoteNodeDiv.addClass("node-diff-node-added");
|
||||
remoteChanged = true;
|
||||
$('<span class="node-diff-status"><i class="fa fa-plus-square"></i> added</span>').appendTo(remoteNodeDiv);
|
||||
} else if (remoteDiff.changed[tab.id]) {
|
||||
remoteNodeDiv.addClass("node-diff-node-changed");
|
||||
remoteChanged = true;
|
||||
$('<span class="node-diff-status"><i class="fa fa-square"></i> changed</span>').appendTo(remoteNodeDiv);
|
||||
} else {
|
||||
remoteNodeDiv.addClass("node-diff-node-unchanged");
|
||||
@ -172,9 +180,9 @@ RED.diff = (function() {
|
||||
$(this).parent().toggleClass('collapsed');
|
||||
});
|
||||
|
||||
createNodePropertiesTable(def,tab,localTabNode,remoteTabNode,object.conflicts).appendTo(div);
|
||||
createNodePropertiesTable(def,tab,localTabNode,remoteTabNode,conflicts).appendTo(div);
|
||||
selectState = "";
|
||||
if (object.conflicts[tab.id]) {
|
||||
if (conflicts[tab.id]) {
|
||||
flowStats.conflicts++;
|
||||
|
||||
if (!localNodeDiv.hasClass("node-diff-empty")) {
|
||||
@ -185,14 +193,10 @@ RED.diff = (function() {
|
||||
}
|
||||
div.addClass("node-diff-node-entry-conflict");
|
||||
} else {
|
||||
if (!localChanged) {
|
||||
selectState = "remote";
|
||||
} else {
|
||||
selectState = "local";
|
||||
}
|
||||
selectState = currentDiff.resolutions[tab.id];
|
||||
}
|
||||
|
||||
createNodeConflictRadioBoxes(tab,div,localNodeDiv,remoteNodeDiv,true,!object.conflicts[tab.id],selectState);
|
||||
// Tab properties row
|
||||
createNodeConflictRadioBoxes(tab,div,localNodeDiv,remoteNodeDiv,true,!conflicts[tab.id],selectState);
|
||||
}
|
||||
}
|
||||
// var stats = $('<span>',{class:"node-diff-tab-stats"}).appendTo(titleRow);
|
||||
@ -201,14 +205,14 @@ RED.diff = (function() {
|
||||
var seen = {};
|
||||
object.tab.nodes.forEach(function(node) {
|
||||
seen[node.id] = true;
|
||||
createNodeDiffRow(node,flowStats,localDiff,remoteDiff,object.conflicts[node.id]).appendTo(nodesDiv)
|
||||
createNodeDiffRow(node,flowStats).appendTo(nodesDiv)
|
||||
});
|
||||
if (object.newTab) {
|
||||
localNodeCount = object.newTab.nodes.length;
|
||||
object.newTab.nodes.forEach(function(node) {
|
||||
if (!seen[node.id]) {
|
||||
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;
|
||||
object.remoteTab.nodes.forEach(function(node) {
|
||||
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 {
|
||||
remoteCell.addClass("node-diff-empty");
|
||||
}
|
||||
selectState = "";
|
||||
if (flowStats.conflicts > 0) {
|
||||
titleRow.addClass("node-diff-node-entry-conflict");
|
||||
} else {
|
||||
selectState = currentDiff.resolutions[tab.id];
|
||||
}
|
||||
if (tab.id) {
|
||||
selectState = "";
|
||||
createNodeConflictRadioBoxes(tab,titleRow,localCell,remoteCell, false, !(flowStats.conflicts > 0 &&(localDiff.deleted[tab.id] || remoteDiff.deleted[tab.id])),selectState);
|
||||
var hide = !(flowStats.conflicts > 0 &&(localDiff.deleted[tab.id] || remoteDiff.deleted[tab.id]));
|
||||
// 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);
|
||||
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 unChanged = true; // existing in original,local,remote unchanged
|
||||
var localChanged = false;
|
||||
@ -450,6 +462,7 @@ RED.diff = (function() {
|
||||
remoteNodeDiv.addClass("node-diff-node-unchanged");
|
||||
$('<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]) {
|
||||
localNodeDiv.addClass("node-diff-node-added");
|
||||
if (remoteNodeDiv) {
|
||||
@ -569,12 +582,9 @@ RED.diff = (function() {
|
||||
}
|
||||
div.addClass("node-diff-node-entry-conflict");
|
||||
} else {
|
||||
if (!localChanged) {
|
||||
selectState = "remote";
|
||||
} else {
|
||||
selectState = "local";
|
||||
}
|
||||
selectState = currentDiff.resolutions[node.id];
|
||||
}
|
||||
// Node row
|
||||
createNodeConflictRadioBoxes(node,div,localNodeDiv,remoteNodeDiv,false,!conflicted,selectState);
|
||||
row.click(function(evt) {
|
||||
$(this).parent().toggleClass('collapsed');
|
||||
@ -840,17 +850,14 @@ RED.diff = (function() {
|
||||
|
||||
}
|
||||
function refreshConflictHeader() {
|
||||
currentDiff.resolutions = {};
|
||||
var resolutionCount = 0;
|
||||
$(".node-diff-selectbox>input:checked").each(function() {
|
||||
if (currentDiff.conflicts[$(this).data('node-id')]) {
|
||||
resolutionCount++;
|
||||
}
|
||||
currentDiff.resolutions[$(this).data('node-id')] = $(this).val();
|
||||
// console.log($(this).data('node-id'),$(this).val())
|
||||
})
|
||||
var conflictCount = Object.keys(currentDiff.conflicts).length;
|
||||
// console.log(resolutionCount,"of",conflictCount,"conflicts resolve");
|
||||
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}));
|
||||
} else {
|
||||
@ -873,30 +880,23 @@ RED.diff = (function() {
|
||||
var remoteFlow = nodes.flows;
|
||||
var localDiff = generateDiff(originalFlow,localFlow);
|
||||
var remoteDiff = generateDiff(originalFlow,remoteFlow);
|
||||
var conflicts = identifyConflicts(localDiff,remoteDiff);
|
||||
console.log(localDiff.moved);
|
||||
console.log(remoteDiff.moved);
|
||||
|
||||
callback({
|
||||
localDiff:localDiff,
|
||||
remoteDiff:remoteDiff,
|
||||
conflicts: conflicts
|
||||
});
|
||||
remoteDiff.rev = nodes.rev;
|
||||
callback(resolveDiffs(localDiff,remoteDiff))
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
function showLocalDiff() {
|
||||
var nns = RED.nodes.createCompleteNodeSet();
|
||||
var originalFlow = RED.nodes.originalFlow();
|
||||
var diff = generateDiff(originalFlow,nns);
|
||||
showDiff(diff);
|
||||
}
|
||||
// function showLocalDiff() {
|
||||
// var nns = RED.nodes.createCompleteNodeSet();
|
||||
// var originalFlow = RED.nodes.originalFlow();
|
||||
// var diff = generateDiff(originalFlow,nns);
|
||||
// showDiff(diff);
|
||||
// }
|
||||
function showRemoteDiff(diff) {
|
||||
if (diff === undefined) {
|
||||
getRemoteDiff(showRemoteDiff);
|
||||
} else {
|
||||
showDiff(diff.localDiff,diff.remoteDiff,diff.conflicts);
|
||||
showDiff(diff);
|
||||
}
|
||||
}
|
||||
function parseNodes(nodeList) {
|
||||
@ -971,11 +971,18 @@ RED.diff = (function() {
|
||||
moved: moved
|
||||
}
|
||||
}
|
||||
function identifyConflicts(localDiff,remoteDiff) {
|
||||
var seen = {};
|
||||
function resolveDiffs(localDiff,remoteDiff) {
|
||||
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) {
|
||||
if (localDiff.currentConfig.all.hasOwnProperty(id)) {
|
||||
seen[id] = true;
|
||||
@ -990,6 +997,13 @@ RED.diff = (function() {
|
||||
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) {
|
||||
@ -998,6 +1012,8 @@ RED.diff = (function() {
|
||||
if (remoteDiff.deleted[node.z]) {
|
||||
conflicted[id] = true;
|
||||
// conflicted[node.z] = true;
|
||||
} else {
|
||||
resolutions[id] = 'local';
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1007,13 +1023,20 @@ RED.diff = (function() {
|
||||
if (localDiff.deleted[node.z]) {
|
||||
conflicted[id] = true;
|
||||
// conflicted[node.z] = true;
|
||||
} else {
|
||||
resolutions[id] = 'remote';
|
||||
}
|
||||
}
|
||||
}
|
||||
// console.log(diff.resolutions);
|
||||
// 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");
|
||||
list.editableList('empty');
|
||||
|
||||
@ -1027,12 +1050,6 @@ RED.diff = (function() {
|
||||
} else {
|
||||
$("#node-diff-view-diff-merge").hide();
|
||||
}
|
||||
currentDiff = {
|
||||
localDiff: localDiff,
|
||||
remoteDiff: remoteDiff,
|
||||
conflicts: conflicts,
|
||||
resolutions: {}
|
||||
}
|
||||
refreshConflictHeader();
|
||||
|
||||
$("#node-dialog-view-diff-headers").empty();
|
||||
@ -1044,7 +1061,6 @@ RED.diff = (function() {
|
||||
conflicts = conflicts || {};
|
||||
|
||||
var el = {
|
||||
conflicts: conflicts,
|
||||
diff: localDiff,
|
||||
def: {
|
||||
category: 'config',
|
||||
@ -1080,7 +1096,6 @@ RED.diff = (function() {
|
||||
currentConfig.tabOrder.forEach(function(tabId) {
|
||||
var tab = currentConfig.tabs[tabId];
|
||||
var el = {
|
||||
conflicts: conflicts,
|
||||
diff: localDiff,
|
||||
def: {},
|
||||
tab:tab
|
||||
@ -1100,7 +1115,6 @@ RED.diff = (function() {
|
||||
seenTabs[tabId] = true;
|
||||
var tab = newConfig.tabs[tabId];
|
||||
var el = {
|
||||
conflicts: conflicts,
|
||||
diff: localDiff,
|
||||
def: {},
|
||||
tab:tab,
|
||||
@ -1118,7 +1132,6 @@ RED.diff = (function() {
|
||||
var tab = remoteDiff.newConfig.tabs[tabId];
|
||||
// TODO how to recognise this is a remotely added flow
|
||||
var el = {
|
||||
conflicts: conflicts,
|
||||
diff: localDiff,
|
||||
remoteDiff: remoteDiff,
|
||||
def: {},
|
||||
@ -1134,7 +1147,6 @@ RED.diff = (function() {
|
||||
if (currentConfig.subflows.hasOwnProperty(subflowId)) {
|
||||
seenTabs[subflowId] = true;
|
||||
el = {
|
||||
conflicts: conflicts,
|
||||
diff: localDiff,
|
||||
def: {
|
||||
defaults:{},
|
||||
@ -1158,7 +1170,6 @@ RED.diff = (function() {
|
||||
if (newConfig.subflows.hasOwnProperty(subflowId) && !seenTabs[subflowId]) {
|
||||
seenTabs[subflowId] = true;
|
||||
el = {
|
||||
conflicts: conflicts,
|
||||
diff: localDiff,
|
||||
def: {
|
||||
defaults:{},
|
||||
@ -1178,9 +1189,7 @@ RED.diff = (function() {
|
||||
if (remoteDiff !== undefined) {
|
||||
for (subflowId in remoteDiff.newConfig.subflows) {
|
||||
if (remoteDiff.newConfig.subflows.hasOwnProperty(subflowId) && !seenTabs[subflowId]) {
|
||||
// TODO how to recognise this is a remotely added flow
|
||||
el = {
|
||||
conflicts: conflicts,
|
||||
diff: localDiff,
|
||||
remoteDiff: remoteDiff,
|
||||
def: {
|
||||
@ -1205,109 +1214,77 @@ RED.diff = (function() {
|
||||
}
|
||||
function mergeDiff(diff) {
|
||||
var currentConfig = diff.localDiff.currentConfig;
|
||||
|
||||
var localDiff = diff.localDiff;
|
||||
var remoteDiff = diff.remoteDiff;
|
||||
var conflicts = diff.conflicts;
|
||||
var resolutions = diff.resolutions;
|
||||
|
||||
var toAdd = [];
|
||||
var toRemove = [];
|
||||
var toMerge = [];
|
||||
var toMove = [];
|
||||
|
||||
var id;
|
||||
for (id in remoteDiff.added) {
|
||||
if (remoteDiff.added.hasOwnProperty(id) && !localDiff.added.hasOwnProperty(id)) {
|
||||
toAdd.push(remoteDiff.newConfig.all[id]);
|
||||
|
||||
for (id in conflicts) {
|
||||
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 node = currentConfig.all[id];
|
||||
|
||||
var newConfig = [];
|
||||
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') {
|
||||
// use local - nothing to change then
|
||||
} else {
|
||||
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]);
|
||||
}
|
||||
}
|
||||
if (node) {
|
||||
nodeChangedStates[id] = node.changed;
|
||||
}
|
||||
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);
|
||||
console.log("deleting",toRemove);
|
||||
console.log("replacing",toMerge);
|
||||
console.log("moving",toMove);
|
||||
|
||||
var removed = [];
|
||||
toRemove.forEach(function(id) {
|
||||
var node = currentConfig.all[id];
|
||||
if (node.type === 'tab') {
|
||||
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);
|
||||
for (id in remoteDiff.added) {
|
||||
if (remoteDiff.added.hasOwnProperty(id)) {
|
||||
node = RED.nodes.node(id);
|
||||
if (node) {
|
||||
nodeChangedStates[id] = node.changed;
|
||||
}
|
||||
if (!localDiff.added.hasOwnProperty(id)) {
|
||||
localChangedStates[id] = true;
|
||||
newConfig.push(remoteDiff.newConfig.all[id]);
|
||||
}
|
||||
}
|
||||
});
|
||||
// Need to refresh the view so when we add back nodes with the same id,
|
||||
// they get properly initialised in the view.
|
||||
RED.view.redraw(true);
|
||||
}
|
||||
var historyEvent = {
|
||||
t:"replace",
|
||||
config: RED.nodes.createCompleteNodeSet(),
|
||||
changed: nodeChangedStates,
|
||||
dirty: RED.nodes.dirty(),
|
||||
rev: RED.nodes.version()
|
||||
}
|
||||
|
||||
var imported = RED.nodes.import(toAdd);
|
||||
RED.history.push(historyEvent);
|
||||
|
||||
|
||||
// toMove.forEach(function(newNode) {
|
||||
// var currentNode;
|
||||
// currentNode = RED.nodes.node(newNode.id);
|
||||
// currentNode.z = newNode.z;
|
||||
// });
|
||||
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.clear();
|
||||
var imported = RED.nodes.import(newConfig);
|
||||
imported[0].forEach(function(n) {
|
||||
if (nodeChangedStates[n.id] || localChangedStates[n.id]) {
|
||||
n.changed = true;
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
RED.nodes.version(remoteDiff.rev);
|
||||
|
||||
RED.view.redraw(true);
|
||||
RED.palette.refresh();
|
||||
@ -1318,6 +1295,7 @@ RED.diff = (function() {
|
||||
return {
|
||||
init: init,
|
||||
getRemoteDiff: getRemoteDiff,
|
||||
showRemoteDiff: showRemoteDiff
|
||||
showRemoteDiff: showRemoteDiff,
|
||||
mergeDiff: mergeDiff
|
||||
}
|
||||
})();
|
||||
|
Loading…
Reference in New Issue
Block a user