Add more content to mentities pages.
Packages list inner groups
* http://nitweb.moz-code.org/package/core
Groups show parent and list inner groups/modules
* http://nitweb.moz-code.org/group/core%3E
* http://nitweb.moz-code.org/group/core%3Ecollection%3E
Modules show imported modules, introduced classes and redefinitions
* http://nitweb.moz-code.org/module/core::array
Classes show super classes, introduced properties, redefined properties
* http://nitweb.moz-code.org/class/core::Array
Bonus, all lists are filterable by raw string or visibility.
Pull-Request: #2152
Reviewed-by: Jean Privat <jean@pryen.org>
--- /dev/null
+<div class='card'>
+ <div class='card-left text-center'>
+ <entity-tag mentity='mentity' />
+ </div>
+ <div class='card-body'>
+ <h5 class='card-heading'>
+ <entity-signature mentity='mentity'/>
+ </h5>
+ <span class='synopsis' ng-bind-html='mentity.mdoc.html_synopsis' />
+ </div>
+</div>
--- /dev/null
+<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 | filter:listObjectFilter | visibility:visibilityFilter' />
+ </div>
+ </div>
+</div>
--- /dev/null
+<span ng-if='mentity.location'>
+ <a ng-href="{{mentity.web_url}}">{{mentity.location.file}}
+ <span ng-if='mentity.location.line_start'>:{{mentity.location.line_start}}</span>
+ </a>
+</span>
--- /dev/null
+<span class="glyphicon glyphicon-tag" ng-class='{
+ "text-success": mentity.visibility == "public",
+ "text-warning": mentity.visibility == "protected",
+ "text-danger": mentity.visibility == "private",
+}' />
--- /dev/null
+<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>
--- /dev/null
+<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>
--- /dev/null
+<form class='form-inline'>
+ <ui-filter-field property='searchFilter.$' />
+ <div class='pull-right'>
+ <ui-filter-group-vis property='visibilityFilter' />
+ </div>
+</form>
--- /dev/null
+<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>
<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>
(function() {
angular
- .module('entities', ['model'])
+ .module('entities', ['ui', 'model'])
.controller('EntityCtrl', ['Model', '$routeParams', '$scope', function(Model, $routeParams, $scope) {
Model.loadEntity($routeParams.id,
templateUrl: '/directives/entity/signature.html'
};
})
+
+ .directive('entityTag', function() {
+ return {
+ restrict: 'E',
+ scope: {
+ mentity: '='
+ },
+ replace: true,
+ templateUrl: '/directives/entity/tag.html'
+ };
+ })
+
+ .directive('entityLocation', function() {
+ return {
+ restrict: 'E',
+ scope: {
+ mentity: '='
+ },
+ templateUrl: '/directives/entity/location.html'
+ };
+ })
+
+ .directive('entityCard', function() {
+ return {
+ restrict: 'E',
+ scope: {
+ mentity: '='
+ },
+ replace: true,
+ templateUrl: '/directives/entity/card.html'
+ };
+ })
+
+ .directive('entityList', function() {
+ return {
+ restrict: 'E',
+ 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;
+ };
+ }
+ };
+ })
})();
--- /dev/null
+/*
+ * 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;
+ }
+ }
+ };
+ })
+})();
width: 10000px;
}
-.card-body {
+.card-body, .card-right, .card-left {
display: table-cell;
vertical-align: top;
}
+.card-left, .card>.pull-left {
+ padding: 15px;
+ padding-right: 0px;
+}
+.card-right, .card>.pull-right {
+ padding: 15px;
+ padding-left: 0px;
+}
+
+.card-list {
+ margin-top: 10px;
+}
+
+.card-list > .card:first-child {
+ border-top: 1px solid #ccc;
+}
+
+.card-list > .card {
+ margin-top: 0;
+ border-top: none;
+}
+
+/* ui */
+
+entity-list .btn-filter {
+ visibility: hidden;
+}
+
+entity-list:hover .btn-filter {
+ visibility: visible;
+}
+
/* doc */
.nitdoc .synopsys {
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
*/
<div class='tab-content'>
<div class='tab-pane fade in active' id='doc'>
<entity-doc mentity='mentity.intro'/>
+
+ <entity-list list-title='Parents'
+ list-entities='mentity.parents'
+ list-object-filter='{}' />
+
+ <entity-list list-title='Constructors'
+ list-entities='mentity.all_mproperties'
+ list-object-filter='{is_init: true}' />
+
+ <entity-list list-title='Introduced properties'
+ list-entities='mentity.intro_mproperties'
+ list-object-filter='{is_init: "!true"}' />
+
+ <entity-list list-title='Redefined properties'
+ list-entities='mentity.redef_mproperties'
+ list-object-filter='{is_init: "!true"}' />
</div>
</div>
</div>
<div class='tab-content'>
<div class='tab-pane fade in active' id='doc'>
<entity-doc mentity='mentity'/>
+
+ <entity-list list-title='Parent group' list-entities='[mentity.parent]'
+ list-object-filter='{}' ng-if='mentity.parent' />
+
+ <entity-list list-title='Subgroups' list-entities='mentity.mgroups'
+ list-object-filter='{}' />
+
+ <entity-list list-title='Modules' list-entities='mentity.mmodules'
+ list-object-filter='{}' />
</div>
</div>
</div>
<div class='tab-content'>
<div role='tabpanel' class='tab-pane fade in active' id='doc'>
<entity-doc mentity='mentity'/>
+
+ <entity-list list-title='Imported modules' list-entities='mentity.imports'
+ list-object-filter='{}' />
+
+ <entity-list list-title='Introduced classes' list-entities='mentity.intro_mclasses'
+ list-object-filter='{}' />
+
+ <entity-list list-title='Class redefinitions' list-entities='mentity.redef_mclassdefs'
+ list-object-filter='{}' />
+
</div>
</div>
</div>
<div class='tab-content'>
<div role='tabpanel' class='tab-pane fade in active' id='doc'>
<entity-doc mentity='mentity'/>
+
+ <entity-list list-title='Groups' list-entities='mentity.mgroups'
+ list-object-filter='{}' />
</div>
</div>
</div>