diff --git a/hyperglass/configuration/models/messages.py b/hyperglass/configuration/models/messages.py index 765712c..037e581 100644 --- a/hyperglass/configuration/models/messages.py +++ b/hyperglass/configuration/models/messages.py @@ -13,8 +13,6 @@ from hyperglass.configuration.models._utils import HyperglassModel class Messages(HyperglassModel): """Class model for params.messages""" - no_query_type: str = "A query type must be specified." - no_location: str = "A location must be selected." no_input: str = "{field} must be specified." acl_denied: str = "{target} is a member of {denied_network}, which is not allowed." acl_not_allowed: str = "{target} is not allowed." diff --git a/hyperglass/static/src/js/errors.es6 b/hyperglass/static/src/js/errors.es6 index 270c7ed..f59617c 100644 --- a/hyperglass/static/src/js/errors.es6 +++ b/hyperglass/static/src/js/errors.es6 @@ -1,4 +1,5 @@ import { frontEndAlert } from './components.es6'; +import jQuery from '../node_modules/jquery'; class InputInvalid extends Error { constructor(validationMsg, invalidField, fieldContainer) { diff --git a/hyperglass/static/src/js/hyperglass.es6 b/hyperglass/static/src/js/hyperglass.es6 index 1b5de99..95582f4 100644 --- a/hyperglass/static/src/js/hyperglass.es6 +++ b/hyperglass/static/src/js/hyperglass.es6 @@ -1,4 +1,5 @@ // Module Imports +import format from '../node_modules/string-format'; import jQuery from '../node_modules/jquery'; import ClipboardJS from '../node_modules/clipboard'; @@ -19,6 +20,9 @@ import { queryApp } from './query.es6'; // JSON Config Import import hgConf from './frontend.json'; +// string-format config +format.extend(String.prototype, {}); + const $ = jQuery; const lgForm = $('#lgForm'); @@ -104,9 +108,15 @@ $(document).ready(() => { } }); -queryType.on('changed.bs.select', () => { - const queryTypeId = queryType.val(); +queryType.on('changed.bs.select', (e) => { + const field = $(e.currentTarget); + const queryTypeId = field.val(); const queryTypeBtn = $('.hg-info-btn'); + + if (field.next('button').hasClass('is-invalid')) { + field.next('button').removeClass('is-invalid'); + field.nextAll('.invalid-feedback').remove(); + } if ((queryTypeId === 'bgp_community') || (queryTypeId === 'bgp_aspath')) { queryTypeBtn.remove(); queryTargetAppend.prepend(supportedBtn(queryTypeId)); @@ -116,11 +126,15 @@ queryType.on('changed.bs.select', () => { }); queryLocation.on('changed.bs.select', (e, clickedIndex, isSelected, previousValue) => { - const net = $(e.currentTarget); + const field = $(e.currentTarget); + if (field.next('button').hasClass('is-invalid')) { + field.next('button').removeClass('is-invalid'); + field.nextAll('.invalid-feedback').remove(); + } vrfContainer.empty().removeClass('col'); - const queryLocationIds = net.val(); + const queryLocationIds = field.val(); if (Array.isArray(queryLocationIds) && (queryLocationIds.length)) { - const queryLocationNet = net[0][clickedIndex].dataset.netname; + const queryLocationNet = field[0][clickedIndex].dataset.netname; const selectedVrfs = () => { const allVrfs = []; $.each(queryLocationIds, (i, loc) => { @@ -189,9 +203,6 @@ lgForm.on('submit', (e) => { if (!Array.isArray(queryLocation)) { queryLocation = new Array(queryLocation); } - const queryTargetContainer = $('#query_target'); - const queryTypeContainer = $('#query_type').next('.dropdown-toggle'); - const queryLocationContainer = $('#location').next('.dropdown-toggle'); try { /* @@ -201,29 +212,33 @@ lgForm.on('submit', (e) => { 3: place to put error message */ if (!queryTarget) { + const msgVars = { field: hgConf.config.branding.text.query_target }; throw new InputInvalid( - hgConf.config.messages.no_input, - queryTargetContainer, - queryTargetContainer.parent(), + hgConf.config.messages.no_input.format(msgVars), + $('#query_target'), + $('#query_target').parent(), ); } if (!queryType) { + const msgVars = { field: hgConf.config.branding.text.query_type }; throw new InputInvalid( - hgConf.config.messages.no_query_type, - queryTypeContainer, - queryTypeContainer.parent(), + hgConf.config.messages.no_input.format(msgVars), + $('#query_type').next('.dropdown-toggle'), + $('#query_type').next('.dropdown-toggle').parent(), ); } if (queryLocation === undefined || queryLocation.length === 0) { + const msgVars = { field: hgConf.config.branding.text.query_location }; throw new InputInvalid( - hgConf.config.messages.no_location, - queryLocationContainer, - queryLocationContainer.parent(), + hgConf.config.messages.no_input.format(msgVars), + $('#location').next('.dropdown-toggle'), + $('#location').next('.dropdown-toggle').parent(), ); } } catch (err) { - err.field.addClass('is-invalid'); - err.container.append(feedbackInvalid(err.message)); + $(err.field).addClass('is-invalid'); + $(err.container).find('.invalid-feedback').remove(); + $(err.container).append(feedbackInvalid(err.message)); submitIcon.empty().removeClass('hg-loading').html(''); $(document).trigger('InvalidInputEvent', err.field); return false; diff --git a/hyperglass/static/src/package.json b/hyperglass/static/src/package.json index e4198b8..de4ea64 100644 --- a/hyperglass/static/src/package.json +++ b/hyperglass/static/src/package.json @@ -19,6 +19,7 @@ "popper.js": "^1.15.0", "remixicon": "^1.3.1", "sass": "^1.22.10", + "string-format": "^2.0.0", "tinyify": "^2.5.1", "watchify": "^3.11.1" }, @@ -38,4 +39,4 @@ "@babel/preset-react" ] } -} \ No newline at end of file +} diff --git a/hyperglass/static/src/yarn.lock b/hyperglass/static/src/yarn.lock index 6f0f348..4cac38c 100644 --- a/hyperglass/static/src/yarn.lock +++ b/hyperglass/static/src/yarn.lock @@ -6512,6 +6512,11 @@ strict-uri-encode@^1.0.0: resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= +string-format@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/string-format/-/string-format-2.0.0.tgz#f2df2e7097440d3b65de31b6d40d54c96eaffb9b" + integrity sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA== + string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"