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:
parent
094c92ed85
commit
68b94737ed
@ -321,7 +321,8 @@
|
||||
"show": "Show",
|
||||
"hide": "Hide",
|
||||
"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": {
|
||||
|
@ -45,6 +45,7 @@ RED.editor = (function() {
|
||||
node.valid = true;
|
||||
var subflow;
|
||||
var isValid;
|
||||
var validationErrors;
|
||||
var hasChanged;
|
||||
if (node.type.indexOf("subflow:")===0) {
|
||||
subflow = RED.nodes.subflow(node.type.substring(8));
|
||||
@ -54,13 +55,17 @@ RED.editor = (function() {
|
||||
isValid = validateNode(subflow);
|
||||
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.validationErrors = validationErrors;
|
||||
} else if (node._def) {
|
||||
node.valid = validateNodeProperties(node, node._def.defaults, node);
|
||||
validationErrors = validateNodeProperties(node, node._def.defaults, node);
|
||||
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") {
|
||||
var subflowNodes = RED.nodes.filterNodes({z:node.id});
|
||||
for (var i=0;i<subflowNodes.length;i++) {
|
||||
@ -103,18 +108,18 @@ RED.editor = (function() {
|
||||
* @param node - the node being validated
|
||||
* @param definition - the node property definitions (either def.defaults or def.creds)
|
||||
* @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) {
|
||||
var isValid = true;
|
||||
var result = [];
|
||||
for (var prop in definition) {
|
||||
if (definition.hasOwnProperty(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) {
|
||||
var valid = true;
|
||||
// Check for $(env-var) and consider it valid
|
||||
if (/^\$\([a-zA-Z_][a-zA-Z0-9_]*\)$/.test(value)) {
|
||||
return true;
|
||||
}
|
||||
// Check for ${env-var} and consider it valid
|
||||
if (/^\$\{[a-zA-Z_][a-zA-Z0-9_]*\}$/.test(value)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -2053,18 +2053,18 @@ RED.view = (function() {
|
||||
.attr("class","red-ui-flow-port-tooltip");
|
||||
|
||||
var lines = content.split("\n");
|
||||
var labelWidth = 0;
|
||||
var labelHeight = 4;
|
||||
var labelWidth = 6;
|
||||
var labelHeight = 12;
|
||||
var labelHeights = [];
|
||||
var lineHeight = 0;
|
||||
lines.forEach(function(l,i) {
|
||||
var labelDimensions = calculateTextDimensions(l||" ", "red-ui-flow-port-tooltip-label", 8,0);
|
||||
labelWidth = Math.max(labelWidth,labelDimensions[0]);
|
||||
labelHeights.push(0.8*labelDimensions[1]);
|
||||
labelWidth = Math.max(labelWidth,labelDimensions[0] + 6);
|
||||
labelHeights.push(labelDimensions[1]);
|
||||
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 labelWidth2 = labelWidth - 4;
|
||||
@ -2073,20 +2073,20 @@ RED.view = (function() {
|
||||
var labelHeight2 = labelHeight - 4;
|
||||
var path;
|
||||
var lx;
|
||||
var ly = -labelHeight/2+1;
|
||||
var ly = -labelHeight/2+3;
|
||||
var anchor;
|
||||
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";
|
||||
lx = -10;
|
||||
lx = -14;
|
||||
anchor = "end";
|
||||
} 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"
|
||||
lx = 10;
|
||||
lx = 14;
|
||||
anchor = "start";
|
||||
} 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"
|
||||
lx = -labelWidth/2 + 4;
|
||||
ly = -labelHeight-lineHeight+5;
|
||||
lx = -labelWidth/2 + 6;
|
||||
ly = -labelHeight-lineHeight+10;
|
||||
anchor = "start";
|
||||
}
|
||||
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);
|
||||
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() {
|
||||
// clearTimeout(portLabelHoverTimeout);
|
||||
// portLabelHoverTimeout = setTimeout(function() {
|
||||
// var pos = getElementPosition(nodeErrorButton.node());
|
||||
// portLabelHoverTimeout = null;
|
||||
// portLabelHover = showTooltip(
|
||||
// (pos[0]),
|
||||
// (pos[1]),
|
||||
// tooltip,
|
||||
// "top"
|
||||
// );
|
||||
// },500);
|
||||
// }).on("mouseleave", function() {
|
||||
// clearTimeout(portLabelHoverTimeout);
|
||||
// if (portLabelHover) {
|
||||
// portLabelHover.remove();
|
||||
// portLabelHover = null;
|
||||
// }
|
||||
// });
|
||||
nodeErrorButton.on("mouseenter", function() {
|
||||
if (d.validationErrors && d.validationErrors.length > 0) {
|
||||
clearTimeout(portLabelHoverTimeout);
|
||||
portLabelHoverTimeout = setTimeout(function() {
|
||||
var pos = getElementPosition(nodeErrorButton.node());
|
||||
portLabelHoverTimeout = null;
|
||||
portLabelHover = showTooltip(
|
||||
(pos[0]),
|
||||
(pos[1]),
|
||||
RED._("editor.errors.invalidProperties")+"\n - "+d.validationErrors.join("\n - "),
|
||||
"top"
|
||||
);
|
||||
},500);
|
||||
}
|
||||
}).on("mouseleave", function() {
|
||||
clearTimeout(portLabelHoverTimeout);
|
||||
if (portLabelHover) {
|
||||
portLabelHover.remove();
|
||||
portLabelHover = null;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
node.each(function(d,i) {
|
||||
|
@ -256,5 +256,6 @@ g.red-ui-flow-link-unknown path.red-ui-flow-link-line {
|
||||
font-size: 12px;
|
||||
pointer-events: none;
|
||||
-webkit-touch-callout: none;
|
||||
white-space: pre;
|
||||
@include disable-selection;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user