mirror of https://github.com/portainer/portainer
feat(applications): application page performance improvements EE-4956 (#8569)
parent
01ea9afe33
commit
bdde278139
|
@ -8,6 +8,22 @@
|
||||||
</div>
|
</div>
|
||||||
Applications
|
Applications
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group namespaces !mb-0 !mr-0 min-w-[280px]">
|
||||||
|
<div class="input-group">
|
||||||
|
<span class="input-group-addon">
|
||||||
|
<pr-icon icon="'filter'"></pr-icon>
|
||||||
|
Namespace
|
||||||
|
</span>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
ng-model="$ctrl.state.namespace"
|
||||||
|
ng-change="$ctrl.onChangeNamespace()"
|
||||||
|
data-cy="component-namespaceSelect"
|
||||||
|
ng-options="o.Value as (o.Name + (o.IsSystem ? ' - system' : '')) for o in $ctrl.state.namespaces"
|
||||||
|
>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="searchBar vertical-center !mr-0 min-w-[280px]">
|
<div class="searchBar vertical-center !mr-0 min-w-[280px]">
|
||||||
<pr-icon icon="'search'" class-name="'searchIcon'"></pr-icon>
|
<pr-icon icon="'search'" class-name="'searchIcon'"></pr-icon>
|
||||||
<input
|
<input
|
||||||
|
|
|
@ -15,5 +15,10 @@ angular.module('portainer.kubernetes').component('kubernetesApplicationsDatatabl
|
||||||
refreshCallback: '<',
|
refreshCallback: '<',
|
||||||
onPublishingModeClick: '<',
|
onPublishingModeClick: '<',
|
||||||
isPrimary: '<',
|
isPrimary: '<',
|
||||||
|
namespaces: '<',
|
||||||
|
namespace: '<',
|
||||||
|
onChangeNamespaceDropdown: '<',
|
||||||
|
isSystemResources: '<',
|
||||||
|
setSystemResources: '<',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -21,6 +21,8 @@ angular.module('portainer.docker').controller('KubernetesApplicationsDatatableCo
|
||||||
this.state = Object.assign(this.state, {
|
this.state = Object.assign(this.state, {
|
||||||
expandAll: false,
|
expandAll: false,
|
||||||
expandedItems: [],
|
expandedItems: [],
|
||||||
|
namespace: '',
|
||||||
|
namespaces: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
this.filters = {
|
this.filters = {
|
||||||
|
@ -70,6 +72,8 @@ angular.module('portainer.docker').controller('KubernetesApplicationsDatatableCo
|
||||||
};
|
};
|
||||||
|
|
||||||
this.onSettingsShowSystemChange = function () {
|
this.onSettingsShowSystemChange = function () {
|
||||||
|
this.updateNamespace();
|
||||||
|
this.setSystemResources(this.settings.showSystem);
|
||||||
DatatableService.setDataTableSettings(this.tableKey, this.settings);
|
DatatableService.setDataTableSettings(this.tableKey, this.settings);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -135,6 +139,43 @@ angular.module('portainer.docker').controller('KubernetesApplicationsDatatableCo
|
||||||
this.filters.state.values = _.uniqBy(availableTypeFilters, 'type');
|
this.filters.state.values = _.uniqBy(availableTypeFilters, 'type');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.onChangeNamespace = function () {
|
||||||
|
this.onChangeNamespaceDropdown(this.state.namespace);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.updateNamespace = function () {
|
||||||
|
if (this.namespaces) {
|
||||||
|
const namespaces = [{ Name: 'All namespaces', Value: '', IsSystem: false }];
|
||||||
|
this.namespaces.find((ns) => {
|
||||||
|
if (!this.settings.showSystem && ns.IsSystem) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
namespaces.push({ Name: ns.Name, Value: ns.Name, IsSystem: ns.IsSystem });
|
||||||
|
});
|
||||||
|
this.state.namespaces = namespaces;
|
||||||
|
|
||||||
|
if (this.state.namespace && !this.state.namespaces.find((ns) => ns.Name === this.state.namespace)) {
|
||||||
|
if (this.state.namespaces.length > 1) {
|
||||||
|
let defaultNS = this.state.namespaces.find((ns) => ns.Name === 'default');
|
||||||
|
defaultNS = defaultNS || this.state.namespaces[1];
|
||||||
|
this.state.namespace = defaultNS.Value;
|
||||||
|
} else {
|
||||||
|
this.state.namespace = this.state.namespaces[0].Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.$onChanges = function () {
|
||||||
|
if (typeof this.isSystemResources !== 'undefined') {
|
||||||
|
this.settings.showSystem = this.isSystemResources;
|
||||||
|
DatatableService.setDataTableSettings(this.settingsKey, this.settings);
|
||||||
|
}
|
||||||
|
this.state.namespace = this.namespace;
|
||||||
|
this.updateNamespace();
|
||||||
|
this.prepareTableFromDataset();
|
||||||
|
};
|
||||||
|
|
||||||
this.$onInit = function () {
|
this.$onInit = function () {
|
||||||
this.isAdmin = Authentication.isAdmin();
|
this.isAdmin = Authentication.isAdmin();
|
||||||
this.KubernetesApplicationDeploymentTypes = KubernetesApplicationDeploymentTypes;
|
this.KubernetesApplicationDeploymentTypes = KubernetesApplicationDeploymentTypes;
|
||||||
|
@ -172,7 +213,16 @@ angular.module('portainer.docker').controller('KubernetesApplicationsDatatableCo
|
||||||
if (storedSettings !== null) {
|
if (storedSettings !== null) {
|
||||||
this.settings = storedSettings;
|
this.settings = storedSettings;
|
||||||
this.settings.open = false;
|
this.settings.open = false;
|
||||||
|
|
||||||
|
this.setSystemResources && this.setSystemResources(this.settings.showSystem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the default selected namespace
|
||||||
|
if (!this.state.namespace) {
|
||||||
|
this.state.namespace = this.namespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateNamespace();
|
||||||
this.onSettingsRepeaterChange();
|
this.onSettingsRepeaterChange();
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
|
@ -10,6 +10,22 @@
|
||||||
Stacks
|
Stacks
|
||||||
</div>
|
</div>
|
||||||
<!-- actions -->
|
<!-- actions -->
|
||||||
|
<div class="form-group namespaces !mb-0 !mr-0 min-w-[280px]">
|
||||||
|
<div class="input-group">
|
||||||
|
<span class="input-group-addon">
|
||||||
|
<pr-icon icon="'filter'"></pr-icon>
|
||||||
|
Namespace
|
||||||
|
</span>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
ng-model="$ctrl.state.namespace"
|
||||||
|
ng-change="$ctrl.onChangeNamespace()"
|
||||||
|
data-cy="component-namespaceSelect"
|
||||||
|
ng-options="o.Value as (o.Name + (o.IsSystem ? ' - system' : '')) for o in $ctrl.state.namespaces"
|
||||||
|
>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="searchBar vertical-center">
|
<div class="searchBar vertical-center">
|
||||||
<pr-icon icon="'search'" class-name="'!h-3'"></pr-icon>
|
<pr-icon icon="'search'" class-name="'!h-3'"></pr-icon>
|
||||||
<input
|
<input
|
||||||
|
|
|
@ -10,5 +10,10 @@ angular.module('portainer.kubernetes').component('kubernetesApplicationsStacksDa
|
||||||
reverseOrder: '<',
|
reverseOrder: '<',
|
||||||
refreshCallback: '<',
|
refreshCallback: '<',
|
||||||
removeAction: '<',
|
removeAction: '<',
|
||||||
|
namespaces: '<',
|
||||||
|
namespace: '<',
|
||||||
|
onChangeNamespaceDropdown: '<',
|
||||||
|
isSystemResources: '<',
|
||||||
|
setSystemResources: '<',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,6 +13,8 @@ angular.module('portainer.kubernetes').controller('KubernetesApplicationsStacksD
|
||||||
this.state = Object.assign(this.state, {
|
this.state = Object.assign(this.state, {
|
||||||
expandedItems: [],
|
expandedItems: [],
|
||||||
expandAll: false,
|
expandAll: false,
|
||||||
|
namespace: '',
|
||||||
|
namespaces: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
var ctrl = this;
|
var ctrl = this;
|
||||||
|
@ -22,6 +24,8 @@ angular.module('portainer.kubernetes').controller('KubernetesApplicationsStacksD
|
||||||
});
|
});
|
||||||
|
|
||||||
this.onSettingsShowSystemChange = function () {
|
this.onSettingsShowSystemChange = function () {
|
||||||
|
this.updateNamespace();
|
||||||
|
this.setSystemResources(this.settings.showSystem);
|
||||||
DatatableService.setDataTableSettings(this.tableKey, this.settings);
|
DatatableService.setDataTableSettings(this.tableKey, this.settings);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -76,6 +80,44 @@ angular.module('portainer.kubernetes').controller('KubernetesApplicationsStacksD
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.onChangeNamespace = function () {
|
||||||
|
this.onChangeNamespaceDropdown(this.state.namespace);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.updateNamespace = function () {
|
||||||
|
if (this.namespaces) {
|
||||||
|
const namespaces = [{ Name: 'All namespaces', Value: '', IsSystem: false }];
|
||||||
|
this.namespaces.find((ns) => {
|
||||||
|
if (!this.settings.showSystem && ns.IsSystem) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
namespaces.push({ Name: ns.Name, Value: ns.Name, IsSystem: ns.IsSystem });
|
||||||
|
});
|
||||||
|
this.state.namespaces = namespaces;
|
||||||
|
|
||||||
|
if (this.state.namespace && !this.state.namespaces.find((ns) => ns.Name === this.state.namespace)) {
|
||||||
|
if (this.state.namespaces.length > 1) {
|
||||||
|
let defaultNS = this.state.namespaces.find((ns) => ns.Name === 'default');
|
||||||
|
defaultNS = defaultNS || this.state.namespaces[1];
|
||||||
|
this.state.namespace = defaultNS.Value;
|
||||||
|
} else {
|
||||||
|
this.state.namespace = this.state.namespaces[0].Value;
|
||||||
|
}
|
||||||
|
this.onChangeNamespaceDropdown(this.state.namespace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.$onChanges = function () {
|
||||||
|
if (typeof this.isSystemResources !== 'undefined') {
|
||||||
|
this.settings.showSystem = this.isSystemResources;
|
||||||
|
DatatableService.setDataTableSettings(this.settingsKey, this.settings);
|
||||||
|
}
|
||||||
|
this.state.namespace = this.namespace;
|
||||||
|
this.updateNamespace();
|
||||||
|
this.prepareTableFromDataset();
|
||||||
|
};
|
||||||
|
|
||||||
this.$onInit = function () {
|
this.$onInit = function () {
|
||||||
this.isAdmin = Authentication.isAdmin();
|
this.isAdmin = Authentication.isAdmin();
|
||||||
this.KubernetesApplicationDeploymentTypes = KubernetesApplicationDeploymentTypes;
|
this.KubernetesApplicationDeploymentTypes = KubernetesApplicationDeploymentTypes;
|
||||||
|
@ -103,11 +145,20 @@ angular.module('portainer.kubernetes').controller('KubernetesApplicationsStacksD
|
||||||
this.filters.state.open = false;
|
this.filters.state.open = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var storedSettings = DatatableService.getDataTableSettings(this.tableKey);
|
var storedSettings = DatatableService.getDataTableSettings(this.settingsKey);
|
||||||
if (storedSettings !== null) {
|
if (storedSettings !== null) {
|
||||||
this.settings = storedSettings;
|
this.settings = storedSettings;
|
||||||
this.settings.open = false;
|
this.settings.open = false;
|
||||||
|
|
||||||
|
this.setSystemResources && this.setSystemResources(this.settings.showSystem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the default selected namespace
|
||||||
|
if (!this.state.namespace) {
|
||||||
|
this.state.namespace = this.namespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateNamespace();
|
||||||
this.onSettingsRepeaterChange();
|
this.onSettingsRepeaterChange();
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
|
@ -7,9 +7,10 @@ import $allSettled from 'Portainer/services/allSettled';
|
||||||
|
|
||||||
class KubernetesNamespaceService {
|
class KubernetesNamespaceService {
|
||||||
/* @ngInject */
|
/* @ngInject */
|
||||||
constructor($async, KubernetesNamespaces) {
|
constructor($async, KubernetesNamespaces, LocalStorage) {
|
||||||
this.$async = $async;
|
this.$async = $async;
|
||||||
this.KubernetesNamespaces = KubernetesNamespaces;
|
this.KubernetesNamespaces = KubernetesNamespaces;
|
||||||
|
this.LocalStorage = LocalStorage;
|
||||||
|
|
||||||
this.getAsync = this.getAsync.bind(this);
|
this.getAsync = this.getAsync.bind(this);
|
||||||
this.getAllAsync = this.getAllAsync.bind(this);
|
this.getAllAsync = this.getAllAsync.bind(this);
|
||||||
|
@ -17,6 +18,7 @@ class KubernetesNamespaceService {
|
||||||
this.deleteAsync = this.deleteAsync.bind(this);
|
this.deleteAsync = this.deleteAsync.bind(this);
|
||||||
this.getJSONAsync = this.getJSONAsync.bind(this);
|
this.getJSONAsync = this.getJSONAsync.bind(this);
|
||||||
this.updateFinalizeAsync = this.updateFinalizeAsync.bind(this);
|
this.updateFinalizeAsync = this.updateFinalizeAsync.bind(this);
|
||||||
|
this.refreshCacheAsync = this.refreshCacheAsync.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -79,11 +81,19 @@ class KubernetesNamespaceService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get(name) {
|
async get(name) {
|
||||||
if (name) {
|
if (name) {
|
||||||
return this.$async(this.getAsync, name);
|
return this.$async(this.getAsync, name);
|
||||||
}
|
}
|
||||||
return this.$async(this.getAllAsync);
|
const cachedAllowedNamespaces = this.LocalStorage.getAllowedNamespaces();
|
||||||
|
if (cachedAllowedNamespaces) {
|
||||||
|
updateNamespaces(cachedAllowedNamespaces);
|
||||||
|
return cachedAllowedNamespaces;
|
||||||
|
} else {
|
||||||
|
const allowedNamespaces = await this.getAllAsync();
|
||||||
|
this.LocalStorage.storeAllowedNamespaces(allowedNamespaces);
|
||||||
|
return allowedNamespaces;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -94,6 +104,7 @@ class KubernetesNamespaceService {
|
||||||
const payload = KubernetesNamespaceConverter.createPayload(namespace);
|
const payload = KubernetesNamespaceConverter.createPayload(namespace);
|
||||||
const params = {};
|
const params = {};
|
||||||
const data = await this.KubernetesNamespaces().create(params, payload).$promise;
|
const data = await this.KubernetesNamespaces().create(params, payload).$promise;
|
||||||
|
await this.refreshCacheAsync();
|
||||||
return data;
|
return data;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw new PortainerError('Unable to create namespace', err);
|
throw new PortainerError('Unable to create namespace', err);
|
||||||
|
@ -104,6 +115,14 @@ class KubernetesNamespaceService {
|
||||||
return this.$async(this.createAsync, namespace);
|
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
|
* DELETE
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -19,6 +19,11 @@
|
||||||
refresh-callback="ctrl.getApplications"
|
refresh-callback="ctrl.getApplications"
|
||||||
on-publishing-mode-click="(ctrl.onPublishingModeClick)"
|
on-publishing-mode-click="(ctrl.onPublishingModeClick)"
|
||||||
is-primary="true"
|
is-primary="true"
|
||||||
|
namespaces="ctrl.state.namespaces"
|
||||||
|
namespace="ctrl.state.namespace"
|
||||||
|
on-change-namespace-dropdown="(ctrl.onChangeNamespaceDropdown)"
|
||||||
|
is-system-resources="ctrl.state.isSystemResources"
|
||||||
|
set-system-resources="(ctrl.setSystemResources)"
|
||||||
>
|
>
|
||||||
</kubernetes-applications-datatable>
|
</kubernetes-applications-datatable>
|
||||||
</uib-tab>
|
</uib-tab>
|
||||||
|
@ -30,6 +35,11 @@
|
||||||
order-by="Name"
|
order-by="Name"
|
||||||
refresh-callback="ctrl.getApplications"
|
refresh-callback="ctrl.getApplications"
|
||||||
remove-action="ctrl.removeStacksAction"
|
remove-action="ctrl.removeStacksAction"
|
||||||
|
namespaces="ctrl.state.namespaces"
|
||||||
|
namespace="ctrl.state.namespace"
|
||||||
|
on-change-namespace-dropdown="(ctrl.onChangeNamespaceDropdown)"
|
||||||
|
is-system-resources="ctrl.state.isSystemResources"
|
||||||
|
set-system-resources="(ctrl.setSystemResources)"
|
||||||
>
|
>
|
||||||
</kubernetes-applications-stacks-datatable>
|
</kubernetes-applications-stacks-datatable>
|
||||||
</uib-tab>
|
</uib-tab>
|
||||||
|
|
|
@ -9,9 +9,22 @@ import { confirmDelete } from '@@/modals/confirm';
|
||||||
|
|
||||||
class KubernetesApplicationsController {
|
class KubernetesApplicationsController {
|
||||||
/* @ngInject */
|
/* @ngInject */
|
||||||
constructor($async, $state, Notifications, KubernetesApplicationService, HelmService, KubernetesConfigurationService, Authentication, LocalStorage, StackService) {
|
constructor(
|
||||||
|
$async,
|
||||||
|
$state,
|
||||||
|
$scope,
|
||||||
|
Notifications,
|
||||||
|
KubernetesApplicationService,
|
||||||
|
HelmService,
|
||||||
|
KubernetesConfigurationService,
|
||||||
|
Authentication,
|
||||||
|
LocalStorage,
|
||||||
|
StackService,
|
||||||
|
KubernetesNamespaceService
|
||||||
|
) {
|
||||||
this.$async = $async;
|
this.$async = $async;
|
||||||
this.$state = $state;
|
this.$state = $state;
|
||||||
|
this.$scope = $scope;
|
||||||
this.Notifications = Notifications;
|
this.Notifications = Notifications;
|
||||||
this.KubernetesApplicationService = KubernetesApplicationService;
|
this.KubernetesApplicationService = KubernetesApplicationService;
|
||||||
this.HelmService = HelmService;
|
this.HelmService = HelmService;
|
||||||
|
@ -19,6 +32,7 @@ class KubernetesApplicationsController {
|
||||||
this.Authentication = Authentication;
|
this.Authentication = Authentication;
|
||||||
this.LocalStorage = LocalStorage;
|
this.LocalStorage = LocalStorage;
|
||||||
this.StackService = StackService;
|
this.StackService = StackService;
|
||||||
|
this.KubernetesNamespaceService = KubernetesNamespaceService;
|
||||||
|
|
||||||
this.onInit = this.onInit.bind(this);
|
this.onInit = this.onInit.bind(this);
|
||||||
this.getApplications = this.getApplications.bind(this);
|
this.getApplications = this.getApplications.bind(this);
|
||||||
|
@ -28,6 +42,8 @@ class KubernetesApplicationsController {
|
||||||
this.removeStacksAction = this.removeStacksAction.bind(this);
|
this.removeStacksAction = this.removeStacksAction.bind(this);
|
||||||
this.removeStacksActionAsync = this.removeStacksActionAsync.bind(this);
|
this.removeStacksActionAsync = this.removeStacksActionAsync.bind(this);
|
||||||
this.onPublishingModeClick = this.onPublishingModeClick.bind(this);
|
this.onPublishingModeClick = this.onPublishingModeClick.bind(this);
|
||||||
|
this.onChangeNamespaceDropdown = this.onChangeNamespaceDropdown.bind(this);
|
||||||
|
this.setSystemResources = this.setSystemResources.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
selectTab(index) {
|
selectTab(index) {
|
||||||
|
@ -126,20 +142,34 @@ class KubernetesApplicationsController {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onChangeNamespaceDropdown(namespace) {
|
||||||
|
this.state.namespace = namespace;
|
||||||
|
this.getApplicationsAsync();
|
||||||
|
}
|
||||||
|
|
||||||
async getApplicationsAsync() {
|
async getApplicationsAsync() {
|
||||||
try {
|
try {
|
||||||
const [applications, configurations] = await Promise.all([this.KubernetesApplicationService.get(), this.KubernetesConfigurationService.get()]);
|
const [applications, configurations] = await Promise.all([
|
||||||
|
this.KubernetesApplicationService.get(this.state.namespace),
|
||||||
|
this.KubernetesConfigurationService.get(this.state.namespace),
|
||||||
|
]);
|
||||||
const configuredApplications = KubernetesConfigurationHelper.getApplicationConfigurations(applications, configurations);
|
const configuredApplications = KubernetesConfigurationHelper.getApplicationConfigurations(applications, configurations);
|
||||||
const { helmApplications, nonHelmApplications } = KubernetesApplicationHelper.getNestedApplications(configuredApplications);
|
const { helmApplications, nonHelmApplications } = KubernetesApplicationHelper.getNestedApplications(configuredApplications);
|
||||||
|
|
||||||
this.state.applications = [...helmApplications, ...nonHelmApplications];
|
this.state.applications = [...helmApplications, ...nonHelmApplications];
|
||||||
this.state.stacks = KubernetesStackHelper.stacksFromApplications(applications);
|
this.state.stacks = KubernetesStackHelper.stacksFromApplications(applications);
|
||||||
this.state.ports = KubernetesApplicationHelper.portMappingsFromApplications(applications);
|
this.state.ports = KubernetesApplicationHelper.portMappingsFromApplications(applications);
|
||||||
|
|
||||||
|
this.$scope.$apply();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.Notifications.error('Failure', err, 'Unable to retrieve applications');
|
this.Notifications.error('Failure', err, 'Unable to retrieve applications');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setSystemResources(flag) {
|
||||||
|
this.state.isSystemResources = flag;
|
||||||
|
}
|
||||||
|
|
||||||
getApplications() {
|
getApplications() {
|
||||||
return this.$async(this.getApplicationsAsync);
|
return this.$async(this.getApplicationsAsync);
|
||||||
}
|
}
|
||||||
|
@ -153,7 +183,16 @@ class KubernetesApplicationsController {
|
||||||
applications: [],
|
applications: [],
|
||||||
stacks: [],
|
stacks: [],
|
||||||
ports: [],
|
ports: [],
|
||||||
|
namespaces: [],
|
||||||
|
namespace: '',
|
||||||
|
isSystemResources: undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.state.namespaces = await this.KubernetesNamespaceService.get();
|
||||||
|
this.state.namespaces = this.state.namespaces.filter((n) => n.Status !== 'Terminating');
|
||||||
|
this.state.namespaces = _.sortBy(this.state.namespaces, 'Name');
|
||||||
|
this.state.namespace = this.state.namespaces.length ? (this.state.namespaces.find((n) => n.Name === 'default') ? 'default' : this.state.namespaces[0].Name) : '';
|
||||||
|
|
||||||
await this.getApplications();
|
await this.getApplications();
|
||||||
|
|
||||||
this.state.viewReady = true;
|
this.state.viewReady = true;
|
||||||
|
|
|
@ -35,7 +35,8 @@ class KubernetesResourcePoolController {
|
||||||
KubernetesPodService,
|
KubernetesPodService,
|
||||||
KubernetesApplicationService,
|
KubernetesApplicationService,
|
||||||
KubernetesIngressService,
|
KubernetesIngressService,
|
||||||
KubernetesVolumeService
|
KubernetesVolumeService,
|
||||||
|
KubernetesNamespaceService
|
||||||
) {
|
) {
|
||||||
Object.assign(this, {
|
Object.assign(this, {
|
||||||
$async,
|
$async,
|
||||||
|
@ -54,6 +55,7 @@ class KubernetesResourcePoolController {
|
||||||
KubernetesApplicationService,
|
KubernetesApplicationService,
|
||||||
KubernetesIngressService,
|
KubernetesIngressService,
|
||||||
KubernetesVolumeService,
|
KubernetesVolumeService,
|
||||||
|
KubernetesNamespaceService,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.IngressClassTypes = KubernetesIngressClassTypes;
|
this.IngressClassTypes = KubernetesIngressClassTypes;
|
||||||
|
@ -219,6 +221,7 @@ class KubernetesResourcePoolController {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await this.KubernetesResourcePoolService.toggleSystem(this.endpoint.Id, namespaceName, !this.isSystem);
|
await this.KubernetesResourcePoolService.toggleSystem(this.endpoint.Id, namespaceName, !this.isSystem);
|
||||||
|
await this.KubernetesNamespaceService.refreshCacheAsync();
|
||||||
|
|
||||||
this.Notifications.success('Namespace successfully updated', namespaceName);
|
this.Notifications.success('Namespace successfully updated', namespaceName);
|
||||||
this.$state.reload(this.$state.current);
|
this.$state.reload(this.$state.current);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<page-header ng-if="ctrl.state.viewReady" title="'Namespace list'" breadcrumbs="['Namespaces']" reload="true"></page-header>
|
<page-header ng-if="ctrl.state.viewReady" title="'Namespace list'" breadcrumbs="['Namespaces']" on-reload="(ctrl.onReload)" reload="true"></page-header>
|
||||||
|
|
||||||
<kubernetes-view-loading view-ready="ctrl.state.viewReady"></kubernetes-view-loading>
|
<kubernetes-view-loading view-ready="ctrl.state.viewReady"></kubernetes-view-loading>
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,12 @@ class KubernetesResourcePoolsController {
|
||||||
this.getResourcePoolsAsync = this.getResourcePoolsAsync.bind(this);
|
this.getResourcePoolsAsync = this.getResourcePoolsAsync.bind(this);
|
||||||
this.removeAction = this.removeAction.bind(this);
|
this.removeAction = this.removeAction.bind(this);
|
||||||
this.removeActionAsync = this.removeActionAsync.bind(this);
|
this.removeActionAsync = this.removeActionAsync.bind(this);
|
||||||
|
this.onReload = this.onReload.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
async onReload() {
|
||||||
|
await this.KubernetesNamespaceService.refreshCacheAsync();
|
||||||
|
this.$state.reload(this.$state.current);
|
||||||
}
|
}
|
||||||
|
|
||||||
async removeActionAsync(selectedItems) {
|
async removeActionAsync(selectedItems) {
|
||||||
|
@ -48,6 +54,7 @@ class KubernetesResourcePoolsController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
await this.KubernetesNamespaceService.refreshCacheAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
removeAction(selectedItems) {
|
removeAction(selectedItems) {
|
||||||
|
|
|
@ -112,7 +112,7 @@ angular.module('portainer.app').factory('LocalStorage', [
|
||||||
localStorageService.clearAll();
|
localStorageService.clearAll();
|
||||||
},
|
},
|
||||||
cleanAuthData() {
|
cleanAuthData() {
|
||||||
localStorageService.remove('JWT', 'APPLICATION_STATE', 'LOGIN_STATE_UUID');
|
localStorageService.remove('JWT', 'APPLICATION_STATE', 'LOGIN_STATE_UUID', 'ALLOWED_NAMESPACES');
|
||||||
},
|
},
|
||||||
storeKubernetesSummaryToggle(value) {
|
storeKubernetesSummaryToggle(value) {
|
||||||
localStorageService.set('kubernetes_summary_expanded', value);
|
localStorageService.set('kubernetes_summary_expanded', value);
|
||||||
|
@ -120,6 +120,15 @@ angular.module('portainer.app').factory('LocalStorage', [
|
||||||
getKubernetesSummaryToggle() {
|
getKubernetesSummaryToggle() {
|
||||||
return localStorageService.get('kubernetes_summary_expanded');
|
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');
|
||||||
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
Loading…
Reference in New Issue