mirror of
https://github.com/portainer/portainer.git
synced 2025-07-19 13:29:41 +02:00
feat(helm/templates): helm app templates EE-943 (#5449)
* feat(helm): add helm chart backport to ce EE-1409 (#5425) * EE-1311 Helm Chart Backport from EE * backport to ce Co-authored-by: Matt Hook <hookenz@gmail.com> * feat(helm): list and configure helm chart (#5431) * backport and tidyup code * --amend * using rocket icon for charts * helm chart bugfix - clear category button * added matomo analytics for helm chart install * fix web editor exit warning without changes * editor modified exit bugfix * fixed notifications typo * updated helm template text * helper text to convey slow helm templates load Co-authored-by: zees-dev <dev.786zshan@gmail.com> * removing redundant time-consuming api call by using prop attribute * feat(helm) helm chart backport from ee EE-1311 (#5436) * Add missing defaultHelmRepoUrl and mock testing * Backport EE-1477 * Backport updates to helm tests from EE * add https by default changes and ssl to tls renaming from EE * Port install integration test. Disabled by default to pass CI checks * merged changes from EE for the integration test * kube proxy whitelist updated to support internal helm install command Co-authored-by: zees-dev <dev.786zshan@gmail.com> * Pull in all changes from tech review in EE-943 * added helm to sidebar after rebase, sync CE with EE * bugfix: kubectl shell not opening - bearer token bug * tidy go modules & remove yarn-error.log * removed redundant handler (not used) - to match EE * resolved merge conflicts, updated code * feat(helm/views): helm release and application views EE-1236 (#5529) * feat(helm): add helm chart backport to ce EE-1409 (#5425) * EE-1311 Helm Chart Backport from EE * backport to ce Co-authored-by: Matt Hook <hookenz@gmail.com> * Pull in all changes from tech review in EE-943 * added helm to sidebar after rebase, sync CE with EE * removed redundant handler (not used) - to match EE * feat(helm) display helm charts - backend EE-1236 * copy over components for new applications view EE-1236 * Add new applications datatable component * Add more migrated files * removed test not applicable to CE * baclkported EE app data table code to CE * removed redundant helm repo url * resolved conflicts, updated code * using endpoint middleware * PR review fixes * using constants, openapi updated Co-authored-by: Richard Wei <54336863+WaysonWei@users.noreply.github.com> Co-authored-by: zees-dev <dev.786zshan@gmail.com> * fixed test conflicts, go linted * feat(helm/templates-add): helm templates add repo for user support EE-1278 (#5514) * feat(helm): add helm chart backport to ce EE-1409 (#5425) * EE-1311 Helm Chart Backport from EE * backport to ce Co-authored-by: Matt Hook <hookenz@gmail.com> * feat(helm) helm chart backport from ee EE-1311 (#5436) * Add missing defaultHelmRepoUrl and mock testing * Backport EE-1477 * Backport updates to helm tests from EE * add https by default changes and ssl to tls renaming from EE * Port install integration test. Disabled by default to pass CI checks * merged changes from EE for the integration test * kube proxy whitelist updated to support internal helm install command Co-authored-by: zees-dev <dev.786zshan@gmail.com> * Pull in all changes from tech review in EE-943 * feat(helm): add helm chart backport to ce EE-1409 (#5425) * EE-1311 Helm Chart Backport from EE * backport to ce Co-authored-by: Matt Hook <hookenz@gmail.com> * Pull in all changes from tech review in EE-943 * added helm to sidebar after rebase, sync CE with EE * backport EE-1278, squashed, diffed, updated * helm install openapi spec update * resolved conflicts, updated code * - matching ee codebase at 0afe57034449ee0e9f333d92c252a13995a93019 - helm install using endpoint middleware - remove trailing slash from added/persisted helm repo urls * feat(helm) use libhelm url validator and improved path assembly EE-1554 (#5561) * feat(helm/userrepos) fix getting global repo for ordinary users EE-1562 (#5567) * feat(helm/userrepos) fix getting global repo for ordinary users EE-1562 * post review changes and further backported changes from EE * resolved conflicts, updated code * fixed helm_install handler unit test * user cannot add existing repo if suffix is '/' (#5571) * feat(helm/docs) fix broken swagger docs EE-1278 (#5572) * Fix swagger docs * minor correction * fix(helm): migrating code from user handler to helm handler (#5573) * - migrated user_helm_repos to helm endpoint handler - migrated api operations from user factory/service to helm factory/service - passing endpointId into helm service/factory as endpoint provider is deprecated * upgrade libhelm to hide secrets Co-authored-by: Matt Hook <hookenz@gmail.com> * removed duplicate file - due to merge conflict * dependency injection in helm factory Co-authored-by: Richard Wei <54336863+WaysonWei@users.noreply.github.com> Co-authored-by: Matt Hook <hookenz@gmail.com> * kubernetes.templates -> kubernetes.templates.helm name conflict fix * Validate the URL added as a public helm repo (#5579) * fix(helm): helm app deletion fix EE-1581 (#5582) * updated helm lib to show correct error on uninstall failure * passing down helm app namespace on deletion * fix(k8s): EE-1591 non-admin users cannot deploy charts containing secrets (#5590) Co-authored-by: Simon Meng <simon.meng@portainer.io> * fix(helm): helm epic bugfixes EE-1582 EE-1593 (#5585) * - trim trailing slash and lowercase before persisting helm repo - browser helm templates url /kubernetes/templates/templates -> /kubernetes/templates/helm - fix publish url - fix helm repo add refresh - semi-fix k8s app expansion * Tidy up swagger documentation related to helm. Make json consistent * fixed helm release page for non-default namespaces * k8s app view table expansion bugfix * EE-1593: publish url load balancer fallback Co-authored-by: Matt Hook <hookenz@gmail.com> * k8s app list fix for charts with deployments containing multiple pods - which use the same label (#5599) * fix(kubernetes): app list view fix for secrets with long keys or values EE-1600 (#5600) * k8s app secrets key value text overflow ellipses * wrapping key value pairs instead of ellipses * fix(helm): helm apps bundling issue across different namespaces EE-1619 (#5602) * helm apps bundling issue across different namespaces * - code comments and indentation to ease reading - moved namespace calc out of loop * feat(helm/test) disable slow helm search test by default EE-1599 (#5598) * skip helm_repo_search as it's an integration test * switch to portainer built in integration test checker * make module order match EE * don't print test struct out when skipping integration test Co-authored-by: Richard Wei <54336863+WaysonWei@users.noreply.github.com> Co-authored-by: Matt Hook <hookenz@gmail.com> Co-authored-by: cong meng <mcpacino@gmail.com> Co-authored-by: Simon Meng <simon.meng@portainer.io>
This commit is contained in:
parent
e86a586651
commit
2a60b8fcdf
89 changed files with 3055 additions and 139 deletions
|
@ -0,0 +1,16 @@
|
|||
.secondary-heading {
|
||||
background-color: #e7f6ff !important;
|
||||
}
|
||||
|
||||
.secondary-body {
|
||||
background-color: #f1f9fd;
|
||||
}
|
||||
|
||||
.datatable-wide {
|
||||
width: 55px;
|
||||
}
|
||||
|
||||
.datatable-padding-vertical {
|
||||
padding-top: 1.5rem;
|
||||
padding-bottom: 1.5rem;
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
<div class="datatable">
|
||||
<rd-widget>
|
||||
<rd-widget-body classes="no-padding">
|
||||
<div class="toolBar">
|
||||
<div ng-if="$ctrl.isPrimary" class="toolBar">
|
||||
<div class="toolBarTitle"> <i class="fa" ng-class="$ctrl.titleIcon" aria-hidden="true" style="margin-right: 2px;"></i> {{ $ctrl.titleText }} </div>
|
||||
<span class="small text-muted" style="float: left; margin-top: 5px;" ng-if="$ctrl.isAdmin && !$ctrl.settings.showSystem">
|
||||
<i class="fa fa-info-circle blue-icon" aria-hidden="true" style="margin-right: 2px;"></i>
|
||||
|
@ -62,7 +62,7 @@
|
|||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="actionBar">
|
||||
<div ng-if="$ctrl.isPrimary" class="actionBar">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm btn-danger"
|
||||
|
@ -79,7 +79,7 @@
|
|||
<i class="fa fa-plus space-right" aria-hidden="true"></i>Create from manifest
|
||||
</button>
|
||||
</div>
|
||||
<div class="searchBar">
|
||||
<div ng-if="$ctrl.isPrimary" class="searchBar">
|
||||
<i class="fa fa-search searchIcon" aria-hidden="true"></i>
|
||||
<input
|
||||
type="text"
|
||||
|
@ -94,13 +94,20 @@
|
|||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover nowrap-cells" data-cy="k8sApp-appTable">
|
||||
<thead>
|
||||
<thead ng-class="{ 'secondary-heading': !$ctrl.isPrimary }">
|
||||
<tr>
|
||||
<th>
|
||||
<span class="md-checkbox">
|
||||
<input id="select_all" type="checkbox" ng-model="$ctrl.state.selectAll" ng-change="$ctrl.selectAll()" data-cy="k8sApp-selectAllCheckbox" />
|
||||
<label for="select_all"></label>
|
||||
<th class="datatable-wide">
|
||||
<span ng-if="$ctrl.isPrimary">
|
||||
<span class="md-checkbox">
|
||||
<input id="select_all" type="checkbox" ng-model="$ctrl.state.selectAll" ng-change="$ctrl.selectAll()" data-cy="k8sApp-selectAllCheckbox" />
|
||||
<label for="select_all"></label>
|
||||
</span>
|
||||
<a ng-click="$ctrl.expandAll()">
|
||||
<i ng-class="{ 'fas fa-angle-down': $ctrl.state.expandAll, 'fas fa-angle-right': !$ctrl.state.expandAll }" aria-hidden="true"></i>
|
||||
</a>
|
||||
</span>
|
||||
</th>
|
||||
<th>
|
||||
<a ng-click="$ctrl.changeOrderBy('Name')">
|
||||
Name
|
||||
<i class="fa fa-sort-alpha-down" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'Name' && !$ctrl.state.reverseOrder"></i>
|
||||
|
@ -152,22 +159,42 @@
|
|||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
dir-paginate="item in ($ctrl.state.filteredDataSet = ($ctrl.dataset | filter:$ctrl.state.textFilter | filter:$ctrl.isDisplayed | orderBy:$ctrl.state.orderBy:$ctrl.state.reverseOrder | itemsPerPage: $ctrl.state.paginatedItemLimit: $ctrl.tableKey))"
|
||||
ng-class="{ active: item.Checked }"
|
||||
ng-click="$ctrl.expandItem(item, !$ctrl.isItemExpanded(item))"
|
||||
dir-paginate-start="item in ($ctrl.state.filteredDataSet = ($ctrl.dataset | filter:$ctrl.state.textFilter | filter:$ctrl.isDisplayed | orderBy:$ctrl.state.orderBy:$ctrl.state.reverseOrder | itemsPerPage: $ctrl.state.paginatedItemLimit: $ctrl.tableKey))"
|
||||
ng-class="{ active: item.Checked, interactive: $ctrl.isExpandable(item), 'secondary-body': !$ctrl.isPrimary }"
|
||||
pagination-id="$ctrl.tableKey"
|
||||
>
|
||||
<td>
|
||||
<span class="md-checkbox">
|
||||
<input id="select_{{ $index }}" type="checkbox" ng-model="item.Checked" ng-click="$ctrl.selectItem(item, $event)" ng-disabled="$ctrl.isSystemNamespace(item)" />
|
||||
<span ng-if="$ctrl.isPrimary" class="md-checkbox">
|
||||
<input
|
||||
id="select_{{ $index }}"
|
||||
type="checkbox"
|
||||
ng-model="item.Checked"
|
||||
ng-click="$ctrl.selectItem(item, $event); $event.stopPropagation()"
|
||||
ng-disabled="$ctrl.isSystemNamespace(item)"
|
||||
/>
|
||||
<label for="select_{{ $index }}"></label>
|
||||
</span>
|
||||
<a ui-sref="kubernetes.applications.application({ name: item.Name, namespace: item.ResourcePool })">{{ item.Name }}</a>
|
||||
<a ng-if="$ctrl.isExpandable(item)">
|
||||
<i ng-class="{ 'fas fa-angle-down': $ctrl.isItemExpanded(item), 'fas fa-angle-right': !$ctrl.isItemExpanded(item) }" class="space-right" aria-hidden="true"></i>
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<a ng-if="item.KubernetesApplications" ui-sref="kubernetes.helm({ name: item.Name, namespace: item.ResourcePool })" ng-click="$event.stopPropagation()"
|
||||
>{{ item.Name }}
|
||||
</a>
|
||||
<a
|
||||
ng-if="!item.KubernetesApplications"
|
||||
ui-sref="kubernetes.applications.application({ name: item.Name, namespace: item.ResourcePool })"
|
||||
ng-click="$event.stopPropagation()"
|
||||
>{{ item.Name }}
|
||||
</a>
|
||||
<span class="label label-info image-tag label-margins" ng-if="$ctrl.isSystemNamespace(item)">system</span>
|
||||
<span class="label label-primary image-tag label-margins" ng-if="!$ctrl.isSystemNamespace(item) && $ctrl.isExternalApplication(item)">external</span>
|
||||
</td>
|
||||
<td>{{ item.StackName || '-' }}</td>
|
||||
<td>
|
||||
<a ui-sref="kubernetes.resourcePools.resourcePool({ id: item.ResourcePool })">{{ item.ResourcePool }}</a>
|
||||
<a ui-sref="kubernetes.resourcePools.resourcePool({ id: item.ResourcePool })" ng-click="$event.stopPropagation()">{{ item.ResourcePool }}</a>
|
||||
</td>
|
||||
<td title="{{ item.Image }}"
|
||||
>{{ item.Image | truncate: 64 }} <span ng-if="item.Containers.length > 1">+ {{ item.Containers.length - 1 }}</span></td
|
||||
|
@ -176,7 +203,10 @@
|
|||
<td ng-if="item.ApplicationType !== $ctrl.KubernetesApplicationTypes.POD">
|
||||
<span ng-if="item.DeploymentType === $ctrl.KubernetesApplicationDeploymentTypes.REPLICATED">Replicated</span>
|
||||
<span ng-if="item.DeploymentType === $ctrl.KubernetesApplicationDeploymentTypes.GLOBAL">Global</span>
|
||||
<code>{{ item.RunningPodsCount }}</code> / <code>{{ item.TotalPodsCount }}</code>
|
||||
<span ng-if="item.RunningPodsCount >= 0 && item.TotalPodsCount >= 0">
|
||||
<code>{{ item.RunningPodsCount }}</code> / <code>{{ item.TotalPodsCount }}</code>
|
||||
</span>
|
||||
<span ng-if="item.KubernetesApplications">{{ item.Status }}</span>
|
||||
</td>
|
||||
<td ng-if="item.ApplicationType === $ctrl.KubernetesApplicationTypes.POD">
|
||||
{{ item.Pods[0].Status }}
|
||||
|
@ -184,7 +214,7 @@
|
|||
<td>
|
||||
<span ng-if="item.PublishedPorts.length">
|
||||
<span>
|
||||
<a ng-click="$ctrl.onPublishingModeClick(item)">
|
||||
<a ng-click="$ctrl.onPublishingModeClick(item); $event.stopPropagation()">
|
||||
<i class="fa {{ item.ServiceType | kubernetesApplicationServiceTypeIcon }}" aria-hidden="true" style="margin-right: 2px;"> </i>
|
||||
{{ item.ServiceType | kubernetesApplicationServiceTypeText }}
|
||||
</a>
|
||||
|
@ -194,6 +224,33 @@
|
|||
</td>
|
||||
<td>{{ item.CreationDate | getisodate }} {{ item.ApplicationOwner ? 'by ' + item.ApplicationOwner : '' }}</td>
|
||||
</tr>
|
||||
<tr dir-paginate-end ng-show="$ctrl.isExpandable(item) && $ctrl.isItemExpanded(item)" ng-class="{ 'secondary-body': $ctrl.isPrimary && !item.KubernetesApplications }">
|
||||
<td></td>
|
||||
<td colspan="8" class="datatable-padding-vertical">
|
||||
<span ng-if="item.KubernetesApplications">
|
||||
<kubernetes-applications-datatable
|
||||
dataset="item.KubernetesApplications"
|
||||
table-key="{{ item.Id }}_table"
|
||||
order-by="Name"
|
||||
remove-action="$ctrl.removeAction"
|
||||
refresh-callback="$ctrl.refreshCallback"
|
||||
on-publishing-mode-click="($ctrl.onPublishingModeClick)"
|
||||
is-primary="false"
|
||||
>
|
||||
</kubernetes-applications-datatable>
|
||||
</span>
|
||||
<span ng-if="!item.KubernetesApplications">
|
||||
<kubernetes-applications-datatable-url
|
||||
ng-if="$ctrl.getPublishedUrl(item)"
|
||||
published-url="{{ $ctrl.getPublishedUrl(item) }}"
|
||||
></kubernetes-applications-datatable-url>
|
||||
<kubernetes-applications-datatable-details
|
||||
ng-if="$ctrl.hasConfigurationSecrets(item)"
|
||||
configurations="item.Configurations"
|
||||
></kubernetes-applications-datatable-details>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr ng-if="!$ctrl.dataset">
|
||||
<td colspan="8" class="text-center text-muted">Loading...</td>
|
||||
</tr>
|
||||
|
@ -203,7 +260,7 @@
|
|||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="footer" ng-if="$ctrl.dataset">
|
||||
<div ng-if="$ctrl.isPrimary" class="footer" ng-if="$ctrl.dataset">
|
||||
<div class="infoBar" ng-if="$ctrl.state.selectedItemCount !== 0"> {{ $ctrl.state.selectedItemCount }} item(s) selected </div>
|
||||
<div class="paginationControls">
|
||||
<form class="form-inline">
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import './applicationsDatatable.css';
|
||||
|
||||
angular.module('portainer.kubernetes').component('kubernetesApplicationsDatatable', {
|
||||
templateUrl: './applicationsDatatable.html',
|
||||
controller: 'KubernetesApplicationsDatatableController',
|
||||
|
@ -11,5 +13,6 @@ angular.module('portainer.kubernetes').component('kubernetesApplicationsDatatabl
|
|||
removeAction: '<',
|
||||
refreshCallback: '<',
|
||||
onPublishingModeClick: '<',
|
||||
isPrimary: '<',
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { KubernetesApplicationDeploymentTypes, KubernetesApplicationTypes } from 'Kubernetes/models/application/models';
|
||||
import KubernetesApplicationHelper from 'Kubernetes/helpers/application';
|
||||
import KubernetesNamespaceHelper from 'Kubernetes/helpers/namespaceHelper';
|
||||
import { KubernetesConfigurationTypes } from 'Kubernetes/models/configuration/models';
|
||||
|
||||
angular.module('portainer.docker').controller('KubernetesApplicationsDatatableController', [
|
||||
'$scope',
|
||||
|
@ -10,12 +11,55 @@ angular.module('portainer.docker').controller('KubernetesApplicationsDatatableCo
|
|||
function ($scope, $controller, DatatableService, Authentication) {
|
||||
angular.extend(this, $controller('GenericDatatableController', { $scope: $scope }));
|
||||
|
||||
var ctrl = this;
|
||||
const ctrl = this;
|
||||
|
||||
this.settings = Object.assign(this.settings, {
|
||||
showSystem: false,
|
||||
});
|
||||
|
||||
this.state = Object.assign(this.state, {
|
||||
expandAll: false,
|
||||
expandedItems: [],
|
||||
});
|
||||
|
||||
this.expandAll = function () {
|
||||
this.state.expandAll = !this.state.expandAll;
|
||||
this.state.filteredDataSet.forEach((item) => this.expandItem(item, this.state.expandAll));
|
||||
};
|
||||
|
||||
this.isItemExpanded = function (item) {
|
||||
return this.state.expandedItems.includes(item.Id);
|
||||
};
|
||||
|
||||
this.isExpandable = function (item) {
|
||||
return item.KubernetesApplications || this.hasConfigurationSecrets(item) || !!this.getPublishedUrl(item).length;
|
||||
};
|
||||
|
||||
this.expandItem = function (item, expanded) {
|
||||
// collapse item
|
||||
if (!expanded) {
|
||||
this.state.expandedItems = this.state.expandedItems.filter((id) => id !== item.Id);
|
||||
// expanded item
|
||||
} else if (expanded && !this.state.expandedItems.includes(item.Id)) {
|
||||
this.state.expandedItems = [...this.state.expandedItems, item.Id];
|
||||
}
|
||||
DatatableService.setDataTableExpandedItems(this.tableKey, this.state.expandedItems);
|
||||
};
|
||||
|
||||
this.expandItems = function (storedExpandedItems) {
|
||||
this.state.expandedItems = storedExpandedItems;
|
||||
if (this.state.expandedItems.length === this.dataset.length) {
|
||||
this.state.expandAll = true;
|
||||
}
|
||||
};
|
||||
|
||||
this.onDataRefresh = function () {
|
||||
const storedExpandedItems = DatatableService.getDataTableExpandedItems(this.tableKey);
|
||||
if (storedExpandedItems !== null) {
|
||||
this.expandItems(storedExpandedItems);
|
||||
}
|
||||
};
|
||||
|
||||
this.onSettingsShowSystemChange = function () {
|
||||
DatatableService.setDataTableSettings(this.tableKey, this.settings);
|
||||
};
|
||||
|
@ -25,6 +69,10 @@ angular.module('portainer.docker').controller('KubernetesApplicationsDatatableCo
|
|||
};
|
||||
|
||||
this.isSystemNamespace = function (item) {
|
||||
// if all charts in a helm app/release are in the system namespace
|
||||
if (item.KubernetesApplications && item.KubernetesApplications.length > 0) {
|
||||
return item.KubernetesApplications.some((app) => KubernetesNamespaceHelper.isSystemNamespace(app.ResourcePool));
|
||||
}
|
||||
return KubernetesNamespaceHelper.isSystemNamespace(item.ResourcePool);
|
||||
};
|
||||
|
||||
|
@ -32,6 +80,33 @@ angular.module('portainer.docker').controller('KubernetesApplicationsDatatableCo
|
|||
return !ctrl.isSystemNamespace(item) || ctrl.settings.showSystem;
|
||||
};
|
||||
|
||||
this.getPublishedUrl = function (item) {
|
||||
// Map all ingress rules in published ports to their respective URLs
|
||||
const ingressUrls = item.PublishedPorts.flatMap((pp) => pp.IngressRules)
|
||||
.filter(({ Host, IP }) => Host || IP)
|
||||
.map(({ Host, IP, Port, Path }) => {
|
||||
let scheme = Port === 443 ? 'https' : 'http';
|
||||
let urlPort = Port === 80 || Port === 443 ? '' : `:${Port}`;
|
||||
return `${scheme}://${Host || IP}${urlPort}${Path}`;
|
||||
});
|
||||
|
||||
// Map all load balancer service ports to ip address
|
||||
let loadBalancerURLs = [];
|
||||
if (item.LoadBalancerIPAddress) {
|
||||
loadBalancerURLs = item.PublishedPorts.map((pp) => `http://${item.LoadBalancerIPAddress}:${pp.Port}`);
|
||||
}
|
||||
|
||||
// combine ingress urls
|
||||
const publishedUrls = [...ingressUrls, ...loadBalancerURLs];
|
||||
|
||||
// Return the first URL - priority given to ingress urls, then services (load balancers)
|
||||
return publishedUrls.length > 0 ? publishedUrls[0] : '';
|
||||
};
|
||||
|
||||
this.hasConfigurationSecrets = function (item) {
|
||||
return item.Configurations && item.Configurations.some((config) => config.Data && config.Type === KubernetesConfigurationTypes.SECRET);
|
||||
};
|
||||
|
||||
/**
|
||||
* Do not allow applications in system namespaces to be selected
|
||||
*/
|
||||
|
@ -47,19 +122,19 @@ angular.module('portainer.docker').controller('KubernetesApplicationsDatatableCo
|
|||
this.prepareTableFromDataset();
|
||||
|
||||
this.state.orderBy = this.orderBy;
|
||||
var storedOrder = DatatableService.getDataTableOrder(this.tableKey);
|
||||
const storedOrder = DatatableService.getDataTableOrder(this.tableKey);
|
||||
if (storedOrder !== null) {
|
||||
this.state.reverseOrder = storedOrder.reverse;
|
||||
this.state.orderBy = storedOrder.orderBy;
|
||||
}
|
||||
|
||||
var textFilter = DatatableService.getDataTableTextFilters(this.tableKey);
|
||||
const textFilter = DatatableService.getDataTableTextFilters(this.tableKey);
|
||||
if (textFilter !== null) {
|
||||
this.state.textFilter = textFilter;
|
||||
this.onTextFilterChange();
|
||||
}
|
||||
|
||||
var storedFilters = DatatableService.getDataTableFilters(this.tableKey);
|
||||
const storedFilters = DatatableService.getDataTableFilters(this.tableKey);
|
||||
if (storedFilters !== null) {
|
||||
this.filters = storedFilters;
|
||||
}
|
||||
|
@ -67,7 +142,12 @@ angular.module('portainer.docker').controller('KubernetesApplicationsDatatableCo
|
|||
this.filters.state.open = false;
|
||||
}
|
||||
|
||||
var storedSettings = DatatableService.getDataTableSettings(this.tableKey);
|
||||
const storedExpandedItems = DatatableService.getDataTableExpandedItems(this.tableKey);
|
||||
if (storedExpandedItems !== null) {
|
||||
this.expandItems(storedExpandedItems);
|
||||
}
|
||||
|
||||
const storedSettings = DatatableService.getDataTableSettings(this.tableKey);
|
||||
if (storedSettings !== null) {
|
||||
this.settings = storedSettings;
|
||||
this.settings.open = false;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue