mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Compare commits
7 Commits
3.0.0-beta
...
fix-dynami
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9729c89f5d | ||
|
|
fc5a5f1b73 | ||
|
|
226ab406b2 | ||
|
|
9eaf5d82b6 | ||
|
|
e3d6d242ac | ||
|
|
53184715bc | ||
|
|
1844633ff1 |
@@ -111,7 +111,7 @@
|
||||
"marked": "4.0.17",
|
||||
"minami": "1.2.3",
|
||||
"mocha": "9.2.2",
|
||||
"node-red-node-test-helper": "^0.2.7",
|
||||
"node-red-node-test-helper": "^0.3.0",
|
||||
"nodemon": "2.0.16",
|
||||
"proxy": "^1.0.2",
|
||||
"sass": "1.52.3",
|
||||
|
||||
@@ -133,6 +133,8 @@ RED.menu = (function() {
|
||||
if (opt.options) {
|
||||
item.addClass("red-ui-menu-dropdown-submenu"+(opt.direction!=='right'?" pull-left":""));
|
||||
var submenu = $('<ul id="'+opt.id+'-submenu" class="red-ui-menu-dropdown"></ul>').appendTo(item);
|
||||
var hasIcons = false
|
||||
var hasSubmenus = false
|
||||
|
||||
for (var i=0;i<opt.options.length;i++) {
|
||||
|
||||
@@ -144,6 +146,8 @@ RED.menu = (function() {
|
||||
opt.options[i].onpostselect = opt.onpostselect
|
||||
}
|
||||
opt.options[i].direction = opt.direction
|
||||
hasIcons = hasIcons || (opt.options[i].icon);
|
||||
hasSubmenus = hasSubmenus || (opt.options[i].options);
|
||||
}
|
||||
|
||||
var li = createMenuItem(opt.options[i]);
|
||||
@@ -151,6 +155,14 @@ RED.menu = (function() {
|
||||
li.appendTo(submenu);
|
||||
}
|
||||
}
|
||||
if (!hasIcons) {
|
||||
submenu.addClass("red-ui-menu-dropdown-noicons")
|
||||
}
|
||||
if (hasSubmenus) {
|
||||
submenu.addClass("red-ui-menu-dropdown-submenus")
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
if (opt.disabled) {
|
||||
item.addClass("disabled");
|
||||
@@ -191,6 +203,8 @@ RED.menu = (function() {
|
||||
}
|
||||
|
||||
var lastAddedSeparator = false;
|
||||
var hasSubmenus = false;
|
||||
var hasIcons = false;
|
||||
for (var i=0;i<options.options.length;i++) {
|
||||
var opt = options.options[i];
|
||||
if (opt) {
|
||||
@@ -203,6 +217,8 @@ RED.menu = (function() {
|
||||
opt.direction = options.direction || 'left'
|
||||
}
|
||||
if (opt !== null || !lastAddedSeparator) {
|
||||
hasIcons = hasIcons || (opt && opt.icon);
|
||||
hasSubmenus = hasSubmenus || (opt && opt.options);
|
||||
var li = createMenuItem(opt);
|
||||
if (li) {
|
||||
li.appendTo(topMenu);
|
||||
@@ -210,7 +226,12 @@ RED.menu = (function() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasIcons) {
|
||||
topMenu.addClass("red-ui-menu-dropdown-noicons")
|
||||
}
|
||||
if (hasSubmenus) {
|
||||
topMenu.addClass("red-ui-menu-dropdown-submenus")
|
||||
}
|
||||
return topMenu;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
* - multi : boolean - if true, .selected will return an array of results
|
||||
* otherwise, returns the first selected item
|
||||
* - sortable: boolean/string - TODO: see editableList
|
||||
* - selectable: boolean - default true - whether individual items can be selected
|
||||
* - rootSortable: boolean - if 'sortable' is set, then setting this to
|
||||
* false, prevents items being sorted to the
|
||||
* top level of the tree
|
||||
@@ -118,6 +119,7 @@
|
||||
switch(evt.keyCode) {
|
||||
case 32: // SPACE
|
||||
case 13: // ENTER
|
||||
if (!that.options.selectable) { return }
|
||||
if (evt.altKey || evt.ctrlKey || evt.metaKey || evt.shiftKey) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -534,6 +534,7 @@
|
||||
var container = $("#red-ui-editor-type-json-tab-ui-container").css({"height":"100%"});
|
||||
var filterDepth = Infinity;
|
||||
var list = $('<div class="red-ui-debug-msg-payload red-ui-editor-type-json-editor">').appendTo(container).treeList({
|
||||
selectable: false,
|
||||
rootSortable: false,
|
||||
sortable: ".red-ui-editor-type-json-editor-item-handle",
|
||||
}).on("treelistchangeparent", function(event, evt) {
|
||||
|
||||
@@ -1071,8 +1071,8 @@ RED.view = (function() {
|
||||
var oy = point[1];
|
||||
|
||||
const offset = $("#red-ui-workspace-chart").offset()
|
||||
var clientX = ox + offset.left
|
||||
var clientY = oy + offset.top
|
||||
var clientX = ox + offset.left - $("#red-ui-workspace-chart").scrollLeft()
|
||||
var clientY = oy + offset.top - $("#red-ui-workspace-chart").scrollTop()
|
||||
|
||||
if (RED.settings.get("editor").view['view-snap-grid']) {
|
||||
// eventLayer.append("circle").attr("cx",point[0]).attr("cy",point[1]).attr("r","2").attr('fill','red')
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
& > li > a,
|
||||
& > li > a:focus {
|
||||
display: block;
|
||||
padding: 4px 20px 4px 12px;
|
||||
padding: 4px 12px 4px 32px;
|
||||
clear: both;
|
||||
font-weight: normal;
|
||||
line-height: 20px;
|
||||
@@ -58,6 +58,18 @@
|
||||
& > li.pull-left > a:focus {
|
||||
padding: 4px 12px 4px 32px;
|
||||
}
|
||||
&.red-ui-menu-dropdown-noicons > li > a,
|
||||
&.red-ui-menu-dropdown-noicons > li > a:focus {
|
||||
padding: 4px 12px 4px 12px;
|
||||
}
|
||||
|
||||
&.red-ui-menu-dropdown-submenus > li > a,
|
||||
&.red-ui-menu-dropdown-submenus > li > a:focus {
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
& > .active > a,
|
||||
& > .active > a:hover,
|
||||
& > .active > a:focus {
|
||||
|
||||
@@ -109,16 +109,13 @@ module.exports = function(RED) {
|
||||
},
|
||||
remove(node) {
|
||||
const target = generateTarget(node);
|
||||
const tn = this.getTarget(target.name, target.flowId);
|
||||
if (tn) {
|
||||
const targs = this.getTargets(tn.name);
|
||||
const idx = getIndex(targs, tn.id);
|
||||
if (idx > -1) {
|
||||
targs.splice(idx, 1);
|
||||
}
|
||||
if (targs.length === 0) {
|
||||
delete registry.name[tn.name];
|
||||
}
|
||||
const targs = this.getTargets(target.name);
|
||||
const idx = getIndex(targs, target.id);
|
||||
if (idx > -1) {
|
||||
targs.splice(idx, 1);
|
||||
}
|
||||
if (targs.length === 0) {
|
||||
delete registry.name[tn.name];
|
||||
}
|
||||
delete registry.id[target.id];
|
||||
},
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
var should = require("should");
|
||||
var linkNode = require("nr-test-utils").require("@node-red/nodes/core/common/60-link.js");
|
||||
var helper = require("node-red-node-test-helper");
|
||||
var clone = require("clone");
|
||||
|
||||
describe('link Node', function() {
|
||||
|
||||
@@ -319,6 +320,48 @@ describe('link Node', function() {
|
||||
linkCall.receive({ payload: "hello", target: "double payload" });
|
||||
});
|
||||
})
|
||||
it('should not raise error after deploying a name change to a duplicate link-in node', async function () {
|
||||
this.timeout(400);
|
||||
const flow = [
|
||||
{ id: "tab-flow-1", type: "tab", label: "Flow 1" },
|
||||
{ id: "link-in-1", z: "tab-flow-1", type: "link in", name: "duplicate", wires: [["link-out-1"]] },
|
||||
{ id: "link-in-2", z: "tab-flow-1", type: "link in", name: "duplicate", wires: [["link-out-1"]] }, //duplicate name
|
||||
{ id: "link-out-1", z: "tab-flow-1", type: "link out", mode: "return" },
|
||||
{ id: "link-call", z: "tab-flow-1", type: "link call", linkType: "dynamic", links: [], wires: [["n4"]] },
|
||||
{ id: "n4", z: "tab-flow-1", type: "helper" }
|
||||
];
|
||||
|
||||
await helper.load(linkNode, flow)
|
||||
|
||||
const linkIn2before = helper.getNode("link-in-2");
|
||||
linkIn2before.should.have.property("name", "duplicate") // check link-in-2 has been deployed with the duplicate name
|
||||
|
||||
//modify the flow and deploy change
|
||||
const newConfig = clone(flow);
|
||||
newConfig[2].name = "add" // change nodes name
|
||||
await helper.setFlows(newConfig, "nodes") // deploy "nodes" only
|
||||
|
||||
const helperNode = helper.getNode("n4");
|
||||
const linkCall2 = helper.getNode("link-call");
|
||||
const linkIn2after = helper.getNode("link-in-2");
|
||||
linkIn2after.should.have.property("name", "add") // check link-in-2 no longer has a duplicate name
|
||||
|
||||
//poke { payload: "hello", target: "add" } into the link-call node and
|
||||
//ensure that a message arrives via the link-in node named "add"
|
||||
await new Promise((resolve, reject) => {
|
||||
helperNode.on("input", function (msg) {
|
||||
try {
|
||||
msg.should.have.property("target", "add");
|
||||
msg.should.not.have.property("error");
|
||||
resolve()
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
linkCall2.receive({ payload: "hello", target: "add" });
|
||||
});
|
||||
|
||||
})
|
||||
it('should allow nested link-call flows', function(done) {
|
||||
this.timeout(500);
|
||||
var flow = [/** Multiply by 2 link flow **/
|
||||
|
||||
Reference in New Issue
Block a user