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

Merge pull request #3503 from node-red/debug-tooltip

Add a tooltip to debug sidebar messages to reveal full path to node
This commit is contained in:
Nick O'Leary 2022-04-05 23:33:14 +01:00 committed by GitHub
commit b4bcb7ace2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 92 additions and 6 deletions

View File

@ -123,17 +123,20 @@
background: $debug-message-background; background: $debug-message-background;
font-size: 11px; font-size: 11px;
color: $secondary-text-color-inactive; color: $secondary-text-color-inactive;
overflow-wrap: anywhere;
} }
.red-ui-debug-msg-date { .red-ui-debug-msg-date {
padding: 1px 5px 1px 1px; padding: 1px 10px 1px 0px;
white-space: nowrap;
} }
.red-ui-debug-msg-topic { .red-ui-debug-msg-topic {
display: block; display: block;
color: $debug-message-text-color-meta; color: $debug-message-text-color-meta;
} }
.red-ui-debug-msg-name { .red-ui-debug-msg-name {
padding: 1px 5px; padding: 1px 0px;
color: $secondary-text-color-inactive; color: $secondary-text-color-inactive;
white-space: nowrap;
} }
.red-ui-debug-msg-tools { .red-ui-debug-msg-tools {
position: absolute; position: absolute;

View File

@ -152,7 +152,20 @@
border-radius:3px; border-radius:3px;
padding: 1px 2px; padding: 1px 2px;
} }
.red-ui-popover {
a {
text-decoration: none;
color: var(--red-ui-popover-color) !important;
}
a:hover,
a:focus {
text-decoration: none;
color: var(--red-ui-popover-color) !important;
}
a:focus {
outline: 1px solid $form-input-focus-color;
}
}
.red-ui-popover a.red-ui-button, .red-ui-popover a.red-ui-button,
.red-ui-popover button.red-ui-button { .red-ui-popover button.red-ui-button {
&:not(.primary) { &:not(.primary) {

View File

@ -160,6 +160,10 @@
}, },
messageSourceClick: function(sourceId, aliasId, path) { messageSourceClick: function(sourceId, aliasId, path) {
// Get all of the nodes that could have logged this message // Get all of the nodes that could have logged this message
if (RED.nodes.workspace(sourceId)) {
RED.view.reveal(sourceId);
return
}
var candidateNodes = [RED.nodes.node(sourceId)] var candidateNodes = [RED.nodes.node(sourceId)]
if (path) { if (path) {
for (var i=2;i<path.length;i++) { for (var i=2;i<path.length;i++) {
@ -235,10 +239,11 @@
// sourceNode should be the top-level node - one that is on a flow. // sourceNode should be the top-level node - one that is on a flow.
var sourceNode; var sourceNode;
var pathParts; var pathParts;
var pathHierarchy;
if (o.path) { if (o.path) {
// Path is a `/`-separated list of ids that identifies the // Path is a `/`-separated list of ids that identifies the
// complete parentage of the node that generated this message. // complete parentage of the node that generated this message.
// flow-id/subflow-A-instance/subflow-A-type/subflow-B-instance/subflow-B-type/node-id // flow-id/subflow-A-instance/subflow-B-instance
// If it has one id, that is a top level flow // If it has one id, that is a top level flow
// each subsequent id is the instance id of a subflow node // each subsequent id is the instance id of a subflow node
@ -251,11 +256,41 @@
// Highlight the subflow instance node. // Highlight the subflow instance node.
sourceNode = RED.nodes.node(pathParts[1]); sourceNode = RED.nodes.node(pathParts[1]);
} }
pathHierarchy = pathParts.map((id,index) => {
if (index === 0) {
return {
id: id,
label: RED.nodes.workspace(id).label
}
} else {
var instanceNode = RED.nodes.node(id)
return {
id: id,
label: (instanceNode.name || RED.nodes.subflow(instanceNode.type.substring(8)).name)
}
}
})
if (pathParts.length === 1) {
pathHierarchy.push({
id: o.id,
label: sourceNode.name || sourceNode.type+":"+sourceNode.id
})
}
if (o._alias) {
let aliasNode = RED.nodes.node(o._alias)
if (aliasNode) {
pathHierarchy.push({
id: o._alias,
label: aliasNode.name || aliasNode.type+":"+aliasNode.id
})
}
}
} else { } else {
// This is probably redundant... // This is probably redundant...
sourceNode = RED.nodes.node(o.id) || RED.nodes.node(o.z); sourceNode = RED.nodes.node(o.id) || RED.nodes.node(o.z);
} }
if (sourceNode) { if (sourceNode) {
var sourceFlow = RED.nodes.workspace(sourceNode.z)
o._source = { o._source = {
id:sourceNode.id, id:sourceNode.id,
z:sourceNode.z, z:sourceNode.z,
@ -266,7 +301,9 @@
// the top-level subflow instance node. // the top-level subflow instance node.
// This means the node's name is displayed in the sidebar. // This means the node's name is displayed in the sidebar.
_alias:o._alias, _alias:o._alias,
path: pathParts flowName: sourceFlow?(sourceFlow.label||sourceNode.z):sourceNode.z,
path: pathParts,
pathHierarchy: pathHierarchy
}; };
} }
RED.debug.handleDebugMessage(o); RED.debug.handleDebugMessage(o);

View File

@ -581,12 +581,45 @@ RED.debug = (function() {
var metaRow = $('<div class="red-ui-debug-msg-meta"></div>').appendTo(msg); var metaRow = $('<div class="red-ui-debug-msg-meta"></div>').appendTo(msg);
$('<span class="red-ui-debug-msg-date">'+ getTimestamp()+'</span>').appendTo(metaRow); $('<span class="red-ui-debug-msg-date">'+ getTimestamp()+'</span>').appendTo(metaRow);
if (sourceNode) { if (sourceNode) {
$('<a>',{href:"#",class:"red-ui-debug-msg-name"}).text('node: '+(o.name||sourceNode.name||sourceNode.id))
var nodeLink = $('<a>',{href:"#",class:"red-ui-debug-msg-name"}).text("node: "+(o.name||sourceNode.name||sourceNode.id))
.appendTo(metaRow) .appendTo(metaRow)
.on("click", function(evt) { .on("click", function(evt) {
evt.preventDefault(); evt.preventDefault();
config.messageSourceClick(sourceNode.id, sourceNode._alias, sourceNode.path); config.messageSourceClick(sourceNode.id, sourceNode._alias, sourceNode.path);
}); });
if (sourceNode.pathHierarchy) {
RED.popover.create({
tooltip: true,
target:nodeLink,
trigger: "hover",
size: "small",
direction: "bottom",
interactive: true,
content: function() {
const content = $("<div>")
sourceNode.pathHierarchy.forEach((pathPart,idx) => {
const link = $("<a>", {href:"#" ,style:'display: block'})
.css({
paddingLeft:((idx*10)+((idx === sourceNode.pathHierarchy.length - 1)?10:0))+"px",
paddingRight:'2px'
})
.text(pathPart.label)
.appendTo(content)
.on("click", function(evt) {
evt.preventDefault();
config.messageSourceClick(pathPart.id);
})
if (idx < sourceNode.pathHierarchy.length - 1) {
$('<i class="fa fa-angle-down" style="margin-right: 3px"></i>').prependTo(link)
}
})
return content
},
delay: { show: 50, hide: 150 }
});
}
} else if (name) { } else if (name) {
$('<span class="red-ui-debug-msg-name">'+name+'</span>').appendTo(metaRow); $('<span class="red-ui-debug-msg-name">'+name+'</span>').appendTo(metaRow);
} }