fix(app): EndpointProvider fallback on URL EndpointID when no endpoint is selected

This commit is contained in:
xAt0mZ
2021-03-02 19:51:15 +01:00
committed by Felix Han
parent f4dd3067ed
commit da5c570968
2 changed files with 44 additions and 8 deletions

View File

@@ -8,11 +8,19 @@ import { KubernetesIngressClassTypes } from 'Kubernetes/ingress/constants';
class KubernetesConfigureController {
/* #region CONSTRUCTOR */
// TODO: technical debt
// $transition$ cannot be injected as bindings: { $transition$: '<' } inside app/portainer/__module.js
// because this view is not using a component (https://ui-router.github.io/guide/ng1/route-to-component#accessing-transition)
// and will cause
// >> Error: Cannot combine: component|bindings|componentProvider
// >> with: templateProvider|templateUrl|template|notify|async|controller|controllerProvider|controllerAs|resolveAs
// >> in stateview: 'content@@portainer.endpoints.endpoint.kubernetesConfig'
/* @ngInject */
constructor(
$async,
$state,
$stateParams,
$transition$,
Notifications,
KubernetesStorageService,
EndpointService,
@@ -24,7 +32,7 @@ class KubernetesConfigureController {
) {
this.$async = $async;
this.$state = $state;
this.$stateParams = $stateParams;
this.$transition$ = $transition$;
this.Notifications = Notifications;
this.KubernetesStorageService = KubernetesStorageService;
this.EndpointService = EndpointService;
@@ -210,7 +218,7 @@ class KubernetesConfigureController {
actionInProgress: false,
displayConfigureClassPanel: {},
viewReady: false,
endpointId: this.$stateParams.id,
endpointId: this.$transition$.params().id,
duplicates: {
ingressClasses: new KubernetesFormValidationReferences(),
},

View File

@@ -1,8 +1,9 @@
import _ from 'lodash-es';
angular.module('portainer.app').factory('EndpointProvider', [
'LocalStorage',
function EndpointProviderFactory(LocalStorage) {
angular.module('portainer.app').factory(
'EndpointProvider',
/* @ngInject */
function EndpointProviderFactory(LocalStorage, $uiRouterGlobals) {
'use strict';
var service = {};
var endpoint = {};
@@ -36,9 +37,36 @@ angular.module('portainer.app').factory('EndpointProvider', [
if (endpoint.ID === undefined) {
endpoint.ID = LocalStorage.getEndpointID();
}
if (endpoint.ID === null || endpoint.ID === undefined) {
return service.getUrlEndpointID();
}
return endpoint.ID;
};
// TODO: technical debt
// Reference issue: JIRA CE-463
// Documentation (https://ui-router.github.io/ng1/docs/latest/modules/injectables.html) show the usage of either
// * $stateParams
// * $transition$
// * $uiRouterGlobals
// to retrieve the URL params
//
// * $stateParams: is deprecated and will cause a circular dependency injection error
// because EndpointProvider is used by EndpointStatusInterceptor which is injected inside $httpProvider
// >> [$injector:cdep] Circular dependency found: $uiRouter <- $stateParams <- EndpointProvider <- EndpointStatusInterceptor <- $http <- $uiRouter
// For more details, see https://stackoverflow.com/questions/20230691/injecting-state-ui-router-into-http-interceptor-causes-circular-dependency#20230786
//
// * $transition$: mentionned as the replacement of $stateParams (https://ui-router.github.io/guide/ng1/migrate-to-1_0#stateparams-deprecation)
// but is not injectable without tweaks inside a service
//
// * $uiRouterGlobal: per https://github.com/angular-ui/ui-router/issues/3237#issuecomment-271979688
// seems the recommanded way to retrieve params inside a service/factory
//
// We need this function to fallback on URL endpoint ID when no endpoint has been selected
service.getUrlEndpointID = () => {
return $uiRouterGlobals.params.id;
};
service.setEndpointID = function (id) {
endpoint.ID = id;
LocalStorage.storeEndpointID(id);
@@ -88,5 +116,5 @@ angular.module('portainer.app').factory('EndpointProvider', [
};
return service;
},
]);
}
);