Merge pull request #663 from wknet123/dev

Add pagination to UI.
This commit is contained in:
kun wang 2016-08-09 11:12:28 +08:00 committed by GitHub
commit b6884900d2
20 changed files with 328 additions and 62 deletions

View File

@ -73,13 +73,11 @@
}
.sub-pane {
margin: 15px;
min-height: 380px;
overflow-y: auto;
}
.well-custom {
width: 100%;
background-color: #f5f5f5;
background-image: none;

View File

@ -48,7 +48,8 @@
</tbody>
</table>
</div>
</div>
</div>
<paginator ng-if="vm.totalCount > 0" total-count="//vm.totalCount//" page-size="//vm.pageSize//" page="vm.page" display-count="5"></paginator>
</div>
</div>
</div>

View File

@ -51,8 +51,18 @@
'projectId': vm.projectId,
'username' : vm.username
};
retrieve(vm.queryParams);
vm.page = 1;
vm.pageSize = 20;
$scope.$watch('vm.page', function(current, origin) {
if(current !== 1) {
vm.page = current;
retrieve(vm.queryParams, vm.page, vm.pageSize);
}
});
retrieve(vm.queryParams, vm.page, vm.pageSize);
$scope.$on('$locationChangeSuccess', function() {
@ -69,11 +79,13 @@
'username' : vm.username
};
vm.username = '';
retrieve(vm.queryParams);
retrieve(vm.queryParams, vm.page, vm.pageSize);
});
function search(e) {
vm.page = 1;
if(e.op[0] === 'all') {
e.op = ['create', 'pull', 'push', 'delete'];
}
@ -83,11 +95,12 @@
vm.queryParams.keywords = e.op.join('/');
vm.queryParams.username = e.username;
vm.queryParams.beginTimestamp = toUTCSeconds(vm.fromDate, 0, 0, 0);
vm.queryParams.endTimestamp = toUTCSeconds(vm.toDate, 23, 59, 59);
retrieve(vm.queryParams);
retrieve(vm.queryParams, vm.page, vm.pageSize);
}
function showAdvancedSearch() {
@ -98,27 +111,30 @@
}
}
function retrieve(queryParams) {
ListLogService(queryParams)
function retrieve(queryParams, page, pageSize) {
ListLogService(queryParams, page, pageSize)
.then(listLogComplete)
.catch(listLogFailed);
}
function listLogComplete(response) {
vm.logs = response.data;
vm.totalCount = response.headers('X-Total-Count');
vm.queryParams = {
'beginTimestamp' : 0,
'endTimestamp' : 0,
'keywords' : '',
'projectId': vm.projectId,
'username' : ''
};
vm.op = ['all'];
vm.fromDate = '';
vm.toDate = '';
vm.others = '';
vm.opOthers = true;
console.log('Total Count in logs:' + vm.totalCount + ', page:' + vm.page);
// vm.queryParams = {
// 'beginTimestamp' : 0,
// 'endTimestamp' : 0,
// 'keywords' : '',
// 'projectId': vm.projectId,
// 'username' : ''
// };
// vm.op = ['all'];
// vm.fromDate = '';
// vm.toDate = '';
// vm.others = '';
// vm.opOthers = true;
vm.isOpen = false;
}
function listLogFailed(response){

View File

@ -0,0 +1,14 @@
<nav aria-label="Page navigation" class="pull-left">
<ul class="pagination" style="margin: 0;">
<li>
<a href="javascript:void(0);" ng-click="vm.previous()" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a>
</li>
<li>
<a href="javascript:void(0);" ng-click="vm.next()" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
</ul>
</nav>

View File

@ -0,0 +1,196 @@
(function() {
'use strict';
angular
.module('harbor.paginator')
.directive('paginator', paginator);
PaginatorController.$inject = [];
function PaginatorController() {
var vm = this;
}
paginator.$inject = [];
function paginator() {
var directive = {
'restrict': 'E',
'templateUrl': '/static/resources/js/components/paginator/paginator.directive.html',
'scope': {
'totalCount': '@',
'pageSize': '@',
'page': '=',
'displayCount': '@'
},
'link': link,
'controller': PaginatorController,
'controllerAs': 'vm',
'bindToController': true
};
return directive;
function link(scope, element, attrs, ctrl) {
scope.$watch('vm.page', function(current) {
if(current) {
ctrl.page = current;
togglePageButton();
}
});
var tc;
scope.$watch('vm.totalCount', function(current) {
if(current) {
var totalCount = current;
element.find('ul li:first a').off('click');
element.find('ul li:last a').off('click');
tc = new TimeCounter();
console.log('Total Count:' + totalCount + ', Page Size:' + ctrl.pageSize + ', Display Count:' + ctrl.displayCount + ', Page:' + ctrl.page);
ctrl.buttonCount = Math.ceil(totalCount / ctrl.pageSize);
if(ctrl.buttonCount <= ctrl.displayCount) {
tc.setMaximum(1);
}else{
tc.setMaximum(Math.ceil(ctrl.buttonCount / ctrl.displayCount));
}
element.find('ul li:first a').on('click', previous);
element.find('ul li:last a').on('click', next);
drawButtons(tc.getTime());
togglePrevious(tc.canDecrement());
toggleNext(tc.canIncrement());
togglePageButton();
}
});
var TimeCounter = function() {
this.time = 0;
this.minimum = 0;
this.maximum = 0;
}
TimeCounter.prototype.setMaximum = function(maximum) {
this.maximum = maximum;
};
TimeCounter.prototype.increment = function() {
if(this.time < this.maximum) {
++this.time;
if((ctrl.page % ctrl.displayCount) != 0) {
ctrl.page = this.time * ctrl.displayCount;
}
++ctrl.page;
}
scope.$apply();
};
TimeCounter.prototype.canIncrement = function() {
if(this.time + 1 < this.maximum) {
return true;
}
return false;
};
TimeCounter.prototype.decrement = function() {
if(this.time > this.minimum) {
if(this.time === 0) {
ctrl.page = ctrl.displayCount;
}else if((ctrl.page % ctrl.displayCount) != 0) {
ctrl.page = this.time * ctrl.displayCount;
}
--this.time;
--ctrl.page;
}
scope.$apply();
};
TimeCounter.prototype.canDecrement = function() {
if(this.time > this.minimum) {
return true;
}
return false;
};
TimeCounter.prototype.getTime = function() {
return this.time;
};
function drawButtons(time) {
element.find('li[tag="pagination-button"]').remove();
var buttons = [];
for(var i = 1; i <= ctrl.displayCount; i++) {
var displayNumber = ctrl.displayCount * time + i;
if(displayNumber <= ctrl.buttonCount) {
buttons.push('<li tag="pagination-button"><a href="javascript:void(0)" page="' + displayNumber + '">' + displayNumber + '<span class="sr-only"></span></a></li>');
}
}
$(buttons.join(''))
.insertAfter(element.find('ul li:eq(0)')).end()
.on('click', buttonClickHandler);
}
function togglePrevious(status) {
if(status){
element.find('ul li:first').removeClass('disabled');
}else{
element.find('ul li:first').addClass('disabled');
}
}
function toggleNext(status) {
if(status) {
element.find('ul li:last').removeClass('disabled');
}else{
element.find('ul li:last').addClass('disabled');
}
}
function buttonClickHandler(e) {
ctrl.page = $(e.target).attr('page');
togglePageButton();
togglePrevious(tc.canDecrement());
toggleNext(tc.canIncrement());
scope.$apply();
}
function togglePageButton() {
element.find('li[tag="pagination-button"]').removeClass('active');
element.find('li[tag="pagination-button"] a[page="' + ctrl.page + '"]').parent().addClass('active');
}
function previous() {
if(tc.canDecrement()) {
tc.decrement();
drawButtons(tc.getTime());
togglePageButton();
togglePrevious(tc.canDecrement());
toggleNext(tc.canIncrement());
}
scope.$apply();
}
function next() {
if(tc.canIncrement()) {
tc.increment();
drawButtons(tc.getTime());
togglePageButton();
togglePrevious(tc.canDecrement());
toggleNext(tc.canIncrement());
}
scope.$apply();
}
}
}
})();

View File

@ -0,0 +1,8 @@
(function() {
'use strict';
angular
.module('harbor.paginator', []);
})();

View File

@ -12,5 +12,5 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<button ng-if="vm.isPublic" ng-disabled="!vm.owned" class="btn btn-success" ng-click="vm.toggle()">// 'button_on' | tr //</button>
<button ng-if="!vm.isPublic" ng-disabled="!vm.owned" class="btn btn-danger" ng-click="vm.toggle()">// 'button_off' | tr //</button>
<button ng-if="vm.isPublic" class="btn btn-success" ng-click="vm.toggle()">// 'button_on' | tr //</button>
<button ng-if="!vm.isPublic" class="btn btn-danger" ng-click="vm.toggle()">// 'button_off' | tr //</button>

View File

@ -73,7 +73,9 @@
</div>
</div>
</div>
<div class="col-xs-4 col-md-12 well well-sm well-custom well-split"><div class="col-md-offset-10">//vm.replicationPolicies ? vm.replicationPolicies.length : 0// // 'items' | tr //</div></div>
<div class="col-xs-4 col-md-12 well well-sm well-custom well-split">
<div class="col-md-offset-10">//vm.replicationPolicies ? vm.replicationPolicies.length : 0// // 'items' | tr //</div>
</div>
<p class="split-handle"><span class="glyphicon glyphicon-align-justify"></span></p>
<h4 class="h4-custom-down">// 'replication_jobs' | tr //</h4>
<hr class="hr-line"/>
@ -147,7 +149,7 @@
</div>
</div>
</div>
<div class="col-xs-4 col-md-12 well well-sm well-custom well-split"><div class="col-md-offset-10">//vm.replicationJobs ? vm.replicationJobs.length : 0// // 'items' | tr //</div></div>
<paginator ng-if="vm.totalCount > 0" total-count="//vm.totalCount//" page-size="//vm.pageSize//" display-count="5" page="vm.page"></paginator>
</div>
</div>
</div>

View File

@ -59,6 +59,17 @@
vm.retrievePolicy = retrievePolicy;
vm.retrieveJob = retrieveJob;
vm.pageSize = 20;
vm.page = 1;
$scope.$watch('vm.page', function(current) {
if(current !== 1) {
vm.page = current;
console.log('replication job: vm.page:' + current);
vm.retrieveJob(vm.lastPolicyId, vm.page, vm.pageSize);
}
});
vm.confirmToTogglePolicy = confirmToTogglePolicy;
vm.togglePolicy = togglePolicy;
@ -84,14 +95,14 @@
function searchReplicationJob() {
if(vm.lastPolicyId !== -1) {
vm.searchJobTIP = true;
vm.retrieveJob(vm.lastPolicyId);
vm.retrieveJob(vm.lastPolicyId, vm.page, vm.pageSize);
}
}
function refreshReplicationJob() {
if(vm.lastPolicyId !== -1) {
vm.refreshJobTIP = true;
vm.retrieveJob(vm.lastPolicyId);
vm.retrieveJob(vm.lastPolicyId, vm.page, vm.pageSize);
}
}
@ -101,11 +112,10 @@
.error(listReplicationPolicyFailed);
}
function retrieveJob(policyId) {
function retrieveJob(policyId, page, pageSize) {
var status = (vm.currentStatus.key === 'all' ? '' : vm.currentStatus.key);
ListReplicationJobService(policyId, vm.replicationJobName, status, toUTCSeconds(vm.fromDate, 0, 0, 0), toUTCSeconds(vm.toDate, 23, 59, 59))
.success(listReplicationJobSuccess)
.error(listReplicationJobFailed);
ListReplicationJobService(policyId, vm.replicationJobName, status, toUTCSeconds(vm.fromDate, 0, 0, 0), toUTCSeconds(vm.toDate, 23, 59, 59), page, pageSize)
.then(listReplicationJobSuccess, listReplicationJobFailed);
}
function listReplicationPolicySuccess(data, status) {
@ -117,8 +127,9 @@
console.log('Failed to list replication policy:' + data);
}
function listReplicationJobSuccess(data, status) {
vm.replicationJobs = data || [];
function listReplicationJobSuccess(response) {
vm.replicationJobs = response.data || [];
vm.totalCount = response.headers('X-Total-Count');
var alertInfo = {
'show': false,
'message': ''
@ -146,8 +157,8 @@
vm.refreshJobTIP = false;
}
function listReplicationJobFailed(data, status) {
console.log('Failed to list replication job:' + data);
function listReplicationJobFailed(response) {
console.log('Failed to list replication job:' + response);
vm.searchJobTIP = false;
vm.refreshJobTIP = false;
}
@ -259,8 +270,8 @@
var uponTableHeight = element.find('#upon-pane .table-body-container').height();
var downTableHeight = element.find('#down-pane .table-body-container').height();
var handleHeight = element.find('.split-handle').height() + element.find('.split-handle').offset().top + element.find('.well').height() - 24;
var handleHeight = element.find('.split-handle').height() + element.find('.split-handle').offset().top + element.find('.well').height() - 32;
console.log('handleHeight:' + handleHeight);
var maxDownPaneHeight = 760;
element.find('.split-handle').on('mousedown', mousedownHandler);
@ -328,7 +339,7 @@
.css({'color': '#fff'});
$('a', this)
.css({'color': '#fff'});
ctrl.retrieveJob($(this).attr('policy_id'));
ctrl.retrieveJob($(this).attr('policy_id'), ctrl.page, ctrl.pageSize);
ctrl.lastPolicyId = $(this).attr('policy_id');
}

View File

@ -30,6 +30,7 @@
</div>
</div>
</div>
<paginator ng-if="vm.totalCount > 0" total-count="//vm.totalCount//" page-size="//vm.pageSize//" page="vm.page" display-count="5"></paginator>
</div>
</div>
</div>

View File

@ -41,7 +41,9 @@
vm.filterInput = hashValue;
}
}
vm.page = 1;
vm.pageSize = 8;
vm.retrieve = retrieve;
vm.tagCount = {};
@ -61,6 +63,15 @@
}
});
$scope.$watch('vm.page', function(current) {
if(current !== 1) {
vm.page = current;
vm.retrieve();
}
});
$scope.$on('repoName', function(e, val) {
vm.repoName = val;
});
@ -76,19 +87,19 @@
$scope.$on('tags', function(e, val) {
vm.tags = val;
});
vm.deleteByRepo = deleteByRepo;
vm.deleteByTag = deleteByTag;
vm.deleteImage = deleteImage;
function retrieve(){
ListRepositoryService(vm.projectId, vm.filterInput)
.success(getRepositoryComplete)
.error(getRepositoryFailed);
ListRepositoryService(vm.projectId, vm.filterInput, vm.page, vm.pageSize)
.then(getRepositoryComplete, getRepositoryFailed);
}
function getRepositoryComplete(data, status) {
vm.repositories = data || [];
function getRepositoryComplete(response) {
vm.repositories = response.data || [];
vm.totalCount = response.headers('X-Total-Count');
$scope.$broadcast('refreshTags', true);
}

View File

@ -44,10 +44,10 @@
<td width="20%">//u.email//</td>
<td width="35%">//u.creation_time | dateL : 'YYYY-MM-DD HH:mm:ss'//</td>
<td width="15%">
<toggle-admin has-admin-role="u.has_admin_role" user-id="//u.user_id//"></toggle-admin>
<toggle-admin current-user="vm.currentUser" has-admin-role="u.has_admin_role" user-id="//u.user_id//"></toggle-admin>
</td>
<td width="20%">
&nbsp;&nbsp;<a href="javascript:void(0)" ng-click="vm.confirmToDelete(u.user_id, u.username)"><span class="glyphicon glyphicon-trash"></span></a>
&nbsp;&nbsp;<a ng-if="vm.currentUser.user_id != u.user_id" href="javascript:void(0)" ng-click="vm.confirmToDelete(u.user_id, u.username)"><span class="glyphicon glyphicon-trash"></span></a>
</td>
</tr>
</tbody>

View File

@ -20,9 +20,9 @@
.module('harbor.user')
.directive('listUser', listUser);
ListUserController.$inject = ['$scope', 'ListUserService', 'DeleteUserService', '$filter', 'trFilter'];
ListUserController.$inject = ['$scope', 'ListUserService', 'DeleteUserService', 'currentUser', '$filter', 'trFilter'];
function ListUserController($scope, ListUserService, DeleteUserService, $filter, $trFilter) {
function ListUserController($scope, ListUserService, DeleteUserService, currentUser, $filter, $trFilter) {
$scope.subsSubPane = 226;
@ -33,6 +33,8 @@
vm.deleteUser = deleteUser;
vm.confirmToDelete = confirmToDelete;
vm.retrieve = retrieve;
vm.currentUser = currentUser.get();
vm.retrieve();

View File

@ -12,5 +12,5 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<button ng-show="vm.isAdmin" class="btn btn-success" ng-click="vm.toggle()">// 'button_on' | tr //</button>
<button ng-show="vm.isAdmin" ng-disabled="!vm.editable" class="btn btn-success" ng-click="vm.toggle()">// 'button_on' | tr //</button>
<button ng-show="!vm.isAdmin" class="btn btn-danger" ng-click="vm.toggle()">// 'button_off' | tr //</button>

View File

@ -28,6 +28,7 @@
vm.isAdmin = (vm.hasAdminRole === 1);
vm.enabled = vm.isAdmin ? 0 : 1;
vm.toggle = toggle;
vm.editable = (vm.currentUser.user_id != vm.userId);
function toggle() {
ToggleAdminService(vm.userId, vm.enabled)
@ -63,7 +64,8 @@
'templateUrl': '/static/resources/js/components/user/toggle-admin.directive.html',
'scope': {
'hasAdminRole': '=',
'userId': '@'
'userId': '@',
'currentUser': '='
},
'link': link,
'controller': ToggleAdminController,

View File

@ -60,6 +60,7 @@
'harbor.system.management',
'harbor.loading.progress',
'harbor.inline.help',
'harbor.dismissable.alerts'
'harbor.dismissable.alerts',
'harbor.paginator'
]);
})();

View File

@ -26,7 +26,7 @@
return LogResult;
function LogResult(queryParams) {
function LogResult(queryParams, page, pageSize) {
var projectId = queryParams.projectId;
var username = queryParams.username;
var beginTimestamp = queryParams.beginTimestamp;
@ -34,7 +34,7 @@
var keywords = queryParams.keywords;
return $http
.post('/api/projects/' + projectId + '/logs/filter', {
.post('/api/projects/' + projectId + '/logs/filter?page=' + page + '&page_size=' + pageSize, {
'begin_timestamp' : beginTimestamp,
'end_timestamp' : endTimestamp,
'keywords' : keywords,

View File

@ -26,9 +26,9 @@
return listReplicationJob;
function listReplicationJob(policyId, repository, status, startTime, endTime) {
function listReplicationJob(policyId, repository, status, startTime, endTime, page, pageSize) {
return $http
.get('/api/jobs/replication/', {
.get('/api/jobs/replication/?page=' + page + '&page_size=' + pageSize, {
'params': {
'policy_id': policyId,
'repository': repository,

View File

@ -25,11 +25,11 @@
return ListRepository;
function ListRepository(projectId, q) {
function ListRepository(projectId, q, page, pageSize) {
$log.info('list repositories:' + projectId + ', q:' + q);
return $http
.get('/api/repositories', {
.get('/api/repositories?page=' + page + '&page_size=' + pageSize, {
'params':{
'project_id': projectId,
'q': q

View File

@ -191,4 +191,7 @@
<script src="/static/resources/js/components/inline-help/inline-help.directive.js"></script>
<script src="/static/resources/js/components/dismissable-alerts/dismissable-alerts.module.js"></script>
<script src="/static/resources/js/components/dismissable-alerts/dismissable-alerts.directive.js"></script>
<script src="/static/resources/js/components/dismissable-alerts/dismissable-alerts.directive.js"></script>
<script src="/static/resources/js/components/paginator/paginator.module.js"></script>
<script src="/static/resources/js/components/paginator/paginator.directive.js"></script>