diff options
-rw-r--r-- | app/assets/images/icon-edit-blue.svg | 24 | ||||
-rw-r--r-- | app/assets/images/icon-plus.svg | 30 | ||||
-rw-r--r-- | app/assets/images/icon-trashcan-blue.svg | 16 | ||||
-rw-r--r-- | app/configuration/controllers/snmp-controller.html | 98 | ||||
-rw-r--r-- | app/configuration/controllers/snmp-controller.js | 25 | ||||
-rw-r--r-- | app/configuration/styles/snmp.scss | 134 |
6 files changed, 243 insertions, 84 deletions
diff --git a/app/assets/images/icon-edit-blue.svg b/app/assets/images/icon-edit-blue.svg new file mode 100644 index 0000000..ba2cc40 --- /dev/null +++ b/app/assets/images/icon-edit-blue.svg @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <!-- Generator: Sketch 51.3 (57544) - http://www.bohemiancoding.com/sketch --> + <title>Colors/Base/Black</title> + <desc>Created with Sketch.</desc> + <defs> + <path d="M7.92572798,3.00428655 L1.00199753,9.34382025 L1.00199753,11.6237002 L3.30623854,11.6237002 L10.2321641,5.30721897 L7.92572798,3.00428655 Z M8.66400508,2.32830232 L10.9718396,4.63263098 L12.4234573,3.30874783 L10.1147108,1.00000135 L8.66400508,2.32830232 Z M0.00199752679,8.9035802 L9.43940417,0.262464274 C9.8341134,-0.0989409664 10.4433938,-0.0855292166 10.8218176,0.29289457 L13.1305641,2.60164105 C13.5210884,2.99216534 13.5210884,3.62533032 13.1305641,4.01585461 C13.1197237,4.02669497 13.1086355,4.03728461 13.0973082,4.04761513 L3.69376146,12.6237002 L0.00199752679,12.6237002 L0.00199752679,8.9035802 Z M0,15.6371142 L0,14.6371142 L16,14.6371142 L16,15.6371142 L0,15.6371142 Z" id="path-1"></path> + </defs> + <g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> + <g id="Icon/Edit"> + <g id="Colors/Base/Black"> + <mask id="mask-2" fill="white"> + <use xlink:href="#path-1"></use> + </mask> + <use id="Mask" fill="#2d60e5" fill-rule="nonzero" xlink:href="#path-1"></use> + <g id="Colors/Base/Blue50" mask="url(#mask-2)" fill="#3c6df0"> + <g transform="translate(-8.377562, -8.431784)" id="Rectangle-6-Copy"> + <rect x="0" y="0" width="35" height="35"></rect> + </g> + </g> + </g> + </g> + </g> +</svg>
\ No newline at end of file diff --git a/app/assets/images/icon-plus.svg b/app/assets/images/icon-plus.svg index 21566bc..0e18b22 100644 --- a/app/assets/images/icon-plus.svg +++ b/app/assets/images/icon-plus.svg @@ -1,13 +1,21 @@ -<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" - viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve"> -<style type="text/css"> - .st0{fill:#FFFFFF;} - .st1{fill:#2d60e5;} -</style> -<g id="Layer_2"> - <rect x="3.7" y="4" class="st0" width="8.4" height="8.1"/> -</g> -<g id="Layer_1"> - <path class="st1" d="M8,0C3.6,0,0,3.6,0,8s3.6,8,8,8s8-3.6,8-8S12.4,0,8,0z M12,9H9v3H7V9H4V7h3V4h2v3h3V9z"/> +<?xml version="1.0" encoding="UTF-8"?> +<svg width="19px" height="19px" viewBox="0 0 19 19" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<defs> + <path d="M10.3189655,8.7447318 L13.822318,8.7447318 L13.822318,10.5464559 L10.3189655,10.5464559 L10.3189655,14.0498084 L8.51724138,14.0498084 L8.51724138,10.5464559 L5.01388889,10.5464559 L5.01388889,8.7447318 L8.51724138,8.7447318 L8.51724138,5.24137931 L10.3189655,5.24137931 L10.3189655,8.7447318 Z M9.5,19 C4.25329488,19 0,14.7467051 0,9.5 C0,4.25329488 4.25329488,0 9.5,0 C14.7467051,0 19,4.25329488 19,9.5 C19,14.7467051 14.7467051,19 9.5,19 Z M9.55533929,17.6650264 C14.0341958,17.6650264 17.6650264,14.0341958 17.6650264,9.55533929 C17.6650264,5.07648277 14.0341958,1.44565217 9.55533929,1.44565217 C5.07648277,1.44565217 1.44565217,5.07648277 1.44565217,9.55533929 C1.44565217,14.0341958 5.07648277,17.6650264 9.55533929,17.6650264 Z" id="path-1"></path> +</defs> +<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> + <g id="Icon/Add" transform="translate(-6.000000, -6.000000)"> + <g id="Icon" transform="translate(6.000000, 6.000000)"> + <mask id="mask-2" fill="white"> + <use xlink:href="#path-1"></use> + </mask> + <use id="Mask" fill="#2d60e5" fill-rule="nonzero" xlink:href="#path-1"></use> + <g id="Colors/Base/Blue50" mask="url(#mask-2)" fill="#3c6df0"> + <g transform="translate(-3.275862, -3.931034)" id="Rectangle-6-Copy"> + <rect x="0" y="0" width="25" height="25"></rect> + </g> + </g> + </g> + </g> </g> </svg> diff --git a/app/assets/images/icon-trashcan-blue.svg b/app/assets/images/icon-trashcan-blue.svg new file mode 100644 index 0000000..87a82d8 --- /dev/null +++ b/app/assets/images/icon-trashcan-blue.svg @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> +<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" + viewBox="0 0 22 22" style="enable-background:new 0 0 22 22;" xml:space="preserve"> +<style type="text/css"> + .st0{fill:#2d60e5;} +</style> +<g> + <rect x="8.1" y="1" class="st0" width="5.7" height="1.4"/> + <path class="st0" d="M3.9,3.1v3.6h0.7V21h12.9V6.7h0.7V3.1H3.9z M16,19.6H6V8.1h10V19.6z"/> + <rect x="7.4" y="9.6" class="st0" width="0.7" height="8.6"/> + <rect x="9.6" y="9.6" class="st0" width="0.7" height="8.6"/> + <rect x="11.7" y="9.6" class="st0" width="0.7" height="8.6"/> + <rect x="13.9" y="9.6" class="st0" width="0.7" height="8.6"/> +</g> +</svg> diff --git a/app/configuration/controllers/snmp-controller.html b/app/configuration/controllers/snmp-controller.html index ac03497..ee3d0d0 100644 --- a/app/configuration/controllers/snmp-controller.html +++ b/app/configuration/controllers/snmp-controller.html @@ -2,30 +2,90 @@ <div id="configuration-snmp"> <div class="row column"> <h1>SNMP settings</h1> + <div class="small-12 snmp_description"> + Set the Simple Network Management Protocol (SNMP) with a host name or IP address and a port. + </div> + <div class="page-header"> + <h2>Managers</h2> + </div> </div> - <form class="snmp__form" role="form" action=""> - <div class="page-header"> - <h2>Set the Simple Network Management Protocol (SNMP)</h2> + <div class="row column"> + <div class="small-8"> + <div class="row column manager_group"> + <div class="small-5 snmp__address"> + <h3>Host name or IP Address</h3> + </div> + <div class="small-5 snmp__port label"> + <h3>Port</h3> + </div> </div> - <fieldset> - <div class="row column snmp__managers-wrap"> - <div class="snmp__managers" ng-repeat="manager in managers track by $index"> - <div class="snmp__manager-field"> - <label>SNMP Manager Server</label> - <input class="inline" id="snmp-manager{{$index+1}}-address" ng-change="manager.updateAddress = true" type="text" ng-model="manager.address" ng-blur="managers[$index].address = manager.address"/> - </div> - <div class="snmp__manager-field"> - <label>Port</label> - <input class="inline" id="snmp-manager{{$index+1}}-port" type="text" ng-change="manager.updatePort = true" ng-model="manager.port" ng-blur="managers[$index].port = manager.port"/> + <div class="row column manager_group empty" ng-if="managers.length <1"> + No managers have been added yet. + </div> + <form id="snmp__form" name="snmp__form" novalidate> + <div class="row column manager_group" ng-form="manager_group" ng-repeat="manager in managers track by $index"> + <div class="small-11 snmp__fields"> + <div class="row column"> + <div class="small-10"> + <div class="row column"> + <div class="small-offset-6 small-6 help__text snmp__port"> + Value must be between 0-65,535 + </div> + </div> + <div class="row column" ng-class="{'submitted':submitted}"> + <div class="small-6 snmp__address"> + <input id="snmp-manager{{$index+1}}-address" + name="snmp-manager{{$index+1}}-address" + type="text" + ng-change="manager.updateAddress=true" + ng-model="manager.address" + required /> + <div ng-messages="manager_group['snmp-manager'+($index+1)+'-address'].$error" class="form-error" ng-class="{'visible': manager_group['snmp-manager'+($index+1)+'-address'].$touched || submitted}"> + <p ng-message="required" role="alert">Field is required</p> + </div> + </div> + <div class="small-6 snmp__port"> + <input id="snmp-manager{{$index+1}}-port" + name="snmp-manager{{$index+1}}-port" + type="number" + min="0" + max="65535" + step="1" + ng-change="manager.updatePort=true" + ng-model="manager.port" + required/> + <div ng-messages="manager_group['snmp-manager'+($index+1)+'-port'].$error" class="form-error" ng-class="{'visible': manager_group['snmp-manager'+($index+1)+'-port'].$touched || submitted}"> + <div ng-message-exp="['min', 'max', 'number', 'step']"> + Invalid format + </div> + <p ng-message="required" role="alert">Field is required</p> + </div> + </div> + </div> + </div> + <div class="small-2 align-self-center snmp__buttons"> + <button class="edit_button" type="button"> + <img src="../../assets/images/icon-edit-blue.svg" alt="Edit"> + </button> + </div> </div> - <button class="snmp__manager-remove" ng-click="removeSNMPManager($index)">Remove</button> </div> - <button type="button" class="btn-primary inline" ng-click="addNewSNMPManager()">Add SNMP manager</button> + <div class="small-1 align-self-center snmp__buttons trash"> + <button class="trash_button" type="button" ng-click="removeSNMPManager($index)"> + <img src="../../assets/images/icon-trashcan-blue.svg" alt="Remove"> + </button> + </div> + </div> + <div class="row column"> + <button class="btn-add" type="button" ng-click="submitted=false; addNewSNMPManager();"><img class="add__icon" src="../../assets/images/icon-plus.svg" alt=""/> Add manager</button> </div> - </fieldset> + </form> + </div> + </div> + <div class="row column"> <div class="snmp__submit-wrapper"> - <button type="button" class="btn-primary inline" ng-click="setSNMP()">Save settings</button> + <button type="button" ng-click="submitted=true; snmp__form.$valid && setSNMP();" class="btn-primary inline">Save settings</button> <button type="button" class="btn-secondary inline" ng-click="refresh()">Cancel</button> </div> - </form> -</div> + </div> +</div>
\ No newline at end of file diff --git a/app/configuration/controllers/snmp-controller.js b/app/configuration/controllers/snmp-controller.js index 9d71765..67e210f 100644 --- a/app/configuration/controllers/snmp-controller.js +++ b/app/configuration/controllers/snmp-controller.js @@ -60,24 +60,19 @@ window.angular && (function(angular) { $scope.loading = true; var promises = []; - // Interate in reverse so can splice - // https://stackoverflow.com/questions/9882284/looping-through-array-and-removing-items-without-breaking-for-loop - var i = $scope.managers.length; - while (i--) { - // Remove any SNMP Manager with an empty address and port - if (!$scope.managers[i].address && !$scope.managers[i].port) { - $scope.removeSNMPManager(i); - continue; - } - - // Throw an error if only 1 of the fields is filled out + // Validate that no field are empty and port is valid. Port value is + // undefined if it is an invalid number. + for (var i in $scope.managers) { if (!$scope.managers[i].address || !$scope.managers[i].port) { - // TODO: Highlight the field that is empty $scope.loading = false; - toastService.error('All fields are required.'); + toastService.error('Cannot save. Please resolve errors on page.'); return; } - + } + // Iterate in reverse so can splice + // https://stackoverflow.com/questions/9882284/looping-through-array-and-removing-items-without-breaking-for-loop + var i = $scope.managers.length; + while (i--) { // If the manager does not have a 'path', it is a new manager // and needs to be created if (!$scope.managers[i].path) { @@ -104,7 +99,7 @@ window.angular && (function(angular) { $q.all(promises) .then( function() { - toastService.success('SNMP Managers set.'); + toastService.success('SNMP settings have been saved.'); }, function(errors) { toastService.error('Unable to set SNMP Managers.'); diff --git a/app/configuration/styles/snmp.scss b/app/configuration/styles/snmp.scss index 1afefd0..47dc80f 100644 --- a/app/configuration/styles/snmp.scss +++ b/app/configuration/styles/snmp.scss @@ -1,51 +1,107 @@ -// SNMP SCSS - -.snmp__form { - - fieldset { - padding-left: 1.8em; - } - .snmp__managers { - padding-bottom: 1.5em; - } - - .snmp__manager-field { - display:inline-block; - padding-right: 4em; - width: 350px; - padding-top: .6em; - padding-left: 0em; - } - - .snmp__metadata-wrapper { - margin: 0; +#configuration-snmp { + .row { + padding-left: 0; + } + .snmp_description { + padding:1em 0 1em 0; + } + .help__text { + font-size: 0.8rem; + color: $disabled-row-txt; + padding-top: .3em; + display: none; + } + .form-error{ + display: none; + } + .manager_group { + border-bottom: 1px solid $lightbg__grey; + &.ng-invalid { + input { + color: black; + border-style: solid; + pointer-events: auto; + } + .help__text { + display: block; + } + .form-error { + display: block; + } + } + &.empty { + color: $disabled-row-txt; + padding: 1em 0 1em 0; + } + } + .snmp__port { + padding: .3em 0 .3em 1em; + &.label { + padding: .3em 0 .3em 0em; + } + } + .snmp__address { + padding: .3em 1em .3em 0; + } + .snmp__fields { + input { + border-style: none; + pointer-events: none; + color: $disabled-row-txt; + height: 2.4em; + } + &:focus-within { + input { + color: $black; + border-style: solid; + pointer-events: auto; + } + .form-error { + display: block; + } + .help__text { + display: block; + } + } + } + .snmp__buttons { + text-align: right; + padding-right: .5em; + &.trash{ + text-align: left; + } + button{ + margin:.3em; + img{ + width: 100%; + height:100%; + } + } + } + .trash_button { padding: 0; + width: 1.3em; + height: 1.3em; } - - .snmp__managers-wrap{ - padding-bottom: 1em; - padding-top: 1em; - padding-left: 3em; - padding-right: 4em; + .edit_button { + padding: 0; + width: 1.3em; + height: 1.2em; + } + .btn-add { + &:focus { + outline:0; + } + margin-top: 1em; + color: $primebtn__bg; + padding: 2em 0 3em 0; } - .snmp__submit-wrapper { width: 100%; - margin-top: 3em; - padding-top: 1em; border-top: 1px solid $medgrey; button { float: right; margin: .5em; } } - .snmp__manager-remove { - display:inline-block; - color: $medblue; - height: 2.1em; - opacity: 1; - &:hover { - cursor: pointer; - } - } } |