1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-08-08 23:35:31 +02:00

feat(templates): remove toggle and add sorting for app templates EE-2522 (#6884)

This commit is contained in:
matias-portainer 2022-07-20 16:27:15 -03:00 committed by GitHub
parent 9223c0226a
commit df381b6a33
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 236 additions and 42 deletions

View file

@ -2,48 +2,53 @@ import _ from 'lodash-es';
angular.module('portainer.app').controller('TemplateListController', TemplateListController);
function TemplateListController($async, $state, DatatableService, Notifications, TemplateService) {
function TemplateListController($scope, $async, $state, DatatableService, Notifications, TemplateService) {
var ctrl = this;
this.state = {
textFilter: '',
selectedCategory: '',
selectedCategory: null,
categories: [],
typeFilters: [],
filterByType: null,
showContainerTemplates: true,
selectedOrderBy: null,
orderByFields: [],
orderDesc: false,
};
this.onTextFilterChange = function () {
DatatableService.setDataTableTextFilters(this.tableKey, this.state.textFilter);
};
this.filterByTemplateType = function (item) {
ctrl.filterByTemplateType = function (item) {
switch (item.Type) {
case 1: // container
return ctrl.state.showContainerTemplates;
case 2: // swarm stack
return ctrl.showSwarmStacks;
return ctrl.showSwarmStacks && !ctrl.state.showContainerTemplates;
case 3: // docker compose
return !ctrl.showSwarmStacks || (ctrl.showSwarmStacks && ctrl.state.showContainerTemplates);
return !ctrl.state.showContainerTemplates || null === ctrl.state.filterByType;
case 4: // Edge stack templates
return false;
}
return false;
};
this.updateCategories = function () {
ctrl.updateCategories = function () {
var availableCategories = [];
for (var i = 0; i < ctrl.templates.length; i++) {
var template = ctrl.templates[i];
if (this.filterByTemplateType(template)) {
if (ctrl.filterByTemplateType(template)) {
availableCategories = availableCategories.concat(template.Categories);
}
}
this.state.categories = _.sortBy(_.uniq(availableCategories));
ctrl.state.categories = _.sortBy(_.uniq(availableCategories));
};
this.filterByCategory = function (item) {
ctrl.filterByCategory = function (item) {
if (!ctrl.state.selectedCategory) {
return true;
}
@ -73,6 +78,40 @@ function TemplateListController($async, $state, DatatableService, Notifications,
}
}
ctrl.changeOrderBy = function (orderField) {
$scope.$evalAsync(() => {
if (null === orderField) {
ctrl.state.selectedOrderBy = null;
ctrl.templates = ctrl.initalTemplates;
}
ctrl.state.selectedOrderBy = orderField;
ctrl.templates = _.orderBy(ctrl.templates, [getSorter(ctrl.state.selectedOrderBy)], [ctrl.state.orderDesc ? 'desc' : 'asc']);
});
};
ctrl.applyTypeFilter = function (type) {
$scope.$evalAsync(() => {
ctrl.state.filterByType = type;
ctrl.state.showContainerTemplates = 'Container' === type || null === type;
ctrl.updateCategories();
});
};
ctrl.invertOrder = function () {
$scope.$evalAsync(() => {
ctrl.state.orderDesc = !ctrl.state.orderDesc;
ctrl.templates = _.orderBy(ctrl.templates, [getSorter(ctrl.state.selectedOrderBy)], [ctrl.state.orderDesc ? 'desc' : 'asc']);
});
};
ctrl.applyCategoriesFilter = function (category) {
$scope.$evalAsync(() => {
ctrl.state.selectedCategory = category;
ctrl.updateCategories();
});
};
this.$onInit = function () {
if (this.showSwarmStacks) {
this.state.showContainerTemplates = false;
@ -83,5 +122,28 @@ function TemplateListController($async, $state, DatatableService, Notifications,
if (textFilter !== null) {
this.state.textFilter = textFilter;
}
this.initalTemplates = this.templates;
this.state.orderByFields = ['Title', 'Categories', 'Description'];
this.state.typeFilters = ['Container', 'Stack'];
};
function categorySorter(template) {
if (template.Categories && template.Categories.length > 0 && template.Categories[0] && template.Categories[0].length > 0) {
return template.Categories[0].toLowerCase();
}
}
function getSorter(orderBy) {
let sorter;
switch (orderBy) {
case 'Categories':
sorter = categorySorter;
break;
default:
sorter = orderBy;
}
return sorter;
}
}

View file

@ -2,45 +2,45 @@
<rd-widget>
<rd-widget-header icon="{{ $ctrl.titleIcon }}" feather-icon="true" title-text="{{ $ctrl.titleText }}"></rd-widget-header>
<rd-widget-body classes="no-padding">
<div class="mx-3">
<div class="actionBar">
<div>
<div class="actionBar">
<div class="row">
<div class="col-sm-12">
<button type="button" class="btn btn-sm btn-primary" ui-sref="docker.templates.new" ng-if="$ctrl.showAddAction">
<i class="fa fa-plus space-right" aria-hidden="true"></i>Add template
</button>
<span ng-class="{ 'pull-right': $ctrl.showAddAction }">
<ui-select ng-model="$ctrl.state.selectedCategory">
<ui-select-match placeholder="Select a category" allow-clear="true">
<span>{{ $select.selected }}</span>
</ui-select-match>
<ui-select-choices repeat="category in ($ctrl.state.categories | filter: $select.search)">
<span>{{ category }}</span>
</ui-select-choices>
</ui-select>
</span>
</div>
<div class="small text-muted mt-3">
<label for="show_stacks" class="control-label text-left"> Show container templates </label>
<label class="switch space-left">
<input type="checkbox" name="show_stacks" ng-model="$ctrl.state.showContainerTemplates" ng-change="$ctrl.updateCategories()" /><i></i>
</label>
</div>
</div>
<div class="searchBar">
<i class="fa fa-search searchIcon" aria-hidden="true"></i>
<input
type="text"
class="searchInput"
ng-model="$ctrl.state.textFilter"
ng-change="$ctrl.onTextFilterChange()"
placeholder="Search..."
auto-focus
ng-model-options="{ debounce: 300 }"
/>
<div class="row">
<div class="col-sm-3">
<template-list-dropdown
options="$ctrl.state.categories"
on-change="($ctrl.applyCategoriesFilter)"
placeholder="'Category'"
value="$ctrl.state.selectedCategory"
></template-list-dropdown>
</div>
<div class="col-sm-3">
<template-list-dropdown
options="$ctrl.state.typeFilters"
on-change="($ctrl.applyTypeFilter)"
placeholder="'Type'"
value="$ctrl.state.filterByType"
></template-list-dropdown>
</div>
<div class="col-sm-3 col-sm-offset-3">
<template-list-sort
on-change="($ctrl.changeOrderBy)"
on-descending="($ctrl.invertOrder)"
options="$ctrl.state.orderByFields"
sort-by-button="true"
sort-by-descending="$ctrl.state.orderDesc"
placeholder="'Sort By'"
value="$ctrl.state.selectedOrderBy"
></template-list-sort>
</div>
</div>
</div>
<div class="blocklist">
<template-item
ng-repeat="template in $ctrl.templates | filter: $ctrl.filterByTemplateType | filter:$ctrl.filterByCategory | filter:$ctrl.state.textFilter"