fix(ui): namespace caching issue EE-5273 (#8709)

* fix namespace caching issue

* fix(apps): add loading state [EE-5273]

* rm endpoint provider

* fix(namespace): remove caching [EE-5273]

* variable typo

---------

Co-authored-by: testa113 <testa113>
pull/8729/head
Prabhat Khera 2023-03-31 13:24:57 +13:00 committed by GitHub
parent d64e7eacfc
commit fc1aec3bb8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 25 additions and 48 deletions

View File

@ -244,6 +244,7 @@
</thead>
<tbody>
<tr
ng-show="!$ctrl.isAppsLoading"
ng-click="$ctrl.expandItem(item, !$ctrl.isItemExpanded(item))"
dir-paginate-start="item in ($ctrl.state.filteredDataSet = ($ctrl.dataset | filter:$ctrl.applyFilters | 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 }"
@ -335,16 +336,16 @@
</span>
</td>
</tr>
<tr ng-if="!$ctrl.dataset">
<tr ng-if="$ctrl.isAppsLoading">
<td colspan="8" class="text-muted text-center">Loading...</td>
</tr>
<tr ng-if="$ctrl.state.filteredDataSet.length === 0">
<tr ng-if="$ctrl.state.filteredDataSet.length === 0 && !$ctrl.isAppsLoading">
<td colspan="8" class="text-muted text-center">No application available.</td>
</tr>
</tbody>
</table>
</div>
<div ng-if="$ctrl.isPrimary" class="footer pl-5" ng-if="$ctrl.dataset">
<div class="footer pl-5" ng-if="$ctrl.isPrimary && $ctrl.dataset">
<div class="infoBar !ml-0" ng-if="$ctrl.state.selectedItemCount !== 0"> {{ $ctrl.state.selectedItemCount }} item(s) selected </div>
<div class="paginationControls">
<form class="form-inline">

View File

@ -18,6 +18,7 @@ angular.module('portainer.kubernetes').component('kubernetesApplicationsDatatabl
namespaces: '<',
namespace: '<',
onChangeNamespaceDropdown: '<',
isAppsLoading: '<',
isSystemResources: '<',
setSystemResources: '<',
},

View File

@ -168,6 +168,7 @@
</thead>
<tbody>
<tr
ng-show="!$ctrl.isAppsLoading"
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, 'datatable-highlighted': item.Highlighted }"
ng-click="$ctrl.expandItem(item, !item.Expanded)"
@ -220,10 +221,10 @@
>
</td>
</tr>
<tr ng-if="!$ctrl.dataset">
<tr ng-if="$ctrl.isAppsLoading">
<td colspan="5" class="text-muted text-center">Loading...</td>
</tr>
<tr ng-if="$ctrl.state.filteredDataSet.length === 0">
<tr ng-if="$ctrl.state.filteredDataSet.length === 0 && !$ctrl.isAppsLoading">
<td colspan="5" class="text-muted text-center">No stack available.</td>
</tr>
</tbody>

View File

@ -13,6 +13,7 @@ angular.module('portainer.kubernetes').component('kubernetesApplicationsStacksDa
namespaces: '<',
namespace: '<',
onChangeNamespaceDropdown: '<',
isAppsLoading: '<',
isSystemResources: '<',
setSystemResources: '<',
},

View File

@ -18,7 +18,6 @@ class KubernetesNamespaceService {
this.deleteAsync = this.deleteAsync.bind(this);
this.getJSONAsync = this.getJSONAsync.bind(this);
this.updateFinalizeAsync = this.updateFinalizeAsync.bind(this);
this.refreshCacheAsync = this.refreshCacheAsync.bind(this);
}
/**
@ -81,20 +80,13 @@ class KubernetesNamespaceService {
}
}
async get(name, refreshCache = false) {
async get(name) {
if (name) {
return this.$async(this.getAsync, name);
}
const cachedAllowedNamespaces = this.LocalStorage.getAllowedNamespaces();
if (!cachedAllowedNamespaces || refreshCache) {
const allowedNamespaces = await this.getAllAsync();
this.LocalStorage.storeAllowedNamespaces(allowedNamespaces);
updateNamespaces(allowedNamespaces);
return allowedNamespaces;
} else {
updateNamespaces(cachedAllowedNamespaces);
return cachedAllowedNamespaces;
}
const allowedNamespaces = await this.getAllAsync();
updateNamespaces(allowedNamespaces);
return allowedNamespaces;
}
/**
@ -105,7 +97,6 @@ class KubernetesNamespaceService {
const payload = KubernetesNamespaceConverter.createPayload(namespace);
const params = {};
const data = await this.KubernetesNamespaces().create(params, payload).$promise;
await this.refreshCacheAsync();
return data;
} catch (err) {
throw new PortainerError('Unable to create namespace', err);
@ -116,14 +107,6 @@ class KubernetesNamespaceService {
return this.$async(this.createAsync, namespace);
}
async refreshCacheAsync() {
this.LocalStorage.deleteAllowedNamespaces();
const allowedNamespaces = await this.getAllAsync();
this.LocalStorage.storeAllowedNamespaces(allowedNamespaces);
updateNamespaces(allowedNamespaces);
return allowedNamespaces;
}
/**
* DELETE
*/

View File

@ -36,8 +36,8 @@ export function KubernetesResourcePoolService(
}
// getting the quota for all namespaces is costly by default, so disable getting it by default
async function getAll({ getQuota = false, refreshCache = false }) {
const namespaces = await KubernetesNamespaceService.get('', refreshCache);
async function getAll({ getQuota = false }) {
const namespaces = await KubernetesNamespaceService.get();
const pools = await Promise.all(
_.map(namespaces, async (namespace) => {
const name = namespace.Name;

View File

@ -22,6 +22,7 @@
namespaces="ctrl.state.namespaces"
namespace="ctrl.state.namespaceName"
on-change-namespace-dropdown="(ctrl.onChangeNamespaceDropdown)"
is-apps-loading="ctrl.state.isAppsLoading"
is-system-resources="ctrl.state.isSystemResources"
set-system-resources="(ctrl.setSystemResources)"
>
@ -38,6 +39,7 @@
namespaces="ctrl.state.namespaces"
namespace="ctrl.state.namespaceName"
on-change-namespace-dropdown="(ctrl.onChangeNamespaceDropdown)"
is-apps-loading="ctrl.state.isAppsLoading"
is-system-resources="ctrl.state.isSystemResources"
set-system-resources="(ctrl.setSystemResources)"
>

View File

@ -143,15 +143,14 @@ class KubernetesApplicationsController {
});
}
onChangeNamespaceDropdown(namespaceName) {
this.state.namespaceName = namespaceName;
// save the selected namespaceName in local storage with the key 'kubernetes_namespace_filter_${environmentId}_${userID}'
this.LocalStorage.storeNamespaceFilter(this.endpoint.Id, this.user.ID, namespaceName);
this.getApplicationsAsync();
onChangeNamespaceDropdown(namespace) {
this.state.namespaceName = namespace;
return this.$async(this.getApplicationsAsync);
}
async getApplicationsAsync() {
try {
this.state.isAppsLoading = true;
const [applications, configurations] = await Promise.all([
this.KubernetesApplicationService.get(this.state.namespaceName),
this.KubernetesConfigurationService.get(this.state.namespaceName),
@ -166,6 +165,8 @@ class KubernetesApplicationsController {
this.$scope.$apply();
} catch (err) {
this.Notifications.error('Failure', err, 'Unable to retrieve applications');
} finally {
this.state.isAppsLoading = false;
}
}

View File

@ -290,7 +290,6 @@
<!-- table -->
<kubernetes-application-services-table
services="ctrl.application.Services"
namespaces="ctrl.allNamespaces"
application="ctrl.application"
public-url="ctrl.state.publicUrl"
></kubernetes-application-services-table>

View File

@ -221,7 +221,6 @@ class KubernetesResourcePoolController {
return;
}
await this.KubernetesResourcePoolService.toggleSystem(this.endpoint.Id, namespaceName, !this.isSystem);
await this.KubernetesNamespaceService.refreshCacheAsync();
this.Notifications.success('Namespace successfully updated', namespaceName);
this.$state.reload(this.$state.current);

View File

@ -21,7 +21,6 @@ class KubernetesResourcePoolsController {
}
async onReload() {
await this.KubernetesNamespaceService.refreshCacheAsync();
this.$state.reload(this.$state.current);
}
@ -50,7 +49,6 @@ class KubernetesResourcePoolsController {
} finally {
--actionCount;
if (actionCount === 0) {
await this.KubernetesNamespaceService.refreshCacheAsync();
this.$state.reload(this.$state.current);
}
}
@ -77,7 +75,7 @@ class KubernetesResourcePoolsController {
async getResourcePoolsAsync() {
try {
this.resourcePools = await this.KubernetesResourcePoolService.get('', { getQuota: true, refreshCache: true });
this.resourcePools = await this.KubernetesResourcePoolService.get('', { getQuota: true });
} catch (err) {
this.Notifications.error('Failure', err, 'Unable to retreive namespaces');
}

View File

@ -127,15 +127,6 @@ angular.module('portainer.app').factory('LocalStorage', [
getKubernetesSummaryToggle() {
return localStorageService.get('kubernetes_summary_expanded');
},
storeAllowedNamespaces: function (namespaces) {
localStorageService.set('ALLOWED_NAMESPACES', namespaces);
},
getAllowedNamespaces: function () {
return localStorageService.get('ALLOWED_NAMESPACES');
},
deleteAllowedNamespaces: function () {
localStorageService.remove('ALLOWED_NAMESPACES');
},
};
},
]);

View File

@ -16,7 +16,7 @@ export function useNamespaces(environmentId: EnvironmentId) {
async () => {
const namespaces = await getNamespaces(environmentId);
const namespaceNames = Object.keys(namespaces);
// use seflsubjectaccess reviews to avoid forbidden requests
// use selfsubjectaccess reviews to avoid forbidden requests
const allNamespaceAccessReviews = await Promise.all(
namespaceNames.map((namespaceName) =>
getSelfSubjectAccessReview(environmentId, namespaceName)