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

Add tooltip on node error icon for validation errs

This commit is contained in:
Nick O'Leary 2019-05-16 14:42:21 +01:00
parent 094c92ed85
commit 68b94737ed
No known key found for this signature in database
GPG Key ID: 4F2157149161A6C9
4 changed files with 49 additions and 38 deletions

View File

@ -321,7 +321,8 @@
"show": "Show", "show": "Show",
"hide": "Hide", "hide": "Hide",
"errors": { "errors": {
"scopeChange": "Changing the scope will make it unavailable to nodes in other flows that use it" "scopeChange": "Changing the scope will make it unavailable to nodes in other flows that use it",
"invalidProperties": "Invalid properties:"
} }
}, },
"keyboard": { "keyboard": {

View File

@ -45,6 +45,7 @@ RED.editor = (function() {
node.valid = true; node.valid = true;
var subflow; var subflow;
var isValid; var isValid;
var validationErrors;
var hasChanged; var hasChanged;
if (node.type.indexOf("subflow:")===0) { if (node.type.indexOf("subflow:")===0) {
subflow = RED.nodes.subflow(node.type.substring(8)); subflow = RED.nodes.subflow(node.type.substring(8));
@ -54,13 +55,17 @@ RED.editor = (function() {
isValid = validateNode(subflow); isValid = validateNode(subflow);
hasChanged = subflow.changed; hasChanged = subflow.changed;
} }
node.valid = isValid && validateNodeProperties(node, node._def.defaults, node); validationErrors = validateNodeProperties(node, node._def.defaults, node);
node.valid = isValid && validationErrors.length === 0;
node.changed = node.changed || hasChanged; node.changed = node.changed || hasChanged;
node.validationErrors = validationErrors;
} else if (node._def) { } else if (node._def) {
node.valid = validateNodeProperties(node, node._def.defaults, node); validationErrors = validateNodeProperties(node, node._def.defaults, node);
if (node._def._creds) { if (node._def._creds) {
node.valid = node.valid && validateNodeProperties(node, node._def.credentials, node._def._creds); validationErrors = validationErrors.concat(validateNodeProperties(node, node._def.credentials, node._def._creds))
} }
node.valid = (validationErrors.length === 0);
node.validationErrors = validationErrors;
} else if (node.type == "subflow") { } else if (node.type == "subflow") {
var subflowNodes = RED.nodes.filterNodes({z:node.id}); var subflowNodes = RED.nodes.filterNodes({z:node.id});
for (var i=0;i<subflowNodes.length;i++) { for (var i=0;i<subflowNodes.length;i++) {
@ -103,18 +108,18 @@ RED.editor = (function() {
* @param node - the node being validated * @param node - the node being validated
* @param definition - the node property definitions (either def.defaults or def.creds) * @param definition - the node property definitions (either def.defaults or def.creds)
* @param properties - the node property values to validate * @param properties - the node property values to validate
* @returns {boolean} whether the node's properties are valid * @returns {array} an array of invalid properties
*/ */
function validateNodeProperties(node, definition, properties) { function validateNodeProperties(node, definition, properties) {
var isValid = true; var result = [];
for (var prop in definition) { for (var prop in definition) {
if (definition.hasOwnProperty(prop)) { if (definition.hasOwnProperty(prop)) {
if (!validateNodeProperty(node, definition, prop, properties[prop])) { if (!validateNodeProperty(node, definition, prop, properties[prop])) {
isValid = false; result.push(prop);
} }
} }
} }
return isValid; return result;
} }
/** /**
@ -127,9 +132,11 @@ RED.editor = (function() {
*/ */
function validateNodeProperty(node,definition,property,value) { function validateNodeProperty(node,definition,property,value) {
var valid = true; var valid = true;
// Check for $(env-var) and consider it valid
if (/^\$\([a-zA-Z_][a-zA-Z0-9_]*\)$/.test(value)) { if (/^\$\([a-zA-Z_][a-zA-Z0-9_]*\)$/.test(value)) {
return true; return true;
} }
// Check for ${env-var} and consider it valid
if (/^\$\{[a-zA-Z_][a-zA-Z0-9_]*\}$/.test(value)) { if (/^\$\{[a-zA-Z_][a-zA-Z0-9_]*\}$/.test(value)) {
return true; return true;
} }

View File

@ -2053,18 +2053,18 @@ RED.view = (function() {
.attr("class","red-ui-flow-port-tooltip"); .attr("class","red-ui-flow-port-tooltip");
var lines = content.split("\n"); var lines = content.split("\n");
var labelWidth = 0; var labelWidth = 6;
var labelHeight = 4; var labelHeight = 12;
var labelHeights = []; var labelHeights = [];
var lineHeight = 0; var lineHeight = 0;
lines.forEach(function(l,i) { lines.forEach(function(l,i) {
var labelDimensions = calculateTextDimensions(l||"&nbsp;", "red-ui-flow-port-tooltip-label", 8,0); var labelDimensions = calculateTextDimensions(l||"&nbsp;", "red-ui-flow-port-tooltip-label", 8,0);
labelWidth = Math.max(labelWidth,labelDimensions[0]); labelWidth = Math.max(labelWidth,labelDimensions[0] + 6);
labelHeights.push(0.8*labelDimensions[1]); labelHeights.push(labelDimensions[1]);
if (i === 0) { if (i === 0) {
lineHeight = 0.8*labelDimensions[1]; lineHeight = labelDimensions[1];
} }
labelHeight += 0.8*labelDimensions[1]; labelHeight += labelDimensions[1];
}); });
var labelWidth1 = (labelWidth/2)-5-2; var labelWidth1 = (labelWidth/2)-5-2;
var labelWidth2 = labelWidth - 4; var labelWidth2 = labelWidth - 4;
@ -2073,20 +2073,20 @@ RED.view = (function() {
var labelHeight2 = labelHeight - 4; var labelHeight2 = labelHeight - 4;
var path; var path;
var lx; var lx;
var ly = -labelHeight/2+1; var ly = -labelHeight/2+3;
var anchor; var anchor;
if (direction === "left") { if (direction === "left") {
path = "M0 0 l -5 -5 v -"+(labelHeight1)+" q 0 -2 -2 -2 h -"+labelWidth+" q -2 0 -2 2 v "+(labelHeight2)+" q 0 2 2 2 h "+labelWidth+" q 2 0 2 -2 v -"+(labelHeight1)+" l 5 -5"; path = "M0 0 l -5 -5 v -"+(labelHeight1)+" q 0 -2 -2 -2 h -"+labelWidth+" q -2 0 -2 2 v "+(labelHeight2)+" q 0 2 2 2 h "+labelWidth+" q 2 0 2 -2 v -"+(labelHeight1)+" l 5 -5";
lx = -10; lx = -14;
anchor = "end"; anchor = "end";
} else if (direction === "right") { } else if (direction === "right") {
path = "M0 0 l 5 -5 v -"+(labelHeight1)+" q 0 -2 2 -2 h "+labelWidth+" q 2 0 2 2 v "+(labelHeight2)+" q 0 2 -2 2 h -"+labelWidth+" q -2 0 -2 -2 v -"+(labelHeight1)+" l -5 -5" path = "M0 0 l 5 -5 v -"+(labelHeight1)+" q 0 -2 2 -2 h "+labelWidth+" q 2 0 2 2 v "+(labelHeight2)+" q 0 2 -2 2 h -"+labelWidth+" q -2 0 -2 -2 v -"+(labelHeight1)+" l -5 -5"
lx = 10; lx = 14;
anchor = "start"; anchor = "start";
} else if (direction === "top") { } else if (direction === "top") {
path = "M0 0 l 5 -5 h "+(labelWidth1)+" q 2 0 2 -2 v -"+labelHeight+" q 0 -2 -2 -2 h -"+(labelWidth2)+" q -2 0 -2 2 v "+labelHeight+" q 0 2 2 2 h "+(labelWidth1)+" l 5 5" path = "M0 0 l 5 -5 h "+(labelWidth1)+" q 2 0 2 -2 v -"+labelHeight+" q 0 -2 -2 -2 h -"+(labelWidth2)+" q -2 0 -2 2 v "+labelHeight+" q 0 2 2 2 h "+(labelWidth1)+" l 5 5"
lx = -labelWidth/2 + 4; lx = -labelWidth/2 + 6;
ly = -labelHeight-lineHeight+5; ly = -labelHeight-lineHeight+10;
anchor = "start"; anchor = "start";
} }
tooltip.append("path").attr("d",path); tooltip.append("path").attr("d",path);
@ -2781,25 +2781,27 @@ RED.view = (function() {
node.append("g").attr("class","red-ui-flow-node-changed hide").attr("transform","translate(20, -2)").append("circle").attr("r",5); node.append("g").attr("class","red-ui-flow-node-changed hide").attr("transform","translate(20, -2)").append("circle").attr("r",5);
var nodeErrorButton = node.append("g").attr("class","red-ui-flow-node-error hide").attr("transform","translate(0, -2)").append("path").attr("d","M -5,4 l 10,0 -5,-8 z"); var nodeErrorButton = node.append("g").attr("class","red-ui-flow-node-error hide").attr("transform","translate(0, -2)").append("path").attr("d","M -5,4 l 10,0 -5,-8 z");
// nodeErrorButton.on("mouseenter", function() { nodeErrorButton.on("mouseenter", function() {
// clearTimeout(portLabelHoverTimeout); if (d.validationErrors && d.validationErrors.length > 0) {
// portLabelHoverTimeout = setTimeout(function() { clearTimeout(portLabelHoverTimeout);
// var pos = getElementPosition(nodeErrorButton.node()); portLabelHoverTimeout = setTimeout(function() {
// portLabelHoverTimeout = null; var pos = getElementPosition(nodeErrorButton.node());
// portLabelHover = showTooltip( portLabelHoverTimeout = null;
// (pos[0]), portLabelHover = showTooltip(
// (pos[1]), (pos[0]),
// tooltip, (pos[1]),
// "top" RED._("editor.errors.invalidProperties")+"\n - "+d.validationErrors.join("\n - "),
// ); "top"
// },500); );
// }).on("mouseleave", function() { },500);
// clearTimeout(portLabelHoverTimeout); }
// if (portLabelHover) { }).on("mouseleave", function() {
// portLabelHover.remove(); clearTimeout(portLabelHoverTimeout);
// portLabelHover = null; if (portLabelHover) {
// } portLabelHover.remove();
// }); portLabelHover = null;
}
});
}); });
node.each(function(d,i) { node.each(function(d,i) {

View File

@ -256,5 +256,6 @@ g.red-ui-flow-link-unknown path.red-ui-flow-link-line {
font-size: 12px; font-size: 12px;
pointer-events: none; pointer-events: none;
-webkit-touch-callout: none; -webkit-touch-callout: none;
white-space: pre;
@include disable-selection; @include disable-selection;
} }