feat(UX): add pagination for all object lists (#352)

pull/362/head
Anthony Lapenna 2016-11-17 21:50:46 +09:00 committed by GitHub
parent 13a8b11d3d
commit 913c580340
27 changed files with 86 additions and 31 deletions

View File

@ -5,6 +5,7 @@ angular.module('portainer', [
'ui.select',
'ngCookies',
'ngSanitize',
'angularUtils.directives.dirPagination',
'portainer.services',
'portainer.helpers',
'portainer.filters',
@ -188,4 +189,5 @@ angular.module('portainer', [
.constant('DOCKER_PORT', '') // Docker port, leave as an empty string if no port is requred. If you have a port, prefix it with a ':' i.e. :4243
.constant('CONFIG_ENDPOINT', 'settings')
.constant('TEMPLATES_ENDPOINT', 'templates')
.constant('PAGINATION_MAX_ITEMS', 10)
.constant('UI_VERSION', 'v1.10.1');

View File

@ -207,7 +207,6 @@
<div class="col-lg-12 col-md-12 col-xs-12">
<rd-widget>
<rd-widget-header icon="fa-sitemap" title="Connected networks"></rd-widget-header>
<rd-widget-body classes="no-padding">
<table class="table">
<thead>
@ -218,7 +217,7 @@
<th>Actions</th>
</thead>
<tbody>
<tr ng-repeat="(key, value) in container.NetworkSettings.Networks">
<tr dir-paginate="(key, value) in container.NetworkSettings.Networks | itemsPerPage: pagination_count">
<td><a ui-sref="network({id: value.NetworkID})">{{ key }}</a></td>
<td>{{ value.IPAddress || '-' }}</td>
<td>{{ value.Gateway || '-' }}</td>
@ -229,6 +228,9 @@
</tr>
</tbody>
</table>
<div class="pagination-controls">
<dir-pagination-controls></dir-pagination-controls>
</div>
</rd-widget-body>
</rd-widget>
</div>

View File

@ -1,12 +1,13 @@
angular.module('container', [])
.controller('ContainerController', ['$scope', '$state','$stateParams', '$filter', 'Container', 'ContainerCommit', 'ImageHelper', 'Network', 'Messages',
function ($scope, $state, $stateParams, $filter, Container, ContainerCommit, ImageHelper, Network, Messages) {
.controller('ContainerController', ['$scope', '$state','$stateParams', '$filter', 'Container', 'ContainerCommit', 'ImageHelper', 'Network', 'Messages', 'Settings',
function ($scope, $state, $stateParams, $filter, Container, ContainerCommit, ImageHelper, Network, Messages, Settings) {
$scope.activityTime = 0;
$scope.portBindings = [];
$scope.config = {
Image: '',
Registry: ''
};
$scope.pagination_count = Settings.pagination_count;
var update = function () {
$('#loadingViewSpinner').show();

View File

@ -83,7 +83,7 @@
</tr>
</thead>
<tbody>
<tr ng-repeat="container in (state.filteredContainers = ( containers | filter:state.filter | orderBy:sortType:sortReverse))">
<tr dir-paginate="container in (state.filteredContainers = ( containers | filter:state.filter | orderBy:sortType:sortReverse | itemsPerPage: pagination_count))">
<td><input type="checkbox" ng-model="container.Checked" ng-change="selectItem(container)"/></td>
<td><span class="label label-{{ container.Status|containerstatusbadge }}">{{ container.Status|containerstatus }}</span></td>
<td ng-if="swarm && !swarm_mode"><a ui-sref="container({id: container.Id})">{{ container|swarmcontainername}}</a></td>
@ -106,6 +106,9 @@
</tr>
</tbody>
</table>
<div ng-if="containers" class="pull-left pagination-controls">
<dir-pagination-controls></dir-pagination-controls>
</div>
</div>
</rd-widget-body>
<rd-widget>

View File

@ -8,6 +8,7 @@ function ($scope, Container, ContainerHelper, Info, Settings, Messages, Config)
$scope.sortReverse = false;
$scope.state.selectedItemCount = 0;
$scope.swarm_mode = false;
$scope.pagination_count = Settings.pagination_count;
$scope.order = function (sortType) {
$scope.sortReverse = ($scope.sortType === sortType) ? !$scope.sortReverse : false;

View File

@ -49,13 +49,16 @@
</tr>
</thead>
<tbody>
<tr ng-repeat="event in (events | filter:state.filter | orderBy:sortType:sortReverse)">
<tr dir-paginate="event in (events | filter:state.filter | orderBy:sortType:sortReverse | itemsPerPage: pagination_count)">
<td>{{ event.Time|getisodatefromtimestamp }}</td>
<td>{{ event.Type }}</td>
<td>{{ event.Details }}</td>
</tr>
</tbody>
</table>
<div ng-if="events" class="pull-left pagination-controls">
<dir-pagination-controls></dir-pagination-controls>
</div>
</div>
</rd-widget-body>
<rd-widget>

View File

@ -4,6 +4,7 @@ function ($scope, Settings, Messages, Events) {
$scope.state = {};
$scope.sortType = 'Time';
$scope.sortReverse = true;
$scope.pagination_count = Settings.pagination_count;
$scope.order = function(sortType) {
$scope.sortReverse = ($scope.sortType === sortType) ? !$scope.sortReverse : false;

View File

@ -98,7 +98,7 @@
</tr>
</thead>
<tbody>
<tr ng-repeat="image in (state.filteredImages = (images | filter:state.filter | orderBy:sortType:sortReverse))">
<tr dir-paginate="image in (state.filteredImages = (images | filter:state.filter | orderBy:sortType:sortReverse | itemsPerPage: pagination_count))">
<td><input type="checkbox" ng-model="image.Checked" ng-change="selectItem(image)" /></td>
<td><a ui-sref="image({id: image.Id})">{{ image.Id|truncate:20}}</a></td>
<td>
@ -115,6 +115,9 @@
</tr>
</tbody>
</table>
<div ng-if="images" class="pull-left pagination-controls">
<dir-pagination-controls></dir-pagination-controls>
</div>
</div>
</rd-widget-body>
<rd-widget>

View File

@ -1,10 +1,11 @@
angular.module('images', [])
.controller('ImagesController', ['$scope', '$state', 'Config', 'Image', 'Messages',
function ($scope, $state, Config, Image, Messages) {
.controller('ImagesController', ['$scope', '$state', 'Config', 'Image', 'Messages', 'Settings',
function ($scope, $state, Config, Image, Messages, Settings) {
$scope.state = {};
$scope.sortType = 'RepoTags';
$scope.sortReverse = true;
$scope.state.selectedItemCount = 0;
$scope.pagination_count = Settings.pagination_count;
$scope.config = {
Image: '',

View File

@ -121,7 +121,7 @@
</tr>
</thead>
<tbody>
<tr ng-repeat="network in ( state.filteredNetworks = (networks | filter:state.filter | orderBy:sortType:sortReverse))">
<tr dir-paginate="network in ( state.filteredNetworks = (networks | filter:state.filter | orderBy:sortType:sortReverse | itemsPerPage: pagination_count))">
<td><input type="checkbox" ng-model="network.Checked" ng-change="selectItem(network)"/></td>
<td><a ui-sref="network({id: network.Id})">{{ network.Name|truncate:40}}</a></td>
<td>{{ network.Id }}</td>
@ -139,6 +139,9 @@
</tr>
</tbody>
</table>
<div ng-if="networks" class="pull-left pagination-controls">
<dir-pagination-controls></dir-pagination-controls>
</div>
</div>
</rd-widget-body>
<rd-widget>

View File

@ -1,11 +1,12 @@
angular.module('networks', [])
.controller('NetworksController', ['$scope', '$state', 'Network', 'Config', 'Messages',
function ($scope, $state, Network, Config, Messages) {
.controller('NetworksController', ['$scope', '$state', 'Network', 'Config', 'Messages', 'Settings',
function ($scope, $state, Network, Config, Messages, Settings) {
$scope.state = {};
$scope.state.selectedItemCount = 0;
$scope.state.advancedSettings = false;
$scope.sortType = 'Name';
$scope.sortReverse = false;
$scope.pagination_count = Settings.pagination_count;
$scope.config = {
Name: ''
};

View File

@ -190,7 +190,7 @@
</tr>
</thead>
<tbody>
<tr ng-repeat="task in (filteredTasks = ( tasks | orderBy:sortType:sortReverse))">
<tr dir-paginate="task in (filteredTasks = ( tasks | orderBy:sortType:sortReverse | itemsPerPage: pagination_count))">
<td><a ui-sref="task({ id: task.Id })">{{ task.Id }}</a></td>
<td><span class="label label-{{ task.Status|taskstatusbadge }}">{{ task.Status }}</span></td>
<td>{{ task.Slot }}</td>
@ -199,6 +199,9 @@
</tr>
</tbody>
</table>
<div ng-if="tasks" class="pagination-controls">
<dir-pagination-controls></dir-pagination-controls>
</div>
</rd-widget-body>
</rd-widget>
</div>

View File

@ -1,12 +1,13 @@
angular.module('service', [])
.controller('ServiceController', ['$scope', '$stateParams', '$state', 'Service', 'ServiceHelper', 'Task', 'Node', 'Messages',
function ($scope, $stateParams, $state, Service, ServiceHelper, Task, Node, Messages) {
.controller('ServiceController', ['$scope', '$stateParams', '$state', 'Service', 'ServiceHelper', 'Task', 'Node', 'Messages', 'Settings',
function ($scope, $stateParams, $state, Service, ServiceHelper, Task, Node, Messages, Settings) {
$scope.service = {};
$scope.tasks = [];
$scope.displayNode = false;
$scope.sortType = 'Status';
$scope.sortReverse = false;
$scope.pagination_count = Settings.pagination_count;
var previousServiceValues = {};

View File

@ -52,7 +52,7 @@
</th>
</thead>
<tbody>
<tr ng-repeat="service in (state.filteredServices = ( services | filter:state.filter | orderBy:sortType:sortReverse))">
<tr dir-paginate="service in (state.filteredServices = ( services | filter:state.filter | orderBy:sortType:sortReverse | itemsPerPage: pagination_count))">
<td><input type="checkbox" ng-model="service.Checked" ng-change="selectItem(service)"/></td>
<td><a ui-sref="service({id: service.Id})">{{ service.Name }}</a></td>
<td>{{ service.Image }}</td>
@ -77,6 +77,9 @@
</tr>
</tbody>
</table>
<div ng-if="services" class="pull-left pagination-controls">
<dir-pagination-controls></dir-pagination-controls>
</div>
</div>
</rd-widget-body>
<rd-widget>

View File

@ -1,10 +1,11 @@
angular.module('services', [])
.controller('ServicesController', ['$scope', '$stateParams', '$state', 'Service', 'ServiceHelper', 'Messages',
function ($scope, $stateParams, $state, Service, ServiceHelper, Messages) {
.controller('ServicesController', ['$scope', '$stateParams', '$state', 'Service', 'ServiceHelper', 'Messages', 'Settings',
function ($scope, $stateParams, $state, Service, ServiceHelper, Messages, Settings) {
$scope.state = {};
$scope.state.selectedItemCount = 0;
$scope.sortType = 'Name';
$scope.sortReverse = false;
$scope.pagination_count = Settings.pagination_count;
$scope.scaleService = function scaleService(service) {
$('#loadServicesSpinner').show();

View File

@ -69,11 +69,14 @@
</tr>
</thead>
<tbody>
<tr ng-repeat="processInfos in state.filteredProcesses = (containerTop.Processes | orderBy:sortType:sortReverse)">
<tr dir-paginate="processInfos in state.filteredProcesses = (containerTop.Processes | orderBy:sortType:sortReverse | itemsPerPage: pagination_count)">
<td ng-repeat="processInfo in processInfos track by $index">{{processInfo}}</td>
</tr>
</tbody>
</table>
<div ng-if="containerTop.Processes" class="pagination-controls">
<dir-pagination-controls></dir-pagination-controls>
</div>
</rd-widget-body>
</rd-widget>
</div>

View File

@ -7,6 +7,7 @@ function (Settings, $scope, Messages, $timeout, Container, ContainerTop, $stateP
$scope.state = {};
$scope.sortType = 'CMD';
$scope.sortReverse = false;
$scope.pagination_count = Settings.pagination_count;
$scope.order = function (sortType) {
$scope.sortReverse = ($scope.sortType === sortType) ? !$scope.sortReverse : false;
$scope.sortType = sortType;

View File

@ -117,7 +117,7 @@
</tr>
</thead>
<tbody>
<tr ng-repeat="node in (state.filteredNodes = (swarm.Status | filter:state.filter | orderBy:sortType:sortReverse))">
<tr dir-paginate="node in (state.filteredNodes = (swarm.Status | filter:state.filter | orderBy:sortType:sortReverse | itemsPerPage: pagination_count))">
<td>{{ node.name }}</td>
<td>{{ node.cpu }}</td>
<td>{{ node.memory }}</td>
@ -127,6 +127,9 @@
</tr>
</tbody>
</table>
<div class="pagination-controls">
<dir-pagination-controls></dir-pagination-controls>
</div>
</rd-widget-body>
</rd-widget>
</div>
@ -182,7 +185,7 @@
</tr>
</thead>
<tbody>
<tr ng-repeat="node in (state.filteredNodes = (nodes | filter:state.filter | orderBy:sortType:sortReverse))">
<tr dir-paginate="node in (state.filteredNodes = (nodes | filter:state.filter | orderBy:sortType:sortReverse | itemsPerPage: pagination_count))">
<td>{{ node.Description.Hostname }}</td>
<td>{{ node.Spec.Role }}</td>
<td>{{ node.Description.Resources.NanoCPUs / 1000000000 }}</td>
@ -192,6 +195,9 @@
</tr>
</tbody>
</table>
<div class="pagination-controls">
<dir-pagination-controls></dir-pagination-controls>
</div>
</rd-widget-body>
</rd-widget>
</div>

View File

@ -1,6 +1,6 @@
angular.module('swarm', [])
.controller('SwarmController', ['$scope', 'Info', 'Version', 'Node',
function ($scope, Info, Version, Node) {
.controller('SwarmController', ['$scope', 'Info', 'Version', 'Node', 'Settings',
function ($scope, Info, Version, Node, Settings) {
$scope.sortType = 'Name';
$scope.sortReverse = true;
@ -10,6 +10,7 @@ function ($scope, Info, Version, Node) {
$scope.swarm_mode = false;
$scope.totalCPU = 0;
$scope.totalMemory = 0;
$scope.pagination_count = Settings.pagination_count;
$scope.order = function(sortType) {
$scope.sortReverse = ($scope.sortType === sortType) ? !$scope.sortReverse : false;

View File

@ -121,7 +121,7 @@
</rd-widget-header>
<rd-widget-body classes="padding">
<div class="template-list">
<div ng-repeat="tpl in templates" class="container-template hvr-underline-from-center" id="template_{{ $index }}" ng-click="selectTemplate($index)">
<div dir-paginate="tpl in templates | itemsPerPage: pagination_count" class="container-template hvr-underline-from-center" id="template_{{ $index }}" ng-click="selectTemplate($index)">
<img class="logo" ng-src="{{ tpl.logo }}" />
<div class="title">{{ tpl.title }}</div>
<div class="description">{{ tpl.description }}</div>
@ -133,6 +133,9 @@
No templates available.
</div>
</div>
<div ng-if="templates">
<dir-pagination-controls></dir-pagination-controls>
</div>
</rd-widget-body>
</rd-widget>
</div>

View File

@ -1,6 +1,6 @@
angular.module('templates', [])
.controller('TemplatesController', ['$scope', '$q', '$state', '$filter', 'Config', 'Info', 'Container', 'ContainerHelper', 'Image', 'Volume', 'Network', 'Templates', 'TemplateHelper', 'Messages',
function ($scope, $q, $state, $filter, Config, Info, Container, ContainerHelper, Image, Volume, Network, Templates, TemplateHelper, Messages) {
.controller('TemplatesController', ['$scope', '$q', '$state', '$filter', 'Config', 'Info', 'Container', 'ContainerHelper', 'Image', 'Volume', 'Network', 'Templates', 'TemplateHelper', 'Messages', 'Settings',
function ($scope, $q, $state, $filter, Config, Info, Container, ContainerHelper, Image, Volume, Network, Templates, TemplateHelper, Messages, Settings) {
$scope.state = {
selectedTemplate: null,
showAdvancedOptions: false
@ -10,6 +10,7 @@ function ($scope, $q, $state, $filter, Config, Info, Container, ContainerHelper,
name: "",
ports: []
};
$scope.pagination_count = Settings.pagination_count;
var selectedItem = -1;

View File

@ -53,7 +53,7 @@
</tr>
</thead>
<tbody>
<tr ng-repeat="volume in (state.filteredVolumes = (volumes | filter:state.filter | orderBy:sortType:sortReverse))">
<tr dir-paginate="volume in (state.filteredVolumes = (volumes | filter:state.filter | orderBy:sortType:sortReverse | itemsPerPage: pagination_count))">
<td><input type="checkbox" ng-model="volume.Checked" ng-change="selectItem(volume)"/></td>
<td>{{ volume.Name|truncate:50 }}</td>
<td>{{ volume.Driver }}</td>
@ -67,6 +67,9 @@
</tr>
</tbody>
</table>
<div ng-if="volumes" class="pull-left pagination-controls">
<dir-pagination-controls></dir-pagination-controls>
</div>
</div>
</rd-widget-body>
<rd-widget>

View File

@ -1,6 +1,6 @@
angular.module('volumes', [])
.controller('VolumesController', ['$scope', '$state', 'Volume', 'Messages',
function ($scope, $state, Volume, Messages) {
.controller('VolumesController', ['$scope', '$state', 'Volume', 'Messages', 'Settings',
function ($scope, $state, Volume, Messages, Settings) {
$scope.state = {};
$scope.state.selectedItemCount = 0;
$scope.sortType = 'Name';
@ -8,6 +8,7 @@ function ($scope, $state, Volume, Messages) {
$scope.config = {
Name: ''
};
$scope.pagination_count = Settings.pagination_count;
$scope.order = function(sortType) {
$scope.sortReverse = ($scope.sortType === sortType) ? !$scope.sortReverse : false;

View File

@ -213,7 +213,7 @@ angular.module('portainer.services', ['ngResource', 'ngSanitize'])
get: {method: 'GET', isArray: true}
});
}])
.factory('Settings', ['DOCKER_ENDPOINT', 'DOCKER_PORT', 'UI_VERSION', function SettingsFactory(DOCKER_ENDPOINT, DOCKER_PORT, UI_VERSION) {
.factory('Settings', ['DOCKER_ENDPOINT', 'DOCKER_PORT', 'UI_VERSION', 'PAGINATION_MAX_ITEMS', function SettingsFactory(DOCKER_ENDPOINT, DOCKER_PORT, UI_VERSION, PAGINATION_MAX_ITEMS) {
'use strict';
var url = DOCKER_ENDPOINT;
if (DOCKER_PORT) {
@ -225,7 +225,8 @@ angular.module('portainer.services', ['ngResource', 'ngSanitize'])
endpoint: DOCKER_ENDPOINT,
uiVersion: UI_VERSION,
url: url,
firstLoad: firstLoad
firstLoad: firstLoad,
pagination_count: PAGINATION_MAX_ITEMS
};
}])
.factory('Messages', ['$rootScope', '$sanitize', function MessagesFactory($rootScope, $sanitize) {

View File

@ -202,3 +202,7 @@ input[type="radio"] {
font-size: 0.8em;
margin-bottom: 5px;
}
.pagination-controls {
margin-left: 10px;
}

View File

@ -32,6 +32,7 @@
"angular-mocks": "~1.5.0",
"angular-resource": "~1.5.0",
"angular-ui-select": "~0.17.1",
"angular-utils-pagination": "~0.11.1",
"bootstrap": "~3.3.6",
"font-awesome": "~4.6.3",
"filesize": "~3.3.0",

View File

@ -196,6 +196,7 @@ module.exports = function (grunt) {
'bower_components/angular-ui-router/release/angular-ui-router.min.js',
'bower_components/angular-resource/angular-resource.min.js',
'bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js',
'bower_components/angular-utils-pagination/dirPagination.js',
'bower_components/angular-ui-select/dist/select.min.js'],
dest: '<%= distdir %>/js/angular.js'
}