From 7cd92faf0d822349b2cb7699cd6ab3bbe82c2768 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Tue, 12 Oct 2021 16:49:38 +0100 Subject: [PATCH 1/3] Separate 'focus' from 'selected' state in treeList --- .../src/js/ui/common/treeList.js | 98 +++++++++++++------ .../src/js/ui/tab-info-outliner.js | 4 +- .../editor-client/src/sass/tab-info.scss | 11 ++- .../src/sass/ui/common/treeList.scss | 6 ++ 4 files changed, 85 insertions(+), 34 deletions(-) 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..9fca87e75 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,96 @@ $.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 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 +486,9 @@ container.addClass("expanded"); } item.treeList.collapse = function() { + if (item.collapsible === false) { + return + } if (!item.children) { return; } @@ -583,7 +609,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 +660,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 +669,7 @@ cb.trigger("click"); } } + item.treeList.checkbox = cb; selectWrapper.appendTo(label) } else if (item.radio) { var selectWrapper = $(''); @@ -669,6 +698,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 +708,7 @@ } } selectWrapper.appendTo(label) + item.treeList.radio = cb; } else { label.on("click", function(e) { if (!that.options.multi) { @@ -684,10 +716,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 +871,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 +881,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/tab-info-outliner.js b/packages/node_modules/@node-red/editor-client/src/js/ui/tab-info-outliner.js index 52606cd88..3159622b6 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/tab-info-outliner.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/tab-info-outliner.js @@ -287,11 +287,11 @@ RED.sidebar.info.outliner = (function() { var node = RED.nodes.node(item.id) || RED.nodes.group(item.id); if (node) { if (node.type === 'group' || node._def.category !== "config") { - RED.view.select({nodes:[node]}) + // RED.view.select({nodes:[node]}) } else if (node._def.category === "config") { RED.sidebar.info.refresh(node); } else { - RED.view.select({nodes:[]}) + // RED.view.select({nodes:[]}) } } }) diff --git a/packages/node_modules/@node-red/editor-client/src/sass/tab-info.scss b/packages/node_modules/@node-red/editor-client/src/sass/tab-info.scss index 89ad06ca2..72422f350 100644 --- a/packages/node_modules/@node-red/editor-client/src/sass/tab-info.scss +++ b/packages/node_modules/@node-red/editor-client/src/sass/tab-info.scss @@ -434,16 +434,19 @@ div.red-ui-info-table { } .red-ui-info-outline-item-controls { position: absolute; - top:0; - bottom: 0; - right: 0px; - padding: 2px 3px 0 1px; + top:1px; + bottom: 1px; + right: 1px; + padding: 1px 2px 0 1px; text-align: right; background: $list-item-background; .red-ui-treeList-label:hover & { background: $list-item-background-hover; } + .red-ui-treeList-label.focus & { + background: $list-item-background-hover; + } .red-ui-treeList-label.selected & { background: $list-item-background-selected; } diff --git a/packages/node_modules/@node-red/editor-client/src/sass/ui/common/treeList.scss b/packages/node_modules/@node-red/editor-client/src/sass/ui/common/treeList.scss index 3621328d8..beba6b047 100644 --- a/packages/node_modules/@node-red/editor-client/src/sass/ui/common/treeList.scss +++ b/packages/node_modules/@node-red/editor-client/src/sass/ui/common/treeList.scss @@ -89,6 +89,12 @@ color: $list-item-color; text-decoration: none; } + &.focus, &.focus .red-ui-treeList-sublabel-text { + background: $list-item-background-hover; + outline: 1px solid $form-input-focus-color !important; + outline-offset: -1px; + color: $list-item-color; + } &.selected, &.selected .red-ui-treeList-sublabel-text { background: $list-item-background-selected; outline: none; From bed1be14ba74c936deb30e8666cf32ad88c8f7e3 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Tue, 12 Oct 2021 16:50:08 +0100 Subject: [PATCH 2/3] Allow toolip action/content to be updated --- .../editor-client/src/js/ui/common/popover.js | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) 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 = $('
    '); From 3204b044553389bd2339263146bb9c0719b48c91 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Tue, 12 Oct 2021 16:50:33 +0100 Subject: [PATCH 3/3] Overhaul Debug sidebar filter and clear button options --- .../editor-client/src/sass/debug.scss | 20 +- .../@node-red/nodes/core/common/21-debug.html | 1 + .../core/common/lib/debug/debug-utils.js | 392 ++++++++++-------- .../nodes/core/common/lib/debug/debug.js | 26 +- .../nodes/locales/en-US/messages.json | 11 +- 5 files changed, 268 insertions(+), 182 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/sass/debug.scss b/packages/node_modules/@node-red/editor-client/src/sass/debug.scss index 1e77e46e1..1cdf15e55 100644 --- a/packages/node_modules/@node-red/editor-client/src/sass/debug.scss +++ b/packages/node_modules/@node-red/editor-client/src/sass/debug.scss @@ -43,12 +43,24 @@ border-bottom: 1px solid $secondary-border-color; box-shadow: 0 2px 6px $shadow; } -.red-ui-debug-filter-row { - .red-ui-nodeList { - margin: 10px 0; +#red-ui-sidebar-debug-filter-node-list-row { + .red-ui-treeList-label.disabled { + font-style: italic; + color: $secondary-text-color-disabled; + } + + .red-ui-treeList-label { + &.selected, &.selected .red-ui-treeList-sublabel-text { + background: inherit; + } + &.selected, &.selected .red-ui-treeList-sublabel-text { + background: inherit; + } + &.focus, &.focus .red-ui-treeList-sublabel-text { + background: $list-item-background-hover !important; + } } } - .red-ui-debug-msg { position: relative; border-bottom: 1px solid $debug-message-border; 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/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/locales/en-US/messages.json b/packages/node_modules/@node-red/nodes/locales/en-US/messages.json index 776b2dae9..21ab968d9 100755 --- a/packages/node_modules/@node-red/nodes/locales/en-US/messages.json +++ b/packages/node_modules/@node-red/nodes/locales/en-US/messages.json @@ -143,12 +143,17 @@ "filterSelected": "selected nodes", "filterCurrent": "current flow", "debugNodes": "Debug nodes", - "clearLog": "Clear log", - "filterLog": "Filter log", + "clearLog": "Clear messages", + "clearFilteredLog": "Clear filtered messages", + "filterLog": "Filter messages", "openWindow": "Open in new window", "copyPath": "Copy path", "copyPayload": "Copy value", - "pinPath": "Pin open" + "pinPath": "Pin open", + "selectAll": "select all", + "selectNone": "select none", + "all": "all", + "filtered": "filtered" }, "messageMenu": { "collapseAll": "Collapse all paths",