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>
 | 
			
		||||
        Applications
 | 
			
		||||
      </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]">
 | 
			
		||||
        <pr-icon icon="'search'" class-name="'searchIcon'"></pr-icon>
 | 
			
		||||
        <input
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,5 +15,10 @@ angular.module('portainer.kubernetes').component('kubernetesApplicationsDatatabl
 | 
			
		|||
    refreshCallback: '<',
 | 
			
		||||
    onPublishingModeClick: '<',
 | 
			
		||||
    isPrimary: '<',
 | 
			
		||||
    namespaces: '<',
 | 
			
		||||
    namespace: '<',
 | 
			
		||||
    onChangeNamespaceDropdown: '<',
 | 
			
		||||
    isSystemResources: '<',
 | 
			
		||||
    setSystemResources: '<',
 | 
			
		||||
  },
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,6 +21,8 @@ angular.module('portainer.docker').controller('KubernetesApplicationsDatatableCo
 | 
			
		|||
    this.state = Object.assign(this.state, {
 | 
			
		||||
      expandAll: false,
 | 
			
		||||
      expandedItems: [],
 | 
			
		||||
      namespace: '',
 | 
			
		||||
      namespaces: [],
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    this.filters = {
 | 
			
		||||
| 
						 | 
				
			
			@ -70,6 +72,8 @@ angular.module('portainer.docker').controller('KubernetesApplicationsDatatableCo
 | 
			
		|||
    };
 | 
			
		||||
 | 
			
		||||
    this.onSettingsShowSystemChange = function () {
 | 
			
		||||
      this.updateNamespace();
 | 
			
		||||
      this.setSystemResources(this.settings.showSystem);
 | 
			
		||||
      DatatableService.setDataTableSettings(this.tableKey, this.settings);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -135,6 +139,43 @@ angular.module('portainer.docker').controller('KubernetesApplicationsDatatableCo
 | 
			
		|||
      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.isAdmin = Authentication.isAdmin();
 | 
			
		||||
      this.KubernetesApplicationDeploymentTypes = KubernetesApplicationDeploymentTypes;
 | 
			
		||||
| 
						 | 
				
			
			@ -172,7 +213,16 @@ angular.module('portainer.docker').controller('KubernetesApplicationsDatatableCo
 | 
			
		|||
      if (storedSettings !== null) {
 | 
			
		||||
        this.settings = storedSettings;
 | 
			
		||||
        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();
 | 
			
		||||
    };
 | 
			
		||||
  },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,6 +10,22 @@
 | 
			
		|||
        Stacks
 | 
			
		||||
      </div>
 | 
			
		||||
      <!-- 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">
 | 
			
		||||
        <pr-icon icon="'search'" class-name="'!h-3'"></pr-icon>
 | 
			
		||||
        <input
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,5 +10,10 @@ angular.module('portainer.kubernetes').component('kubernetesApplicationsStacksDa
 | 
			
		|||
    reverseOrder: '<',
 | 
			
		||||
    refreshCallback: '<',
 | 
			
		||||
    removeAction: '<',
 | 
			
		||||
    namespaces: '<',
 | 
			
		||||
    namespace: '<',
 | 
			
		||||
    onChangeNamespaceDropdown: '<',
 | 
			
		||||
    isSystemResources: '<',
 | 
			
		||||
    setSystemResources: '<',
 | 
			
		||||
  },
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,6 +13,8 @@ angular.module('portainer.kubernetes').controller('KubernetesApplicationsStacksD
 | 
			
		|||
    this.state = Object.assign(this.state, {
 | 
			
		||||
      expandedItems: [],
 | 
			
		||||
      expandAll: false,
 | 
			
		||||
      namespace: '',
 | 
			
		||||
      namespaces: [],
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    var ctrl = this;
 | 
			
		||||
| 
						 | 
				
			
			@ -22,6 +24,8 @@ angular.module('portainer.kubernetes').controller('KubernetesApplicationsStacksD
 | 
			
		|||
    });
 | 
			
		||||
 | 
			
		||||
    this.onSettingsShowSystemChange = function () {
 | 
			
		||||
      this.updateNamespace();
 | 
			
		||||
      this.setSystemResources(this.settings.showSystem);
 | 
			
		||||
      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.isAdmin = Authentication.isAdmin();
 | 
			
		||||
      this.KubernetesApplicationDeploymentTypes = KubernetesApplicationDeploymentTypes;
 | 
			
		||||
| 
						 | 
				
			
			@ -103,11 +145,20 @@ angular.module('portainer.kubernetes').controller('KubernetesApplicationsStacksD
 | 
			
		|||
        this.filters.state.open = false;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      var storedSettings = DatatableService.getDataTableSettings(this.tableKey);
 | 
			
		||||
      var storedSettings = DatatableService.getDataTableSettings(this.settingsKey);
 | 
			
		||||
      if (storedSettings !== null) {
 | 
			
		||||
        this.settings = storedSettings;
 | 
			
		||||
        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();
 | 
			
		||||
    };
 | 
			
		||||
  },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,9 +7,10 @@ import $allSettled from 'Portainer/services/allSettled';
 | 
			
		|||
 | 
			
		||||
class KubernetesNamespaceService {
 | 
			
		||||
  /* @ngInject */
 | 
			
		||||
  constructor($async, KubernetesNamespaces) {
 | 
			
		||||
  constructor($async, KubernetesNamespaces, LocalStorage) {
 | 
			
		||||
    this.$async = $async;
 | 
			
		||||
    this.KubernetesNamespaces = KubernetesNamespaces;
 | 
			
		||||
    this.LocalStorage = LocalStorage;
 | 
			
		||||
 | 
			
		||||
    this.getAsync = this.getAsync.bind(this);
 | 
			
		||||
    this.getAllAsync = this.getAllAsync.bind(this);
 | 
			
		||||
| 
						 | 
				
			
			@ -17,6 +18,7 @@ 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);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
| 
						 | 
				
			
			@ -79,11 +81,19 @@ class KubernetesNamespaceService {
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  get(name) {
 | 
			
		||||
  async get(name) {
 | 
			
		||||
    if (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 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);
 | 
			
		||||
| 
						 | 
				
			
			@ -104,6 +115,14 @@ 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
 | 
			
		||||
   */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,6 +19,11 @@
 | 
			
		|||
                refresh-callback="ctrl.getApplications"
 | 
			
		||||
                on-publishing-mode-click="(ctrl.onPublishingModeClick)"
 | 
			
		||||
                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>
 | 
			
		||||
            </uib-tab>
 | 
			
		||||
| 
						 | 
				
			
			@ -30,6 +35,11 @@
 | 
			
		|||
                order-by="Name"
 | 
			
		||||
                refresh-callback="ctrl.getApplications"
 | 
			
		||||
                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>
 | 
			
		||||
            </uib-tab>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,9 +9,22 @@ import { confirmDelete } from '@@/modals/confirm';
 | 
			
		|||
 | 
			
		||||
class KubernetesApplicationsController {
 | 
			
		||||
  /* @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.$state = $state;
 | 
			
		||||
    this.$scope = $scope;
 | 
			
		||||
    this.Notifications = Notifications;
 | 
			
		||||
    this.KubernetesApplicationService = KubernetesApplicationService;
 | 
			
		||||
    this.HelmService = HelmService;
 | 
			
		||||
| 
						 | 
				
			
			@ -19,6 +32,7 @@ class KubernetesApplicationsController {
 | 
			
		|||
    this.Authentication = Authentication;
 | 
			
		||||
    this.LocalStorage = LocalStorage;
 | 
			
		||||
    this.StackService = StackService;
 | 
			
		||||
    this.KubernetesNamespaceService = KubernetesNamespaceService;
 | 
			
		||||
 | 
			
		||||
    this.onInit = this.onInit.bind(this);
 | 
			
		||||
    this.getApplications = this.getApplications.bind(this);
 | 
			
		||||
| 
						 | 
				
			
			@ -28,6 +42,8 @@ class KubernetesApplicationsController {
 | 
			
		|||
    this.removeStacksAction = this.removeStacksAction.bind(this);
 | 
			
		||||
    this.removeStacksActionAsync = this.removeStacksActionAsync.bind(this);
 | 
			
		||||
    this.onPublishingModeClick = this.onPublishingModeClick.bind(this);
 | 
			
		||||
    this.onChangeNamespaceDropdown = this.onChangeNamespaceDropdown.bind(this);
 | 
			
		||||
    this.setSystemResources = this.setSystemResources.bind(this);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  selectTab(index) {
 | 
			
		||||
| 
						 | 
				
			
			@ -126,20 +142,34 @@ class KubernetesApplicationsController {
 | 
			
		|||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  onChangeNamespaceDropdown(namespace) {
 | 
			
		||||
    this.state.namespace = namespace;
 | 
			
		||||
    this.getApplicationsAsync();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async getApplicationsAsync() {
 | 
			
		||||
    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 { helmApplications, nonHelmApplications } = KubernetesApplicationHelper.getNestedApplications(configuredApplications);
 | 
			
		||||
 | 
			
		||||
      this.state.applications = [...helmApplications, ...nonHelmApplications];
 | 
			
		||||
      this.state.stacks = KubernetesStackHelper.stacksFromApplications(applications);
 | 
			
		||||
      this.state.ports = KubernetesApplicationHelper.portMappingsFromApplications(applications);
 | 
			
		||||
 | 
			
		||||
      this.$scope.$apply();
 | 
			
		||||
    } catch (err) {
 | 
			
		||||
      this.Notifications.error('Failure', err, 'Unable to retrieve applications');
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  setSystemResources(flag) {
 | 
			
		||||
    this.state.isSystemResources = flag;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  getApplications() {
 | 
			
		||||
    return this.$async(this.getApplicationsAsync);
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -153,7 +183,16 @@ class KubernetesApplicationsController {
 | 
			
		|||
      applications: [],
 | 
			
		||||
      stacks: [],
 | 
			
		||||
      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();
 | 
			
		||||
 | 
			
		||||
    this.state.viewReady = true;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,7 +35,8 @@ class KubernetesResourcePoolController {
 | 
			
		|||
    KubernetesPodService,
 | 
			
		||||
    KubernetesApplicationService,
 | 
			
		||||
    KubernetesIngressService,
 | 
			
		||||
    KubernetesVolumeService
 | 
			
		||||
    KubernetesVolumeService,
 | 
			
		||||
    KubernetesNamespaceService
 | 
			
		||||
  ) {
 | 
			
		||||
    Object.assign(this, {
 | 
			
		||||
      $async,
 | 
			
		||||
| 
						 | 
				
			
			@ -54,6 +55,7 @@ class KubernetesResourcePoolController {
 | 
			
		|||
      KubernetesApplicationService,
 | 
			
		||||
      KubernetesIngressService,
 | 
			
		||||
      KubernetesVolumeService,
 | 
			
		||||
      KubernetesNamespaceService,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    this.IngressClassTypes = KubernetesIngressClassTypes;
 | 
			
		||||
| 
						 | 
				
			
			@ -219,6 +221,7 @@ 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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,6 +17,12 @@ class KubernetesResourcePoolsController {
 | 
			
		|||
    this.getResourcePoolsAsync = this.getResourcePoolsAsync.bind(this);
 | 
			
		||||
    this.removeAction = this.removeAction.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) {
 | 
			
		||||
| 
						 | 
				
			
			@ -48,6 +54,7 @@ class KubernetesResourcePoolsController {
 | 
			
		|||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    await this.KubernetesNamespaceService.refreshCacheAsync();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  removeAction(selectedItems) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -112,7 +112,7 @@ angular.module('portainer.app').factory('LocalStorage', [
 | 
			
		|||
        localStorageService.clearAll();
 | 
			
		||||
      },
 | 
			
		||||
      cleanAuthData() {
 | 
			
		||||
        localStorageService.remove('JWT', 'APPLICATION_STATE', 'LOGIN_STATE_UUID');
 | 
			
		||||
        localStorageService.remove('JWT', 'APPLICATION_STATE', 'LOGIN_STATE_UUID', 'ALLOWED_NAMESPACES');
 | 
			
		||||
      },
 | 
			
		||||
      storeKubernetesSummaryToggle(value) {
 | 
			
		||||
        localStorageService.set('kubernetes_summary_expanded', value);
 | 
			
		||||
| 
						 | 
				
			
			@ -120,6 +120,15 @@ 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');
 | 
			
		||||
      },
 | 
			
		||||
    };
 | 
			
		||||
  },
 | 
			
		||||
]);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue