Add toast notifications to SNMP page

Design team proposed that our error and success messages be
delivered as 'toast' messages on the right side of the screen.
This brings in ngToast and implements notifications on SNMP page.
Notifications will fade after 10 seconds or can be dismissed.

https://github.com/tameraydin/ngToast

Change-Id: I1053534cd1ab189ae5c2ac07e2a922acea231c70
Signed-off-by: beccabroek <beccabroek@gmail.com>
diff --git a/app/common/styles/elements/index.scss b/app/common/styles/elements/index.scss
index 9a6fe55..dd32703 100644
--- a/app/common/styles/elements/index.scss
+++ b/app/common/styles/elements/index.scss
@@ -13,3 +13,4 @@
 @import "quicklinks";
 @import "errors";
 @import "success";
+@import "toast";
diff --git a/app/common/styles/elements/toast.scss b/app/common/styles/elements/toast.scss
new file mode 100644
index 0000000..ae6d1bc
--- /dev/null
+++ b/app/common/styles/elements/toast.scss
@@ -0,0 +1,28 @@
+// Overrides style for ngToast notifications
+.ng-toast {
+  margin-top: 9em;
+  .close {
+    margin: .3em;
+  }
+  .title {
+    font-weight: bold;
+  }
+  .ng-toast__message {
+    max-width: 400px;
+  }
+  .alert {
+    color: #333;
+    border-radius: 0;
+    text-align: left;
+  }
+  .alert-success::before {
+    content: "Success!";
+    display: block;
+    font-weight: bold;
+  }
+  .alert-danger::before {
+    content: "Error";
+    display: block;
+    font-weight: bold;
+  }
+}
diff --git a/app/configuration/controllers/snmp-controller.html b/app/configuration/controllers/snmp-controller.html
index e1f2bc9..586ee33 100644
--- a/app/configuration/controllers/snmp-controller.html
+++ b/app/configuration/controllers/snmp-controller.html
@@ -27,7 +27,5 @@
       <button type="button" class="btn-primary inline" ng-click="setSNMP()">Save settings</button>
       <button type="button" class="btn-secondary inline" ng-click="refresh()">Cancel</button>
     </div>
-    <p class="success-msg" ng-show="success" role="alert">Success! SNMP managers updated!</p>
-    <p class="error error-msg" ng-show="error" role="alert">Error setting SNMP Managers!</p>
   </form>
 </div>
diff --git a/app/configuration/controllers/snmp-controller.js b/app/configuration/controllers/snmp-controller.js
index e2c2b22..4ad0685 100644
--- a/app/configuration/controllers/snmp-controller.js
+++ b/app/configuration/controllers/snmp-controller.js
@@ -10,12 +10,10 @@
   'use strict';
 
   angular.module('app.configuration').controller('snmpController', [
-    '$scope', '$window', 'APIUtils', '$route', '$q',
-    function($scope, $window, APIUtils, $route, $q) {
+    '$scope', '$window', 'APIUtils', '$route', '$q', 'ngToast',
+    function($scope, $window, APIUtils, $route, $q, ngToast) {
       $scope.managers = [];
       $scope.loading = true;
-      $scope.error = false;
-      $scope.success = false;
       $scope.managersToDelete = [];
 
       var getSNMPManagers = APIUtils.getSNMPManagers().then(
@@ -33,6 +31,7 @@
             }
           },
           function(error) {
+            ngToast.danger('Unable to load SNMP settings.');
             console.log(JSON.stringify(error));
           });
 
@@ -58,8 +57,6 @@
       };
 
       $scope.setSNMP = function() {
-        $scope.error = false;
-        $scope.success = false;
         $scope.loading = true;
         var promises = [];
 
@@ -77,7 +74,7 @@
           if (!$scope.managers[i].address || !$scope.managers[i].port) {
             // TODO: Highlight the field that is empty
             $scope.loading = false;
-            $scope.error = true;
+            ngToast.danger('All fields are required.');
             return;
           }
 
@@ -107,11 +104,11 @@
         $q.all(promises)
             .then(
                 function() {
-                  $scope.success = true;
+                  ngToast.success('SNMP Managers set.');
                 },
                 function(errors) {
+                  ngToast.danger('Unable to set SNMP Managers.');
                   console.log(JSON.stringify(errors));
-                  $scope.error = true;
                 })
             .finally(function() {
               $scope.loading = false;
diff --git a/app/index.html b/app/index.html
index 63ee778..96f66c1 100644
--- a/app/index.html
+++ b/app/index.html
@@ -13,6 +13,7 @@
 
     <app-header ng-if="dataService.showNavigation" path="dataService.path"></app-header>
     <app-navigation ng-if="dataService.showNavigation" path="dataService.path" show-navigation="dataService.showNavigation"></app-navigation>
+    <toast ng-if="dataService.showNavigation"></toast>
 
     <main ng-view ng-class="{'content__container': dataService.showNavigation, 'login__wrapper': !dataService.showNavigation}">
     </main>
diff --git a/app/index.js b/app/index.js
index e0bc431..5e00f63 100644
--- a/app/index.js
+++ b/app/index.js
@@ -17,6 +17,10 @@
 import angular_sanitize from 'angular-sanitize';
 import angular_ui_bootstrap from 'angular-ui-bootstrap';
 import angular_ui_router from 'angular-ui-router';
+import ngToast from 'ng-toast';
+import ngToast_animate from 'ng-toast/dist/ngToast-animations.css';
+import ngToast_style from 'ng-toast/dist/ngToast.css';
+
 
 require('./styles/index.scss');
 var config = require('../config.json');
@@ -87,7 +91,7 @@
           'app',
           [
             // Dependencies
-            'ngRoute', 'angular-clipboard',
+            'ngRoute', 'angular-clipboard', 'ngToast', 'ngAnimate',
             'app.common.directives.dirPagination', 'ngSanitize',
             // Basic resources
             'app.common.services', 'app.common.directives',
@@ -129,6 +133,17 @@
           };
         }
       ])
+      .config([
+        'ngToastProvider',
+        function(ngToastProvider) {
+          ngToastProvider.configure({
+            animation: 'fade',
+            timeout: 10000,
+            dismissButton: true,
+            maxNumber: 6
+          });
+        }
+      ])
       .run([
         '$rootScope', '$location', 'dataService', 'userModel',
         function($rootScope, $location, dataService, userModel) {
diff --git a/package-lock.json b/package-lock.json
index bffde60..9b131a1 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -6052,6 +6052,27 @@
       "integrity": "sha512-vdqTKI9GBIYcAEbFAcpKPErKINfPF5zIuz3/niBfq8WUZjpT2tytLlFVrBgWdOtqI4uaA/Rb6No0hux39XXDuw==",
       "dev": true
     },
+    "ng-toast": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ng-toast/-/ng-toast-2.0.0.tgz",
+      "integrity": "sha1-f8Ez/AXohpCDDofNPR8ZPfHDNIM=",
+      "requires": {
+        "angular": "1.5.11",
+        "angular-sanitize": "1.5.11"
+      },
+      "dependencies": {
+        "angular": {
+          "version": "1.5.11",
+          "resolved": "https://registry.npmjs.org/angular/-/angular-1.5.11.tgz",
+          "integrity": "sha1-jFunOG8VllyazzQp9ogVU6raMNY="
+        },
+        "angular-sanitize": {
+          "version": "1.5.11",
+          "resolved": "https://registry.npmjs.org/angular-sanitize/-/angular-sanitize-1.5.11.tgz",
+          "integrity": "sha1-6/s/ND5UP5su8FD7TC6e4EjRdy8="
+        }
+      }
+    },
     "nice-try": {
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
diff --git a/package.json b/package.json
index 7382335..bdcb04d 100644
--- a/package.json
+++ b/package.json
@@ -38,6 +38,7 @@
     "angular-ui-router": "^1.0.20",
     "angular-websocket": "^2.0.1",
     "bootstrap": "^4.2.1",
+    "ng-toast": "^2.0.0",
     "xterm": "^3.10.1"
   },
   "peerDependencies": {},