mirror of https://github.com/apache/nifi.git
[NIFI-9423-NIFI-9429]: Show icon and tooltip for Parameters with leading and/or trailing whitespace (#5569)
* NIFI-9423 - Show icon and tooltip for Parameter values that have leading and/or trailing whitespaces NIFI-9429 - Parameters should allow blank values that are non-null (only whitespace) * - Update areas to clean up tooltips in parameter values - Show whitespaces and ellipsis in parameter and property values and tooltips - Update serializeValue to accommodate for blank values * - Address review findings * - Remove commented out code * - Add multiline check for ellipsis * NIFI-9459 - Empty string checked will disable Edit Parameter value field on dialog open * - Add multi-line style to parameter and property table * - Safely insert title attribute content * - Fix Edit Parameter bug that clears textarea for sensitive and empty string values on dialog open This closes #5569
This commit is contained in:
parent
b5414ab195
commit
3d5f357de8
|
@ -53,6 +53,20 @@ div.context-menu-provenance {
|
|||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ellipsis-white-space-pre {
|
||||
white-space: pre;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
/* max 1 line text with ellipsis - works in Chrome and Firefox */
|
||||
.multi-line-clamp-ellipsis {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ellipsis.multiline {
|
||||
white-space: normal;
|
||||
}
|
||||
|
|
|
@ -1292,7 +1292,7 @@
|
|||
// function for formatting the property value
|
||||
var valueFormatter = function (row, cell, value, columnDef, dataContext) {
|
||||
var valueMarkup;
|
||||
var nameWidthOffset = 0;
|
||||
var valueWidthOffset = 0;
|
||||
if (nfCommon.isDefinedAndNotNull(value)) {
|
||||
// get the property descriptor
|
||||
var descriptors = table.data('descriptors');
|
||||
|
@ -1323,14 +1323,20 @@
|
|||
if (!resolvedAllowableValue && nfCommon.isDefinedAndNotNull(propertyDescriptor.identifiesControllerService)) {
|
||||
valueMarkup = '<span class="table-cell blank">Incompatible Controller Service Configured</div>';
|
||||
} else {
|
||||
valueMarkup = '<div class="table-cell value"><pre class="ellipsis">' + nfCommon.escapeHtml(value) + '</pre></div>';
|
||||
valueWidthOffset = 10;
|
||||
|
||||
// add a tooltip icon for trailing and/or leading whitespace
|
||||
if (nfCommon.hasLeadTrailWhitespace(value)) {
|
||||
valueMarkup += '<div class="fa fa-info" alt="Info" style="float: right;"></div>';
|
||||
nameWidthOffset = 20; // 10 + icon width (10)
|
||||
// check for multi-line
|
||||
if (nfCommon.isMultiLine(value)) {
|
||||
valueMarkup = '<div class="table-cell value"><div class="ellipsis-white-space-pre multi-line-clamp-ellipsis">' + nfCommon.escapeHtml(value) + '</div></div>';
|
||||
} else {
|
||||
valueMarkup = '<div class="table-cell value"><div class="ellipsis-white-space-pre">' + nfCommon.escapeHtml(value) + '</div></div>';
|
||||
}
|
||||
|
||||
// check for leading or trailing whitespace
|
||||
if (nfCommon.hasLeadTrailWhitespace(value)) {
|
||||
valueMarkup += '<div class="fa fa-info" alt="Info" style="float: right;"></div>';
|
||||
valueWidthOffset = 20;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1343,7 +1349,8 @@
|
|||
if (dataContext.type === 'required') {
|
||||
content.addClass('required');
|
||||
}
|
||||
content.find('.ellipsis').width(columnDef.width - 10 - nameWidthOffset).ellipsis();
|
||||
var contentValue = content.find('.ellipsis-white-space-pre');
|
||||
contentValue.attr('title', contentValue.text()).width(columnDef.width - 10 - valueWidthOffset);
|
||||
|
||||
// return the appropriate markup
|
||||
return $('<div />').append(content).html();
|
||||
|
@ -1789,13 +1796,11 @@
|
|||
if (whitespaceIcon.length && !whitespaceIcon.data('qtip')) {
|
||||
var whitespaceTooltip = nfCommon.formatWhitespaceTooltip();
|
||||
|
||||
if (nfCommon.isDefinedAndNotNull(whitespaceTooltip)) {
|
||||
whitespaceIcon.qtip($.extend({},
|
||||
nfCommon.config.tooltipConfig,
|
||||
{
|
||||
content: whitespaceTooltip
|
||||
}));
|
||||
}
|
||||
whitespaceIcon.qtip($.extend({},
|
||||
nfCommon.config.tooltipConfig,
|
||||
{
|
||||
content: whitespaceTooltip
|
||||
}));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
@ -196,6 +196,9 @@
|
|||
* Reset the dialog.
|
||||
*/
|
||||
var resetDialog = function () {
|
||||
// clean up any tooltips that may have been generated
|
||||
nfCommon.cleanUpTooltips($('#parameter-table'), 'div.fa-question-circle, div.fa-info');
|
||||
|
||||
$('#parameter-context-name').val('');
|
||||
$('#parameter-context-name-read-only').text('');
|
||||
|
||||
|
@ -227,9 +230,6 @@
|
|||
|
||||
// reset the current parameter context
|
||||
currentParameterContextEntity = null;
|
||||
|
||||
// clean up any tooltips that may have been generated
|
||||
nfCommon.cleanUpTooltips($('#parameter-table'), 'div.fa-question-circle');
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -861,6 +861,9 @@
|
|||
parameterContext: parameterContext
|
||||
});
|
||||
|
||||
// clean up any tooltips that may have been generated
|
||||
nfCommon.cleanUpTooltips($('#parameter-table'), 'div.fa-question-circle, div.fa-info');
|
||||
|
||||
if (_.isNil(param.id)) {
|
||||
var matchingParameter = _.find(parameterData.getItems(), {name: parameter.name});
|
||||
if (_.isNil(matchingParameter)) {
|
||||
|
@ -993,13 +996,13 @@
|
|||
var serializedValue;
|
||||
|
||||
var value = input.val();
|
||||
if (!isChecked && _.isEmpty(value)) {
|
||||
if (!isChecked && value === '') {
|
||||
value = null;
|
||||
}
|
||||
|
||||
var hasChanged = parameter.value !== value;
|
||||
|
||||
if (!nfCommon.isBlank(value)) {
|
||||
if (nfCommon.isDefinedAndNotNull(value)) {
|
||||
// if the value is sensitive and the user has not made a change
|
||||
if (!_.isEmpty(parameter) && parameter.sensitive === true && input.hasClass('sensitive') && parameter.isNew === false) {
|
||||
serializedValue = parameter.previousValue;
|
||||
|
@ -1007,7 +1010,6 @@
|
|||
} else {
|
||||
// value is not sensitive or it is sensitive and the user has changed it then always take the current value
|
||||
serializedValue = value;
|
||||
|
||||
// if the param is sensitive and the param value has not "changed", that means it matches the mask and it should still be considered changed
|
||||
if (!hasChanged && !_.isEmpty(parameter) && parameter.sensitive === true && parameter.isNew === false) {
|
||||
hasChanged = true;
|
||||
|
@ -1061,6 +1063,9 @@
|
|||
parameterContext: originalParameter.parameterContext
|
||||
});
|
||||
|
||||
// clean up any tooltips that may have been generated
|
||||
nfCommon.cleanUpTooltips($('#parameter-table'), 'div.fa-question-circle, div.fa-info');
|
||||
|
||||
// update row for the parameter
|
||||
parameterData.updateItem(originalParameter.id, parameter);
|
||||
|
||||
|
@ -1129,6 +1134,9 @@
|
|||
* @returns {*}
|
||||
*/
|
||||
var updateParameterContext = function (parameterContextEntity) {
|
||||
// clean up any tooltips that may have been generated
|
||||
nfCommon.cleanUpTooltips($('#parameter-table'), 'div.fa-question-circle, div.fa-info');
|
||||
|
||||
var parameters = marshalParameters();
|
||||
var inheritedParameterContexts = marshalInheritedParameterContexts();
|
||||
|
||||
|
@ -1831,6 +1839,7 @@
|
|||
};
|
||||
|
||||
var valueFormatter = function (row, cell, value, columnDef, dataContext) {
|
||||
var valueWidthOffset = 0;
|
||||
if (dataContext.sensitive === true && !_.isNil(value)) {
|
||||
return '<span class="table-cell sensitive">Sensitive value set</span>';
|
||||
} else if (value === '') {
|
||||
|
@ -1838,7 +1847,28 @@
|
|||
} else if (_.isNil(value)) {
|
||||
return '<span class="unset">No value set</span>';
|
||||
} else {
|
||||
return nfCommon.escapeHtml(value);
|
||||
var valueMarkup;
|
||||
valueWidthOffset = 15;
|
||||
|
||||
// check for multi-line
|
||||
if (nfCommon.isMultiLine(value)) {
|
||||
valueMarkup = '<div class="table-cell value"><div class="ellipsis-white-space-pre multi-line-clamp-ellipsis">' + nfCommon.escapeHtml(value) + '</div></div>';
|
||||
} else {
|
||||
valueMarkup = '<div class="table-cell value"><div class="ellipsis-white-space-pre">' + nfCommon.escapeHtml(value) + '</div></div>';
|
||||
}
|
||||
|
||||
// check for leading or trailing whitespace
|
||||
if (nfCommon.hasLeadTrailWhitespace(value)) {
|
||||
valueMarkup += '<div class="fa fa-info" alt="Info" style="float: right;"></div>';
|
||||
valueWidthOffset = 30;
|
||||
}
|
||||
|
||||
// adjust the width accordingly
|
||||
var content = $(valueMarkup);
|
||||
var contentValue = content.find('.ellipsis-white-space-pre');
|
||||
contentValue.attr('title', contentValue.text()).width(columnDef.width - valueWidthOffset);
|
||||
|
||||
return $('<div />').append(content).html();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1922,6 +1952,9 @@
|
|||
|
||||
// determine the desired action
|
||||
if (target.hasClass('delete-parameter')) {
|
||||
// clean any tooltips that may have been added for this item
|
||||
nfCommon.cleanUpTooltips($('#parameter-table'), 'div.fa-question-circle, div.fa-info');
|
||||
|
||||
if (!parameter.isNew) {
|
||||
// mark the parameter in question for removal and refresh the table
|
||||
parameterData.updateItem(parameter.id, $.extend(parameter, {
|
||||
|
@ -1978,7 +2011,10 @@
|
|||
$('#parameter-sensitive-radio-button').prop('disabled', true);
|
||||
$('#parameter-not-sensitive-radio-button').prop('disabled', true);
|
||||
if (parameter.value === '') {
|
||||
$('#parameter-set-empty-string-field').removeClass('checkbox-unchecked').addClass('checkbox-checked');
|
||||
if (!parameter.sensitive) {
|
||||
$('#parameter-set-empty-string-field').removeClass('checkbox-unchecked').addClass('checkbox-checked');
|
||||
$('#parameter-value-field').prop('disabled', true);
|
||||
}
|
||||
} else {
|
||||
$('#parameter-set-empty-string-field').removeClass('checkbox-checked').addClass('checkbox-unchecked');
|
||||
}
|
||||
|
@ -1988,6 +2024,7 @@
|
|||
$('#parameter-not-sensitive-radio-button').prop('checked', false);
|
||||
if (!_.isNil(parameter.value)) {
|
||||
$('#parameter-value-field').addClass('sensitive').val(nfCommon.config.sensitiveText).select();
|
||||
$('#parameter-set-empty-string-field').removeClass('checkbox-checked').addClass('checkbox-unchecked');
|
||||
}
|
||||
} else {
|
||||
$('#parameter-sensitive-radio-button').prop('checked', false);
|
||||
|
@ -2124,6 +2161,17 @@
|
|||
}));
|
||||
}
|
||||
}
|
||||
|
||||
var whitespaceIcon = $(this).find('div.fa-info');
|
||||
if (whitespaceIcon.length && !whitespaceIcon.data('qtip')) {
|
||||
var whitespaceTooltip = nfCommon.formatWhitespaceTooltip();
|
||||
|
||||
whitespaceIcon.qtip($.extend({},
|
||||
nfCommon.config.tooltipConfig,
|
||||
{
|
||||
content: whitespaceTooltip
|
||||
}));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -2202,6 +2250,8 @@
|
|||
|
||||
$('#add-parameter').on('click', function () {
|
||||
var closeHandler = function () {
|
||||
// clean up any tooltips that may have been generated
|
||||
nfCommon.cleanUpTooltips($('#parameter-table'), 'div.fa-question-circle, div.fa-info');
|
||||
resetParameterDialog();
|
||||
};
|
||||
|
||||
|
|
|
@ -1008,16 +1008,20 @@
|
|||
},
|
||||
|
||||
/**
|
||||
* Checks the specified value for leading and/or trailing whitespace.
|
||||
* Constant regex for leading and/or trailing whitespace.
|
||||
*/
|
||||
LEAD_TRAIL_WHITE_SPACE_REGEX: /^[ \s]+|[ \s]+$/,
|
||||
|
||||
/**
|
||||
* Checks the specified value for leading and/or trailing whitespace only.
|
||||
*
|
||||
* @argument {string} value The value to check
|
||||
*/
|
||||
hasLeadTrailWhitespace : function (value) {
|
||||
if ( !value || value.trim().length === 0 ) {
|
||||
if (nfCommon.isBlank(value)) {
|
||||
return false;
|
||||
}
|
||||
var leadOrTrailWhitespaceRegex = /^[ \s]+|[ \s]+$/;
|
||||
return leadOrTrailWhitespaceRegex.test(value);
|
||||
return nfCommon.LEAD_TRAIL_WHITE_SPACE_REGEX.test(value);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1817,6 +1821,20 @@
|
|||
return key.split('.').reduce(function(o,x){
|
||||
return(typeof o === undefined || o === null)? o : (typeof o[x] == 'function')?o[x]():o[x];
|
||||
}, obj);
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if the given value has multi-lines.
|
||||
*
|
||||
* @param value to check
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isMultiLine: function (value) {
|
||||
const multiLineMatcher = /\n/.exec(value);
|
||||
if (multiLineMatcher) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue