diff --git a/app/kubernetes/views/configure/configureController.js b/app/kubernetes/views/configure/configureController.js index 27dd0b348..502dcaaf4 100644 --- a/app/kubernetes/views/configure/configureController.js +++ b/app/kubernetes/views/configure/configureController.js @@ -43,6 +43,7 @@ class KubernetesConfigureController { this.configureAsync = this.configureAsync.bind(this); this.areControllersChanged = this.areControllersChanged.bind(this); this.areFormValuesChanged = this.areFormValuesChanged.bind(this); + this.areStorageClassesChanged = this.areStorageClassesChanged.bind(this); this.onBeforeOnload = this.onBeforeOnload.bind(this); this.limitedFeature = FeatureId.K8S_SETUP_DEFAULT; this.limitedFeatureAutoWindow = FeatureId.HIDE_AUTO_UPDATE_WINDOW; @@ -298,7 +299,7 @@ class KubernetesConfigureController { [this.StorageClasses, this.endpoint] = await Promise.all([this.KubernetesStorageService.get(this.state.endpointId), this.EndpointService.endpoint(this.state.endpointId)]); this.ingressControllers = await getIngressControllerClassMap({ environmentId: this.state.endpointId }); - this.originalIngressControllers = structuredClone(this.ingressControllers); + this.originalIngressControllers = structuredClone(this.ingressControllers) || []; this.state.autoUpdateSettings = this.endpoint.ChangeWindow; @@ -313,8 +314,6 @@ class KubernetesConfigureController { } }); - this.oldStorageClasses = angular.copy(this.StorageClasses); - this.formValues.UseLoadBalancer = this.endpoint.Kubernetes.Configuration.UseLoadBalancer; this.formValues.UseServerMetrics = this.endpoint.Kubernetes.Configuration.UseServerMetrics; this.formValues.EnableResourceOverCommit = this.endpoint.Kubernetes.Configuration.EnableResourceOverCommit; @@ -328,7 +327,8 @@ class KubernetesConfigureController { this.formValues.IngressAvailabilityPerNamespace = this.endpoint.Kubernetes.Configuration.IngressAvailabilityPerNamespace; this.formValues.AllowNoneIngressClass = this.endpoint.Kubernetes.Configuration.AllowNoneIngressClass; - this.oldFormValues = Object.assign({}, this.formValues); + this.oldStorageClasses = angular.copy(this.StorageClasses); + this.oldFormValues = angular.copy(this.formValues); } catch (err) { this.Notifications.error('Failure', err, 'Unable to retrieve environment configuration'); } finally { @@ -356,15 +356,23 @@ class KubernetesConfigureController { return !_.isEqual(this.formValues, this.oldFormValues); } + areStorageClassesChanged() { + // angular is pesky and modifies this.StorageClasses (adds $$hashkey to each item) + // angular.toJson removes this to make the comparison work + const storageClassesWithoutHashKey = angular.toJson(this.StorageClasses); + const oldStorageClassesWithoutHashKey = angular.toJson(this.oldStorageClasses); + return !_.isEqual(storageClassesWithoutHashKey, oldStorageClassesWithoutHashKey); + } + onBeforeOnload(event) { - if (!this.state.isSaving && (this.areControllersChanged() || this.areFormValuesChanged())) { + if (!this.state.isSaving && (this.areControllersChanged() || this.areFormValuesChanged() || this.areStorageClassesChanged())) { event.preventDefault(); event.returnValue = ''; } } uiCanExit() { - if (!this.state.isSaving && (this.areControllersChanged() || this.areFormValuesChanged()) && !this.isIngressControllersLoading) { + if (!this.state.isSaving && (this.areControllersChanged() || this.areFormValuesChanged() || this.areStorageClassesChanged()) && !this.isIngressControllersLoading) { return this.ModalService.confirmAsync({ title: 'Are you sure?', message: 'You currently have unsaved changes in the cluster setup view. Are you sure you want to leave?', diff --git a/app/portainer/views/settings/settings.html b/app/portainer/views/settings/settings.html index 440d03274..bc437aa0d 100644 --- a/app/portainer/views/settings/settings.html +++ b/app/portainer/views/settings/settings.html @@ -157,7 +157,7 @@ -
Kubernetes
+
Kubeconfig