mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Complete overhaul of Group UX
This commit is contained in:
@@ -68,7 +68,6 @@ RED.nodes = (function() {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var exports = {
|
||||
setModulePendingUpdated: function(module,version) {
|
||||
moduleList[module].pending_version = version;
|
||||
@@ -240,6 +239,43 @@ RED.nodes = (function() {
|
||||
var allNodes = (function() {
|
||||
var nodes = {};
|
||||
var tabMap = {};
|
||||
|
||||
function changeCollectionDepth(tabNodes, toMove, direction, singleStep) {
|
||||
const result = []
|
||||
const moved = new Set();
|
||||
const startIndex = direction ? tabNodes.length - 1 : 0
|
||||
const endIndex = direction ? -1 : tabNodes.length
|
||||
const step = direction ? -1 : 1
|
||||
let target = startIndex // Only used for all-the-way moves
|
||||
for (let i = startIndex; i != endIndex; i += step) {
|
||||
if (toMove.size === 0) {
|
||||
break;
|
||||
}
|
||||
const n = tabNodes[i]
|
||||
if (toMove.has(n)) {
|
||||
if (singleStep) {
|
||||
if (i !== startIndex && !moved.has(tabNodes[i - step])) {
|
||||
tabNodes.splice(i, 1)
|
||||
tabNodes.splice(i - step, 0, n)
|
||||
n._reordered = true
|
||||
result.push(n)
|
||||
}
|
||||
} else {
|
||||
if (i !== target) {
|
||||
tabNodes.splice(i, 1)
|
||||
tabNodes.splice(target, 0, n)
|
||||
n._reordered = true
|
||||
result.push(n)
|
||||
}
|
||||
target += step
|
||||
}
|
||||
toMove.delete(n);
|
||||
moved.add(n);
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
var api = {
|
||||
addTab: function(id) {
|
||||
tabMap[id] = [];
|
||||
@@ -280,152 +316,54 @@ RED.nodes = (function() {
|
||||
n.z = newZ;
|
||||
api.addNode(n)
|
||||
},
|
||||
moveNodesForwards: function(nodes) {
|
||||
var result = [];
|
||||
/**
|
||||
* @param {array} nodes
|
||||
* @param {boolean} direction true:forwards false:back
|
||||
* @param {boolean} singleStep true:single-step false:all-the-way
|
||||
*/
|
||||
changeDepth: function(nodes, direction, singleStep) {
|
||||
if (!Array.isArray(nodes)) {
|
||||
nodes = [nodes]
|
||||
}
|
||||
// Can only do this for nodes on the same tab.
|
||||
// Use nodes[0] to get the z
|
||||
var tabNodes = tabMap[nodes[0].z];
|
||||
var toMove = new Set(nodes.filter(function(n) { return n.type !== "group" && n.type !== "subflow" }));
|
||||
var moved = new Set();
|
||||
for (var i = tabNodes.length-1; i >= 0; i--) {
|
||||
if (toMove.size === 0) {
|
||||
break;
|
||||
}
|
||||
var n = tabNodes[i];
|
||||
if (toMove.has(n)) {
|
||||
// This is a node to move.
|
||||
if (i < tabNodes.length-1 && !moved.has(tabNodes[i+1])) {
|
||||
// Remove from current position
|
||||
tabNodes.splice(i,1);
|
||||
// Add it back one position higher
|
||||
tabNodes.splice(i+1,0,n);
|
||||
n._reordered = true;
|
||||
result.push(n);
|
||||
}
|
||||
toMove.delete(n);
|
||||
moved.add(n);
|
||||
let result = []
|
||||
const tabNodes = tabMap[nodes[0].z];
|
||||
const toMove = new Set(nodes.filter(function(n) { return n.type !== "group" && n.type !== "subflow" }));
|
||||
if (toMove.size > 0) {
|
||||
result = result.concat(changeCollectionDepth(tabNodes, toMove, direction, singleStep))
|
||||
if (result.length > 0) {
|
||||
RED.events.emit('nodes:reorder',{
|
||||
z: nodes[0].z,
|
||||
nodes: result
|
||||
});
|
||||
}
|
||||
}
|
||||
if (result.length > 0) {
|
||||
RED.events.emit('nodes:reorder',{
|
||||
z: nodes[0].z,
|
||||
nodes: result
|
||||
});
|
||||
|
||||
const groupNodes = groupsByZ[nodes[0].z] || []
|
||||
const groupsToMove = new Set(nodes.filter(function(n) { return n.type === 'group'}))
|
||||
if (groupsToMove.size > 0) {
|
||||
const groupResult = changeCollectionDepth(groupNodes, groupsToMove, direction, singleStep)
|
||||
if (groupResult.length > 0) {
|
||||
result = result.concat(groupResult)
|
||||
RED.events.emit('groups:reorder',{
|
||||
z: nodes[0].z,
|
||||
nodes: groupResult
|
||||
});
|
||||
}
|
||||
}
|
||||
return result;
|
||||
RED.view.redraw(true)
|
||||
return result
|
||||
},
|
||||
moveNodesForwards: function(nodes) {
|
||||
return api.changeDepth(nodes, true, true)
|
||||
},
|
||||
moveNodesBackwards: function(nodes) {
|
||||
var result = [];
|
||||
if (!Array.isArray(nodes)) {
|
||||
nodes = [nodes]
|
||||
}
|
||||
// Can only do this for nodes on the same tab.
|
||||
// Use nodes[0] to get the z
|
||||
var tabNodes = tabMap[nodes[0].z];
|
||||
var toMove = new Set(nodes.filter(function(n) { return n.type !== "group" && n.type !== "subflow" }));
|
||||
var moved = new Set();
|
||||
for (var i = 0; i < tabNodes.length; i++) {
|
||||
if (toMove.size === 0) {
|
||||
break;
|
||||
}
|
||||
var n = tabNodes[i];
|
||||
if (toMove.has(n)) {
|
||||
// This is a node to move.
|
||||
if (i > 0 && !moved.has(tabNodes[i-1])) {
|
||||
// Remove from current position
|
||||
tabNodes.splice(i,1);
|
||||
// Add it back one position lower
|
||||
tabNodes.splice(i-1,0,n);
|
||||
n._reordered = true;
|
||||
result.push(n);
|
||||
}
|
||||
toMove.delete(n);
|
||||
moved.add(n);
|
||||
}
|
||||
}
|
||||
if (result.length > 0) {
|
||||
RED.events.emit('nodes:reorder',{
|
||||
z: nodes[0].z,
|
||||
nodes: result
|
||||
});
|
||||
}
|
||||
return result;
|
||||
return api.changeDepth(nodes, false, true)
|
||||
},
|
||||
moveNodesToFront: function(nodes) {
|
||||
var result = [];
|
||||
if (!Array.isArray(nodes)) {
|
||||
nodes = [nodes]
|
||||
}
|
||||
// Can only do this for nodes on the same tab.
|
||||
// Use nodes[0] to get the z
|
||||
var tabNodes = tabMap[nodes[0].z];
|
||||
var toMove = new Set(nodes.filter(function(n) { return n.type !== "group" && n.type !== "subflow" }));
|
||||
var target = tabNodes.length-1;
|
||||
for (var i = tabNodes.length-1; i >= 0; i--) {
|
||||
if (toMove.size === 0) {
|
||||
break;
|
||||
}
|
||||
var n = tabNodes[i];
|
||||
if (toMove.has(n)) {
|
||||
// This is a node to move.
|
||||
if (i < target) {
|
||||
// Remove from current position
|
||||
tabNodes.splice(i,1);
|
||||
tabNodes.splice(target,0,n);
|
||||
n._reordered = true;
|
||||
result.push(n);
|
||||
}
|
||||
target--;
|
||||
toMove.delete(n);
|
||||
}
|
||||
}
|
||||
if (result.length > 0) {
|
||||
RED.events.emit('nodes:reorder',{
|
||||
z: nodes[0].z,
|
||||
nodes: result
|
||||
});
|
||||
}
|
||||
return result;
|
||||
return api.changeDepth(nodes, true, false)
|
||||
},
|
||||
moveNodesToBack: function(nodes) {
|
||||
var result = [];
|
||||
if (!Array.isArray(nodes)) {
|
||||
nodes = [nodes]
|
||||
}
|
||||
// Can only do this for nodes on the same tab.
|
||||
// Use nodes[0] to get the z
|
||||
var tabNodes = tabMap[nodes[0].z];
|
||||
var toMove = new Set(nodes.filter(function(n) { return n.type !== "group" && n.type !== "subflow" }));
|
||||
var target = 0;
|
||||
for (var i = 0; i < tabNodes.length; i++) {
|
||||
if (toMove.size === 0) {
|
||||
break;
|
||||
}
|
||||
var n = tabNodes[i];
|
||||
if (toMove.has(n)) {
|
||||
// This is a node to move.
|
||||
if (i > target) {
|
||||
// Remove from current position
|
||||
tabNodes.splice(i,1);
|
||||
// Add it back one position lower
|
||||
tabNodes.splice(target,0,n);
|
||||
n._reordered = true;
|
||||
result.push(n);
|
||||
}
|
||||
target++;
|
||||
toMove.delete(n);
|
||||
}
|
||||
}
|
||||
if (result.length > 0) {
|
||||
RED.events.emit('nodes:reorder',{
|
||||
z: nodes[0].z,
|
||||
nodes: result
|
||||
});
|
||||
}
|
||||
return result;
|
||||
return api.changeDepth(nodes, false, false)
|
||||
},
|
||||
getNodes: function(z) {
|
||||
return tabMap[z];
|
||||
@@ -498,7 +436,7 @@ RED.nodes = (function() {
|
||||
return result;
|
||||
},
|
||||
getNodeOrder: function(z) {
|
||||
return tabMap[z].map(function(n) { return n.id })
|
||||
return (groupsByZ[z] || []).concat(tabMap[z]).map(n => n.id)
|
||||
},
|
||||
setNodeOrder: function(z, order) {
|
||||
var orderMap = {};
|
||||
@@ -510,6 +448,11 @@ RED.nodes = (function() {
|
||||
B._reordered = true;
|
||||
return orderMap[A.id] - orderMap[B.id];
|
||||
})
|
||||
if (groupsByZ[z]) {
|
||||
groupsByZ[z].sort(function(A,B) {
|
||||
return orderMap[A.id] - orderMap[B.id];
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return api;
|
||||
@@ -2615,6 +2558,10 @@ RED.nodes = (function() {
|
||||
delete groups[group.id];
|
||||
RED.events.emit("groups:remove",group);
|
||||
}
|
||||
function getGroupOrder(z) {
|
||||
const groups = groupsByZ[z]
|
||||
return groups.map(g => g.id)
|
||||
}
|
||||
|
||||
function addJunction(junction) {
|
||||
if (!junction.__isProxy__) {
|
||||
|
||||
Reference in New Issue
Block a user