diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/main.css b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/main.css index fc6c807ea2..8f0500fd85 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/main.css +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/main.css @@ -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; } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/propertytable/jquery.propertytable.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/propertytable/jquery.propertytable.js index 88691721c0..dfa9aa1a2f 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/propertytable/jquery.propertytable.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/propertytable/jquery.propertytable.js @@ -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 = 'Incompatible Controller Service Configured'; } else { - valueMarkup = '
' + nfCommon.escapeHtml(value) + '
'; + valueWidthOffset = 10; - // add a tooltip icon for trailing and/or leading whitespace - if (nfCommon.hasLeadTrailWhitespace(value)) { - valueMarkup += '
'; - nameWidthOffset = 20; // 10 + icon width (10) + // check for multi-line + if (nfCommon.isMultiLine(value)) { + valueMarkup = '
' + nfCommon.escapeHtml(value) + '
'; + } else { + valueMarkup = '
' + nfCommon.escapeHtml(value) + '
'; } + // check for leading or trailing whitespace + if (nfCommon.hasLeadTrailWhitespace(value)) { + valueMarkup += '
'; + 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 $('
').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 + })); } }); }; diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-parameter-contexts.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-parameter-contexts.js index 146b627d68..2503d67e0a 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-parameter-contexts.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-parameter-contexts.js @@ -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 'Sensitive value set'; } else if (value === '') { @@ -1838,7 +1847,28 @@ } else if (_.isNil(value)) { return 'No value set'; } else { - return nfCommon.escapeHtml(value); + var valueMarkup; + valueWidthOffset = 15; + + // check for multi-line + if (nfCommon.isMultiLine(value)) { + valueMarkup = '
' + nfCommon.escapeHtml(value) + '
'; + } else { + valueMarkup = '
' + nfCommon.escapeHtml(value) + '
'; + } + + // check for leading or trailing whitespace + if (nfCommon.hasLeadTrailWhitespace(value)) { + valueMarkup += '
'; + 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 $('
').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(); }; diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js index aa646c0db3..86483c9cb9 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js @@ -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; } };