nitweb/angular: filter entity lists
authorAlexandre Terrasa <alexandre@moz-code.org>
Wed, 1 Jun 2016 00:39:55 +0000 (20:39 -0400)
committerAlexandre Terrasa <alexandre@moz-code.org>
Thu, 2 Jun 2016 22:39:05 +0000 (18:39 -0400)
Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>

share/nitweb/directives/entity/list.html
share/nitweb/directives/ui-filter-button-vis.html [new file with mode: 0644]
share/nitweb/directives/ui-filter-field.html [new file with mode: 0644]
share/nitweb/directives/ui-filter-form.html [new file with mode: 0644]
share/nitweb/directives/ui-filter-group-vis.html [new file with mode: 0644]
share/nitweb/index.html
share/nitweb/javascripts/entities.js
share/nitweb/javascripts/ui.js [new file with mode: 0644]
share/nitweb/stylesheets/nitweb.css

index 9e40d82..cc026a4 100644 (file)
@@ -1,11 +1,19 @@
-<div ng-if='listEntities.length > 0'>
+<div class='entity-list'
+       ng-if='(listEntities | filter:listObjectFilter).length > 0'>
        <h3 id={{listId}}>
                <span>{{listTitle}}</span>
+               <button class='btn btn-link btn-xs pull-right btn-filter' ng-click='toggleFilters()'>
+                       <span class='glyphicon glyphicon-filter text-muted' />
+               </button>
        </h3>
+               <div ng-if='showFilters'>
+                       <ui-filter-form
+                               search-filter='listObjectFilter'
+                               visibility-filter='visibilityFilter'>
+               </div>
                <div class='card-list'>
-                       <entity-card
-                               mentity='mentity'
-                               ng-repeat='mentity in listEntities' />
+                       <entity-card mentity='mentity'
+                               ng-repeat='mentity in listEntities | filter:listObjectFilter | visibility:visibilityFilter' />
                </div>
        </div>
 </div>
diff --git a/share/nitweb/directives/ui-filter-button-vis.html b/share/nitweb/directives/ui-filter-button-vis.html
new file mode 100644 (file)
index 0000000..8d4f8d4
--- /dev/null
@@ -0,0 +1,6 @@
+<button
+       class='btn btn-link btn-xs'
+       ng-click='toggle()'>
+       <span ng-if='property' ng-class='classesOn'/>
+       <span ng-if='!property' ng-class='classesOff'/>
+</button>
diff --git a/share/nitweb/directives/ui-filter-field.html b/share/nitweb/directives/ui-filter-field.html
new file mode 100644 (file)
index 0000000..05c51e4
--- /dev/null
@@ -0,0 +1,4 @@
+<div class='form-group has-icon'>
+       <input type='text' class='form-control' ng-model='property' placeholder='Filter...'>
+       <span class='glyphicon glyphicon-search form-control-icon text-muted'></span>
+</div>
diff --git a/share/nitweb/directives/ui-filter-form.html b/share/nitweb/directives/ui-filter-form.html
new file mode 100644 (file)
index 0000000..9782af8
--- /dev/null
@@ -0,0 +1,6 @@
+<form class='form-inline'>
+       <ui-filter-field property='searchFilter.$' />
+       <div class='pull-right'>
+               <ui-filter-group-vis property='visibilityFilter' />
+       </div>
+</form>
diff --git a/share/nitweb/directives/ui-filter-group-vis.html b/share/nitweb/directives/ui-filter-group-vis.html
new file mode 100644 (file)
index 0000000..7fcd475
--- /dev/null
@@ -0,0 +1,14 @@
+<div class='form-group'>
+       <ui-filter-button-vis property='property.public'
+                       classes-on='"glyphicon glyphicon-eye-open text-success"'
+                       classes-off='"glyphicon glyphicon-eye-close text-success"'
+                       title='Toggle public' />
+       <ui-filter-button-vis property='property.protected'
+                       classes-on='"glyphicon glyphicon-eye-open text-warning"'
+                       classes-off='"glyphicon glyphicon-eye-close text-warning"'
+                       title='Toggle protected' />
+       <ui-filter-button-vis property='property.private'
+                       classes-on='"glyphicon glyphicon-eye-open text-danger"'
+                       classes-off='"glyphicon glyphicon-eye-close text-danger"'
+                       title='Toggle private' />
+</div>
index 2a4bdde..f2a54c5 100644 (file)
@@ -40,5 +40,6 @@
                <script src='/javascripts/nitweb.js'></script>
                <script src='/javascripts/model.js'></script>
                <script src='/javascripts/entities.js'></script>
+               <script src='/javascripts/ui.js'></script>
        </body>
 </html>
index e56d676..255602c 100644 (file)
@@ -16,7 +16,7 @@
 
 (function() {
        angular
-               .module('entities', ['model'])
+               .module('entities', ['ui', 'model'])
 
                .controller('EntityCtrl', ['Model', '$routeParams', '$scope', function(Model, $routeParams, $scope) {
                        Model.loadEntity($routeParams.id,
                                scope: {
                                        listEntities: '=',
                                        listTitle: '@',
+                                       listObjectFilter: '=',
                                },
                                templateUrl: '/directives/entity/list.html',
+                               link: function ($scope, element, attrs) {
+                                       $scope.showFilters = false;
+                                       if(!$scope.listObjectFilter) {
+                                               $scope.listObjectFilter = {};
+                                       }
+                                       if(!$scope.visibilityFilter) {
+                                               $scope.visibilityFilter = {
+                                                       public: true,
+                                                       protected: true,
+                                                       private: false
+                                               };
+                                       }
+                                       $scope.toggleFilters = function() {
+                                               $scope.showFilters = !$scope.showFilters;
+                                       };
+                               }
                        };
                })
 })();
diff --git a/share/nitweb/javascripts/ui.js b/share/nitweb/javascripts/ui.js
new file mode 100644 (file)
index 0000000..aae0234
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2016 Alexandre Terrasa <alexandre@moz-code.org>.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+(function() {
+       angular
+               .module('ui', [ 'model' ])
+
+               .directive('uiFilters', function() {
+                       return {
+                               restrict: 'E',
+                               scope: {
+                                       property: '=',
+                                       classesOn: '=',
+                                       classesOff: '='
+                               },
+                               replace: true,
+                               templateUrl: '/directives/ui-filter-button-vis.html',
+                               link: function ($scope, element, attrs) {
+                                       $scope.toggle = function() {
+                                               $scope.property = !$scope.property;
+                                       }
+                               }
+                       };
+               })
+
+               .filter('visibility', function() {
+                       return function(input, visibilityFilter) {
+                               var res = [];
+                               input.forEach(function(entry) {
+                                       if(visibilityFilter.public == false && entry.visibility == "public") {
+                                               return;
+                                       }
+                                       if(visibilityFilter.protected == false && entry.visibility == "protected") {
+                                               return;
+                                       }
+                                       if(visibilityFilter.private == false && entry.visibility == "private") {
+                                               return;
+                                       }
+                                       res.push(entry);
+                               });
+                               return res;
+                       };
+               })
+
+               .directive('uiFilterForm', function() {
+                       return {
+                               restrict: 'E',
+                               scope: {
+                                       searchFilter: '=',
+                                       visibilityFilter: '='
+                               },
+                               replace: true,
+                               templateUrl: '/directives/ui-filter-form.html'
+                       };
+               })
+
+               .directive('uiFilterField', function() {
+                       return {
+                               restrict: 'E',
+                               scope: {
+                                       property: '='
+                               },
+                               replace: true,
+                               templateUrl: '/directives/ui-filter-field.html'
+                       };
+               })
+
+               .directive('uiFilterGroupVis', function() {
+                       return {
+                               restrict: 'E',
+                               scope: {
+                                       property: '='
+                               },
+                               replace: true,
+                               templateUrl: '/directives/ui-filter-group-vis.html'
+                       };
+               })
+
+               .directive('uiFilterButtonVis', function() {
+                       return {
+                               restrict: 'E',
+                               scope: {
+                                       property: '=',
+                                       classesOn: '=',
+                                       classesOff: '='
+                               },
+                               replace: true,
+                               templateUrl: '/directives/ui-filter-button-vis.html',
+                               link: function ($scope, element, attrs) {
+                                       $scope.toggle = function() {
+                                               $scope.property = !$scope.property;
+                                       }
+                               }
+                       };
+               })
+})();
index ccecb1b..eca9c48 100644 (file)
@@ -75,6 +75,16 @@ a {
        border-top: none;
 }
 
+/* ui */
+
+entity-list .btn-filter {
+       visibility: hidden;
+}
+
+entity-list:hover .btn-filter {
+       visibility: visible;
+}
+
 /* doc */
 
 .nitdoc .synopsys {
@@ -112,6 +122,29 @@ a {
     background-color: #ff9c0f;
 }
 
+/* forms */
+
+.has-icon {
+    position: relative;
+}
+
+.has-icon .form-control {
+       padding-left: 35px;
+}
+
+.form-control-icon {
+    position: absolute;
+    top: 0;
+    left: 0;
+    z-index: 2;
+    display: block;
+    width: 34px;
+    height: 34px;
+    line-height: 34px;
+    text-align: center;
+    pointer-events: none;
+}
+
 /*
  * Code Highlighting
  */