From 31a72b65624fd51ca2287303b011a85839a94093 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Tue, 20 Dec 2016 19:42:38 +0000 Subject: [PATCH] Three-way-diff --- editor/js/nodes.js | 33 +- editor/js/ui/deploy.js | 63 ++- editor/js/ui/diff.js | 659 +++++++++++++++++++----------- editor/js/ui/subflow.js | 87 ++-- editor/sass/diff.scss | 104 ++++- editor/templates/index.mst | 22 +- red/api/locales/en-US/editor.json | 9 +- 7 files changed, 645 insertions(+), 332 deletions(-) diff --git a/editor/js/nodes.js b/editor/js/nodes.js index e471d9081..e50d02eca 100644 --- a/editor/js/nodes.js +++ b/editor/js/nodes.js @@ -24,10 +24,6 @@ RED.nodes = (function() { var workspacesOrder =[]; var subflows = {}; var loadedFlowVersion = null; - var pending = { - deleted: {}, - added: {} - }; var initialLoad; @@ -35,12 +31,6 @@ RED.nodes = (function() { function setDirty(d) { dirty = d; - if (!d) { - pending = { - deleted: {}, - added: {} - }; - } RED.events.emit("nodes:change",{dirty:dirty}); } @@ -191,8 +181,6 @@ RED.nodes = (function() { } nodes.push(n); } - delete pending.deleted[n.id]; - pending.added[n.id] = true; RED.events.emit('nodes:add',n); } function addLink(l) { @@ -258,12 +246,6 @@ RED.nodes = (function() { if (node && node._def.onremove) { node._def.onremove.call(n); } - delete pending.added[id]; - pending.deleted[id] = true; - removedNodes.forEach(function(node) { - delete pending.added[node.id]; - pending.deleted[node.id] = true; - }); return {links:removedLinks,nodes:removedNodes}; } @@ -276,8 +258,6 @@ RED.nodes = (function() { function addWorkspace(ws) { workspaces[ws.id] = ws; - pending.added[ws.id] = true; - delete pending.deleted[ws.id]; ws._def = { defaults: { label: {value:""} @@ -315,8 +295,6 @@ RED.nodes = (function() { var result = removeNode(removedNodes[n].id); removedLinks = removedLinks.concat(result.links); } - pending.deleted[id] = true; - delete pending.added[id] return {nodes:removedNodes,links:removedLinks}; } @@ -346,8 +324,6 @@ RED.nodes = (function() { outputs: sf.out.length } subflows[sf.id] = sf; - delete pending.deleted[sf.id]; - pending.added[sf.id] = true; RED.nodes.registerType("subflow:"+sf.id, { defaults:{name:{value:""}}, info: sf.info, @@ -371,8 +347,6 @@ RED.nodes = (function() { } function removeSubflow(sf) { delete subflows[sf.id]; - delete pending.added[sf.id]; - pending.deleted[sf.id] = true; registry.removeNodeType("subflow:"+sf.id); } @@ -1027,8 +1001,9 @@ RED.nodes = (function() { for (var w1=0;w1
    ').appendTo(document.body); var toolbar = $('
    '+ - ''+ - 'all nodes'+ - 'changed nodes'+ - ''+ + ' '+ + // ''+ + // 'previous'+ + // 'next'+ + // ''+ '
    ').prependTo(dialog); - - toolbar.find(".node-diff-filter").click(function(evt) { - evt.preventDefault(); - if (!$(this).hasClass('selected')) { - $(this).siblings().removeClass('selected'); - $(this).addClass('selected'); - } - if ($(this).attr('id') === 'node-diff-filter-all') { - diffList.find('.node-diff-node-unchanged').parent().removeClass('hide'); - diffList.find('.node-diff-tab-unchanged').parent().removeClass('hide'); - } else { - diffList.find('.node-diff-node-unchanged').parent().addClass('hide'); - diffList.find('.node-diff-tab-unchanged').parent().addClass('hide'); - $(".node-diff-tab.node-diff-tab-unchanged").addClass("collapsed"); - } - }) + // + // toolbar.find(".node-diff-filter").click(function(evt) { + // evt.preventDefault(); + // if (!$(this).hasClass('selected')) { + // $(this).siblings().removeClass('selected'); + // $(this).addClass('selected'); + // } + // if ($(this).attr('id') === 'node-diff-filter-all') { + // diffList.find('.node-diff-node-unchanged').parent().removeClass('hide'); + // diffList.find('.node-diff-tab-unchanged').parent().removeClass('hide'); + // } else { + // diffList.find('.node-diff-node-unchanged').parent().addClass('hide'); + // diffList.find('.node-diff-tab-unchanged').parent().addClass('hide'); + // $(".node-diff-tab.node-diff-tab-unchanged").addClass("collapsed"); + // } + // }) $("#node-dialog-view-diff").dialog({ title: RED._('deploy.confirm.button.review'), modal: true, autoOpen: false, buttons: [ - // { - // text: RED._("deploy.confirm.button.cancel"), - // click: function() { - // $( this ).dialog( "close" ); - // } - // }, { - text: RED._("common.label.close"), - class: "primary", + text: RED._("common.label.cancel"), click: function() { $( this ).dialog( "close" ); } + }, + { + id: "node-diff-view-diff-merge", + text: RED._("deploy.confirm.button.merge"), + class: "primary disabled", + click: function() { + if (!$("#node-diff-view-diff-merge").hasClass('disabled')) { + refreshConflictHeader(); + mergeDiff(currentDiff); + $( this ).dialog( "close" ); + } + } } ], open: function() { @@ -67,27 +75,17 @@ RED.diff = (function() { var tab = object.tab.n; var def = object.def; var tabDiv = $('
    ',{class:"node-diff-tab"}).appendTo(container); + tabDiv.addClass('collapsed'); var titleRow = $('
    ',{class:"node-diff-tab-title"}).appendTo(tabDiv); var nodesDiv = $('
    ').appendTo(tabDiv); var originalCell = $('
    ',{class:"node-diff-node-entry-cell"}).appendTo(titleRow); - var localCell = $('
    ',{class:"node-diff-node-entry-cell"}).appendTo(titleRow); + var localCell = $('
    ',{class:"node-diff-node-entry-cell node-diff-node-local"}).appendTo(titleRow); var remoteCell; - if (remoteDiff) { - remoteCell = $('
    ',{class:"node-diff-node-entry-cell"}).appendTo(titleRow); - } - // if (localDiff.added[tab.id]) { - // titleRow.addClass("node-diff-node-added"); - // } else if (localDiff.deleted[tab.id]) { - // titleRow.addClass("node-diff-node-deleted"); - // } - // var status = $('').appendTo(originalCell); + var selectState; - // if (!object.newTab && object.remoteTab) { - // $('').appendTo(remoteCell); - // //} else if (object.newTab && (remoteDiff && !object.remoteTab)) { - // } else if (localDiff.added[tab.id]) { - // $('').appendTo(localCell); - // } + if (remoteDiff) { + remoteCell = $('
    ',{class:"node-diff-node-entry-cell node-diff-node-remote"}).appendTo(titleRow); + } $('').appendTo(originalCell); createNodeIcon(tab,def).appendTo(originalCell); var tabForLabel = (object.newTab || object.tab).n; @@ -97,7 +95,7 @@ RED.diff = (function() { } else if (tab.type === 'subflow') { titleSpan.html((tabForLabel.name||tabForLabel.id)); } else { - titleSpan.html("Global configuration nodes"); + titleSpan.html("Global nodes"); } var flowStats = { local: { @@ -132,27 +130,27 @@ RED.diff = (function() { var div = $("
    ",{class:"node-diff-node-entry node-diff-node-props collapsed"}).appendTo(nodesDiv); var row = $("
    ",{class:"node-diff-node-entry-header"}).appendTo(div); var originalNodeDiv = $("
    ",{class:"node-diff-node-entry-cell"}).appendTo(row); - var localNodeDiv = $("
    ",{class:"node-diff-node-entry-cell"}).appendTo(row); + var localNodeDiv = $("
    ",{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"); } else if (localDiff.added[tab.id]) { localNodeDiv.addClass("node-diff-node-added"); + localChanged = true; $(' added').appendTo(localNodeDiv); } else if (localDiff.changed[tab.id]) { localNodeDiv.addClass("node-diff-node-changed"); - $(' changed').appendTo(localNodeDiv); + localChanged = true; + $(' changed').appendTo(localNodeDiv); } else { localNodeDiv.addClass("node-diff-node-unchanged"); - $(' unchanged').appendTo(localNodeDiv); + $(' unchanged').appendTo(localNodeDiv); } - var remoteNodeDiv; if (remoteDiff) { - remoteNodeDiv = $("
    ",{class:"node-diff-node-entry-cell"}).appendTo(row); + remoteNodeDiv = $("
    ",{class:"node-diff-node-entry-cell node-diff-node-remote"}).appendTo(row); if (!remoteDiff.newConfig.all[tab.id]) { remoteNodeDiv.addClass("node-diff-empty"); } else if (remoteDiff.added[tab.id]) { @@ -160,48 +158,69 @@ RED.diff = (function() { $(' added').appendTo(remoteNodeDiv); } else if (remoteDiff.changed[tab.id]) { remoteNodeDiv.addClass("node-diff-node-changed"); - $(' changed').appendTo(remoteNodeDiv); + $(' changed').appendTo(remoteNodeDiv); } else { remoteNodeDiv.addClass("node-diff-node-unchanged"); - $(' unchanged').appendTo(remoteNodeDiv); + $(' unchanged').appendTo(remoteNodeDiv); } } $('').appendTo(originalNodeDiv); $('').html("Flow Properties").appendTo(originalNodeDiv); + row.click(function(evt) { evt.preventDefault(); $(this).parent().toggleClass('collapsed'); }); - createNodePropertiesTable(def,tab,localTabNode,remoteTabNode,flowStats).appendTo(div); + + createNodePropertiesTable(def,tab,localTabNode,remoteTabNode,object.conflicts).appendTo(div); + selectState = ""; + if (object.conflicts[tab.id]) { + flowStats.conflicts++; + + if (!localNodeDiv.hasClass("node-diff-empty")) { + $('').prependTo(localNodeDiv); + } + if (!remoteNodeDiv.hasClass("node-diff-empty")) { + $('').prependTo(remoteNodeDiv); + } + div.addClass("node-diff-node-entry-conflict"); + } else { + if (!localChanged) { + selectState = "remote"; + } else { + selectState = "local"; + } + } + + createNodeConflictRadioBoxes(tab,div,localNodeDiv,remoteNodeDiv,true,!object.conflicts[tab.id],selectState); } } - // var stats = $('',{class:"node-diff-tab-stats"}).appendTo(titleRow); - - + var localNodeCount = 0; + var remoteNodeCount = 0; var seen = {}; object.tab.nodes.forEach(function(node) { seen[node.id] = true; - createNodeDiffRow(node,flowStats,localDiff,remoteDiff).appendTo(nodesDiv) + createNodeDiffRow(node,flowStats,localDiff,remoteDiff,object.conflicts[node.id]).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).appendTo(nodesDiv) + createNodeDiffRow(node,flowStats,localDiff,remoteDiff,object.conflicts[node.id]).appendTo(nodesDiv) } }); } if (object.remoteTab) { + remoteNodeCount = object.remoteTab.nodes.length; object.remoteTab.nodes.forEach(function(node) { if (!seen[node.id]) { - createNodeDiffRow(node,flowStats,localDiff,remoteDiff).appendTo(nodesDiv) + createNodeDiffRow(node,flowStats,localDiff,remoteDiff,object.conflicts[node.id]).appendTo(nodesDiv) } }); } titleRow.click(function(evt) { - evt.preventDefault(); - // if (titleRow.parent().find(".node-diff-node-entry:not(.hide)").length > 0) { titleRow.parent().toggleClass('collapsed'); if ($(this).parent().hasClass('collapsed')) { @@ -211,9 +230,6 @@ RED.diff = (function() { // } }) - var localChangesCount = flowStats.local.addedCount+flowStats.local.deletedCount+flowStats.local.changedCount; - var remoteChangesCount = flowStats.remote.addedCount+flowStats.remote.deletedCount+flowStats.remote.changedCount; - if (localDiff.deleted[tab.id]) { $(' flow deleted').appendTo(localCell); } else if (object.newTab) { @@ -222,28 +238,31 @@ RED.diff = (function() { } else { if (tab.id) { if (localDiff.changed[tab.id]) { - localChangesCount++; flowStats.local.changedCount++; } else { flowStats.local.unchangedCount++; } } var localStats = $('',{class:"node-diff-tab-stats"}).appendTo(localCell); - if (flowStats.conflicts > 0) { - $(' '+flowStats.conflicts+'').appendTo(localStats); - } - if (flowStats.local.unchangedCount > 0) { - $(' '+flowStats.local.unchangedCount+'').appendTo(localStats); - } - if (flowStats.local.addedCount > 0) { - $(' '+flowStats.local.addedCount+'').appendTo(localStats); - } - if (flowStats.local.changedCount > 0) { - $(' '+flowStats.local.changedCount+'').appendTo(localStats); - } - if (flowStats.local.deletedCount > 0) { - $(' '+flowStats.local.deletedCount+'').appendTo(localStats); + $(''+localNodeCount+' nodes').appendTo(localStats); + + if (flowStats.conflicts + flowStats.local.addedCount + flowStats.local.changedCount + flowStats.local.deletedCount > 0) { + $(' [ ').appendTo(localStats); + if (flowStats.conflicts > 0) { + $(' '+flowStats.conflicts+'').appendTo(localStats); + } + if (flowStats.local.addedCount > 0) { + $(' '+flowStats.local.addedCount+'').appendTo(localStats); + } + if (flowStats.local.changedCount > 0) { + $(' '+flowStats.local.changedCount+'').appendTo(localStats); + } + if (flowStats.local.deletedCount > 0) { + $(' '+flowStats.local.deletedCount+'').appendTo(localStats); + } + $(' ] ').appendTo(localStats); } + } } else { localCell.addClass("node-diff-empty"); @@ -258,33 +277,42 @@ RED.diff = (function() { } else { if (tab.id) { if (remoteDiff.changed[tab.id]) { - remoteChangesCount++; flowStats.remote.changedCount++; } else { flowStats.remote.unchangedCount++; } } var remoteStats = $('',{class:"node-diff-tab-stats"}).appendTo(remoteCell); - if (flowStats.conflicts > 0) { - $(' '+flowStats.conflicts+'').appendTo(remoteStats); - } - if (flowStats.remote.unchangedCount > 0) { - $(' '+flowStats.remote.unchangedCount+'').appendTo(remoteStats); - } - if (flowStats.remote.addedCount > 0) { - $(' '+flowStats.remote.addedCount+'').appendTo(remoteStats); - } - if (flowStats.remote.changedCount > 0) { - $(' '+flowStats.remote.changedCount+'').appendTo(remoteStats); - } - if (flowStats.remote.deletedCount > 0) { - $(' '+flowStats.remote.deletedCount+'').appendTo(remoteStats); + $(''+remoteNodeCount+' nodes').appendTo(remoteStats); + if (flowStats.conflicts + flowStats.remote.addedCount + flowStats.remote.changedCount + flowStats.remote.deletedCount > 0) { + $(' [ ').appendTo(remoteStats); + if (flowStats.conflicts > 0) { + $(' '+flowStats.conflicts+'').appendTo(remoteStats); + } + if (flowStats.remote.addedCount > 0) { + $(' '+flowStats.remote.addedCount+'').appendTo(remoteStats); + } + if (flowStats.remote.changedCount > 0) { + $(' '+flowStats.remote.changedCount+'').appendTo(remoteStats); + } + if (flowStats.remote.deletedCount > 0) { + $(' '+flowStats.remote.deletedCount+'').appendTo(remoteStats); + } + $(' ] ').appendTo(remoteStats); } } } else { remoteCell.addClass("node-diff-empty"); } + if (flowStats.conflicts > 0) { + titleRow.addClass("node-diff-node-entry-conflict"); + } + if (tab.id) { + selectState = ""; + createNodeConflictRadioBoxes(tab,titleRow,localCell,remoteCell, false, !(flowStats.conflicts > 0 &&(localDiff.deleted[tab.id] || remoteDiff.deleted[tab.id])),selectState); + } } + if (tabDiv.find(".node-diff-node-entry").length === 0) { tabDiv.addClass("node-diff-tab-empty"); } @@ -295,7 +323,6 @@ RED.diff = (function() { } }); } - function formatWireProperty(wires,allNodes) { var result = $("
    ",{class:"node-diff-property-wires"}) var list = $("
      "); @@ -356,10 +383,10 @@ RED.diff = (function() { $('',{class:"node-diff-node-label"}).html(nodeLabel).appendTo(contentDiv); return nodeTitleDiv; } - function createNodeDiffRow(node,stats,localDiff,remoteDiff) { + function createNodeDiffRow(node,stats,localDiff,remoteDiff,conflicted) { var hasChanges = false; // exists in original and local/remote but with changes var unChanged = true; // existing in original,local,remote unchanged - var conflicted = false; + var localChanged = false; if (localDiff.added[node.id]) { stats.local.addedCount++; @@ -387,7 +414,7 @@ RED.diff = (function() { hasChanges = true; unChanged = false; } - + // console.log(node.id,localDiff.added[node.id],remoteDiff.added[node.id],localDiff.deleted[node.id],remoteDiff.deleted[node.id],localDiff.changed[node.id],remoteDiff.changed[node.id]) var def = RED.nodes.getType(node.type); if (def === undefined) { if (/^subflow:/.test(node.type)) { @@ -402,38 +429,28 @@ RED.diff = (function() { } } var div = $("
      ",{class:"node-diff-node-entry collapsed"}); - var row = $("
      ").appendTo(div); + var row = $("
      ",{class:"node-diff-node-entry-header"}).appendTo(div); var originalNodeDiv = $("
      ",{class:"node-diff-node-entry-cell"}).appendTo(row); - var localNodeDiv = $("
      ",{class:"node-diff-node-entry-cell"}).appendTo(row); + var localNodeDiv = $("
      ",{class:"node-diff-node-entry-cell node-diff-node-local"}).appendTo(row); var remoteNodeDiv; var chevron; if (remoteDiff) { - remoteNodeDiv = $("
      ",{class:"node-diff-node-entry-cell"}).appendTo(row); + remoteNodeDiv = $("
      ",{class:"node-diff-node-entry-cell node-diff-node-remote"}).appendTo(row); } $('').appendTo(originalNodeDiv); if (unChanged) { stats.local.unchangedCount++; - // $('').appendTo(originalNodeDiv); - //$('').appendTo(originalNodeDiv); createNode(node,def).appendTo(originalNodeDiv); localNodeDiv.addClass("node-diff-node-unchanged"); - $(' unchanged').appendTo(localNodeDiv); + $(' unchanged').appendTo(localNodeDiv); if (remoteDiff) { stats.remote.unchangedCount++; remoteNodeDiv.addClass("node-diff-node-unchanged"); - $(' unchanged').appendTo(remoteNodeDiv); + $(' unchanged').appendTo(remoteNodeDiv); } - - //$('').appendTo(localNodeDiv); - // createNode(node,def).appendTo(localNodeDiv); - // if (remoteDiff) { - // //$('').appendTo(remoteNodeDiv); - // createNode(node,def).appendTo(remoteNodeDiv); - // } } else if (localDiff.added[node.id]) { - // $('').appendTo(originalNodeDiv); localNodeDiv.addClass("node-diff-node-added"); if (remoteNodeDiv) { remoteNodeDiv.addClass("node-diff-empty"); @@ -441,32 +458,28 @@ RED.diff = (function() { $(' added').appendTo(localNodeDiv); createNode(node,def).appendTo(originalNodeDiv); } else if (remoteDiff && remoteDiff.added[node.id]) { - // $('').appendTo(originalNodeDiv); localNodeDiv.addClass("node-diff-empty"); remoteNodeDiv.addClass("node-diff-node-added"); $(' added').appendTo(remoteNodeDiv); createNode(node,def).appendTo(originalNodeDiv); } else { - // chevron = $('').appendTo(originalNodeDiv); - // if (localDiff.changed[node.id] || (remoteDiff && remoteDiff.changed[node.id])) { - // $('').appendTo(chevron); - // } - //$('').appendTo(originalNodeDiv); createNode(node,def).appendTo(originalNodeDiv); if (localDiff.deleted[node.z]) { localNodeDiv.addClass("node-diff-empty"); + localChanged = true; } else if (localDiff.deleted[node.id]) { localNodeDiv.addClass("node-diff-node-deleted"); $(' deleted').appendTo(localNodeDiv); + localChanged = true; } else if (localDiff.changed[node.id]) { localNodeDiv.addClass("node-diff-node-changed"); - $(' changed').appendTo(localNodeDiv); + $(' changed').appendTo(localNodeDiv); + localChanged = true; } else { stats.local.unchangedCount++; localNodeDiv.addClass("node-diff-node-unchanged"); - $(' unchanged').appendTo(localNodeDiv); + $(' unchanged').appendTo(localNodeDiv); } - // createNode(node,def).appendTo(localNodeDiv); if (remoteDiff) { if (remoteDiff.deleted[node.z]) { @@ -476,13 +489,12 @@ RED.diff = (function() { $(' deleted').appendTo(remoteNodeDiv); } else if (remoteDiff.changed[node.id]) { remoteNodeDiv.addClass("node-diff-node-changed"); - $(' changed').appendTo(remoteNodeDiv); + $(' changed').appendTo(remoteNodeDiv); } else { stats.remote.unchangedCount++; remoteNodeDiv.addClass("node-diff-node-unchanged"); - $(' unchanged').appendTo(remoteNodeDiv); + $(' unchanged').appendTo(remoteNodeDiv); } - //createNode(node,def).appendTo(remoteNodeDiv); } } var localNode = { @@ -498,20 +510,34 @@ RED.diff = (function() { diff: remoteDiff } } - var currentConflictCount = stats.conflicts; - createNodePropertiesTable(def,node,localNode,remoteNode,stats).appendTo(div); - if (currentConflictCount !== stats.conflicts) { - $('').prependTo(localNodeDiv); - $('').prependTo(remoteNodeDiv); + createNodePropertiesTable(def,node,localNode,remoteNode).appendTo(div); + + var selectState = ""; + + if (conflicted) { + stats.conflicts++; + if (!localNodeDiv.hasClass("node-diff-empty")) { + $('').prependTo(localNodeDiv); + } + if (!remoteNodeDiv.hasClass("node-diff-empty")) { + $('').prependTo(remoteNodeDiv); + } + div.addClass("node-diff-node-entry-conflict"); + } else { + if (!localChanged) { + selectState = "remote"; + } else { + selectState = "local"; + } } + createNodeConflictRadioBoxes(node,div,localNodeDiv,remoteNodeDiv,false,!conflicted,selectState); row.click(function(evt) { - evt.preventDefault(); $(this).parent().toggleClass('collapsed'); }); return div; } - function createNodePropertiesTable(def,node,localNodeObj,remoteNodeObj,stats) { + function createNodePropertiesTable(def,node,localNodeObj,remoteNodeObj) { var localNode = localNodeObj.node; var remoteNode; if (remoteNodeObj) { @@ -519,9 +545,7 @@ RED.diff = (function() { } var nodePropertiesDiv = $("
      ",{class:"node-diff-node-entry-properties"}); - var nodePropertiesTable = $("").appendTo(nodePropertiesDiv); - //var nodePropertiesTable = $("
      ").appendTo(nodePropertiesDiv); var row; var localCell, remoteCell; var currentValue, localValue, remoteValue; @@ -530,16 +554,8 @@ RED.diff = (function() { var localChanges = 0; var remoteChanges = 0; var conflict = false; - var conflicted = false; var status; - if (remoteNodeObj) { - if ( (remoteNodeObj.diff.changed[node.id] && localNodeObj.diff.deleted[node.id]) || - (remoteNodeObj.diff.deleted[node.id] && localNodeObj.diff.changed[node.id]) - ) { - conflicted = true; - } - } if (node.hasOwnProperty('x')) { if (localNode) { if (localNode.x !== node.x || localNode.y !== node.y) { @@ -553,29 +569,28 @@ RED.diff = (function() { remoteChanges++; } } - if ( (remoteChanged && localChanged && (localNode.x !== remoteNode.y || localNode.y !== remoteNode.x)) || + if ( (remoteChanged && localChanged && (localNode.x !== remoteNode.x || localNode.y !== remoteNode.y)) || (!localChanged && remoteChanged && localNodeObj.diff.deleted[node.id]) || (localChanged && !remoteChanged && remoteNodeObj.diff.deleted[node.id]) ) { - conflicted = true; conflict = true; } row = $("
      ").appendTo(nodePropertiesTable); $("").appendTo(nodePropertiesTable); $("").appendTo(nodePropertiesTable); $("",{class:"node-diff-property-header"}).prependTo(nodePropertiesTable); - // $("').appendTo(row); - // } else if (localChanges > 0) { - // cell = $('').appendTo(row); - // if (conflicted) { - // $(' conflict ').appendTo(cell); - // } - // $(' changed').appendTo(cell); - // } else { - // $('').appendTo(row); - // } - // } else if (localNodeObj.diff.deleted[node.id]) { - // cell = $('').appendTo(row); - // if (conflicted) { - // $(' conflict ').appendTo(cell); - // } - // $(' deleted').appendTo(cell); - // } else { - // $('').appendTo(row); - // } - // if (remoteNode) { - // if (remoteNodeObj.diff.added[node.id]) { - // $('').appendTo(row); - // } else if (remoteChanges > 0) { - // cell = $('').appendTo(row); - // if (conflicted) { - // $(' conflict ').appendTo(cell); - // } - // $(' changed').appendTo(cell); - // } else { - // $('').appendTo(row); - // } - // } else if (remoteNodeObj.diff.deleted[node.id]) { - // cell = $('').appendTo(row); - // if (conflicted) { - // $(' conflict ').appendTo(cell); - // } - // $(' deleted').appendTo(cell); - // } else { - // $('').appendTo(row); - // } - if (conflicted) { - stats.conflicts++; - } return nodePropertiesDiv; } - function showLocalDiff() { - var nns = RED.nodes.createCompleteNodeSet(); - var originalFlow = RED.nodes.originalFlow(); - var diff = generateDiff(originalFlow,nns); - showDiff(diff); + function createNodeConflictRadioBoxes(node,row,localDiv,remoteDiv,propertiesTable,hide,state) { + var safeNodeId = "node-diff-selectbox-"+node.id.replace(/\./g,'-')+(propertiesTable?"-props":""); + var className = ""; + if (node.z||propertiesTable) { + className = "node-diff-selectbox-tab-"+(propertiesTable?node.id:node.z).replace(/\./g,'-'); + } + var titleRow = !propertiesTable && (node.type === 'tab' || node.type === 'subflow'); + var changeHandler = function(evt) { + var className; + if (node.type === undefined) { + // TODO: handle globals + } else if (titleRow) { + className = "node-diff-selectbox-tab-"+node.id.replace(/\./g,'-'); + $("."+className+"-"+this.value).prop('checked',true); + if (this.value === 'local') { + $("."+className+"-"+this.value).closest(".node-diff-node-entry").addClass("node-diff-select-local"); + $("."+className+"-"+this.value).closest(".node-diff-node-entry").removeClass("node-diff-select-remote"); + } else { + $("."+className+"-"+this.value).closest(".node-diff-node-entry").removeClass("node-diff-select-local"); + $("."+className+"-"+this.value).closest(".node-diff-node-entry").addClass("node-diff-select-remote"); + } + } else { + // Individual node or properties table + var parentId = "node-diff-selectbox-"+(propertiesTable?node.id:node.z).replace(/\./g,'-'); + $('#'+parentId+"-local").prop('checked',false); + $('#'+parentId+"-remote").prop('checked',false); + var titleRowDiv = $('#'+parentId+"-local").closest(".node-diff-tab").find(".node-diff-tab-title"); + titleRowDiv.removeClass("node-diff-select-local"); + titleRowDiv.removeClass("node-diff-select-remote"); + } + if (this.value === 'local') { + row.removeClass("node-diff-select-remote"); + row.addClass("node-diff-select-local"); + } else if (this.value === 'remote') { + row.addClass("node-diff-select-remote"); + row.removeClass("node-diff-select-local"); + } + refreshConflictHeader(); + } + + var localSelectDiv = $('
      ",{class:"node-diff-property-cell-label"}).html("position").appendTo(row); - localCell = $("",{class:"node-diff-property-cell"}).appendTo(row); + localCell = $("",{class:"node-diff-property-cell node-diff-node-local"}).appendTo(row); if (localNode) { localCell.addClass("node-diff-node-"+(localChanged?"changed":"unchanged")); - $(''+(localChanged?'':'')+'').appendTo(localCell); + $(''+(localChanged?'':'')+'').appendTo(localCell); RED.utils.createObjectElement({x:localNode.x,y:localNode.y}).appendTo(localCell); } else { localCell.addClass("node-diff-empty"); } if (remoteNode !== undefined) { - remoteCell = $("",{class:"node-diff-property-cell"}).appendTo(row); + remoteCell = $("",{class:"node-diff-property-cell node-diff-node-remote"}).appendTo(row); remoteCell.addClass("node-diff-node-"+(remoteChanged?"changed":"unchanged")); if (remoteNode) { - $(''+(remoteChanged?'':'')+'').appendTo(remoteCell); + $(''+(remoteChanged?'':'')+'').appendTo(remoteCell); RED.utils.createObjectElement({x:remoteNode.x,y:remoteNode.y}).appendTo(remoteCell); } else { remoteCell.addClass("node-diff-empty"); @@ -604,16 +619,15 @@ RED.diff = (function() { (!localChanged && remoteChanged && localNodeObj.diff.deleted[node.id]) || (localChanged && !remoteChanged && remoteNodeObj.diff.deleted[node.id]) ){ - conflicted = true; conflict = true; } row = $("
      ",{class:"node-diff-property-cell-label"}).html("wires").appendTo(row); - localCell = $("",{class:"node-diff-property-cell"}).appendTo(row); + localCell = $("",{class:"node-diff-property-cell node-diff-node-local"}).appendTo(row); if (localNode) { if (!conflict) { localCell.addClass("node-diff-node-"+(localChanged?"changed":"unchanged")); - $(''+(localChanged?'':'')+'').appendTo(localCell); + $(''+(localChanged?'':'')+'').appendTo(localCell); } else { localCell.addClass("node-diff-node-conflict"); $('').appendTo(localCell); @@ -624,11 +638,11 @@ RED.diff = (function() { } if (remoteNode !== undefined) { - remoteCell = $("",{class:"node-diff-property-cell"}).appendTo(row); + remoteCell = $("",{class:"node-diff-property-cell node-diff-node-remote"}).appendTo(row); if (remoteNode) { if (!conflict) { remoteCell.addClass("node-diff-node-"+(remoteChanged?"changed":"unchanged")); - $(''+(remoteChanged?'':'')+'').appendTo(remoteCell); + $(''+(remoteChanged?'':'')+'').appendTo(remoteCell); } else { remoteCell.addClass("node-diff-node-conflict"); $('').appendTo(remoteCell); @@ -667,17 +681,16 @@ RED.diff = (function() { (!localChanged && remoteChanged && localNodeObj.diff.deleted[node.id]) || (localChanged && !remoteChanged && remoteNodeObj.diff.deleted[node.id]) ){ - conflicted = true; conflict = true; } row = $("
      ",{class:"node-diff-property-cell-label"}).html(d).appendTo(row); - localCell = $("",{class:"node-diff-property-cell"}).appendTo(row); + localCell = $("",{class:"node-diff-property-cell node-diff-node-local"}).appendTo(row); if (localNode) { if (!conflict) { localCell.addClass("node-diff-node-"+(localChanged?"changed":"unchanged")); - $(''+(localChanged?'':'')+'').appendTo(localCell); + $(''+(localChanged?'':'')+'').appendTo(localCell); } else { localCell.addClass("node-diff-node-conflict"); $('').appendTo(localCell); @@ -687,11 +700,11 @@ RED.diff = (function() { localCell.addClass("node-diff-empty"); } if (remoteNode !== undefined) { - remoteCell = $("",{class:"node-diff-property-cell"}).appendTo(row); + remoteCell = $("",{class:"node-diff-property-cell node-diff-node-remote"}).appendTo(row); if (remoteNode) { if (!conflict) { remoteCell.addClass("node-diff-node-"+(remoteChanged?"changed":"unchanged")); - $(''+(remoteChanged?'':'')+'').appendTo(remoteCell); + $(''+(remoteChanged?'':'')+'').appendTo(remoteCell); } else { remoteCell.addClass("node-diff-node-conflict"); $('').appendTo(remoteCell); @@ -702,64 +715,85 @@ RED.diff = (function() { } } }); - - // row = $("
      ").appendTo(row); - // var cell; - // if (localNode) { - // if (localNodeObj.diff.added[node.id]) { - // $(' added unchanged added unchanged