diff --git a/data/model.py b/data/model.py index a13100865..97414a552 100644 --- a/data/model.py +++ b/data/model.py @@ -498,13 +498,23 @@ def get_user_teams_within_org(username, organization): User.username == username) -def get_visible_repositories(username=None, include_public=True, limit=None, +def get_visible_repository_count(username=None, include_public=True, sort=False, namespace=None): + return get_visible_repository_internal(username=username, include_public=include_public, + sort=sort, namespace=namespace, get_count=True) + +def get_visible_repositories(username=None, include_public=True, page=None, limit=None, sort=False, namespace=None): + return get_visible_repository_internal(username=username, include_public=include_public, page=page, + limit=limit, sort=sort, namespace=namespace, get_count=False) + + +def get_visible_repository_internal(username=None, include_public=True, limit=None, page=None, + sort=False, namespace=None, get_count=False): if not username and not include_public: return [] query = (Repository - .select(Repository, Visibility) + .select() # Note: We need to leave this blank for the get_count case. Otherwise, MySQL/RDS complains. .distinct() .join(Visibility) .switch(Repository) @@ -552,10 +562,19 @@ def get_visible_repositories(username=None, include_public=True, limit=None, else: where_clause = new_clause - if limit: + if sort: + query = query.order_by(Repository.description.desc()) + + if page: + query = query.paginate(page, limit) + elif limit: query = query.limit(limit) - return query.where(where_clause) + where = query.where(where_clause) + if get_count: + return where.count() + else: + return where def get_matching_repositories(repo_term, username=None): diff --git a/endpoints/api.py b/endpoints/api.py index 479efdb45..d4811d761 100644 --- a/endpoints/api.py +++ b/endpoints/api.py @@ -790,11 +790,13 @@ def list_repos(): 'is_public': repo_obj.visibility.name == 'public', } + page = request.args.get('page', None) limit = request.args.get('limit', None) namespace_filter = request.args.get('namespace', None) include_public = request.args.get('public', 'true') include_private = request.args.get('private', 'true') sort = request.args.get('sort', 'false') + include_count = request.args.get('count', 'false') try: limit = int(limit) if limit else None @@ -803,21 +805,38 @@ def list_repos(): include_public = include_public == 'true' include_private = include_private == 'true' + include_count = include_count == 'true' sort = sort == 'true' + if page: + try: + page = int(page) + except: + page = None username = None if current_user.is_authenticated() and include_private: username = current_user.db_user().username - repo_query = model.get_visible_repositories(username, limit=limit, + repo_count = None + if include_count: + repo_count = model.get_visible_repository_count(username, + include_public=include_public, + sort=sort, + namespace=namespace_filter) + + repo_query = model.get_visible_repositories(username, limit=limit, page=page, include_public=include_public, sort=sort, namespace=namespace_filter) + repos = [repo_view(repo) for repo in repo_query] response = { 'repositories': repos } + if include_count: + response['count'] = repo_count + return jsonify(response) diff --git a/static/js/controllers.js b/static/js/controllers.js index 01232a578..900a12cb8 100644 --- a/static/js/controllers.js +++ b/static/js/controllers.js @@ -50,6 +50,8 @@ function SecurityCtrl($scope) { function RepoListCtrl($scope, Restangular, UserService, ApiService) { $scope.namespace = null; + $scope.page = 1; + $scope.publicPageCount = null; // Monitor changes in the user. UserService.updateUserIn($scope, function() { @@ -61,6 +63,23 @@ function RepoListCtrl($scope, Restangular, UserService, ApiService) { loadMyRepos(namespace); }); + $scope.movePublicPage = function(increment) { + if ($scope.publicPageCount == null) { + return; + } + + $scope.page += increment; + if ($scope.page < 1) { + $scope.page = 1; + } + + if ($scope.page > $scope.publicPageCount) { + $scope.page = $scope.publicPageCount; + } + + loadPublicRepos(); + }; + var loadMyRepos = function(namespace) { if (!$scope.user || $scope.user.anonymous || !namespace) { return; @@ -74,8 +93,19 @@ function RepoListCtrl($scope, Restangular, UserService, ApiService) { }; var loadPublicRepos = function() { - var options = {'public': true, 'private': false, 'sort': true, 'limit': 10}; + var options = { + 'public': true, + 'private': false, + 'sort': true, + 'limit': 10, + 'page': $scope.page, + 'count': $scope.page == 1 + }; + $scope.public_repositories = ApiService.listReposAsResource().withOptions(options).get(function(resp) { + if (resp.count) { + $scope.publicPageCount = Math.ceil(resp.count / 10); + } return resp.repositories; }); }; diff --git a/static/partials/repo-list.html b/static/partials/repo-list.html index 42f3aa5cc..9b740f768 100644 --- a/static/partials/repo-list.html +++ b/static/partials/repo-list.html @@ -53,6 +53,16 @@ {{repository.namespace}}/{{repository.name}}
+
+ + +