1
0
mirror of https://github.com/node-red/node-red.git synced 2023-10-10 13:36:53 +02:00

Merge branch 'master' into dev

This commit is contained in:
Nick O'Leary 2020-09-03 16:14:55 +01:00
commit 4dd619b8c6
No known key found for this signature in database
GPG Key ID: 4F2157149161A6C9
6 changed files with 176 additions and 111 deletions

View File

@ -27,6 +27,7 @@
], ],
"dependencies": { "dependencies": {
"ajv": "6.12.3", "ajv": "6.12.3",
"async-mutex": "0.2.4",
"basic-auth": "2.0.1", "basic-auth": "2.0.1",
"bcryptjs": "2.4.3", "bcryptjs": "2.4.3",
"body-parser": "1.19.0", "body-parser": "1.19.0",

View File

@ -119,6 +119,9 @@
if (evt.keyCode === 27) { if (evt.keyCode === 27) {
that.element.val(""); that.element.val("");
} }
if (evt.keyCode === 13) {
evt.preventDefault();
}
}) })
this.element.on("keyup",function(evt) { this.element.on("keyup",function(evt) {
that._change($(this).val()); that._change($(this).val());

View File

@ -380,11 +380,16 @@ RED.group = (function() {
return; return;
} }
} }
var existingGroup;
// Second pass, ungroup any groups in the selection and add their contents // Second pass, ungroup any groups in the selection and add their contents
// to the selection // to the selection
for (var i=0; i<selection.nodes.length; i++) { for (var i=0; i<selection.nodes.length; i++) {
n = selection.nodes[i]; n = selection.nodes[i];
if (n.type === "group") { if (n.type === "group") {
if (!existingGroup) {
existingGroup = n;
}
ungroupHistoryEvent.groups.push(n); ungroupHistoryEvent.groups.push(n);
nodes = nodes.concat(ungroup(n)); nodes = nodes.concat(ungroup(n));
} else { } else {
@ -398,6 +403,10 @@ RED.group = (function() {
// Finally, create the new group // Finally, create the new group
var group = createGroup(nodes); var group = createGroup(nodes);
if (group) { if (group) {
if (existingGroup) {
group.style = existingGroup.style;
group.name = existingGroup.name;
}
RED.view.select({nodes:[group]}) RED.view.select({nodes:[group]})
} }
historyEvent.events.push({ historyEvent.events.push({

View File

@ -1678,7 +1678,7 @@ RED.view = (function() {
} }
} }
if (ns.length > 0) { if (ns.length > 0 && mouse_mode == RED.state.MOVING_ACTIVE) {
historyEvent = {t:"move",nodes:ns,dirty:RED.nodes.dirty()}; historyEvent = {t:"move",nodes:ns,dirty:RED.nodes.dirty()};
if (activeSpliceLink) { if (activeSpliceLink) {
// TODO: DRY - droppable/nodeMouseDown/canvasMouseUp // TODO: DRY - droppable/nodeMouseDown/canvasMouseUp
@ -2354,6 +2354,10 @@ RED.view = (function() {
mousedown_port_type = null; mousedown_port_type = null;
activeSpliceLink = null; activeSpliceLink = null;
spliceActive = false; spliceActive = false;
if (activeHoverGroup) {
activeHoverGroup.hovered = false;
activeHoverGroup = null;
}
d3.select(".red-ui-flow-link-splice").classed("red-ui-flow-link-splice",false); d3.select(".red-ui-flow-link-splice").classed("red-ui-flow-link-splice",false);
if (spliceTimer) { if (spliceTimer) {
clearTimeout(spliceTimer); clearTimeout(spliceTimer);
@ -2869,7 +2873,7 @@ RED.view = (function() {
//RED.touch.radialMenu.show(d3.select(this),pos); //RED.touch.radialMenu.show(d3.select(this),pos);
if (mouse_mode == RED.state.IMPORT_DRAGGING) { if (mouse_mode == RED.state.IMPORT_DRAGGING) {
RED.keyboard.remove("escape"); RED.keyboard.remove("escape");
var historyEvent = RED.history.peek();
if (activeSpliceLink) { if (activeSpliceLink) {
// TODO: DRY - droppable/nodeMouseDown/canvasMouseUp // TODO: DRY - droppable/nodeMouseDown/canvasMouseUp
var spliceLink = d3.select(activeSpliceLink).data()[0]; var spliceLink = d3.select(activeSpliceLink).data()[0];
@ -2886,12 +2890,27 @@ RED.view = (function() {
}; };
RED.nodes.addLink(link1); RED.nodes.addLink(link1);
RED.nodes.addLink(link2); RED.nodes.addLink(link2);
var historyEvent = RED.history.peek();
historyEvent.links = [link1,link2]; historyEvent.links = [link1,link2];
historyEvent.removedLinks = [spliceLink]; historyEvent.removedLinks = [spliceLink];
updateActiveNodes(); updateActiveNodes();
} }
if (activeHoverGroup) {
for (var j=0;j<movingSet.length();j++) {
var n = movingSet.get(j);
RED.group.addToGroup(activeHoverGroup,n.n);
}
historyEvent.addedToGroup = activeHoverGroup;
activeHoverGroup.hovered = false;
enterActiveGroup(activeHoverGroup)
// TODO: check back whether this should add to moving_set
activeGroup.selected = true;
activeHoverGroup = null;
}
updateSelection(); updateSelection();
RED.nodes.dirty(true); RED.nodes.dirty(true);
redraw(); redraw();
@ -4418,6 +4437,7 @@ RED.view = (function() {
} }
if (d.dirty || dirtyGroups[d.id]) { if (d.dirty || dirtyGroups[d.id]) {
var g = d3.select(this); var g = d3.select(this);
var recalculateLabelOffsets = false;
if (d.nodes.length > 0) { if (d.nodes.length > 0) {
// If the group was just moved, all of its contents was // If the group was just moved, all of its contents was
// also moved - so no need to recalculate its bounding box // also moved - so no need to recalculate its bounding box
@ -4446,6 +4466,7 @@ RED.view = (function() {
d.y = minY; d.y = minY;
d.w = maxX - minX; d.w = maxX - minX;
d.h = maxY - minY; d.h = maxY - minY;
recalculateLabelOffsets = true;
// if set explicitly to false, this group has just been // if set explicitly to false, this group has just been
// imported so needed this initial resize calculation. // imported so needed this initial resize calculation.
// Now that's done, delete the flag so the normal // Now that's done, delete the flag so the normal
@ -4459,7 +4480,9 @@ RED.view = (function() {
} else { } else {
d.w = 40; d.w = 40;
d.h = 40; d.h = 40;
recalculateLabelOffsets = true;
} }
if (recalculateLabelOffsets) {
if (!d.minWidth) { if (!d.minWidth) {
if (d.style.label && d.name) { if (d.style.label && d.name) {
var labelParts = getLabelParts(d.name||"","red-ui-flow-group-label"); var labelParts = getLabelParts(d.name||"","red-ui-flow-group-label");
@ -4484,6 +4507,7 @@ RED.view = (function() {
} }
} }
} }
}
g.attr("transform","translate("+d.x+","+d.y+")") g.attr("transform","translate("+d.x+","+d.y+")")
g.selectAll(".red-ui-flow-group-outline") g.selectAll(".red-ui-flow-group-outline")

View File

@ -34,6 +34,8 @@
*/ */
var runtime; var runtime;
var Mutex = require('async-mutex').Mutex;
const mutex = new Mutex();
var api = module.exports = { var api = module.exports = {
init: function(_runtime) { init: function(_runtime) {
@ -64,6 +66,7 @@ var api = module.exports = {
* @memberof @node-red/runtime_flows * @memberof @node-red/runtime_flows
*/ */
setFlows: function(opts) { setFlows: function(opts) {
return mutex.runExclusive(function() {
return new Promise(function(resolve,reject) { return new Promise(function(resolve,reject) {
var flows = opts.flows; var flows = opts.flows;
@ -95,6 +98,7 @@ var api = module.exports = {
return reject(err); return reject(err);
}); });
}); });
});
}, },
/** /**
@ -107,19 +111,23 @@ var api = module.exports = {
* @memberof @node-red/runtime_flows * @memberof @node-red/runtime_flows
*/ */
addFlow: function(opts) { addFlow: function(opts) {
return mutex.runExclusive(function() {
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
var flow = opts.flow; var flow = opts.flow;
runtime.nodes.addFlow(flow).then(function (id) { runtime.nodes.addFlow(flow).then(function (id) {
runtime.log.audit({event: "flow.add", id: id}, opts.req); runtime.log.audit({event: "flow.add", id: id}, opts.req);
return resolve(id); return resolve(id);
}).catch(function (err) { }).catch(function (err) {
runtime.log.audit({event: "flow.add",error:err.code||"unexpected_error",message:err.toString()}, opts.req); runtime.log.audit({
event: "flow.add",
error: err.code || "unexpected_error",
message: err.toString()
}, opts.req);
err.status = 400; err.status = 400;
return reject(err); return reject(err);
}) })
}) })
});
}, },
/** /**
@ -145,7 +153,6 @@ var api = module.exports = {
return reject(err); return reject(err);
} }
}) })
}, },
/** /**
* Updates an existing flow configuration * Updates an existing flow configuration
@ -158,6 +165,7 @@ var api = module.exports = {
* @memberof @node-red/runtime_flows * @memberof @node-red/runtime_flows
*/ */
updateFlow: function(opts) { updateFlow: function(opts) {
return mutex.runExclusive(function() {
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
var flow = opts.flow; var flow = opts.flow;
var id = opts.id; var id = opts.id;
@ -166,7 +174,11 @@ var api = module.exports = {
runtime.log.audit({event: "flow.update", id: id}, opts.req); runtime.log.audit({event: "flow.update", id: id}, opts.req);
return resolve(id); return resolve(id);
}).catch(function (err) { }).catch(function (err) {
runtime.log.audit({event: "flow.update",error:err.code||"unexpected_error",message:err.toString()}, opts.req); runtime.log.audit({
event: "flow.update",
error: err.code || "unexpected_error",
message: err.toString()
}, opts.req);
err.status = 400; err.status = 400;
return reject(err); return reject(err);
}) })
@ -178,13 +190,17 @@ var api = module.exports = {
err.code = "not_found"; err.code = "not_found";
return reject(err); return reject(err);
} else { } else {
runtime.log.audit({event: "flow.update",error:err.code||"unexpected_error",message:err.toString()}, opts.req); runtime.log.audit({
event: "flow.update",
error: err.code || "unexpected_error",
message: err.toString()
}, opts.req);
err.status = 400; err.status = 400;
return reject(err); return reject(err);
} }
} }
}); });
});
}, },
/** /**
* Deletes a flow * Deletes a flow
@ -196,6 +212,7 @@ var api = module.exports = {
* @memberof @node-red/runtime_flows * @memberof @node-red/runtime_flows
*/ */
deleteFlow: function(opts) { deleteFlow: function(opts) {
return mutex.runExclusive(function() {
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
var id = opts.id; var id = opts.id;
try { try {
@ -203,7 +220,12 @@ var api = module.exports = {
runtime.log.audit({event: "flow.remove", id: id}, opts.req); runtime.log.audit({event: "flow.remove", id: id}, opts.req);
return resolve(); return resolve();
}).catch(function (err) { }).catch(function (err) {
runtime.log.audit({event: "flow.remove",id:id,error:err.code||"unexpected_error",message:err.toString()}, opts.req); runtime.log.audit({
event: "flow.remove",
id: id,
error: err.code || "unexpected_error",
message: err.toString()
}, opts.req);
err.status = 400; err.status = 400;
return reject(err); return reject(err);
}); });
@ -215,12 +237,18 @@ var api = module.exports = {
err.code = "not_found"; err.code = "not_found";
return reject(err); return reject(err);
} else { } else {
runtime.log.audit({event: "flow.remove",id:id,error:err.code||"unexpected_error",message:err.toString()}, opts.req); runtime.log.audit({
event: "flow.remove",
id: id,
error: err.code || "unexpected_error",
message: err.toString()
}, opts.req);
err.status = 400; err.status = 400;
return reject(err); return reject(err);
} }
} }
}); });
});
}, },
/** /**
@ -264,5 +292,4 @@ var api = module.exports = {
resolve(sendCredentials); resolve(sendCredentials);
}) })
} }
} }

View File

@ -18,6 +18,7 @@
"dependencies": { "dependencies": {
"@node-red/registry": "1.2.0-alpha.1", "@node-red/registry": "1.2.0-alpha.1",
"@node-red/util": "1.2.0-alpha.1", "@node-red/util": "1.2.0-alpha.1",
"async-mutex": "0.2.4",
"clone": "2.1.2", "clone": "2.1.2",
"express": "4.17.1", "express": "4.17.1",
"fs-extra": "8.1.0", "fs-extra": "8.1.0",