ONOS-1937, ONOS-1938 - CORD-GUI -- User view now can change the level of URL filtering per user. CSS WIP.

Change-Id: I65f494bca184a6337f703a0ecdb40ce09d166a42
diff --git a/apps/demo/cord-gui/src/main/webapp/app/view/bundle/bundle.css b/apps/demo/cord-gui/src/main/webapp/app/view/bundle/bundle.css
index 27338c0..bc36f1d 100644
--- a/apps/demo/cord-gui/src/main/webapp/app/view/bundle/bundle.css
+++ b/apps/demo/cord-gui/src/main/webapp/app/view/bundle/bundle.css
@@ -15,10 +15,11 @@
  */
 
 div#bundle div.main-left {
-    width: 62%;
+    width: 61%;
+    padding-left: 1%;
 }
 div#bundle div.main-right {
-    width: 38%;
+    width: 37%;
     height: 85vh;
     background-color: rgba(173, 216, 230, 0.25);
     border-radius: 5px;
diff --git a/apps/demo/cord-gui/src/main/webapp/app/view/bundle/bundle.js b/apps/demo/cord-gui/src/main/webapp/app/view/bundle/bundle.js
index 987c70a..564fd58 100644
--- a/apps/demo/cord-gui/src/main/webapp/app/view/bundle/bundle.js
+++ b/apps/demo/cord-gui/src/main/webapp/app/view/bundle/bundle.js
@@ -28,61 +28,20 @@
         avScope,
         avCb;
 
-    function setInfo(resource, scope) {
+    function setAndRefresh(resource, scope) {
         current = resource.bundle.id;
         scope.name = resource.bundle.name;
         scope.desc = resource.bundle.desc;
         scope.funcs = resource.bundle.functions;
+        // emit event will say when avCb should be invoked
         avCb(resource);
     }
 
+    // TODO: figure out timing issues with bundle page
+    // available bundles sometimes is loaded before avCb and avScope is created?
+    // emit event that avCb can be called upon
+
     angular.module('cordBundle', [])
-        .directive('bundleAvailable', ['$resource', function ($resource) {
-            return {
-                templateUrl: 'app/view/bundle/available.html',
-                link: function (scope, elem) {
-                    var button = $(elem).find('button'),
-                        ApplyData, resource;
-
-                    button.click(function () {
-                        ApplyData = $resource(url + '/' + avScope.available.id);
-                        resource = ApplyData.get({},
-                            // success
-                            function () {
-                                setInfo(resource, bundleScope);
-                            },
-                            // error
-                            function () {
-                                $log.error('Problem with resource', resource);
-                            }
-                        );
-                    });
-                }
-            };
-        }])
-
-        .controller('CordBundleCtrl', ['$log', '$scope', '$resource',
-            function (_$log_, $scope, _$resource_) {
-                var BundleData, resource;
-                $scope.page = 'bundle';
-                bundleScope = $scope;
-                $log = _$log_;
-                $resource = _$resource_;
-
-                BundleData = $resource(url);
-                resource = BundleData.get({},
-                    // success
-                    function () {
-                        setInfo(resource, $scope);
-                    },
-                    // error
-                    function () {
-                        $log.error('Problem with resource', resource);
-                    });
-
-                $log.debug('Cord Bundle Ctrl has been created.');
-        }])
-
         .controller('CordAvailable', ['$scope',
             function ($scope) {
                 avScope = $scope;
@@ -98,5 +57,51 @@
                 };
 
                 $log.debug('Cord Available Ctrl has been created.');
+        }])
+
+        .controller('CordBundleCtrl', ['$log', '$scope', '$resource',
+            function (_$log_, $scope, _$resource_) {
+                var BundleData, resource;
+                $scope.page = 'bundle';
+                bundleScope = $scope;
+                $log = _$log_;
+                $resource = _$resource_;
+
+                BundleData = $resource(url);
+                resource = BundleData.get({},
+                    // success
+                    function () {
+                        setAndRefresh(resource, $scope);
+                    },
+                    // error
+                    function () {
+                        $log.error('Problem with resource', resource);
+                    });
+
+                $log.debug('Cord Bundle Ctrl has been created.');
+            }])
+
+        .directive('bundleAvailable', ['$resource', function ($resource) {
+            return {
+                templateUrl: 'app/view/bundle/available.html',
+                link: function (scope, elem) {
+                    var button = $(elem).find('button'),
+                        ApplyData, resource;
+
+                    button.click(function () {
+                        ApplyData = $resource(url + '/' + avScope.available.id);
+                        resource = ApplyData.get({},
+                            // success
+                            function () {
+                                setAndRefresh(resource, bundleScope);
+                            },
+                            // error
+                            function () {
+                                $log.error('Problem with resource', resource);
+                            }
+                        );
+                    });
+                }
+            };
         }]);
 }());
diff --git a/apps/demo/cord-gui/src/main/webapp/app/view/common/common.css b/apps/demo/cord-gui/src/main/webapp/app/view/common/common.css
index 6769356..968b9c8 100644
--- a/apps/demo/cord-gui/src/main/webapp/app/view/common/common.css
+++ b/apps/demo/cord-gui/src/main/webapp/app/view/common/common.css
@@ -55,7 +55,9 @@
     text-align: justify;
 }
 
-button {
+button,
+input[type="button"],
+input[type="reset"] {
     height: 30px;
     box-shadow: none;
     border: none;
@@ -66,9 +68,18 @@
     background-color: lightgray;
     transition: background-color 0.4s;
 }
-button:hover {
+button:hover,
+input[type="button"]:hover,
+input[type="reset"]:hover {
     color: white;
-    background-color: #CE5650;
+    background-color: rgb(122, 188, 229);
+}
+
+button[disabled]:hover,
+input[type="button"][disabled]:hover,
+input[type="reset"][disabled]:hover {
+    background-color: lightgray;
+    color: graytext;
 }
 
 div.container {
@@ -79,10 +90,11 @@
     float: left;
 }
 div.main-left {
-    width: 38%;
+    width: 37%;
+    padding-left: 1%;
 }
 div.main-right {
-    width: 62%;
+    width: 61%;
 }
 
 svg#icon-defs {
diff --git a/apps/demo/cord-gui/src/main/webapp/app/view/login/login.css b/apps/demo/cord-gui/src/main/webapp/app/view/login/login.css
index 05d2fee..e35062b 100644
--- a/apps/demo/cord-gui/src/main/webapp/app/view/login/login.css
+++ b/apps/demo/cord-gui/src/main/webapp/app/view/login/login.css
@@ -103,5 +103,5 @@
 
 #login-form input[type="button"]:hover {
     color: white;
-    background-color: #CE5650;
+    background-color: rgb(122, 188, 229);
 }
diff --git a/apps/demo/cord-gui/src/main/webapp/app/view/user/user.css b/apps/demo/cord-gui/src/main/webapp/app/view/user/user.css
index 3b9c9df..acb98e0 100644
--- a/apps/demo/cord-gui/src/main/webapp/app/view/user/user.css
+++ b/apps/demo/cord-gui/src/main/webapp/app/view/user/user.css
@@ -14,3 +14,6 @@
  * limitations under the License.
  */
 
+#user table.user-info {
+    float: left;
+}
diff --git a/apps/demo/cord-gui/src/main/webapp/app/view/user/user.html b/apps/demo/cord-gui/src/main/webapp/app/view/user/user.html
index ce82ed2..1de09bb 100644
--- a/apps/demo/cord-gui/src/main/webapp/app/view/user/user.html
+++ b/apps/demo/cord-gui/src/main/webapp/app/view/user/user.html
@@ -2,24 +2,32 @@
 <div class="container">
     <nav></nav>
     <div id="user">
-        <table>
+        <table class="user-info">
             <tr>
                 <th>Name</th>
                 <th>Mac</th>
-                <th ng-if="isFamily">URL Filtering</th>
+                <th ng-if="isFamily">Select Site Rating</th>
             </tr>
             <tr ng-repeat="user in users" class="fadein">
                 <td>{{user.name}}</td>
                 <td>{{user.mac}}</td>
-                <td ng-if="isFamily">
-                    <select ng-model="newLevels[user.id]"
-                            ng-options="l for l in levels">
-                    </select>
-                    <!--How to save the id of the user with what level they want
-                     for the submit button, and also have a default value?
-                     Look into forms or study ng-options syntax a bit more-->
-                </td>
             </tr>
         </table>
+
+        <form ng-if="isFamily"
+                name="changeLevels">
+            <select ng-repeat-start="user in users" class="fadein"
+                    ng-init="newLevels[user.id]=user.profile.url_filter.level"
+                    ng-model="newLevels[user.id]"
+                    ng-options="l for l in levels">
+            </select>
+            <br ng-repeat-end>
+            <input type="reset" value="Cancel"
+                    ng-click="cancelChanges(changeLevels)"
+                    ng-disabled="changeLevels.$pristine">
+            <input type="button" value="Apply"
+                    ng-click="applyChanges()"
+                    ng-disabled="changeLevels.$pristine">
+        </form>
     </div>
 </div>
\ No newline at end of file
diff --git a/apps/demo/cord-gui/src/main/webapp/app/view/user/user.js b/apps/demo/cord-gui/src/main/webapp/app/view/user/user.js
index f31e1d6..8e97c015b 100644
--- a/apps/demo/cord-gui/src/main/webapp/app/view/user/user.js
+++ b/apps/demo/cord-gui/src/main/webapp/app/view/user/user.js
@@ -25,11 +25,13 @@
     angular.module('cordUser', [])
         .controller('CordUserCtrl', ['$log', '$scope', '$resource',
             function ($log, $scope, $resource) {
-                var BundleData, bundleResource, UserData, userResource;
+                var BundleData, bundleResource;
                 $scope.page = 'user';
                 $scope.isFamily = false;
                 $scope.newLevels = {};
 
+                // === Get data functions ---
+
                 BundleData = $resource(bundleUrl);
                 bundleResource = BundleData.get({},
                     // success
@@ -52,26 +54,57 @@
                     }
                 );
 
-                UserData = $resource(userUrl);
-                userResource = UserData.get({},
-                    // success
-                    function () {
-                        $scope.users = userResource.users;
-                    },
-                    // error
-                    function () {
-                        $log.error('Problem with resource', userResource);
+                function getUsers(url) {
+                    var UserData, userResource;
+                    UserData = $resource(url);
+                    userResource = UserData.get({},
+                        // success
+                        function () {
+                            $scope.users = userResource.users;
+                        },
+                        // error
+                        function () {
+                            $log.error('Problem with resource', userResource);
+                        }
+                    );
+                }
+
+                getUsers(userUrl);
+
+                // === Form functions ---
+
+                function levelUrl(id, level) {
+                    return userUrl + '/' + id + '/apply/url_filter/level/' + level;
+                }
+
+                $scope.applyChanges = function () {
+                    var requests = [];
+
+                    if ($scope.users) {
+                        $.each($scope.users, function (index, user) {
+                            var id = user.id,
+                                level = user.profile.url_filter.level;
+                            if ($scope.newLevels[id] !== level) {
+                                requests.push(levelUrl(id, $scope.newLevels[id]));
+                            }
+                        });
+
+                        $.each(requests, function (index, req) {
+                            getUsers(req);
+                        });
                     }
-                );
+                };
+
+                $scope.cancelChanges = function (changeLevels) {
+                    if ($scope.users) {
+                        $.each($scope.users, function (index, user) {
+                            $scope.newLevels[user.id] = user.profile.url_filter.level;
+                        });
+                    }
+                    changeLevels.$setPristine();
+                };
 
             $log.debug('Cord User Ctrl has been created.');
-        }])
-        .directive('editUser', [function () {
-            return {
-                link: function (scope, elem) {
-
-                }
-            };
         }]);
 
 }());
diff --git a/apps/demo/cord-gui/src/main/webapp/index.html b/apps/demo/cord-gui/src/main/webapp/index.html
index ee927ab..3a3b686 100644
--- a/apps/demo/cord-gui/src/main/webapp/index.html
+++ b/apps/demo/cord-gui/src/main/webapp/index.html
@@ -47,6 +47,7 @@
     <link rel="stylesheet" href="app/view/home/home.css">
 
     <script src="app/view/user/user.js"></script>
+    <link rel="stylesheet" href="app/view/user/user.css">
 
     <script src="app/view/bundle/bundle.js"></script>
     <link rel="stylesheet" href="app/view/bundle/bundle.css">