1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-07-24 07:49:41 +02:00

fix(datatables): allow selecting range using shift (#344) (#2962)

* fix(datatables): allow selecting range using shift (#344)

* feat(datatables): more intuitive batch select behaviour

* feat(datatables): add overridable function called on selection change

* refactor(datatables): remove custom selectAll on Generic-extending Controllers

* fix(datatables): stored state data retrieval on Generic-extanding datatables controllers

* refactor(datatables): remove code duplication between GenericController and extending controllers
This commit is contained in:
xAt0mZ 2019-07-02 17:51:17 +02:00 committed by GitHub
parent 6591498ab9
commit 1138fd5ab1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
39 changed files with 477 additions and 582 deletions

View file

@ -23,7 +23,7 @@
<table class="table table-hover table-filters nowrap-cells">
<thead>
<tr>
<th uib-dropdown dropdown-append-to-body auto-close="disabled" is-open="$ctrl.filters.usage.open">
<th uib-dropdown dropdown-append-to-body auto-close="disabled" is-open="$ctrl.filters.state.open">
<span class="md-checkbox" ng-if="!$ctrl.offlineMode" authorization="DockerVolumeDelete, DockerVolumeCreate">
<input id="select_all" type="checkbox" ng-model="$ctrl.state.selectAll" ng-change="$ctrl.selectAll()" />
<label for="select_all"></label>
@ -34,8 +34,8 @@
<i class="fa fa-sort-alpha-up" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'Id' && $ctrl.state.reverseOrder"></i>
</a>
<div>
<span uib-dropdown-toggle class="table-filter" ng-if="!$ctrl.filters.usage.enabled">Filter <i class="fa fa-filter" aria-hidden="true"></i></span>
<span uib-dropdown-toggle class="table-filter filter-active" ng-if="$ctrl.filters.usage.enabled">Filter <i class="fa fa-check" aria-hidden="true"></i></span>
<span uib-dropdown-toggle class="table-filter" ng-if="!$ctrl.filters.state.enabled">Filter <i class="fa fa-filter" aria-hidden="true"></i></span>
<span uib-dropdown-toggle class="table-filter filter-active" ng-if="$ctrl.filters.state.enabled">Filter <i class="fa fa-check" aria-hidden="true"></i></span>
</div>
<div class="dropdown-menu" uib-dropdown-menu>
<div class="tableMenu">
@ -44,16 +44,16 @@
</div>
<div class="menuContent">
<div class="md-checkbox">
<input id="filter_usage_usedImages" type="checkbox" ng-model="$ctrl.filters.usage.showUsedVolumes" ng-change="$ctrl.onUsageFilterChange()"/>
<input id="filter_usage_usedImages" type="checkbox" ng-model="$ctrl.filters.state.showUsedVolumes" ng-change="$ctrl.onUsageFilterChange()"/>
<label for="filter_usage_usedImages">Used volumes</label>
</div>
<div class="md-checkbox">
<input id="filter_usage_unusedImages" type="checkbox" ng-model="$ctrl.filters.usage.showUnusedVolumes" ng-change="$ctrl.onUsageFilterChange()"/>
<input id="filter_usage_unusedImages" type="checkbox" ng-model="$ctrl.filters.state.showUnusedVolumes" ng-change="$ctrl.onUsageFilterChange()"/>
<label for="filter_usage_unusedImages">Unused volumes</label>
</div>
</div>
<div>
<a type="button" class="btn btn-default btn-sm" ng-click="$ctrl.filters.usage.open = false;">Close</a>
<a type="button" class="btn btn-default btn-sm" ng-click="$ctrl.filters.state.open = false;">Close</a>
</div>
</div>
</div>
@ -106,7 +106,7 @@
<tr dir-paginate="item in ($ctrl.state.filteredDataSet = ($ctrl.dataset | filter: $ctrl.applyFilters | filter:$ctrl.state.textFilter | orderBy:$ctrl.state.orderBy:$ctrl.state.reverseOrder | itemsPerPage: $ctrl.state.paginatedItemLimit))" ng-class="{active: item.Checked}">
<td>
<span class="md-checkbox" ng-if="!$ctrl.offlineMode" authorization="DockerVolumeDelete, DockerVolumeCreate">
<input id="select_{{ $index }}" type="checkbox" ng-model="item.Checked" ng-change="$ctrl.selectItem(item)"/>
<input id="select_{{ $index }}" type="checkbox" ng-model="item.Checked" ng-click="$ctrl.selectItem(item, $event)"/>
<label for="select_{{ $index }}"></label>
</span>
<a ng-if="!$ctrl.offlineMode" ui-sref="docker.volumes.volume({ id: item.Id, nodeName: item.NodeName })" class="monospaced" title="{{ item.Id }}">{{ item.Id | truncate:40 }}</a>

View file

@ -1,20 +1,13 @@
angular.module('portainer.docker')
.controller('VolumesDatatableController', ['PaginationService', 'DatatableService',
function (PaginationService, DatatableService) {
.controller('VolumesDatatableController', ['$scope', '$controller', 'DatatableService',
function ($scope, $controller, DatatableService) {
angular.extend(this, $controller('GenericDatatableController', {$scope: $scope}));
var ctrl = this;
this.state = {
selectAll: false,
orderBy: this.orderBy,
paginatedItemLimit: PaginationService.getPaginationLimit(this.tableKey),
displayTextFilter: false,
selectedItemCount: 0,
selectedItems: []
};
this.filters = {
usage: {
state: {
open: false,
enabled: false,
showUsedVolumes: true,
@ -22,62 +15,29 @@ function (PaginationService, DatatableService) {
}
};
this.onTextFilterChange = function() {
DatatableService.setDataTableTextFilters(this.tableKey, this.state.textFilter);
};
this.changeOrderBy = function(orderField) {
this.state.reverseOrder = this.state.orderBy === orderField ? !this.state.reverseOrder : false;
this.state.orderBy = orderField;
DatatableService.setDataTableOrder(this.tableKey, orderField, this.state.reverseOrder);
};
this.selectItem = function(item) {
if (item.Checked) {
this.state.selectedItemCount++;
this.state.selectedItems.push(item);
} else {
this.state.selectedItems.splice(this.state.selectedItems.indexOf(item), 1);
this.state.selectedItemCount--;
}
};
this.selectAll = function() {
for (var i = 0; i < this.state.filteredDataSet.length; i++) {
var item = this.state.filteredDataSet[i];
if (item.Checked !== this.state.selectAll) {
item.Checked = this.state.selectAll;
this.selectItem(item);
}
}
};
this.changePaginationLimit = function() {
PaginationService.setPaginationLimit(this.tableKey, this.state.paginatedItemLimit);
};
this.applyFilters = function(value) {
var volume = value;
var filters = ctrl.filters;
if ((volume.dangling && filters.usage.showUnusedVolumes)
|| (!volume.dangling && filters.usage.showUsedVolumes)) {
if ((volume.dangling && filters.state.showUnusedVolumes)
|| (!volume.dangling && filters.state.showUsedVolumes)) {
return true;
}
return false;
};
this.onUsageFilterChange = function() {
var filters = this.filters.usage;
this.onstateFilterChange = function() {
var filters = this.filters.state;
var filtered = false;
if (!filters.showUsedVolumes || !filters.showUnusedVolumes) {
filtered = true;
}
this.filters.usage.enabled = filtered;
this.filters.state.enabled = filtered;
DatatableService.setDataTableFilters(this.tableKey, this.filters);
};
this.$onInit = function() {
setDefaults(this);
this.setDefaults();
this.prepareTableFromDataset();
var storedOrder = DatatableService.getDataTableOrder(this.tableKey);
if (storedOrder !== null) {
@ -85,20 +45,18 @@ function (PaginationService, DatatableService) {
this.state.orderBy = storedOrder.orderBy;
}
var textFilter = DatatableService.getDataTableTextFilters(this.tableKey);
if (textFilter !== null) {
this.state.textFilter = textFilter;
this.onTextFilterChange();
}
var storedFilters = DatatableService.getDataTableFilters(this.tableKey);
if (storedFilters !== null) {
this.filters = storedFilters;
}
this.filters.usage.open = false;
var textFilter = DatatableService.getDataTableTextFilters(this.tableKey);
if (textFilter !== null) {
this.state.textFilter = textFilter;
if (this.filters && this.filters.state) {
this.filters.state.open = false;
}
};
function setDefaults(ctrl) {
ctrl.showTextFilter = ctrl.showTextFilter ? ctrl.showTextFilter : false;
ctrl.state.reverseOrder = ctrl.reverseOrder ? ctrl.reverseOrder : false;
}
}]);