diff --git a/CHANGELOG.md b/CHANGELOG.md index 52a257e13..460d2fc02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,33 @@ +#### 2.1.0-beta.2: Beta Release + +Editor + + - Fix switching projects (#3199) @knolleary + - Use locale setting when installing/enabling node (#3198) @knolleary + - Do not show projects-wecome dialog until welcome tour completes (#3197) @knolleary + - Fix converting selection to subflow (#3196) @knolleary + - Avoid conflicts with native browser cmd-ctrl type shortcuts (#3195) @knolleary + - Ensure message tools stay attached to top-level entry in Debug/Context (#3186) @knolleary + - Ensure tab state updates properly when toggling enable state (#3175) @knolleary + - Improve handling of long labels in TreeList (#3176) @knolleary + - Shift-click tab scroll arrows to jump to start/end (#3177) @knolleary + +Runtime + + - Update package dependencies + - Update to latest node-red-admin + +Nodes + + - Dynamic MQTT connections (#3189) + - Link: Filter out Link Out Return nodes in Link In edit dialog Fixes #3187 + - Link: Fix link call label (#3200) @knolleary + - Debug: Redesign debug filter options and make them persistant (#3183) @knolleary + - Inject: Widen Inject interval box for >1 digit (#3184) @knolleary + - Switch: Fix rule focus when switch 'otherwise' rule is used (#3185) @knolleary + + + #### 2.1.0-beta.1: Beta Release Editor @@ -46,7 +76,7 @@ Nodes - Switch: Copy previous rule type when adding rule to switch node (#3170) @knolleary - Delay node: add option to send intermediate messages on separate output (#3166) @knolleary - Typo in http request set method translation (#3173) @mailsvb - + #### 2.0.6: Maintenance Release Editor diff --git a/package.json b/package.json index aea1e7144..ad4ac26d3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node-red", - "version": "2.1.0-beta.1", + "version": "2.1.0-beta.2", "description": "Low-code programming for event-driven applications", "homepage": "http://nodered.org", "license": "Apache-2.0", @@ -50,7 +50,7 @@ "hash-sum": "2.0.0", "hpagent": "0.1.2", "https-proxy-agent": "5.0.0", - "i18next": "21.2.4", + "i18next": "21.3.1", "iconv-lite": "0.6.3", "is-utf8": "0.2.1", "js-yaml": "3.14.1", @@ -64,7 +64,7 @@ "mqtt": "4.2.8", "multer": "1.4.3", "mustache": "4.2.0", - "node-red-admin": "^2.2.0", + "node-red-admin": "^2.2.1", "nopt": "5.0.0", "oauth2orize": "1.11.0", "on-headers": "1.0.2", @@ -107,13 +107,13 @@ "i18next-http-backend": "1.3.1", "jquery-i18next": "1.2.1", "jsdoc-nr-template": "github:node-red/jsdoc-nr-template", - "marked": "3.0.4", + "marked": "3.0.7", "minami": "1.2.3", "mocha": "9.1.2", "node-red-node-test-helper": "^0.2.7", "nodemon": "2.0.13", "proxy": "^1.0.2", - "sass": "1.42.1", + "sass": "1.43.2", "should": "13.2.3", "sinon": "11.1.2", "stoppable": "^1.1.0", diff --git a/packages/node_modules/@node-red/editor-api/package.json b/packages/node_modules/@node-red/editor-api/package.json index 660dbf90f..5085b5624 100644 --- a/packages/node_modules/@node-red/editor-api/package.json +++ b/packages/node_modules/@node-red/editor-api/package.json @@ -1,6 +1,6 @@ { "name": "@node-red/editor-api", - "version": "2.1.0-beta.1", + "version": "2.1.0-beta.2", "license": "Apache-2.0", "main": "./lib/index.js", "repository": { @@ -16,8 +16,8 @@ } ], "dependencies": { - "@node-red/util": "2.1.0-beta.1", - "@node-red/editor-client": "2.1.0-beta.1", + "@node-red/util": "2.1.0-beta.2", + "@node-red/editor-client": "2.1.0-beta.2", "bcryptjs": "2.4.3", "body-parser": "1.19.0", "clone": "2.1.2", diff --git a/packages/node_modules/@node-red/editor-client/package.json b/packages/node_modules/@node-red/editor-client/package.json index 40d77064d..ad229c1c1 100644 --- a/packages/node_modules/@node-red/editor-client/package.json +++ b/packages/node_modules/@node-red/editor-client/package.json @@ -1,6 +1,6 @@ { "name": "@node-red/editor-client", - "version": "2.1.0-beta.1", + "version": "2.1.0-beta.2", "license": "Apache-2.0", "repository": { "type": "git", diff --git a/packages/node_modules/@node-red/editor-client/src/js/nodes.js b/packages/node_modules/@node-red/editor-client/src/js/nodes.js index f4378850f..76f544396 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/nodes.js +++ b/packages/node_modules/@node-red/editor-client/src/js/nodes.js @@ -266,8 +266,8 @@ RED.nodes = (function() { }, moveNode: function(n, newZ) { api.removeNode(n); - tabMap[newZ] = tabMap[newZ] || []; - tabMap[newZ].push(n); + n.z = newZ; + api.addNode(n) }, moveNodesForwards: function(nodes) { var result = []; @@ -719,29 +719,29 @@ RED.nodes = (function() { moveGroupToTab(node,z); return; } + var oldZ = node.z; allNodes.moveNode(node,z); var nl = nodeLinks[node.id]; if (nl) { nl.in.forEach(function(l) { - var idx = linkTabMap[node.z].indexOf(l); + var idx = linkTabMap[oldZ].indexOf(l); if (idx != -1) { - linkTabMap[node.z].splice(idx, 1); + linkTabMap[oldZ].splice(idx, 1); } if ((l.source.z === z) && linkTabMap[z]) { linkTabMap[z].push(l); } }); nl.out.forEach(function(l) { - var idx = linkTabMap[node.z].indexOf(l); + var idx = linkTabMap[oldZ].indexOf(l); if (idx != -1) { - linkTabMap[node.z].splice(idx, 1); + linkTabMap[oldZ].splice(idx, 1); } if ((l.target.z === z) && linkTabMap[z]) { linkTabMap[z].push(l); } }); } - node.z = z; RED.events.emit("nodes:change",node); } function moveGroupToTab(group, z) { @@ -2384,7 +2384,6 @@ RED.nodes = (function() { } function clear() { - allNodes.clear(); links = []; linkTabMap = {}; nodeLinks = {}; @@ -2405,6 +2404,8 @@ RED.nodes = (function() { initialLoad = null; workspaces = {}; + allNodes.clear(); + RED.nodes.dirty(false); RED.view.redraw(true, true); RED.palette.refresh(); diff --git a/packages/node_modules/@node-red/editor-client/src/js/red.js b/packages/node_modules/@node-red/editor-client/src/js/red.js index b2cc64dd9..11fd72837 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/red.js +++ b/packages/node_modules/@node-red/editor-client/src/js/red.js @@ -201,6 +201,7 @@ var RED = (function() { RED.projects.refresh(function(activeProject) { loadFlows(function() { RED.sidebar.info.refresh() + var showProjectWelcome = false; if (!activeProject) { // Projects enabled but no active project RED.menu.setDisabled('menu-item-projects-open',true); @@ -208,10 +209,10 @@ var RED = (function() { if (activeProject === false) { // User previously decline the migration to projects. } else { // null/undefined - RED.projects.showStartup(); + showProjectWelcome = true; } } - completeLoad(); + completeLoad(showProjectWelcome); }); }); } else { @@ -251,6 +252,9 @@ var RED = (function() { if (/^#flow\/.+$/.test(currentHash)) { RED.workspaces.show(currentHash.substring(6),true); } + if (RED.workspaces.active() === 0 && RED.workspaces.count() > 0) { + RED.workspaces.show(RED.nodes.getWorkspaceOrder()[0]) + } } catch(err) { console.warn(err); RED.notify( @@ -267,7 +271,7 @@ var RED = (function() { }); } - function completeLoad() { + function completeLoad(showProjectWelcome) { var persistentNotifications = {}; RED.comms.subscribe("notification/#",function(topic,msg) { var parts = topic.split("/"); @@ -477,8 +481,17 @@ var RED = (function() { RED.nodes.addNodeSet(m); addedTypes = addedTypes.concat(m.types); RED.i18n.loadNodeCatalog(id, function() { - $.get('nodes/'+id, function(data) { - appendNodeConfig(data); + var lang = localStorage.getItem("editor-language")||RED.i18n.detectLanguage(); + $.ajax({ + headers: { + "Accept":"text/html", + "Accept-Language": lang + }, + cache: false, + url: 'nodes/'+id, + success: function(data) { + appendNodeConfig(data); + } }); }); }); @@ -505,10 +518,19 @@ var RED = (function() { typeList = ""; RED.notify(RED._("palette.event.nodeEnabled", {count:msg.types.length})+typeList,"success"); } else { - $.get('nodes/'+msg.id, function(data) { - appendNodeConfig(data); - typeList = ""; - RED.notify(RED._("palette.event.nodeAdded", {count:msg.types.length})+typeList,"success"); + var lang = localStorage.getItem("editor-language")||RED.i18n.detectLanguage(); + $.ajax({ + headers: { + "Accept":"text/html", + "Accept-Language": lang + }, + cache: false, + url: 'nodes/'+msg.id, + success: function(data) { + appendNodeConfig(data); + typeList = ""; + RED.notify(RED._("palette.event.nodeAdded", {count:msg.types.length})+typeList,"success"); + } }); } } @@ -535,18 +557,24 @@ var RED = (function() { setTimeout(function() { loader.end(); - checkFirstRun(); + checkFirstRun(function() { + if (showProjectWelcome) { + RED.projects.showStartup(); + } + }); },100); } - function checkFirstRun() { + function checkFirstRun(done) { if (RED.settings.theme("tours") === false) { + done(); return; } if (!RED.settings.get("editor.view.view-show-welcome-tours", true)) { + done(); return; } - RED.actions.invoke("core:show-welcome-tour", RED.settings.get("editor.tours.welcome")); + RED.actions.invoke("core:show-welcome-tour", RED.settings.get("editor.tours.welcome"), done); } function buildMainMenu() { diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/common/popover.js b/packages/node_modules/@node-red/editor-client/src/js/ui/common/popover.js index 27a454dc6..762109774 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/common/popover.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/common/popover.js @@ -436,18 +436,17 @@ RED.popover = (function() { return { create: createPopover, tooltip: function(target,content, action) { - var label = content; - if (action) { - label = function() { - var label = content; + var label = function() { + var label = content; + if (action) { var shortcut = RED.keyboard.getShortcut(action); if (shortcut && shortcut.key) { label = $(''+content+' '+RED.keyboard.formatKey(shortcut.key, true)+''); } - return label; } + return label; } - return RED.popover.create({ + var popover = RED.popover.create({ tooltip: true, target:target, trigger: "hover", @@ -456,6 +455,14 @@ RED.popover = (function() { content: label, delay: { show: 750, hide: 50 } }); + popover.setContent = function(newContent) { + content = newContent; + } + popover.setAction = function(newAction) { + action = newAction; + } + return popover; + }, menu: function(options) { var list = $(''); diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/common/treeList.js b/packages/node_modules/@node-red/editor-client/src/js/ui/common/treeList.js index 9ee508de6..d4523f88f 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/common/treeList.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/common/treeList.js @@ -24,6 +24,9 @@ * - rootSortable: boolean - if 'sortable' is set, then setting this to * false, prevents items being sorted to the * top level of the tree + * - autoSelect: boolean - default true - triggers item selection when navigating + * list by keyboard. If the list has checkboxed items + * you probably want to set this to false * * methods: * - data(items) - clears existing items and replaces with new data @@ -50,6 +53,7 @@ * deferBuild: true/false, // don't build any ui elements for the item's children * until it is expanded by the user. * element: // custom dom element to use for the item - ignored if `label` is set + * collapsible: true/false, // prevent a parent item from being collapsed. default true. * } * ] * @@ -90,77 +94,99 @@ $.widget( "nodered.treeList", { _create: function() { var that = this; - + var autoSelect = true; + if (that.options.autoSelect === false) { + autoSelect = false; + } this.element.addClass('red-ui-treeList'); this.element.attr("tabIndex",0); var wrapper = $('
',{class:'red-ui-treeList-container'}).appendTo(this.element); this.element.on('keydown', function(evt) { - var selected = that._topList.find(".selected").parent().data('data'); - if (!selected && (evt.keyCode === 40 || evt.keyCode === 38)) { - that.select(that._data[0]); + var focussed = that._topList.find(".focus").parent().data('data'); + if (!focussed && (evt.keyCode === 40 || evt.keyCode === 38)) { + if (that._data[0]) { + if (autoSelect) { + that.select(that._data[0]); + } else { + that._topList.find(".focus").removeClass("focus") + } + that._data[0].treeList.label.addClass('focus') + } return; } var target; switch(evt.keyCode) { + case 32: // SPACE case 13: // ENTER + if (evt.altKey || evt.ctrlKey || evt.metaKey || evt.shiftKey) { + return + } evt.preventDefault(); evt.stopPropagation(); - if (selected.children) { - if (selected.treeList.container.hasClass("expanded")) { - selected.treeList.collapse() + if (focussed.checkbox) { + focussed.treeList.checkbox.trigger("click"); + } else if (focussed.radio) { + focussed.treeList.radio.trigger("click"); + } else if (focussed.children) { + if (focussed.treeList.container.hasClass("expanded")) { + focussed.treeList.collapse() } else { - selected.treeList.expand() + focussed.treeList.expand() } } else { - that._trigger("confirm",null,selected) + that._trigger("confirm",null,focussed) } - break; case 37: // LEFT evt.preventDefault(); evt.stopPropagation(); - if (selected.children&& selected.treeList.container.hasClass("expanded")) { - selected.treeList.collapse() - } else if (selected.parent) { - target = selected.parent; + if (focussed.children&& focussed.treeList.container.hasClass("expanded")) { + focussed.treeList.collapse() + } else if (focussed.parent) { + target = focussed.parent; } break; case 38: // UP evt.preventDefault(); evt.stopPropagation(); - target = that._getPreviousSibling(selected); + target = that._getPreviousSibling(focussed); if (target) { target = that._getLastDescendant(target); } - if (!target && selected.parent) { - target = selected.parent; + if (!target && focussed.parent) { + target = focussed.parent; } break; case 39: // RIGHT evt.preventDefault(); evt.stopPropagation(); - if (selected.children) { - if (!selected.treeList.container.hasClass("expanded")) { - selected.treeList.expand() + if (focussed.children) { + if (!focussed.treeList.container.hasClass("expanded")) { + focussed.treeList.expand() } } break case 40: //DOWN evt.preventDefault(); evt.stopPropagation(); - if (selected.children && Array.isArray(selected.children) && selected.children.length > 0 && selected.treeList.container.hasClass("expanded")) { - target = selected.children[0]; + if (focussed.children && Array.isArray(focussed.children) && focussed.children.length > 0 && focussed.treeList.container.hasClass("expanded")) { + target = focussed.children[0]; } else { - target = that._getNextSibling(selected); - while (!target && selected.parent) { - selected = selected.parent; - target = that._getNextSibling(selected); + target = that._getNextSibling(focussed); + while (!target && focussed.parent) { + focussed = focussed.parent; + target = that._getNextSibling(focussed); } } break } if (target) { - that.select(target); + if (autoSelect) { + that.select(target); + } else { + that._topList.find(".focus").removeClass("focus") + } + target.treeList.label.addClass('focus') } }); this._data = []; @@ -463,6 +489,9 @@ container.addClass("expanded"); } item.treeList.collapse = function() { + if (item.collapsible === false) { + return + } if (!item.children) { return; } @@ -583,7 +612,7 @@ // Already a parent because we've got the angle-right icon return; } - $('').appendTo(treeListIcon); + $('').toggleClass("hide",item.collapsible === false).appendTo(treeListIcon); treeListIcon.on("click.red-ui-treeList-expand", function(e) { e.stopPropagation(); e.preventDefault(); @@ -634,6 +663,8 @@ label.on("click", function(e) { e.stopPropagation(); cb.trigger("click"); + that._topList.find(".focus").removeClass("focus") + label.addClass('focus') }) } item.treeList.select = function(v) { @@ -641,6 +672,7 @@ cb.trigger("click"); } } + item.treeList.checkbox = cb; selectWrapper.appendTo(label) } else if (item.radio) { var selectWrapper = $(''); @@ -669,6 +701,8 @@ label.on("click", function(e) { e.stopPropagation(); cb.trigger("click"); + that._topList.find(".focus").removeClass("focus") + label.addClass('focus') }) } item.treeList.select = function(v) { @@ -677,6 +711,7 @@ } } selectWrapper.appendTo(label) + item.treeList.radio = cb; } else { label.on("click", function(e) { if (!that.options.multi) { @@ -684,10 +719,14 @@ } label.addClass("selected"); that._selected.add(item); + that._topList.find(".focus").removeClass("focus") + label.addClass('focus') that._trigger("select",e,item) }) label.on("dblclick", function(e) { + that._topList.find(".focus").removeClass("focus") + label.addClass('focus') if (!item.children) { that._trigger("confirm",e,item); } @@ -835,6 +874,9 @@ if (item.treeList.label) { item.treeList.label.addClass("selected"); } + + that._topList.find(".focus").removeClass("focus"); + if (triggerEvent !== false) { this._trigger("select",null,item) } @@ -842,6 +884,9 @@ clearSelection: function() { this._selected.forEach(function(item) { item.selected = false; + if (item.treeList.checkbox) { + item.treeList.checkbox.prop('checked',false) + } if (item.treeList.label) { item.treeList.label.removeClass("selected") } diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js b/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js index 1386a8ea5..ba7e48900 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js @@ -345,6 +345,47 @@ } } }; + + // For a type with options, check value is a valid selection + // If !opt.multiple, returns the valid option object + // if opt.multiple, returns an array of valid option objects + // If not valid, returns null; + + function isOptionValueValid(opt, currentVal) { + if (!opt.multiple) { + for (var i=0;i').appendTo(this.uiSelect); this.optionExpandButtonIcon = $('').appendTo(this.optionExpandButton); - // Used to remember selections per-type to restore them when switching between types - this.oldValues = {}; - this.type(this.options.default||this.typeList[0].value); }catch(err) { console.log(err.stack); @@ -859,22 +899,44 @@ return this.propertyType; } else { var that = this; + var previousValue = null; var opt = this.typeMap[type]; if (opt && this.propertyType !== type) { // If previousType is !null, then this is a change of the type, rather than the initialisation var previousType = this.typeMap[this.propertyType]; var typeChanged = !!previousType; + previousValue = this.input.val(); if (typeChanged) { if (previousType.options && opt.hasValue !== true) { - this.oldValues[previousType.value] = this.input.val(); + this.oldValues[previousType.value] = previousValue; } else if (previousType.hasValue === false) { - this.oldValues[previousType.value] = this.input.val(); + this.oldValues[previousType.value] = previousValue; } else { - this.oldValues["_"] = this.input.val(); + this.oldValues["_"] = previousValue; } if ((opt.options && opt.hasValue !== true) || opt.hasValue === false) { - this.input.val(this.oldValues.hasOwnProperty(opt.value)?this.oldValues[opt.value]:(opt.default||[]).join(",")) + if (this.oldValues.hasOwnProperty(opt.value)) { + this.input.val(this.oldValues[opt.value]); + } else { + // No old value for the option type. + // It is possible code has called 'value' then 'type' + // to set the selected option. This is what the Inject/Switch/Change + // nodes did before 2.1. + // So we need to be careful to not reset the value if it is a valid option. + var validOptions = isOptionValueValid(opt,previousValue); + if (previousValue && validOptions) { + this.input.val(previousValue); + } else { + if (typeof opt.default === "string") { + this.input.val(opt.default); + } else if (Array.isArray(opt.default)) { + this.input.val(opt.default.join(",")) + } else { + this.input.val(""); + } + } + } } else { this.input.val(this.oldValues.hasOwnProperty("_")?this.oldValues["_"]:(opt.default||"")) } @@ -951,22 +1013,12 @@ var op; if (!opt.hasValue) { - var validValue = false; - var currentVal = this.input.val(); + // Check the value is valid for the available options + var validValues = isOptionValueValid(opt,this.input.val()); if (!opt.multiple) { - for (var i=0;iLink Callノードを用いることで、Link Inノードから始まるフローを呼び出し、Link Outノードに到達した時に、結果を取得できます。

" } }, + { + title: { + "en-US": "MQTT nodes support dynamic connections", + "ja": "MQTTノードが動的接続をサポート" + }, + prepare(done) { + $('[data-palette-type="mqtt out"]')[0].scrollIntoView({block:"center"}) + setTimeout(done,100); + }, + element: '[data-palette-type="mqtt out"]', + direction: "right", + description: { + "en-US": '

The MQTT nodes now support creating their connections and subscriptions dynamically.

', + "ja": '

MQTTノードは、動的な接続や購読ができるようになりました。

' + }, + }, { title: { "en-US": "File nodes renamed", @@ -163,6 +181,11 @@ export default { $('[data-palette-type="file"]')[0].scrollIntoView({block:"center"}); setTimeout(done,100); }, + complete() { + if (this.paletteWasClosed) { + RED.actions.invoke("core:toggle-palette",false) + } + }, element: '[data-palette-type="file"]', direction: "right", description: { diff --git a/packages/node_modules/@node-red/nodes/core/common/20-inject.html b/packages/node_modules/@node-red/nodes/core/common/20-inject.html index 7bcb3111f..bd17e1635 100644 --- a/packages/node_modules/@node-red/nodes/core/common/20-inject.html +++ b/packages/node_modules/@node-red/nodes/core/common/20-inject.html @@ -143,7 +143,8 @@ margin-bottom: 8px; } .inject-time-count { - width: 40px !important; + padding-left: 3px !important; + width: 80px !important; } @@ -538,12 +539,10 @@ var propertyValue = $('',{class:"node-input-prop-property-value",type:"text"}) .css("width","calc(70% - 30px)") .appendTo(row) - .typedInput({default:'str',types:['flow','global','str','num','bool','json','bin','date','jsonata','env','msg']}); + .typedInput({default:prop.vt,types:['flow','global','str','num','bool','json','bin','date','jsonata','env','msg']}); propertyName.typedInput('value',prop.p); - propertyValue.typedInput('value',prop.v); - propertyValue.typedInput('type',prop.vt); }, removable: true, sortable: true diff --git a/packages/node_modules/@node-red/nodes/core/common/21-debug.html b/packages/node_modules/@node-red/nodes/core/common/21-debug.html index 886ed68fa..195423482 100644 --- a/packages/node_modules/@node-red/nodes/core/common/21-debug.html +++ b/packages/node_modules/@node-red/nodes/core/common/21-debug.html @@ -292,6 +292,7 @@ }; RED.events.on("project:change", this.clearMessageList); RED.actions.add("core:clear-debug-messages", function() { RED.debug.clearMessageList(true) }); + RED.actions.add("core:clear-filtered-debug-messages", function() { RED.debug.clearMessageList(true, true) }); RED.actions.add("core:activate-selected-debug-nodes", function() { setDebugNodeState(getSelectedDebugNodes(true), true); }); RED.actions.add("core:activate-all-debug-nodes", function() { setDebugNodeState(getMatchingDebugNodes(true, true),true); }); diff --git a/packages/node_modules/@node-red/nodes/core/common/60-link.html b/packages/node_modules/@node-red/nodes/core/common/60-link.html index 05fa8b429..f3fabba59 100644 --- a/packages/node_modules/@node-red/nodes/core/common/60-link.html +++ b/packages/node_modules/@node-red/nodes/core/common/60-link.html @@ -52,7 +52,7 @@ treeList = $("
") .css({width: "100%", height: "100%"}) .appendTo(".node-input-link-row") - .treeList({}) + .treeList({autoSelect:false}) .on('treelistitemmouseover',function(e,item) { if (item.node) { item.node.highlighted = true; @@ -68,6 +68,8 @@ } }); var candidateNodes = RED.nodes.filterNodes({type:targetType}); + var candidateNodesCount = 0; + var search = $("#node-input-link-target-filter").searchBox({ style: "compact", delay: 300, @@ -80,7 +82,7 @@ var count = treeList.treeList("filter", function(item) { return item.label.toLowerCase().indexOf(val) > -1 || (item.node && item.node.type.toLowerCase().indexOf(val) > -1) }); - search.searchBox("count",count+" / "+candidateNodes.length); + search.searchBox("count",count+" / "+candidateNodesCount); } } }); @@ -113,6 +115,11 @@ candidateNodes.forEach(function(n) { if (flowMap[n.z]) { + if (targetType === "link out" && n.mode === 'return') { + // Link In nodes looking for Link Out nodes should not + // include return-mode nodes. + return + } var isChecked = false; isChecked = (node.links.indexOf(n.id) !== -1) || (n.links||[]).indexOf(node.id) !== -1; if (isChecked) { @@ -126,6 +133,7 @@ checkbox: node.type !== "link call", radio: node.type === "link call" }) + candidateNodesCount++; } }); flows = flows.filter(function(f) { return f.children.length > 0 }) @@ -149,7 +157,7 @@ function onEditSave(node) { var flows = treeList.treeList('data'); node.links = []; - if (node.type !== "link out" || $("node-input-mode").val() === 'link') { + if (node.type !== "link out" || $("#node-input-mode").val() === 'link') { flows.forEach(function(f) { f.children.forEach(function(n) { if (n.selected) { @@ -234,6 +242,12 @@ }, oneditsave: function() { onEditSave(this); + // In case the name has changed, ensure any link call nodes on this + // tab are redrawn with the updated name + var localCallNodes = RED.nodes.filterNodes({z:RED.workspaces.active(), type:"link call"}); + localCallNodes.forEach(function(node) { + node.dirty = true; + }); }, onadd: onAdd, oneditresize: resizeNodeList @@ -259,12 +273,12 @@ } if (this.links.length > 0) { var targetNode = RED.nodes.node(this.links[0]); - return targetNode && (targetNode.name || targetNode.id); + return targetNode && (targetNode.name || this._("link.linkCall")); } - return this._("link.linkCall"); + return this._("inject.none"); }, labelStyle: function() { - return (this.name || this.links.length > 0)?"node_label_italic":""; + return this.name?"node_label_italic":""; }, oneditprepare: function() { onEditPrepare(this,"link in"); @@ -275,7 +289,6 @@ oneditresize: resizeNodeList }); - RED.nodes.registerType('link out',{ category: 'common', color:"#ddd",//"#87D8CF", diff --git a/packages/node_modules/@node-red/nodes/core/common/lib/debug/debug-utils.js b/packages/node_modules/@node-red/nodes/core/common/lib/debug/debug-utils.js index a865f9387..746a23d17 100644 --- a/packages/node_modules/@node-red/nodes/core/common/lib/debug/debug-utils.js +++ b/packages/node_modules/@node-red/nodes/core/common/lib/debug/debug-utils.js @@ -31,24 +31,22 @@ RED.debug = (function() { var activeWorkspace; var numMessages = 100; // Hardcoded number of message to show in debug window scrollback - var filterVisible = false; - - var debugNodeList; - var debugNodeListExpandedFlows = {}; + var debugNodeTreeList; function init(_config) { config = _config; var content = $("
").css({"position":"relative","height":"100%"}); var toolbar = $('
'+ - ' '+ - '
').appendTo(content); + ''+ + ' '+ + ''+ + ''+ + ' all' + + ''+ + '
').appendTo(content); var footerToolbar = $('
'+ - // ''+ - // 'list'+ - // 'table '+ - // ''+ ' ' + '
'); @@ -56,85 +54,100 @@ RED.debug = (function() { sbc = messageList[0]; messageTable = $('
').appendTo(content); - var filterDialog = $('
'+ - '
'+ - ''+ - ''+ - ''+ - ' '+ + var filterDialogCloseTimeout; + var filterDialogShown = false; + var filterDialog = $('
').appendTo(toolbar);//content); + filterDialog.on('mouseleave' ,function(evt) { + if (filterDialogShown) { + filterDialogCloseTimeout = setTimeout(function() { + filterDialog.slideUp(200); + filterDialogShown = false; + },500) + } + }) + filterDialog.on('mouseenter' ,function(evt) { + clearTimeout(filterDialogCloseTimeout) + }) + var filterToolbar = $('
'+ + ''+ + '' + + '' + ''+ - '
'+ - '
').appendTo(toolbar);//content); + ''+ + '
').appendTo(filterDialog); - // var filterTypeRow = $('
').appendTo(filterDialog); - // $('').appendTo(filterTypeRow); + filterToolbar.find("#red-ui-sidebar-filter-select-close").on('click', function(evt) { + clearTimeout(filterDialogCloseTimeout) + filterDialogShown = false; + filterDialog.slideUp(200); + }) - var debugNodeListRow = $('
').appendTo(filterDialog); - var flowCheckboxes = {}; - var debugNodeListHeader = $('
'); - var headerCheckbox = $('').appendTo(debugNodeListHeader.find("span")[1]).checkboxSet(); - - debugNodeList = $('
    ',{style:"text-align: left; min-height: 250px; max-height: 250px"}).appendTo(debugNodeListRow).editableList({ - header: debugNodeListHeader, - class: 'red-ui-nodeList', - addItem: function(container,i,node) { - var row = $("
    ").appendTo(container); - row.attr('id','debug-filter-node-list-node-'+node.id.replace(/\./g,"_")); - if (node.type === 'tab') { - container.parent().addClass('red-ui-editableList-section-header'); - if (!debugNodeListExpandedFlows.hasOwnProperty(node.id)) { - debugNodeListExpandedFlows[node.id] = true; + filterToolbar.find("#red-ui-sidebar-filter-select-all").on('click', function(evt) { + evt.preventDefault(); + var data = debugNodeTreeList.treeList('data'); + data.forEach(function(flow) { + if (!flow.selected) { + if (flow.treeList.checkbox) { + flow.treeList.checkbox.trigger('click') } - var chevron = $('').appendTo(row); - $('').text(RED.utils.getNodeLabel(node,node.id)).appendTo(row); - var muteControl = $('').appendTo($('').appendTo(row)); - muteControl.checkboxSet({ - parent: headerCheckbox - }); - flowCheckboxes[node.id] = muteControl; - row.on("click", function(e) { - e.stopPropagation(); - debugNodeListExpandedFlows[node.id] = !debugNodeListExpandedFlows[node.id]; - row.toggleClass('expanded',debugNodeListExpandedFlows[node.id]); - debugNodeList.editableList('filter'); - }) - row.addClass("expandable"); - if (node.disabled) { - container.addClass('disabled'); - muteControl.checkboxSet('disable'); - debugNodeListExpandedFlows[node.id] = false; - } - row.toggleClass('expanded',debugNodeListExpandedFlows[node.id]); } else { - $('',{style: "margin-left: 20px"}).text(RED.utils.getNodeLabel(node,node.id)).appendTo(row); - row.on("mouseenter",function() { - config.messageMouseEnter(node.id); - }); - row.on("mouseleave",function() { - config.messageMouseLeave(node.id); - }); - var muteControl = $('').prop('checked',!filteredNodes[node.id]).appendTo($('').appendTo(row)); - muteControl.checkboxSet({ - parent: flowCheckboxes[node.z] - }).on("change", function(e) { - filteredNodes[node.id] = !$(this).prop('checked'); - $(".red-ui-debug-msg-node-"+node.id.replace(/\./g,"_")).toggleClass('hide',filteredNodes[node.id]); - }); - if ((node.hasOwnProperty("active") && !node.active) || RED.nodes.workspace(node.z).disabled) { - container.addClass('disabled'); - muteControl.checkboxSet('disable'); + flow.children.forEach(function(item) { + if (!item.selected) { + item.treeList.select(); + } + }) + } + }); + refreshMessageList(); + }) + + filterToolbar.find("#red-ui-sidebar-filter-select-none").on('click', function(evt) { + evt.preventDefault(); + debugNodeTreeList.treeList('clearSelection'); + var data = debugNodeTreeList.treeList('data'); + data.forEach(function(flow) { + if (flow.children) { + flow.children.forEach(function(item) { + filteredNodes[item.node.id] = true; + }) + } + }); + RED.settings.set('debug.filteredNodes',Object.keys(filteredNodes)) + refreshMessageList(); + }) + var debugNodeListRow = $('
    ').appendTo(filterDialog); + debugNodeTreeList = $("
    ").appendTo(debugNodeListRow).css({width: "100%", height: "300px"}) + .treeList({autoSelect: false}).on("treelistitemmouseover", function(e, item) { + if (item.node) { + item.node.highlighted = true; + item.node.dirty = true; + RED.view.redraw(); + } + }).on("treelistitemmouseout", function(e, item) { + if (item.node) { + item.node.highlighted = false; + item.node.dirty = true; + RED.view.redraw(); + } + }).on("treelistselect", function(e, item) { + if (item.children) { + item.children.forEach(function(child) { + if (child.checkbox) { + child.treeList.select(item.selected) + } + }) + } else { + if (item.node) { + if (item.selected) { + delete filteredNodes[item.node.id] + } else { + filteredNodes[item.node.id] = true; + } + RED.settings.set('debug.filteredNodes',Object.keys(filteredNodes)) + refreshMessageList(); } } - }, - addButton: false, - scrollOnAdd: false, - filter: function(node) { - return (node.type === 'tab' || debugNodeListExpandedFlows[node.z] ) - }, - sort: function(A,B) { - - } - }); + }) try { content.i18n(); @@ -144,85 +157,95 @@ RED.debug = (function() { toolbar.find('#red-ui-sidebar-debug-filter span').text(RED._('node-red:debug.sidebar.filterAll')); - var filterButtonHandler = function(type) { - return function(e) { - e.preventDefault(); - if (filterType !== type) { - $('.red-ui-sidebar-debug-filter-option').removeClass('selected'); - $(this).addClass('selected'); - if (filterType === 'filterSelected') { - debugNodeListRow.slideUp(); - } - filterType = type; - if (filterType === 'filterSelected') { - debugNodeListRow.slideDown(); - } - - $('#red-ui-sidebar-debug-filter span').text(RED._('node-red:debug.sidebar.'+filterType)); - refreshMessageList(); - } - } - } - filterDialog.find('#red-ui-sidebar-debug-filterAll').on("click",filterButtonHandler('filterAll')); - filterDialog.find('#red-ui-sidebar-debug-filterSelected').on("click",filterButtonHandler('filterSelected')); - filterDialog.find('#red-ui-sidebar-debug-filterCurrent').on("click",filterButtonHandler('filterCurrent')); - - - // $('#red-ui-sidebar-debug-view-list').on("click",function(e) { - // e.preventDefault(); - // if (!$(this).hasClass('selected')) { - // $(this).addClass('selected'); - // $('#red-ui-sidebar-debug-view-table').removeClass('selected'); - // showMessageList(); - // } - // }); - // $('#red-ui-sidebar-debug-view-table').on("click",function(e) { - // e.preventDefault(); - // if (!$(this).hasClass('selected')) { - // $(this).addClass('selected'); - // $('#red-ui-sidebar-debug-view-list').removeClass('selected'); - // showMessageTable(); - // } - // }); - - - var hideFilterTimeout; - toolbar.on('mouseleave',function() { - if ($('#red-ui-sidebar-debug-filter').hasClass('selected')) { - clearTimeout(hideFilterTimeout); - hideFilterTimeout = setTimeout(function() { - filterVisible = false; - $('#red-ui-sidebar-debug-filter').removeClass('selected'); - filterDialog.slideUp(200); - },300); - } - }); - toolbar.on('mouseenter',function() { - if ($('#red-ui-sidebar-debug-filter').hasClass('selected')) { - clearTimeout(hideFilterTimeout); - } - }) toolbar.find('#red-ui-sidebar-debug-filter').on("click",function(e) { e.preventDefault(); - if ($(this).hasClass('selected')) { - filterVisible = false; - $(this).removeClass('selected'); - clearTimeout(hideFilterTimeout); - filterDialog.slideUp(200); - } else { - $(this).addClass('selected'); - filterVisible = true; - refreshDebugNodeList(); - filterDialog.slideDown(200); - } + var options = [ + { label: $(' ').i18n() , value: "filterAll" }, + { label: $(' ...').i18n(), value: "filterSelected" }, + { label: $(' ').i18n(), value: "filterCurrent" } + ] + var menu = RED.popover.menu({ + options: options, + onselect: function(item) { + if (item.value !== filterType) { + filterType = item.value; + $('#red-ui-sidebar-debug-filter span').text(RED._('node-red:debug.sidebar.'+filterType)); + refreshMessageList(); + RED.settings.set("debug.filter",filterType) + } + if (filterType === 'filterSelected') { + refreshDebugNodeList(); + filterDialog.slideDown(200); + filterDialogShown = true; + debugNodeTreeList.focus(); + } + + } + }); + menu.show({ + target: $("#red-ui-sidebar-debug-filter"), + align: "left", + offset: [$("#red-ui-sidebar-debug-filter").outerWidth()-2, -1] + }) + $('input[name="filter-type"][value="'+RED.settings.get("debug.filter","filterAll")+'"]').prop("checked", true) }); RED.popover.tooltip(toolbar.find('#red-ui-sidebar-debug-filter'),RED._('node-red:debug.sidebar.filterLog')); toolbar.find("#red-ui-sidebar-debug-clear").on("click", function(e) { e.preventDefault(); - clearMessageList(false); + var action = RED.settings.get("debug.clearType","all") + clearMessageList(false, action === 'filtered'); }); - RED.popover.tooltip(toolbar.find("#red-ui-sidebar-debug-clear"),RED._('node-red:debug.sidebar.clearLog'),"core:clear-debug-messages"); + var clearTooltip = RED.popover.tooltip(toolbar.find("#red-ui-sidebar-debug-clear"),RED._('node-red:debug.sidebar.clearLog'),"core:clear-debug-messages"); + toolbar.find("#red-ui-sidebar-debug-clear-opts").on("click", function(e) { + e.preventDefault(); + var options = [ + { label: $(' ').i18n() , value: "all" }, + { label: $(' ').i18n(), value: "filtered" } + ] + var menu = RED.popover.menu({ + options: options, + onselect: function(item) { + if (item.value === "all") { + $("#red-ui-sidebar-debug-clear > span").text(RED._('node-red:debug.sidebar.all')); + clearTooltip.setAction("core:clear-debug-messages"); + clearTooltip.setContent(RED._('node-red:debug.sidebar.clearLog')) + RED.settings.set("debug.clearType","all") + } else { + $("#red-ui-sidebar-debug-clear > span").text(RED._('node-red:debug.sidebar.filtered')); + clearTooltip.setAction("core:clear-filtered-debug-messages"); + clearTooltip.setContent(RED._('node-red:debug.sidebar.clearFilteredLog')) + RED.settings.set("debug.clearType","filtered") + } + } + }); + menu.show({ + target: $("#red-ui-sidebar-debug-clear-opts"), + align: "left", + offset: [$("#red-ui-sidebar-debug-clear-opts").outerWidth()-2, -1] + }) + $('input[name="clear-type"][value="'+RED.settings.get("debug.clearType","all")+'"]').prop("checked", true) + }) + + var clearType = RED.settings.get("debug.clearType","all"); + if (clearType === "all") { + toolbar.find("#red-ui-sidebar-debug-clear > span").text(RED._('node-red:debug.sidebar.all')); + clearTooltip.setAction("core:clear-debug-messages"); + clearTooltip.setContent(RED._('node-red:debug.sidebar.clearLog')) + } else { + toolbar.find("#red-ui-sidebar-debug-clear > span").text(RED._('node-red:debug.sidebar.filtered')); + clearTooltip.setAction("core:clear-filtered-debug-messages"); + clearTooltip.setContent(RED._('node-red:debug.sidebar.clearFilteredLog')) + } + + filterType = RED.settings.get("debug.filter","filterAll") + var filteredNodeList = RED.settings.get("debug.filteredNodes",[]); + filteredNodes = {} + filteredNodeList.forEach(function(id) { + filteredNodes[id] = true + }) + toolbar.find('#red-ui-sidebar-debug-filter span').text(RED._('node-red:debug.sidebar.'+filterType)); + refreshMessageList(); return { content: content, @@ -254,8 +277,6 @@ RED.debug = (function() { function refreshDebugNodeList() { - debugNodeList.editableList('empty'); - var workspaceOrder = RED.nodes.getWorkspaceOrder(); var workspaceOrderMap = {}; workspaceOrder.forEach(function(ws,i) { @@ -320,15 +341,45 @@ RED.debug = (function() { return labelA.localeCompare(labelB); }); var currentWs = null; - var nodeList = []; + var data = []; + var currentFlow; + var currentSelectedCount = 0; candidateNodes.forEach(function(node) { if (currentWs !== node.z) { + if (currentFlow && currentFlow.checkbox) { + currentFlow.selected = currentSelectedCount === currentFlow.children.length + } + currentSelectedCount = 0; currentWs = node.z; - nodeList.push(RED.nodes.workspace(node.z)); + var parent = RED.nodes.workspace(currentWs) || RED.nodes.subflow(currentWs); + currentFlow = { + label: RED.utils.getNodeLabel(parent, currentWs), + } + if (!parent.disabled) { + currentFlow.children = []; + currentFlow.checkbox = true; + } else { + currentFlow.class = "disabled" + } + data.push(currentFlow); + } + if (currentFlow.children) { + if (!filteredNodes[node.id]) { + currentSelectedCount++; + } + currentFlow.children.push({ + label: RED.utils.getNodeLabel(node,node.id), + node: node, + checkbox: true, + selected: !filteredNodes[node.id] + }); } - nodeList.push(node); }); - debugNodeList.editableList('addItems',nodeList); + if (currentFlow && currentFlow.checkbox) { + currentFlow.selected = currentSelectedCount === currentFlow.children.length + } + + debugNodeTreeList.treeList("data", data); } function getTimestamp() { @@ -340,7 +391,16 @@ RED.debug = (function() { return m.replace(/&/g,"&").replace(//g,">"); } + var refreshTimeout; function refreshMessageList(_activeWorkspace) { + if (refreshTimeout) { + clearTimeout(refreshTimeout); + } + refreshTimeout = setTimeout(function() { + _refreshMessageList(_activeWorkspace); + },200); + } + function _refreshMessageList(_activeWorkspace) { if (_activeWorkspace) { activeWorkspace = _activeWorkspace.replace(/\./g,"_"); } @@ -415,6 +475,7 @@ RED.debug = (function() { }); delete filteredNodes[sourceId]; $("#red-ui-sidebar-debug-filterSelected").trigger("click"); + RED.settings.set('debug.filteredNodes',Object.keys(filteredNodes)) refreshMessageList(); }}, {id:"red-ui-debug-msg-menu-item-clear-filter",label:RED._("node-red:debug.messageMenu.clearFilter"),onselect:function(){ @@ -601,8 +662,12 @@ RED.debug = (function() { } } - function clearMessageList(clearFilter) { - $(".red-ui-debug-msg").remove(); + function clearMessageList(clearFilter, filteredOnly) { + if (!filteredOnly) { + $(".red-ui-debug-msg").remove(); + } else { + $(".red-ui-debug-msg:not(.hide)").remove(); + } config.clear(); if (!!clearFilter) { clearFilterSettings(); @@ -613,10 +678,9 @@ RED.debug = (function() { function clearFilterSettings() { filteredNodes = {}; filterType = 'filterAll'; - $('.red-ui-sidebar-debug-filter-option').removeClass('selected'); - $('#red-ui-sidebar-debug-filterAll').addClass('selected'); + RED.settings.set("debug.filter",filterType); + RED.settings.set('debug.filteredNodes',Object.keys(filteredNodes)) $('#red-ui-sidebar-debug-filter span').text(RED._('node-red:debug.sidebar.filterAll')); - $('#red-ui-sidebar-debug-filter-node-list-row').slideUp(); } return { diff --git a/packages/node_modules/@node-red/nodes/core/common/lib/debug/debug.js b/packages/node_modules/@node-red/nodes/core/common/lib/debug/debug.js index 9ccdee099..792d9895a 100644 --- a/packages/node_modules/@node-red/nodes/core/common/lib/debug/debug.js +++ b/packages/node_modules/@node-red/nodes/core/common/lib/debug/debug.js @@ -15,18 +15,22 @@ $(function() { } } - var uiComponents = RED.debug.init(options); + try { + var uiComponents = RED.debug.init(options); + $(".red-ui-debug-window").append(uiComponents.content); - $(".red-ui-debug-window").append(uiComponents.content); + window.addEventListener('message',function(evt) { + if (evt.data.event === "message") { + RED.debug.handleDebugMessage(evt.data.msg); + } else if (evt.data.event === "workspaceChange") { + RED.debug.refreshMessageList(evt.data.activeWorkspace); + } else if (evt.data.event === "projectChange") { + RED.debug.clearMessageList(true); + } + },false); + } catch(err) { + console.error(err) + } - window.addEventListener('message',function(evt) { - if (evt.data.event === "message") { - RED.debug.handleDebugMessage(evt.data.msg); - } else if (evt.data.event === "workspaceChange") { - RED.debug.refreshMessageList(evt.data.activeWorkspace); - } else if (evt.data.event === "projectChange") { - RED.debug.clearMessageList(true); - } - },false); }) }); diff --git a/packages/node_modules/@node-red/nodes/core/function/10-switch.html b/packages/node_modules/@node-red/nodes/core/function/10-switch.html index 54ca33e0f..f6fc82f0a 100644 --- a/packages/node_modules/@node-red/nodes/core/function/10-switch.html +++ b/packages/node_modules/@node-red/nodes/core/function/10-switch.html @@ -117,30 +117,35 @@ return r; } - function createValueField(row){ - return $('',{class:"node-input-rule-value",type:"text",style:"width: 100%;"}).appendTo(row).typedInput({default:'str',types:['msg','flow','global','str','num','jsonata','env',previousValueType]}); + function createValueField(row, defaultType){ + return $('',{class:"node-input-rule-value",type:"text",style:"width: 100%;"}).appendTo(row) + .typedInput({default:defaultType||'str',types:['msg','flow','global','str','num','jsonata','env',previousValueType]}); } - function createNumValueField(row){ - return $('',{class:"node-input-rule-num-value",type:"text",style:"width: 100%;"}).appendTo(row).typedInput({default:'num',types:['flow','global','num','jsonata','env']}); + function createNumValueField(row, defaultType){ + return $('',{class:"node-input-rule-num-value",type:"text",style:"width: 100%;"}).appendTo(row) + .typedInput({default:defaultType||'num',types:['flow','global','num','jsonata','env']}); } function createExpValueField(row){ - return $('',{class:"node-input-rule-exp-value",type:"text",style:"width: 100%;"}).appendTo(row).typedInput({default:'jsonata',types:['jsonata']}); + return $('',{class:"node-input-rule-exp-value",type:"text",style:"width: 100%;"}).appendTo(row) + .typedInput({default:'jsonata',types:['jsonata']}); } - function createBtwnValueField(row){ - return $('',{class:"node-input-rule-btwn-value",type:"text",style:"width: 100%;"}).appendTo(row).typedInput({default:'num',types:['msg','flow','global','str','num','jsonata','env',previousValueType]}); + function createBtwnValueField(row, defaultType){ + return $('',{class:"node-input-rule-btwn-value",type:"text",style:"width: 100%;"}).appendTo(row) + .typedInput({default:defaultType||'num',types:['msg','flow','global','str','num','jsonata','env',previousValueType]}); } - function createBtwnValue2Field(row3, andLabel){ + function createBtwnValue2Field(row3, andLabel, defaultType){ $('
    ',{class:"node-input-rule-btwn-label", style:"width: 120px; text-align: right;"}).text(" "+andLabel+" ").appendTo(row3); var row3InputCell = $('
    ',{style:"flex-grow:1; margin-left: 5px;"}).appendTo(row3); - return $('',{class:"node-input-rule-btwn-value2",type:"text",style:"width: 100%"}).appendTo(row3InputCell).typedInput({default:'num',types:['msg','flow','global','str','num','jsonata','env',previousValueType]}); + return $('',{class:"node-input-rule-btwn-value2",type:"text",style:"width: 100%"}).appendTo(row3InputCell) + .typedInput({default:defaultType||'num',types:['msg','flow','global','str','num','jsonata','env',previousValueType]}); } - function createTypeValueField(){ - return $('',{class:"node-input-rule-type-value",type:"text",style:"width: 100%;"}).appendTo(row).typedInput({default:'string',types:[ + function createTypeValueField(row, defaultType){ + return $('',{class:"node-input-rule-type-value",type:"text",style:"width: 100%;"}).appendTo(row).typedInput({default:defaultType || 'string',types:[ {value:"string",label:RED._("common.type.string"),hasValue:false,icon:"red/images/typedInput/az.png"}, {value:"number",label:RED._("common.type.number"),hasValue:false,icon:"red/images/typedInput/09.png"}, {value:"boolean",label:RED._("common.type.boolean"),hasValue:false,icon:"red/images/typedInput/bool.png"}, @@ -211,6 +216,7 @@ var lastRule = $("#node-input-rule-container").editableList('getItemAt',i-1); var exportedRule = exportRule(lastRule.element); opt.r.vt = exportedRule.vt; + opt.r.v = ""; // We could copy the value over as well and preselect it (see the 'activeElement' code below) // But not sure that feels right. Is copying over the last value 'expected' behaviour? // It would make sense for an explicit 'copy' action, but not sure where the copy button would @@ -278,24 +284,12 @@ selectField.on("change", function() { var fieldToFocus; var type = selectField.val(); - if (valueField){ - valueField.typedInput('hide'); - } - if (expValueField){ - expValueField.typedInput('hide'); - } - if (numValueField){ - numValueField.typedInput('hide'); - } - if (typeValueField){ - typeValueField.typedInput('hide'); - } - if (btwnValueField){ - btwnValueField.typedInput('hide'); - } - if (btwnValue2Field){ - btwnValue2Field.typedInput('hide'); - } + if (valueField) { valueField.typedInput('hide'); } + if (expValueField) { expValueField.typedInput('hide'); } + if (numValueField) { numValueField.typedInput('hide'); } + if (typeValueField) { typeValueField.typedInput('hide'); } + if (btwnValueField) { btwnValueField.typedInput('hide'); } + if (btwnValue2Field) { btwnValue2Field.typedInput('hide'); } if ((type === "btwn") || (type === "index")) { if (!btwnValueField){ @@ -318,7 +312,7 @@ } else if (type === "istype") { if (!typeValueField){ - typeValueField = createTypeValueField(); + typeValueField = createTypeValueField(rowInputCell); } typeValueField.typedInput('show'); fieldToFocus = typeValueField; @@ -351,7 +345,9 @@ } else { selectField.width("auto") } - fieldToFocus.typedInput("focus"); + if (fieldToFocus) { + fieldToFocus.typedInput("focus"); + } // Preselect the contents of the element // if (focusValueField && document.activeElement) { // document.activeElement.selectionStart = 0; @@ -359,48 +355,26 @@ // } }); selectField.val(rule.t); - if ((rule.t == "btwn") || (rule.t == "index")) { - if (!btwnValueField){ - btwnValueField = createBtwnValueField(rowInputCell); - } - btwnValueField.typedInput('value',rule.v); - btwnValueField.typedInput('type',rule.vt||'num'); - if (!btwnValue2Field){ - btwnValue2Field = createBtwnValue2Field(row3, andLabel); - } + if ((rule.t == "btwn") || (rule.t == "index")) { + btwnValueField = createBtwnValueField(rowInputCell,rule.vt||'num'); + btwnValueField.typedInput('value',rule.v); + btwnValue2Field = createBtwnValue2Field(row3, andLabel,rule.v2t||'num'); btwnValue2Field.typedInput('value',rule.v2); - btwnValue2Field.typedInput('type',rule.v2t||'num'); } else if ((rule.t === "head") || (rule.t === "tail")) { - if (!numValueField){ - numValueField = createNumValueField(row); - } + numValueField = createNumValueField(rowInputCell,rule.vt||'num'); numValueField.typedInput('value',rule.v); - numValueField.typedInput('type',rule.vt||'num'); } else if (rule.t === "istype") { - if (!typeValueField){ - typeValueField =createTypeValueField(); - } + typeValueField = createTypeValueField(rowInputCell,rule.vt); typeValueField.typedInput('value',rule.vt); - typeValueField.typedInput('type',rule.vt); } else if (rule.t === "jsonata_exp") { - if (!expValueField){ - expValueField = createExpValueField(row); - } + expValueField = createExpValueField(rowInputCell,rule.vt||'jsonata'); expValueField.typedInput('value',rule.v); - expValueField.typedInput('type',rule.vt||'jsonata'); } else if (typeof rule.v != "undefined") { - if (!valueField){ - valueField = createValueField(rowInputCell); - } + valueField = createValueField(rowInputCell,rule.vt||'str'); valueField.typedInput('value',rule.v); - valueField.typedInput('type',rule.vt||'str'); - } - if (rule.case) { - caseSensitive.prop('checked',true); - } else { - caseSensitive.prop('checked',false); } + caseSensitive.prop('checked',!!rule.case); selectField.change(); var currentOutputs = JSON.parse(outputCount.val()||"{}"); diff --git a/packages/node_modules/@node-red/nodes/core/function/15-change.html b/packages/node_modules/@node-red/nodes/core/function/15-change.html index 80bba7361..b40039028 100644 --- a/packages/node_modules/@node-red/nodes/core/function/15-change.html +++ b/packages/node_modules/@node-red/nodes/core/function/15-change.html @@ -115,12 +115,12 @@ var regex = this._("change.label.regex"); var deepCopyLabel = this._("change.label.deepCopy"); - function createPropertyValue(row2_1,row2_2) { + function createPropertyValue(row2_1, row2_2, defaultType) { var propValInput = $('',{class:"node-input-rule-property-value",type:"text"}) .appendTo(row2_1) - .typedInput({default:'str',types:['msg','flow','global','str','num','bool','json','bin','date','jsonata','env']}); + .typedInput({default:defaultType||'str',types:['msg','flow','global','str','num','bool','json','bin','date','jsonata','env']}); - var dcLabel = $('').appendTo(row2_2); + var dcLabel = $('').appendTo(row2_2); var deepCopy = $('').appendTo(dcLabel) $('').text(deepCopyLabel).appendTo(dcLabel) @@ -129,20 +129,20 @@ }) return [propValInput, deepCopy]; } - function createFromValue(row3_1) { + function createFromValue(row3_1, defaultType) { return $('',{class:"node-input-rule-property-search-value",type:"text"}) .appendTo(row3_1) - .typedInput({default:'str',types:['msg','flow','global','str','re','num','bool','env']}); + .typedInput({default:defaultType||'str',types:['msg','flow','global','str','re','num','bool','env']}); } - function createToValue(row3_2) { + function createToValue(row3_2, defaultType) { return $('',{class:"node-input-rule-property-replace-value",type:"text"}) .appendTo(row3_2) - .typedInput({default:'str',types:['msg','flow','global','str','num','bool','json','bin','env']}); + .typedInput({default:defaultType||'str',types:['msg','flow','global','str','num','bool','json','bin','env']}); } - function createMoveValue(row4) { + function createMoveValue(row4, defaultType) { return $('',{class:"node-input-rule-property-move-value",type:"text"}) .appendTo(row4) - .typedInput({default:'msg',types:['msg','flow','global']}); + .typedInput({default:defaultType||'msg',types:['msg','flow','global']}); } $('#node-input-rule-container').css('min-height','150px').css('min-width','450px').editableList({ @@ -268,33 +268,22 @@ propertyName.typedInput('value',rule.p); propertyName.typedInput('type',rule.pt); if (rule.t == "set") { - if(!propertyValue) { - var parts = createPropertyValue(row2_1, row2_2); - propertyValue = parts[0]; - deepCopy = parts[1]; - } + var parts = createPropertyValue(row2_1, row2_2, rule.tot); + propertyValue = parts[0]; + deepCopy = parts[1]; propertyValue.typedInput('value',rule.to); - propertyValue.typedInput('type',rule.tot); deepCopy.prop("checked", !!rule.dc); } if (rule.t == "move") { - if(!moveValue) { - moveValue = createMoveValue(row4); - } + moveValue = createMoveValue(row4,rule.tot); moveValue.typedInput('value',rule.to); - moveValue.typedInput('type',rule.tot); } if (rule.t == "change") { - if(!fromValue) { - fromValue = createFromValue(row3_1); - } + fromValue = createFromValue(row3_1, rule.fromt); fromValue.typedInput('value',rule.from); - fromValue.typedInput('type',rule.fromt); - if (!toValue) { - toValue = createToValue(row3_2); - } + + toValue = createToValue(row3_2,rule.tot); toValue.typedInput('value',rule.to); - toValue.typedInput('type',rule.tot); } selectField.change(); container[0].appendChild(fragment); diff --git a/packages/node_modules/@node-red/nodes/core/network/10-mqtt.html b/packages/node_modules/@node-red/nodes/core/network/10-mqtt.html index 406abf57d..747281ad0 100644 --- a/packages/node_modules/@node-red/nodes/core/network/10-mqtt.html +++ b/packages/node_modules/@node-red/nodes/core/network/10-mqtt.html @@ -54,6 +54,18 @@ width: 15px; height: 15px; } + .form-row-mqtt5 { + display: none; + } + .form-row-mqtt5.form-row-mqtt5-active:not(.form-row-mqtt-static-disabled) { + display: block + } + .form-row-mqtt-static-disabled { + display: none; + /* opacity: 0.3; + pointer-events: none; */ + } +