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

Merge pull request #3183 from node-red/debug-filter-opts

Redesign debug filter options and make them persistant
This commit is contained in:
Nick O'Leary 2021-10-13 14:47:08 +01:00 committed by GitHub
commit f030694ef4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 366 additions and 222 deletions

View File

@ -436,18 +436,17 @@ RED.popover = (function() {
return { return {
create: createPopover, create: createPopover,
tooltip: function(target,content, action) { tooltip: function(target,content, action) {
var label = content; var label = function() {
if (action) { var label = content;
label = function() { if (action) {
var label = content;
var shortcut = RED.keyboard.getShortcut(action); var shortcut = RED.keyboard.getShortcut(action);
if (shortcut && shortcut.key) { if (shortcut && shortcut.key) {
label = $('<span>'+content+' <span class="red-ui-popover-key">'+RED.keyboard.formatKey(shortcut.key, true)+'</span></span>'); label = $('<span>'+content+' <span class="red-ui-popover-key">'+RED.keyboard.formatKey(shortcut.key, true)+'</span></span>');
} }
return label;
} }
return label;
} }
return RED.popover.create({ var popover = RED.popover.create({
tooltip: true, tooltip: true,
target:target, target:target,
trigger: "hover", trigger: "hover",
@ -456,6 +455,14 @@ RED.popover = (function() {
content: label, content: label,
delay: { show: 750, hide: 50 } delay: { show: 750, hide: 50 }
}); });
popover.setContent = function(newContent) {
content = newContent;
}
popover.setAction = function(newAction) {
action = newAction;
}
return popover;
}, },
menu: function(options) { menu: function(options) {
var list = $('<ul class="red-ui-menu"></ul>'); var list = $('<ul class="red-ui-menu"></ul>');

View File

@ -24,6 +24,9 @@
* - rootSortable: boolean - if 'sortable' is set, then setting this to * - rootSortable: boolean - if 'sortable' is set, then setting this to
* false, prevents items being sorted to the * false, prevents items being sorted to the
* top level of the tree * 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: * methods:
* - data(items) - clears existing items and replaces with new data * - 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 * deferBuild: true/false, // don't build any ui elements for the item's children
* until it is expanded by the user. * until it is expanded by the user.
* element: // custom dom element to use for the item - ignored if `label` is set * 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", { $.widget( "nodered.treeList", {
_create: function() { _create: function() {
var that = this; var that = this;
var autoSelect = true;
if (that.options.autoSelect === false) {
autoSelect = false;
}
this.element.addClass('red-ui-treeList'); this.element.addClass('red-ui-treeList');
this.element.attr("tabIndex",0); this.element.attr("tabIndex",0);
var wrapper = $('<div>',{class:'red-ui-treeList-container'}).appendTo(this.element); var wrapper = $('<div>',{class:'red-ui-treeList-container'}).appendTo(this.element);
this.element.on('keydown', function(evt) { this.element.on('keydown', function(evt) {
var selected = that._topList.find(".selected").parent().data('data'); var focussed = that._topList.find(".focus").parent().data('data');
if (!selected && (evt.keyCode === 40 || evt.keyCode === 38)) { if (!focussed && (evt.keyCode === 40 || evt.keyCode === 38)) {
that.select(that._data[0]); 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; return;
} }
var target; var target;
switch(evt.keyCode) { switch(evt.keyCode) {
case 32: // SPACE
case 13: // ENTER case 13: // ENTER
evt.preventDefault(); evt.preventDefault();
evt.stopPropagation(); evt.stopPropagation();
if (selected.children) { if (focussed.checkbox) {
if (selected.treeList.container.hasClass("expanded")) { focussed.treeList.checkbox.trigger("click");
selected.treeList.collapse() } else if (focussed.radio) {
focussed.treeList.radio.trigger("click");
} else if (focussed.children) {
if (focussed.treeList.container.hasClass("expanded")) {
focussed.treeList.collapse()
} else { } else {
selected.treeList.expand() focussed.treeList.expand()
} }
} else { } else {
that._trigger("confirm",null,selected) that._trigger("confirm",null,focussed)
} }
break; break;
case 37: // LEFT case 37: // LEFT
evt.preventDefault(); evt.preventDefault();
evt.stopPropagation(); evt.stopPropagation();
if (selected.children&& selected.treeList.container.hasClass("expanded")) { if (focussed.children&& focussed.treeList.container.hasClass("expanded")) {
selected.treeList.collapse() focussed.treeList.collapse()
} else if (selected.parent) { } else if (focussed.parent) {
target = selected.parent; target = focussed.parent;
} }
break; break;
case 38: // UP case 38: // UP
evt.preventDefault(); evt.preventDefault();
evt.stopPropagation(); evt.stopPropagation();
target = that._getPreviousSibling(selected); target = that._getPreviousSibling(focussed);
if (target) { if (target) {
target = that._getLastDescendant(target); target = that._getLastDescendant(target);
} }
if (!target && selected.parent) { if (!target && focussed.parent) {
target = selected.parent; target = focussed.parent;
} }
break; break;
case 39: // RIGHT case 39: // RIGHT
evt.preventDefault(); evt.preventDefault();
evt.stopPropagation(); evt.stopPropagation();
if (selected.children) { if (focussed.children) {
if (!selected.treeList.container.hasClass("expanded")) { if (!focussed.treeList.container.hasClass("expanded")) {
selected.treeList.expand() focussed.treeList.expand()
} }
} }
break break
case 40: //DOWN case 40: //DOWN
evt.preventDefault(); evt.preventDefault();
evt.stopPropagation(); evt.stopPropagation();
if (selected.children && Array.isArray(selected.children) && selected.children.length > 0 && selected.treeList.container.hasClass("expanded")) { if (focussed.children && Array.isArray(focussed.children) && focussed.children.length > 0 && focussed.treeList.container.hasClass("expanded")) {
target = selected.children[0]; target = focussed.children[0];
} else { } else {
target = that._getNextSibling(selected); target = that._getNextSibling(focussed);
while (!target && selected.parent) { while (!target && focussed.parent) {
selected = selected.parent; focussed = focussed.parent;
target = that._getNextSibling(selected); target = that._getNextSibling(focussed);
} }
} }
break break
} }
if (target) { if (target) {
that.select(target); if (autoSelect) {
that.select(target);
} else {
that._topList.find(".focus").removeClass("focus")
}
target.treeList.label.addClass('focus')
} }
}); });
this._data = []; this._data = [];
@ -463,6 +486,9 @@
container.addClass("expanded"); container.addClass("expanded");
} }
item.treeList.collapse = function() { item.treeList.collapse = function() {
if (item.collapsible === false) {
return
}
if (!item.children) { if (!item.children) {
return; return;
} }
@ -583,7 +609,7 @@
// Already a parent because we've got the angle-right icon // Already a parent because we've got the angle-right icon
return; return;
} }
$('<i class="fa fa-angle-right" />').appendTo(treeListIcon); $('<i class="fa fa-angle-right" />').toggleClass("hide",item.collapsible === false).appendTo(treeListIcon);
treeListIcon.on("click.red-ui-treeList-expand", function(e) { treeListIcon.on("click.red-ui-treeList-expand", function(e) {
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); e.preventDefault();
@ -634,6 +660,8 @@
label.on("click", function(e) { label.on("click", function(e) {
e.stopPropagation(); e.stopPropagation();
cb.trigger("click"); cb.trigger("click");
that._topList.find(".focus").removeClass("focus")
label.addClass('focus')
}) })
} }
item.treeList.select = function(v) { item.treeList.select = function(v) {
@ -641,6 +669,7 @@
cb.trigger("click"); cb.trigger("click");
} }
} }
item.treeList.checkbox = cb;
selectWrapper.appendTo(label) selectWrapper.appendTo(label)
} else if (item.radio) { } else if (item.radio) {
var selectWrapper = $('<span class="red-ui-treeList-icon"></span>'); var selectWrapper = $('<span class="red-ui-treeList-icon"></span>');
@ -669,6 +698,8 @@
label.on("click", function(e) { label.on("click", function(e) {
e.stopPropagation(); e.stopPropagation();
cb.trigger("click"); cb.trigger("click");
that._topList.find(".focus").removeClass("focus")
label.addClass('focus')
}) })
} }
item.treeList.select = function(v) { item.treeList.select = function(v) {
@ -677,6 +708,7 @@
} }
} }
selectWrapper.appendTo(label) selectWrapper.appendTo(label)
item.treeList.radio = cb;
} else { } else {
label.on("click", function(e) { label.on("click", function(e) {
if (!that.options.multi) { if (!that.options.multi) {
@ -684,10 +716,14 @@
} }
label.addClass("selected"); label.addClass("selected");
that._selected.add(item); that._selected.add(item);
that._topList.find(".focus").removeClass("focus")
label.addClass('focus')
that._trigger("select",e,item) that._trigger("select",e,item)
}) })
label.on("dblclick", function(e) { label.on("dblclick", function(e) {
that._topList.find(".focus").removeClass("focus")
label.addClass('focus')
if (!item.children) { if (!item.children) {
that._trigger("confirm",e,item); that._trigger("confirm",e,item);
} }
@ -835,6 +871,9 @@
if (item.treeList.label) { if (item.treeList.label) {
item.treeList.label.addClass("selected"); item.treeList.label.addClass("selected");
} }
that._topList.find(".focus").removeClass("focus");
if (triggerEvent !== false) { if (triggerEvent !== false) {
this._trigger("select",null,item) this._trigger("select",null,item)
} }
@ -842,6 +881,9 @@
clearSelection: function() { clearSelection: function() {
this._selected.forEach(function(item) { this._selected.forEach(function(item) {
item.selected = false; item.selected = false;
if (item.treeList.checkbox) {
item.treeList.checkbox.prop('checked',false)
}
if (item.treeList.label) { if (item.treeList.label) {
item.treeList.label.removeClass("selected") item.treeList.label.removeClass("selected")
} }

View File

@ -287,11 +287,11 @@ RED.sidebar.info.outliner = (function() {
var node = RED.nodes.node(item.id) || RED.nodes.group(item.id); var node = RED.nodes.node(item.id) || RED.nodes.group(item.id);
if (node) { if (node) {
if (node.type === 'group' || node._def.category !== "config") { if (node.type === 'group' || node._def.category !== "config") {
RED.view.select({nodes:[node]}) // RED.view.select({nodes:[node]})
} else if (node._def.category === "config") { } else if (node._def.category === "config") {
RED.sidebar.info.refresh(node); RED.sidebar.info.refresh(node);
} else { } else {
RED.view.select({nodes:[]}) // RED.view.select({nodes:[]})
} }
} }
}) })

View File

@ -43,12 +43,24 @@
border-bottom: 1px solid $secondary-border-color; border-bottom: 1px solid $secondary-border-color;
box-shadow: 0 2px 6px $shadow; box-shadow: 0 2px 6px $shadow;
} }
.red-ui-debug-filter-row { #red-ui-sidebar-debug-filter-node-list-row {
.red-ui-nodeList { .red-ui-treeList-label.disabled {
margin: 10px 0; 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 { .red-ui-debug-msg {
position: relative; position: relative;
border-bottom: 1px solid $debug-message-border; border-bottom: 1px solid $debug-message-border;

View File

@ -434,16 +434,19 @@ div.red-ui-info-table {
} }
.red-ui-info-outline-item-controls { .red-ui-info-outline-item-controls {
position: absolute; position: absolute;
top:0; top:1px;
bottom: 0; bottom: 1px;
right: 0px; right: 1px;
padding: 2px 3px 0 1px; padding: 1px 2px 0 1px;
text-align: right; text-align: right;
background: $list-item-background; background: $list-item-background;
.red-ui-treeList-label:hover & { .red-ui-treeList-label:hover & {
background: $list-item-background-hover; background: $list-item-background-hover;
} }
.red-ui-treeList-label.focus & {
background: $list-item-background-hover;
}
.red-ui-treeList-label.selected & { .red-ui-treeList-label.selected & {
background: $list-item-background-selected; background: $list-item-background-selected;
} }

View File

@ -89,6 +89,12 @@
color: $list-item-color; color: $list-item-color;
text-decoration: none; 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 { &.selected, &.selected .red-ui-treeList-sublabel-text {
background: $list-item-background-selected; background: $list-item-background-selected;
outline: none; outline: none;

View File

@ -292,6 +292,7 @@
}; };
RED.events.on("project:change", this.clearMessageList); RED.events.on("project:change", this.clearMessageList);
RED.actions.add("core:clear-debug-messages", function() { RED.debug.clearMessageList(true) }); 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-selected-debug-nodes", function() { setDebugNodeState(getSelectedDebugNodes(true), true); });
RED.actions.add("core:activate-all-debug-nodes", function() { setDebugNodeState(getMatchingDebugNodes(true, true),true); }); RED.actions.add("core:activate-all-debug-nodes", function() { setDebugNodeState(getMatchingDebugNodes(true, true),true); });

View File

@ -31,24 +31,22 @@ RED.debug = (function() {
var activeWorkspace; var activeWorkspace;
var numMessages = 100; // Hardcoded number of message to show in debug window scrollback var numMessages = 100; // Hardcoded number of message to show in debug window scrollback
var filterVisible = false; var debugNodeTreeList;
var debugNodeList;
var debugNodeListExpandedFlows = {};
function init(_config) { function init(_config) {
config = _config; config = _config;
var content = $("<div>").css({"position":"relative","height":"100%"}); var content = $("<div>").css({"position":"relative","height":"100%"});
var toolbar = $('<div class="red-ui-sidebar-header">'+ var toolbar = $('<div class="red-ui-sidebar-header">'+
'<span class="button-group"><a id="red-ui-sidebar-debug-filter" class="red-ui-sidebar-header-button" href="#"><i class="fa fa-filter"></i> <span></span></a></span>'+ '<span class="button-group">'+
'<span class="button-group"><a id="red-ui-sidebar-debug-clear" class="red-ui-sidebar-header-button" href="#"><i class="fa fa-trash"></i></a></span></div>').appendTo(content); '<a id="red-ui-sidebar-debug-filter" style="padding-right: 5px" class="red-ui-sidebar-header-button" href="#"><i class="fa fa-filter"></i> <span></span> <i style="padding-left: 5px;" class="fa fa-caret-down"></i></a>'+
'</span>'+
'<span class="button-group">'+
'<a id="red-ui-sidebar-debug-clear" style="border-right: none; padding-right: 6px" class="red-ui-sidebar-header-button" href="#" data-clear-type="all"><i class="fa fa-trash"></i> <span>all</span></a>' +
'<a id="red-ui-sidebar-debug-clear-opts" style="padding: 5px; border-left: none;" class="red-ui-sidebar-header-button" href="#"><i class="fa fa-caret-down"></i></a>'+
'</span></div>').appendTo(content);
var footerToolbar = $('<div>'+ var footerToolbar = $('<div>'+
// '<span class="button-group">'+
// '<a class="red-ui-footer-button-toggle text-button selected" id="red-ui-sidebar-debug-view-list" href="#"><span data-i18n="">list</span></a>'+
// '<a class="red-ui-footer-button-toggle text-button" id="red-ui-sidebar-debug-view-table" href="#"><span data-i18n="">table</span></a> '+
// '</span>'+
'<span class="button-group"><a id="red-ui-sidebar-debug-open" class="red-ui-footer-button" href="#"><i class="fa fa-desktop"></i></a></span> ' + '<span class="button-group"><a id="red-ui-sidebar-debug-open" class="red-ui-footer-button" href="#"><i class="fa fa-desktop"></i></a></span> ' +
'</div>'); '</div>');
@ -56,85 +54,100 @@ RED.debug = (function() {
sbc = messageList[0]; sbc = messageList[0];
messageTable = $('<div class="red-ui-debug-content red-ui-debug-content-table hide"/>').appendTo(content); messageTable = $('<div class="red-ui-debug-content red-ui-debug-content-table hide"/>').appendTo(content);
var filterDialog = $('<div class="red-ui-debug-filter-box hide">'+ var filterDialogCloseTimeout;
'<div class="red-ui-debug-filter-row">'+ var filterDialogShown = false;
'<span class="button-group">'+ var filterDialog = $('<div class="red-ui-debug-filter-box hide"></div>').appendTo(toolbar);//content);
'<a class="red-ui-sidebar-header-button-toggle red-ui-sidebar-debug-filter-option selected" id="red-ui-sidebar-debug-filterAll" href="#"><span data-i18n="node-red:debug.sidebar.filterAll"></span></a>'+ filterDialog.on('mouseleave' ,function(evt) {
'<a class="red-ui-sidebar-header-button-toggle red-ui-sidebar-debug-filter-option" id="red-ui-sidebar-debug-filterSelected" href="#"><span data-i18n="node-red:debug.sidebar.filterSelected"></span></a>'+ if (filterDialogShown) {
'<a class="red-ui-sidebar-header-button-toggle red-ui-sidebar-debug-filter-option" id="red-ui-sidebar-debug-filterCurrent" href="#"><span data-i18n="node-red:debug.sidebar.filterCurrent"></span></a> '+ filterDialogCloseTimeout = setTimeout(function() {
filterDialog.slideUp(200);
filterDialogShown = false;
},500)
}
})
filterDialog.on('mouseenter' ,function(evt) {
clearTimeout(filterDialogCloseTimeout)
})
var filterToolbar = $('<div style="margin-bottom: 3px; display: flex;">'+
'<span style="flex-grow:1; text-align: left;">'+
'<span class="button-group"><button type="button" id="red-ui-sidebar-filter-select-all" class="red-ui-sidebar-header-button red-ui-button-small" data-i18n="node-red:debug.sidebar.selectAll"></button></span>' +
'<span class="button-group"><button type="button" id="red-ui-sidebar-filter-select-none" class="red-ui-sidebar-header-button red-ui-button-small" data-i18n="node-red:debug.sidebar.selectNone"></button></span>' +
'</span>'+ '</span>'+
'</div>'+ '<span class="button-group"><button type="button" id="red-ui-sidebar-filter-select-close" class="red-ui-sidebar-header-button red-ui-button-small"><i class="fa fa-times"></i></button></span>'+
'</div>').appendTo(toolbar);//content); '</div>').appendTo(filterDialog);
// var filterTypeRow = $('<div class="red-ui-debug-filter-row"></div>').appendTo(filterDialog); filterToolbar.find("#red-ui-sidebar-filter-select-close").on('click', function(evt) {
// $('<select><option>Show all debug nodes</option><option>Show selected debug nodes</option><option>Show current flow only</option></select>').appendTo(filterTypeRow); clearTimeout(filterDialogCloseTimeout)
filterDialogShown = false;
filterDialog.slideUp(200);
})
var debugNodeListRow = $('<div class="red-ui-debug-filter-row hide" id="red-ui-sidebar-debug-filter-node-list-row"></div>').appendTo(filterDialog); filterToolbar.find("#red-ui-sidebar-filter-select-all").on('click', function(evt) {
var flowCheckboxes = {}; evt.preventDefault();
var debugNodeListHeader = $('<div><span data-i18n="node-red:debug.sidebar.debugNodes"></span><span></span></div>'); var data = debugNodeTreeList.treeList('data');
var headerCheckbox = $('<input type="checkbox">').appendTo(debugNodeListHeader.find("span")[1]).checkboxSet(); data.forEach(function(flow) {
if (!flow.selected) {
debugNodeList = $('<ol>',{style:"text-align: left; min-height: 250px; max-height: 250px"}).appendTo(debugNodeListRow).editableList({ if (flow.treeList.checkbox) {
header: debugNodeListHeader, flow.treeList.checkbox.trigger('click')
class: 'red-ui-nodeList',
addItem: function(container,i,node) {
var row = $("<div>").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;
} }
var chevron = $('<i class="fa fa-angle-right"></i>').appendTo(row);
$('<span>').text(RED.utils.getNodeLabel(node,node.id)).appendTo(row);
var muteControl = $('<input type="checkbox">').appendTo($('<span class="meta">').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 { } else {
$('<span>',{style: "margin-left: 20px"}).text(RED.utils.getNodeLabel(node,node.id)).appendTo(row); flow.children.forEach(function(item) {
row.on("mouseenter",function() { if (!item.selected) {
config.messageMouseEnter(node.id); item.treeList.select();
}); }
row.on("mouseleave",function() { })
config.messageMouseLeave(node.id); }
}); });
var muteControl = $('<input type="checkbox">').prop('checked',!filteredNodes[node.id]).appendTo($('<span class="meta">').appendTo(row)); refreshMessageList();
muteControl.checkboxSet({ })
parent: flowCheckboxes[node.z]
}).on("change", function(e) { filterToolbar.find("#red-ui-sidebar-filter-select-none").on('click', function(evt) {
filteredNodes[node.id] = !$(this).prop('checked'); evt.preventDefault();
$(".red-ui-debug-msg-node-"+node.id.replace(/\./g,"_")).toggleClass('hide',filteredNodes[node.id]); debugNodeTreeList.treeList('clearSelection');
}); var data = debugNodeTreeList.treeList('data');
if ((node.hasOwnProperty("active") && !node.active) || RED.nodes.workspace(node.z).disabled) { data.forEach(function(flow) {
container.addClass('disabled'); if (flow.children) {
muteControl.checkboxSet('disable'); flow.children.forEach(function(item) {
filteredNodes[item.node.id] = true;
})
}
});
RED.settings.set('debug.filteredNodes',Object.keys(filteredNodes))
refreshMessageList();
})
var debugNodeListRow = $('<div class="red-ui-debug-filter-row" id="red-ui-sidebar-debug-filter-node-list-row"></div>').appendTo(filterDialog);
debugNodeTreeList = $("<div></div>").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 { try {
content.i18n(); content.i18n();
@ -144,85 +157,95 @@ RED.debug = (function() {
toolbar.find('#red-ui-sidebar-debug-filter span').text(RED._('node-red:debug.sidebar.filterAll')); 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) { toolbar.find('#red-ui-sidebar-debug-filter').on("click",function(e) {
e.preventDefault(); e.preventDefault();
if ($(this).hasClass('selected')) { var options = [
filterVisible = false; { label: $('<span data-i18n="[append]node-red:debug.sidebar.filterAll"><input type="radio" value="filterAll" name="filter-type" style="margin-top:0"> </span>').i18n() , value: "filterAll" },
$(this).removeClass('selected'); { label: $('<span><span data-i18n="[append]node-red:debug.sidebar.filterSelected"><input type="radio" value="filterSelected" name="filter-type" style="margin-top:0"> </span>...</span>').i18n(), value: "filterSelected" },
clearTimeout(hideFilterTimeout); { label: $('<span data-i18n="[append]node-red:debug.sidebar.filterCurrent"><input type="radio" value="filterCurrent" name="filter-type" style="margin-top:0"> </span>').i18n(), value: "filterCurrent" }
filterDialog.slideUp(200); ]
} else { var menu = RED.popover.menu({
$(this).addClass('selected'); options: options,
filterVisible = true; onselect: function(item) {
refreshDebugNodeList(); if (item.value !== filterType) {
filterDialog.slideDown(200); 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')); 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) { toolbar.find("#red-ui-sidebar-debug-clear").on("click", function(e) {
e.preventDefault(); 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: $('<span data-i18n="[append]node-red:debug.sidebar.clearLog"><input type="radio" value="all" name="clear-type" style="margin-top:0"> </span>').i18n() , value: "all" },
{ label: $('<span data-i18n="[append]node-red:debug.sidebar.clearFilteredLog"><input type="radio" value="filtered" name="clear-type" style="margin-top:0"> </span>').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 { return {
content: content, content: content,
@ -254,8 +277,6 @@ RED.debug = (function() {
function refreshDebugNodeList() { function refreshDebugNodeList() {
debugNodeList.editableList('empty');
var workspaceOrder = RED.nodes.getWorkspaceOrder(); var workspaceOrder = RED.nodes.getWorkspaceOrder();
var workspaceOrderMap = {}; var workspaceOrderMap = {};
workspaceOrder.forEach(function(ws,i) { workspaceOrder.forEach(function(ws,i) {
@ -320,15 +341,45 @@ RED.debug = (function() {
return labelA.localeCompare(labelB); return labelA.localeCompare(labelB);
}); });
var currentWs = null; var currentWs = null;
var nodeList = []; var data = [];
var currentFlow;
var currentSelectedCount = 0;
candidateNodes.forEach(function(node) { candidateNodes.forEach(function(node) {
if (currentWs !== node.z) { if (currentWs !== node.z) {
if (currentFlow && currentFlow.checkbox) {
currentFlow.selected = currentSelectedCount === currentFlow.children.length
}
currentSelectedCount = 0;
currentWs = node.z; 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() { function getTimestamp() {
@ -340,7 +391,16 @@ RED.debug = (function() {
return m.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"); return m.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
} }
var refreshTimeout;
function refreshMessageList(_activeWorkspace) { function refreshMessageList(_activeWorkspace) {
if (refreshTimeout) {
clearTimeout(refreshTimeout);
}
refreshTimeout = setTimeout(function() {
_refreshMessageList(_activeWorkspace);
},200);
}
function _refreshMessageList(_activeWorkspace) {
if (_activeWorkspace) { if (_activeWorkspace) {
activeWorkspace = _activeWorkspace.replace(/\./g,"_"); activeWorkspace = _activeWorkspace.replace(/\./g,"_");
} }
@ -415,6 +475,7 @@ RED.debug = (function() {
}); });
delete filteredNodes[sourceId]; delete filteredNodes[sourceId];
$("#red-ui-sidebar-debug-filterSelected").trigger("click"); $("#red-ui-sidebar-debug-filterSelected").trigger("click");
RED.settings.set('debug.filteredNodes',Object.keys(filteredNodes))
refreshMessageList(); refreshMessageList();
}}, }},
{id:"red-ui-debug-msg-menu-item-clear-filter",label:RED._("node-red:debug.messageMenu.clearFilter"),onselect:function(){ {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) { function clearMessageList(clearFilter, filteredOnly) {
$(".red-ui-debug-msg").remove(); if (!filteredOnly) {
$(".red-ui-debug-msg").remove();
} else {
$(".red-ui-debug-msg:not(.hide)").remove();
}
config.clear(); config.clear();
if (!!clearFilter) { if (!!clearFilter) {
clearFilterSettings(); clearFilterSettings();
@ -613,10 +678,9 @@ RED.debug = (function() {
function clearFilterSettings() { function clearFilterSettings() {
filteredNodes = {}; filteredNodes = {};
filterType = 'filterAll'; filterType = 'filterAll';
$('.red-ui-sidebar-debug-filter-option').removeClass('selected'); RED.settings.set("debug.filter",filterType);
$('#red-ui-sidebar-debug-filterAll').addClass('selected'); 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 span').text(RED._('node-red:debug.sidebar.filterAll'));
$('#red-ui-sidebar-debug-filter-node-list-row').slideUp();
} }
return { return {

View File

@ -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);
}) })
}); });

View File

@ -143,12 +143,17 @@
"filterSelected": "selected nodes", "filterSelected": "selected nodes",
"filterCurrent": "current flow", "filterCurrent": "current flow",
"debugNodes": "Debug nodes", "debugNodes": "Debug nodes",
"clearLog": "Clear log", "clearLog": "Clear messages",
"filterLog": "Filter log", "clearFilteredLog": "Clear filtered messages",
"filterLog": "Filter messages",
"openWindow": "Open in new window", "openWindow": "Open in new window",
"copyPath": "Copy path", "copyPath": "Copy path",
"copyPayload": "Copy value", "copyPayload": "Copy value",
"pinPath": "Pin open" "pinPath": "Pin open",
"selectAll": "select all",
"selectNone": "select none",
"all": "all",
"filtered": "filtered"
}, },
"messageMenu": { "messageMenu": {
"collapseAll": "Collapse all paths", "collapseAll": "Collapse all paths",