mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Merge pull request #4695 from node-red/improve-merge-diff-view
Improve diff view display of nodes that have only moved
This commit is contained in:
commit
14dfb9aef8
@ -372,6 +372,7 @@
|
||||
"deleted": "deleted",
|
||||
"flowDeleted": "flow deleted",
|
||||
"flowAdded": "flow added",
|
||||
"moved": "moved",
|
||||
"movedTo": "moved to __id__",
|
||||
"movedFrom": "moved from __id__"
|
||||
},
|
||||
|
@ -1,5 +1,4 @@
|
||||
RED.diff = (function() {
|
||||
|
||||
var currentDiff = {};
|
||||
var diffVisible = false;
|
||||
var diffList;
|
||||
@ -62,12 +61,14 @@ RED.diff = (function() {
|
||||
addedCount:0,
|
||||
deletedCount:0,
|
||||
changedCount:0,
|
||||
movedCount:0,
|
||||
unchangedCount: 0
|
||||
},
|
||||
remote: {
|
||||
addedCount:0,
|
||||
deletedCount:0,
|
||||
changedCount:0,
|
||||
movedCount:0,
|
||||
unchangedCount: 0
|
||||
},
|
||||
conflicts: 0
|
||||
@ -138,7 +139,7 @@ RED.diff = (function() {
|
||||
$(this).parent().toggleClass('collapsed');
|
||||
});
|
||||
|
||||
createNodePropertiesTable(def,tab,localTabNode,remoteTabNode,conflicts).appendTo(div);
|
||||
createNodePropertiesTable(def,tab,localTabNode,remoteTabNode).appendTo(div);
|
||||
selectState = "";
|
||||
if (conflicts[tab.id]) {
|
||||
flowStats.conflicts++;
|
||||
@ -208,19 +209,26 @@ RED.diff = (function() {
|
||||
var localStats = $('<span>',{class:"red-ui-diff-list-flow-stats"}).appendTo(localCell);
|
||||
$('<span class="red-ui-diff-status"></span>').text(RED._('diff.nodeCount',{count:localNodeCount})).appendTo(localStats);
|
||||
|
||||
if (flowStats.conflicts + flowStats.local.addedCount + flowStats.local.changedCount + flowStats.local.deletedCount > 0) {
|
||||
if (flowStats.conflicts + flowStats.local.addedCount + flowStats.local.changedCount + flowStats.local.movedCount + flowStats.local.deletedCount > 0) {
|
||||
$('<span class="red-ui-diff-status"> [ </span>').appendTo(localStats);
|
||||
if (flowStats.conflicts > 0) {
|
||||
$('<span class="red-ui-diff-status-conflict"><span class="red-ui-diff-status"><i class="fa fa-exclamation"></i> '+flowStats.conflicts+'</span></span>').appendTo(localStats);
|
||||
}
|
||||
if (flowStats.local.addedCount > 0) {
|
||||
$('<span class="red-ui-diff-status-added"><span class="red-ui-diff-status"><i class="fa fa-plus-square"></i> '+flowStats.local.addedCount+'</span></span>').appendTo(localStats);
|
||||
const cell = $('<span class="red-ui-diff-status-added"><span class="red-ui-diff-status"><i class="fa fa-plus-square"></i> '+flowStats.local.addedCount+'</span></span>').appendTo(localStats);
|
||||
RED.popover.tooltip(cell, RED._('diff.type.added'))
|
||||
}
|
||||
if (flowStats.local.changedCount > 0) {
|
||||
$('<span class="red-ui-diff-status-changed"><span class="red-ui-diff-status"><i class="fa fa-square"></i> '+flowStats.local.changedCount+'</span></span>').appendTo(localStats);
|
||||
const cell = $('<span class="red-ui-diff-status-changed"><span class="red-ui-diff-status"><i class="fa fa-square"></i> '+flowStats.local.changedCount+'</span></span>').appendTo(localStats);
|
||||
RED.popover.tooltip(cell, RED._('diff.type.changed'))
|
||||
}
|
||||
if (flowStats.local.movedCount > 0) {
|
||||
const cell = $('<span class="red-ui-diff-status-moved"><span class="red-ui-diff-status"><i class="fa fa-square"></i> '+flowStats.local.movedCount+'</span></span>').appendTo(localStats);
|
||||
RED.popover.tooltip(cell, RED._('diff.type.moved'))
|
||||
}
|
||||
if (flowStats.local.deletedCount > 0) {
|
||||
$('<span class="red-ui-diff-status-deleted"><span class="red-ui-diff-status"><i class="fa fa-minus-square"></i> '+flowStats.local.deletedCount+'</span></span>').appendTo(localStats);
|
||||
const cell = $('<span class="red-ui-diff-status-deleted"><span class="red-ui-diff-status"><i class="fa fa-minus-square"></i> '+flowStats.local.deletedCount+'</span></span>').appendTo(localStats);
|
||||
RED.popover.tooltip(cell, RED._('diff.type.deleted'))
|
||||
}
|
||||
$('<span class="red-ui-diff-status"> ] </span>').appendTo(localStats);
|
||||
}
|
||||
@ -246,19 +254,26 @@ RED.diff = (function() {
|
||||
}
|
||||
var remoteStats = $('<span>',{class:"red-ui-diff-list-flow-stats"}).appendTo(remoteCell);
|
||||
$('<span class="red-ui-diff-status"></span>').text(RED._('diff.nodeCount',{count:remoteNodeCount})).appendTo(remoteStats);
|
||||
if (flowStats.conflicts + flowStats.remote.addedCount + flowStats.remote.changedCount + flowStats.remote.deletedCount > 0) {
|
||||
if (flowStats.conflicts + flowStats.remote.addedCount + flowStats.remote.changedCount + flowStats.remote.movedCount + flowStats.remote.deletedCount > 0) {
|
||||
$('<span class="red-ui-diff-status"> [ </span>').appendTo(remoteStats);
|
||||
if (flowStats.conflicts > 0) {
|
||||
$('<span class="red-ui-diff-status-conflict"><span class="red-ui-diff-status"><i class="fa fa-exclamation"></i> '+flowStats.conflicts+'</span></span>').appendTo(remoteStats);
|
||||
}
|
||||
if (flowStats.remote.addedCount > 0) {
|
||||
$('<span class="red-ui-diff-status-added"><span class="red-ui-diff-status"><i class="fa fa-plus-square"></i> '+flowStats.remote.addedCount+'</span></span>').appendTo(remoteStats);
|
||||
const cell = $('<span class="red-ui-diff-status-added"><span class="red-ui-diff-status"><i class="fa fa-plus-square"></i> '+flowStats.remote.addedCount+'</span></span>').appendTo(remoteStats);
|
||||
RED.popover.tooltip(cell, RED._('diff.type.added'))
|
||||
}
|
||||
if (flowStats.remote.changedCount > 0) {
|
||||
$('<span class="red-ui-diff-status-changed"><span class="red-ui-diff-status"><i class="fa fa-square"></i> '+flowStats.remote.changedCount+'</span></span>').appendTo(remoteStats);
|
||||
const cell = $('<span class="red-ui-diff-status-changed"><span class="red-ui-diff-status"><i class="fa fa-square"></i> '+flowStats.remote.changedCount+'</span></span>').appendTo(remoteStats);
|
||||
RED.popover.tooltip(cell, RED._('diff.type.changed'))
|
||||
}
|
||||
if (flowStats.remote.movedCount > 0) {
|
||||
const cell = $('<span class="red-ui-diff-status-moved"><span class="red-ui-diff-status"><i class="fa fa-square"></i> '+flowStats.remote.movedCount+'</span></span>').appendTo(remoteStats);
|
||||
RED.popover.tooltip(cell, RED._('diff.type.moved'))
|
||||
}
|
||||
if (flowStats.remote.deletedCount > 0) {
|
||||
$('<span class="red-ui-diff-status-deleted"><span class="red-ui-diff-status"><i class="fa fa-minus-square"></i> '+flowStats.remote.deletedCount+'</span></span>').appendTo(remoteStats);
|
||||
const cell = $('<span class="red-ui-diff-status-deleted"><span class="red-ui-diff-status"><i class="fa fa-minus-square"></i> '+flowStats.remote.deletedCount+'</span></span>').appendTo(remoteStats);
|
||||
RED.popover.tooltip(cell, RED._('diff.type.deleted'))
|
||||
}
|
||||
$('<span class="red-ui-diff-status"> ] </span>').appendTo(remoteStats);
|
||||
}
|
||||
@ -293,7 +308,7 @@ RED.diff = (function() {
|
||||
if (options.mode === "merge") {
|
||||
diffPanel.addClass("red-ui-diff-panel-merge");
|
||||
}
|
||||
var diffList = createDiffTable(diffPanel, diff);
|
||||
var diffList = createDiffTable(diffPanel, diff, options);
|
||||
|
||||
var localDiff = diff.localDiff;
|
||||
var remoteDiff = diff.remoteDiff;
|
||||
@ -516,7 +531,6 @@ RED.diff = (function() {
|
||||
|
||||
var hasChanges = false; // exists in original and local/remote but with changes
|
||||
var unChanged = true; // existing in original,local,remote unchanged
|
||||
var localChanged = false;
|
||||
|
||||
if (localDiff.added[node.id]) {
|
||||
stats.local.addedCount++;
|
||||
@ -535,12 +549,20 @@ RED.diff = (function() {
|
||||
unChanged = false;
|
||||
}
|
||||
if (localDiff.changed[node.id]) {
|
||||
stats.local.changedCount++;
|
||||
if (localDiff.positionChanged[node.id]) {
|
||||
stats.local.movedCount++
|
||||
} else {
|
||||
stats.local.changedCount++;
|
||||
}
|
||||
hasChanges = true;
|
||||
unChanged = false;
|
||||
}
|
||||
if (remoteDiff && remoteDiff.changed[node.id]) {
|
||||
stats.remote.changedCount++;
|
||||
if (remoteDiff.positionChanged[node.id]) {
|
||||
stats.remote.movedCount++
|
||||
} else {
|
||||
stats.remote.changedCount++;
|
||||
}
|
||||
hasChanges = true;
|
||||
unChanged = false;
|
||||
}
|
||||
@ -605,27 +627,32 @@ RED.diff = (function() {
|
||||
localNodeDiv.addClass("red-ui-diff-status-moved");
|
||||
var localMovedMessage = "";
|
||||
if (node.z === localN.z) {
|
||||
localMovedMessage = RED._("diff.type.movedFrom",{id:(localDiff.currentConfig.all[node.id].z||'global')});
|
||||
const movedFromNodeTab = localDiff.currentConfig.all[localDiff.currentConfig.all[node.id].z]
|
||||
const movedFromLabel = `'${movedFromNodeTab ? (movedFromNodeTab.label || movedFromNodeTab.id) : 'global'}'`
|
||||
localMovedMessage = RED._("diff.type.movedFrom",{id: movedFromLabel});
|
||||
} else {
|
||||
localMovedMessage = RED._("diff.type.movedTo",{id:(localN.z||'global')});
|
||||
const movedToNodeTab = localDiff.newConfig.all[localN.z]
|
||||
const movedToLabel = `'${movedToNodeTab ? (movedToNodeTab.label || movedToNodeTab.id) : 'global'}'`
|
||||
localMovedMessage = RED._("diff.type.movedTo",{id:movedToLabel});
|
||||
}
|
||||
$('<span class="red-ui-diff-status"><i class="fa fa-caret-square-o-right"></i> '+localMovedMessage+'</span>').appendTo(localNodeDiv);
|
||||
}
|
||||
localChanged = true;
|
||||
} else if (localDiff.deleted[node.z]) {
|
||||
localNodeDiv.addClass("red-ui-diff-empty");
|
||||
localChanged = true;
|
||||
} else if (localDiff.deleted[node.id]) {
|
||||
localNodeDiv.addClass("red-ui-diff-status-deleted");
|
||||
$('<span class="red-ui-diff-status"><i class="fa fa-minus-square"></i> <span data-i18n="diff.type.deleted"></span></span>').appendTo(localNodeDiv);
|
||||
localChanged = true;
|
||||
} else if (localDiff.changed[node.id]) {
|
||||
if (localDiff.newConfig.all[node.id].z !== node.z) {
|
||||
localNodeDiv.addClass("red-ui-diff-empty");
|
||||
} else {
|
||||
localNodeDiv.addClass("red-ui-diff-status-changed");
|
||||
$('<span class="red-ui-diff-status"><i class="fa fa-square"></i> <span data-i18n="diff.type.changed"></span></span>').appendTo(localNodeDiv);
|
||||
localChanged = true;
|
||||
if (localDiff.positionChanged[node.id]) {
|
||||
localNodeDiv.addClass("red-ui-diff-status-moved");
|
||||
$('<span class="red-ui-diff-status"><i class="fa fa-square"></i> <span data-i18n="diff.type.moved"></span></span>').appendTo(localNodeDiv);
|
||||
} else {
|
||||
localNodeDiv.addClass("red-ui-diff-status-changed");
|
||||
$('<span class="red-ui-diff-status"><i class="fa fa-square"></i> <span data-i18n="diff.type.changed"></span></span>').appendTo(localNodeDiv);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (localDiff.newConfig.all[node.id].z !== node.z) {
|
||||
@ -646,9 +673,13 @@ RED.diff = (function() {
|
||||
remoteNodeDiv.addClass("red-ui-diff-status-moved");
|
||||
var remoteMovedMessage = "";
|
||||
if (node.z === remoteN.z) {
|
||||
remoteMovedMessage = RED._("diff.type.movedFrom",{id:(remoteDiff.currentConfig.all[node.id].z||'global')});
|
||||
const movedFromNodeTab = remoteDiff.currentConfig.all[remoteDiff.currentConfig.all[node.id].z]
|
||||
const movedFromLabel = `'${movedFromNodeTab ? (movedFromNodeTab.label || movedFromNodeTab.id) : 'global'}'`
|
||||
remoteMovedMessage = RED._("diff.type.movedFrom",{id:movedFromLabel});
|
||||
} else {
|
||||
remoteMovedMessage = RED._("diff.type.movedTo",{id:(remoteN.z||'global')});
|
||||
const movedToNodeTab = remoteDiff.newConfig.all[remoteN.z]
|
||||
const movedToLabel = `'${movedToNodeTab ? (movedToNodeTab.label || movedToNodeTab.id) : 'global'}'`
|
||||
remoteMovedMessage = RED._("diff.type.movedTo",{id:movedToLabel});
|
||||
}
|
||||
$('<span class="red-ui-diff-status"><i class="fa fa-caret-square-o-right"></i> '+remoteMovedMessage+'</span>').appendTo(remoteNodeDiv);
|
||||
}
|
||||
@ -661,8 +692,13 @@ RED.diff = (function() {
|
||||
if (remoteDiff.newConfig.all[node.id].z !== node.z) {
|
||||
remoteNodeDiv.addClass("red-ui-diff-empty");
|
||||
} else {
|
||||
remoteNodeDiv.addClass("red-ui-diff-status-changed");
|
||||
$('<span class="red-ui-diff-status"><i class="fa fa-square"></i> <span data-i18n="diff.type.changed"></span></span>').appendTo(remoteNodeDiv);
|
||||
if (remoteDiff.positionChanged[node.id]) {
|
||||
remoteNodeDiv.addClass("red-ui-diff-status-moved");
|
||||
$('<span class="red-ui-diff-status"><i class="fa fa-square"></i> <span data-i18n="diff.type.moved"></span></span>').appendTo(remoteNodeDiv);
|
||||
} else {
|
||||
remoteNodeDiv.addClass("red-ui-diff-status-changed");
|
||||
$('<span class="red-ui-diff-status"><i class="fa fa-square"></i> <span data-i18n="diff.type.changed"></span></span>').appendTo(remoteNodeDiv);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (remoteDiff.newConfig.all[node.id].z !== node.z) {
|
||||
@ -788,7 +824,7 @@ RED.diff = (function() {
|
||||
$("<td>",{class:"red-ui-diff-list-cell-label"}).text("position").appendTo(row);
|
||||
localCell = $("<td>",{class:"red-ui-diff-list-cell red-ui-diff-list-node-local"}).appendTo(row);
|
||||
if (localNode) {
|
||||
localCell.addClass("red-ui-diff-status-"+(localChanged?"changed":"unchanged"));
|
||||
localCell.addClass("red-ui-diff-status-"+(localChanged?"moved":"unchanged"));
|
||||
$('<span class="red-ui-diff-status">'+(localChanged?'<i class="fa fa-square"></i>':'')+'</span>').appendTo(localCell);
|
||||
element = $('<span class="red-ui-diff-list-element"></span>').appendTo(localCell);
|
||||
var localPosition = {x:localNode.x,y:localNode.y};
|
||||
@ -813,7 +849,7 @@ RED.diff = (function() {
|
||||
|
||||
if (remoteNode !== undefined) {
|
||||
remoteCell = $("<td>",{class:"red-ui-diff-list-cell red-ui-diff-list-node-remote"}).appendTo(row);
|
||||
remoteCell.addClass("red-ui-diff-status-"+(remoteChanged?"changed":"unchanged"));
|
||||
remoteCell.addClass("red-ui-diff-status-"+(remoteChanged?"moved":"unchanged"));
|
||||
if (remoteNode) {
|
||||
$('<span class="red-ui-diff-status">'+(remoteChanged?'<i class="fa fa-square"></i>':'')+'</span>').appendTo(remoteCell);
|
||||
element = $('<span class="red-ui-diff-list-element"></span>').appendTo(remoteCell);
|
||||
@ -1144,23 +1180,53 @@ RED.diff = (function() {
|
||||
}
|
||||
}
|
||||
function generateDiff(currentNodes,newNodes) {
|
||||
var currentConfig = parseNodes(currentNodes);
|
||||
var newConfig = parseNodes(newNodes);
|
||||
var added = {};
|
||||
var deleted = {};
|
||||
var changed = {};
|
||||
var moved = {};
|
||||
const currentConfig = parseNodes(currentNodes);
|
||||
const newConfig = parseNodes(newNodes);
|
||||
const added = {};
|
||||
const deleted = {};
|
||||
const changed = {};
|
||||
const positionChanged = {};
|
||||
const moved = {};
|
||||
|
||||
Object.keys(currentConfig.all).forEach(function(id) {
|
||||
var node = RED.nodes.workspace(id)||RED.nodes.subflow(id)||RED.nodes.node(id);
|
||||
const node = RED.nodes.workspace(id)||RED.nodes.subflow(id)||RED.nodes.node(id);
|
||||
if (!newConfig.all.hasOwnProperty(id)) {
|
||||
deleted[id] = true;
|
||||
} else if (JSON.stringify(currentConfig.all[id]) !== JSON.stringify(newConfig.all[id])) {
|
||||
return
|
||||
}
|
||||
const currentConfigJSON = JSON.stringify(currentConfig.all[id])
|
||||
const newConfigJSON = JSON.stringify(newConfig.all[id])
|
||||
|
||||
if (currentConfigJSON !== newConfigJSON) {
|
||||
changed[id] = true;
|
||||
|
||||
if (currentConfig.all[id].z !== newConfig.all[id].z) {
|
||||
moved[id] = true;
|
||||
} else if (
|
||||
currentConfig.all[id].x !== newConfig.all[id].x ||
|
||||
currentConfig.all[id].y !== newConfig.all[id].y ||
|
||||
currentConfig.all[id].w !== newConfig.all[id].w ||
|
||||
currentConfig.all[id].h !== newConfig.all[id].h
|
||||
) {
|
||||
// This node's position on its parent has changed. We want to
|
||||
// check if this is the *only* change for this given node
|
||||
const currentNodeClone = JSON.parse(currentConfigJSON)
|
||||
const newNodeClone = JSON.parse(newConfigJSON)
|
||||
|
||||
delete currentNodeClone.x
|
||||
delete currentNodeClone.y
|
||||
delete currentNodeClone.w
|
||||
delete currentNodeClone.h
|
||||
delete newNodeClone.x
|
||||
delete newNodeClone.y
|
||||
delete newNodeClone.w
|
||||
delete newNodeClone.h
|
||||
|
||||
if (JSON.stringify(currentNodeClone) === JSON.stringify(newNodeClone)) {
|
||||
// Only the position has changed - everything else is the same
|
||||
positionChanged[id] = true
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
Object.keys(newConfig.all).forEach(function(id) {
|
||||
@ -1169,13 +1235,14 @@ RED.diff = (function() {
|
||||
}
|
||||
});
|
||||
|
||||
var diff = {
|
||||
currentConfig: currentConfig,
|
||||
newConfig: newConfig,
|
||||
added: added,
|
||||
deleted: deleted,
|
||||
changed: changed,
|
||||
moved: moved
|
||||
const diff = {
|
||||
currentConfig,
|
||||
newConfig,
|
||||
added,
|
||||
deleted,
|
||||
changed,
|
||||
positionChanged,
|
||||
moved
|
||||
};
|
||||
return diff;
|
||||
}
|
||||
@ -1246,6 +1313,8 @@ RED.diff = (function() {
|
||||
}
|
||||
options = options || {};
|
||||
var mode = options.mode || 'merge';
|
||||
|
||||
options.hidePositionChanges = true
|
||||
|
||||
var localDiff = diff.localDiff;
|
||||
var remoteDiff = diff.remoteDiff;
|
||||
|
Loading…
x
Reference in New Issue
Block a user