mirror of https://github.com/portainer/portainer
				
				
				
			refactor(router): show endpoint id in url (#3966)
* refactor(module): provide basic endpoint id url * fix(stacks): fix route to include endpointId * fix(stacks): fix stacks urls * fix(sidebar): fix urls to docker routes * refactor(app): set endpoint id on change view * refactor(dashboard): revert to old version * refactor(sidebar): revert file * feat(app): wip load endpoint on route change * feat(home): show error * feat(app): load endpoint route * feat(sidebar): show endpoint per provider * refactor(app): revert * refactor(app): clean endpoint startup * feat(edge): check for edge k8s * refactor(endpoints): move all modules under endpoint route * refactor(stacks): move stacks route to docker * refactor(templates): move templates route to docker * refactor(app): check endpoint when entering docker module * fix(app): load endpoint when entering endpoints modules * feat(azure): check endpoint * feat(kubernetes): check endpoint * feat(home): show loading state when loading edge * style(app): revert small changes * refactor(sidebar): remove refernce to endpointId * fix(stacks): fix stacks route * style(docker): sort routes * feat(app): change route to home if endpoint failed * fix(services): guard against empty snapshots * feat(app): show error when failed to load endpoint * feat(app): reload home route when failing * refactor(router): replace resolvers with onEnterpull/4029/head
							parent
							
								
									1b3e2c8f69
								
							
						
					
					
						commit
						3c34fbd8f2
					
				| 
						 | 
				
			
			@ -6,8 +6,20 @@ angular.module('portainer.azure', ['portainer.app']).config([
 | 
			
		|||
    var azure = {
 | 
			
		||||
      name: 'azure',
 | 
			
		||||
      url: '/azure',
 | 
			
		||||
      parent: 'root',
 | 
			
		||||
      parent: 'endpoint',
 | 
			
		||||
      abstract: true,
 | 
			
		||||
      /* ngInject */
 | 
			
		||||
      async onEnter($state, endpoint, EndpointProvider, Notifications, StateManager) {
 | 
			
		||||
        try {
 | 
			
		||||
          EndpointProvider.setEndpointID(endpoint.Id);
 | 
			
		||||
          EndpointProvider.setEndpointPublicURL(endpoint.PublicURL);
 | 
			
		||||
          EndpointProvider.setOfflineModeFromStatus(endpoint.Status);
 | 
			
		||||
          await StateManager.updateEndpointState(endpoint, []);
 | 
			
		||||
        } catch (e) {
 | 
			
		||||
          Notifications.error('Failed loading endpoint', e);
 | 
			
		||||
          $state.go('portainer.home', {}, { reload: true });
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    var containerInstances = {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,19 +5,53 @@ angular.module('portainer.docker', ['portainer.app']).config([
 | 
			
		|||
 | 
			
		||||
    var docker = {
 | 
			
		||||
      name: 'docker',
 | 
			
		||||
      parent: 'root',
 | 
			
		||||
      parent: 'endpoint',
 | 
			
		||||
      abstract: true,
 | 
			
		||||
      resolve: {
 | 
			
		||||
        endpointID: [
 | 
			
		||||
          'EndpointProvider',
 | 
			
		||||
          '$state',
 | 
			
		||||
          function (EndpointProvider, $state) {
 | 
			
		||||
            var id = EndpointProvider.endpointID();
 | 
			
		||||
            if (!id) {
 | 
			
		||||
              return $state.go('portainer.home');
 | 
			
		||||
      /* ngInject */
 | 
			
		||||
      async onEnter(endpoint, $state, EndpointService, EndpointProvider, LegacyExtensionManager, Notifications, StateManager, SystemService) {
 | 
			
		||||
        try {
 | 
			
		||||
          const status = await checkEndpointStatus(endpoint);
 | 
			
		||||
 | 
			
		||||
          if (endpoint.Type !== 4) {
 | 
			
		||||
            await updateEndpointStatus(endpoint, status);
 | 
			
		||||
          }
 | 
			
		||||
          endpoint.Status = status;
 | 
			
		||||
 | 
			
		||||
          if (status === 2) {
 | 
			
		||||
            if (!endpoint.Snapshots[0]) {
 | 
			
		||||
              throw new Error('Endpoint is unreachable and there is no snapshot available for offline browsing.');
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
        ],
 | 
			
		||||
            if (endpoint.Snapshots[0].Swarm) {
 | 
			
		||||
              throw new Error('Endpoint is unreachable. Connect to another swarm manager.');
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          EndpointProvider.setEndpointID(endpoint.Id);
 | 
			
		||||
          EndpointProvider.setEndpointPublicURL(endpoint.PublicURL);
 | 
			
		||||
          EndpointProvider.setOfflineModeFromStatus(endpoint.Status);
 | 
			
		||||
 | 
			
		||||
          const extensions = await LegacyExtensionManager.initEndpointExtensions(endpoint);
 | 
			
		||||
          await StateManager.updateEndpointState(endpoint, extensions);
 | 
			
		||||
        } catch (e) {
 | 
			
		||||
          Notifications.error('Failed loading endpoint', e);
 | 
			
		||||
          $state.go('portainer.home', {}, { reload: true });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        async function checkEndpointStatus(endpoint) {
 | 
			
		||||
          try {
 | 
			
		||||
            await SystemService.ping(endpoint.Id);
 | 
			
		||||
            return 1;
 | 
			
		||||
          } catch (e) {
 | 
			
		||||
            return 2;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        async function updateEndpointStatus(endpoint, status) {
 | 
			
		||||
          if (endpoint.Status === status) {
 | 
			
		||||
            return;
 | 
			
		||||
          }
 | 
			
		||||
          await EndpointService.updateEndpoint(endpoint.Id, { Status: status });
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -144,6 +178,43 @@ angular.module('portainer.docker', ['portainer.app']).config([
 | 
			
		|||
      },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const customTemplates = {
 | 
			
		||||
      name: 'portainer.templates.custom',
 | 
			
		||||
      url: '/custom',
 | 
			
		||||
 | 
			
		||||
      views: {
 | 
			
		||||
        'content@': {
 | 
			
		||||
          component: 'customTemplatesView',
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const customTemplatesNew = {
 | 
			
		||||
      name: 'portainer.templates.custom.new',
 | 
			
		||||
      url: '/new?fileContent&type',
 | 
			
		||||
 | 
			
		||||
      views: {
 | 
			
		||||
        'content@': {
 | 
			
		||||
          component: 'createCustomTemplateView',
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
      params: {
 | 
			
		||||
        fileContent: '',
 | 
			
		||||
        type: '',
 | 
			
		||||
      },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const customTemplatesEdit = {
 | 
			
		||||
      name: 'portainer.templates.custom.edit',
 | 
			
		||||
      url: '/:id',
 | 
			
		||||
 | 
			
		||||
      views: {
 | 
			
		||||
        'content@': {
 | 
			
		||||
          component: 'editCustomTemplateView',
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    var dashboard = {
 | 
			
		||||
      name: 'docker.dashboard',
 | 
			
		||||
      url: '/dashboard',
 | 
			
		||||
| 
						 | 
				
			
			@ -366,6 +437,39 @@ angular.module('portainer.docker', ['portainer.app']).config([
 | 
			
		|||
      },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    var stacks = {
 | 
			
		||||
      name: 'docker.stacks',
 | 
			
		||||
      url: '/stacks',
 | 
			
		||||
      views: {
 | 
			
		||||
        'content@': {
 | 
			
		||||
          templateUrl: '~Portainer/views/stacks/stacks.html',
 | 
			
		||||
          controller: 'StacksController',
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    var stack = {
 | 
			
		||||
      name: 'docker.stacks.stack',
 | 
			
		||||
      url: '/:name?id&type&external',
 | 
			
		||||
      views: {
 | 
			
		||||
        'content@': {
 | 
			
		||||
          templateUrl: '~Portainer/views/stacks/edit/stack.html',
 | 
			
		||||
          controller: 'StackController',
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    var stackCreation = {
 | 
			
		||||
      name: 'docker.stacks.newstack',
 | 
			
		||||
      url: '/newstack',
 | 
			
		||||
      views: {
 | 
			
		||||
        'content@': {
 | 
			
		||||
          templateUrl: '~Portainer/views/stacks/create/createstack.html',
 | 
			
		||||
          controller: 'CreateStackController',
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    var swarm = {
 | 
			
		||||
      name: 'docker.swarm',
 | 
			
		||||
      url: '/swarm',
 | 
			
		||||
| 
						 | 
				
			
			@ -416,6 +520,17 @@ angular.module('portainer.docker', ['portainer.app']).config([
 | 
			
		|||
      },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    var templates = {
 | 
			
		||||
      name: 'docker.templates',
 | 
			
		||||
      url: '/templates',
 | 
			
		||||
      views: {
 | 
			
		||||
        'content@': {
 | 
			
		||||
          templateUrl: '~Portainer/views/templates/templates.html',
 | 
			
		||||
          controller: 'TemplatesController',
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    var volumes = {
 | 
			
		||||
      name: 'docker.volumes',
 | 
			
		||||
      url: '/volumes',
 | 
			
		||||
| 
						 | 
				
			
			@ -471,6 +586,9 @@ angular.module('portainer.docker', ['portainer.app']).config([
 | 
			
		|||
    $stateRegistryProvider.register(containerInspect);
 | 
			
		||||
    $stateRegistryProvider.register(containerLogs);
 | 
			
		||||
    $stateRegistryProvider.register(containerStats);
 | 
			
		||||
    $stateRegistryProvider.register(customTemplates);
 | 
			
		||||
    $stateRegistryProvider.register(customTemplatesNew);
 | 
			
		||||
    $stateRegistryProvider.register(customTemplatesEdit);
 | 
			
		||||
    $stateRegistryProvider.register(docker);
 | 
			
		||||
    $stateRegistryProvider.register(dashboard);
 | 
			
		||||
    $stateRegistryProvider.register(host);
 | 
			
		||||
| 
						 | 
				
			
			@ -493,11 +611,15 @@ angular.module('portainer.docker', ['portainer.app']).config([
 | 
			
		|||
    $stateRegistryProvider.register(service);
 | 
			
		||||
    $stateRegistryProvider.register(serviceCreation);
 | 
			
		||||
    $stateRegistryProvider.register(serviceLogs);
 | 
			
		||||
    $stateRegistryProvider.register(stacks);
 | 
			
		||||
    $stateRegistryProvider.register(stack);
 | 
			
		||||
    $stateRegistryProvider.register(stackCreation);
 | 
			
		||||
    $stateRegistryProvider.register(swarm);
 | 
			
		||||
    $stateRegistryProvider.register(swarmVisualizer);
 | 
			
		||||
    $stateRegistryProvider.register(tasks);
 | 
			
		||||
    $stateRegistryProvider.register(task);
 | 
			
		||||
    $stateRegistryProvider.register(taskLogs);
 | 
			
		||||
    $stateRegistryProvider.register(templates);
 | 
			
		||||
    $stateRegistryProvider.register(volumes);
 | 
			
		||||
    $stateRegistryProvider.register(volume);
 | 
			
		||||
    $stateRegistryProvider.register(volumeBrowse);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,14 +2,14 @@
 | 
			
		|||
  <a ui-sref="docker.dashboard" ui-sref-active="active">Dashboard <span class="menu-icon fa fa-tachometer-alt fa-fw"></span></a>
 | 
			
		||||
</li>
 | 
			
		||||
<li class="sidebar-list" ng-if="!$ctrl.offlineMode" authorization="DockerContainerCreate, PortainerStackCreate">
 | 
			
		||||
  <a ui-sref="portainer.templates" ui-sref-active="active">App Templates <span class="menu-icon fa fa-rocket fa-fw"></span></a>
 | 
			
		||||
  <a ui-sref="docker.templates" ui-sref-active="active">App Templates <span class="menu-icon fa fa-rocket fa-fw"></span></a>
 | 
			
		||||
 | 
			
		||||
  <div class="sidebar-sublist" ng-if="$ctrl.toggle && $ctrl.currentRouteName.includes('portainer.templates')">
 | 
			
		||||
    <a ui-sref="portainer.templates.custom" ui-sref-active="active">Custom Templates</a></div
 | 
			
		||||
  >
 | 
			
		||||
  <div class="sidebar-sublist" ng-if="$ctrl.toggle && $ctrl.currentRouteName.includes('docker.templates')">
 | 
			
		||||
    <a ui-sref="docker.templates.custom" ui-sref-active="active">Custom Templates</a>
 | 
			
		||||
  </div>
 | 
			
		||||
</li>
 | 
			
		||||
<li class="sidebar-list">
 | 
			
		||||
  <a ui-sref="portainer.stacks" ui-sref-active="active">Stacks <span class="menu-icon fa fa-th-list fa-fw"></span></a>
 | 
			
		||||
  <a ui-sref="docker.stacks" ui-sref-active="active">Stacks <span class="menu-icon fa fa-th-list fa-fw"></span></a>
 | 
			
		||||
</li>
 | 
			
		||||
<li class="sidebar-list" ng-if="$ctrl.swarmManagement">
 | 
			
		||||
  <a ui-sref="docker.services" ui-sref-active="active">Services <span class="menu-icon fa fa-list-alt fa-fw"></span></a>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,7 +10,7 @@ angular.module('portainer.app').factory('InfoInterceptor', [
 | 
			
		|||
    function responseErrorInterceptor(rejection) {
 | 
			
		||||
      if (rejection.status === 502 || rejection.status === 503 || rejection.status === -1) {
 | 
			
		||||
        var endpoint = EndpointProvider.currentEndpoint();
 | 
			
		||||
        if (endpoint !== undefined) {
 | 
			
		||||
        if (endpoint !== undefined && endpoint.Snapshots.length && endpoint.Snapshots[0].SnapshotRaw) {
 | 
			
		||||
          var data = endpoint.Snapshots[0].SnapshotRaw.Info;
 | 
			
		||||
          if (data !== undefined) {
 | 
			
		||||
            return data;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,7 +10,7 @@ angular.module('portainer.app').factory('VersionInterceptor', [
 | 
			
		|||
    function responseErrorInterceptor(rejection) {
 | 
			
		||||
      if (rejection.status === 502 || rejection.status === 503 || rejection.status === -1) {
 | 
			
		||||
        var endpoint = EndpointProvider.currentEndpoint();
 | 
			
		||||
        if (endpoint !== undefined) {
 | 
			
		||||
        if (endpoint !== undefined && endpoint.Snapshots.length && endpoint.Snapshots[0].SnapshotRaw) {
 | 
			
		||||
          var data = endpoint.Snapshots[0].SnapshotRaw.Version;
 | 
			
		||||
          if (data !== undefined) {
 | 
			
		||||
            return data;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -82,7 +82,7 @@
 | 
			
		|||
 | 
			
		||||
<div class="row">
 | 
			
		||||
  <div class="col-xs-12 col-md-6">
 | 
			
		||||
    <a ui-sref="portainer.stacks">
 | 
			
		||||
    <a ui-sref="docker.stacks">
 | 
			
		||||
      <rd-widget>
 | 
			
		||||
        <rd-widget-body>
 | 
			
		||||
          <div class="widget-icon blue pull-left">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,8 +34,9 @@ angular.module('portainer.docker').controller('DashboardController', [
 | 
			
		|||
    $scope.offlineMode = false;
 | 
			
		||||
 | 
			
		||||
    function initView() {
 | 
			
		||||
      var endpointMode = $scope.applicationState.endpoint.mode;
 | 
			
		||||
      var endpointId = EndpointProvider.endpointID();
 | 
			
		||||
      const endpointMode = $scope.applicationState.endpoint.mode;
 | 
			
		||||
      const endpointId = EndpointProvider.endpointID();
 | 
			
		||||
      $scope.endpointId = endpointId;
 | 
			
		||||
 | 
			
		||||
      $q.all({
 | 
			
		||||
        containers: ContainerService.containers(1),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,19 +6,26 @@ angular.module('portainer.kubernetes', ['portainer.app']).config([
 | 
			
		|||
    const kubernetes = {
 | 
			
		||||
      name: 'kubernetes',
 | 
			
		||||
      url: '/kubernetes',
 | 
			
		||||
      parent: 'root',
 | 
			
		||||
      parent: 'endpoint',
 | 
			
		||||
      abstract: true,
 | 
			
		||||
      resolve: {
 | 
			
		||||
        endpointID: [
 | 
			
		||||
          'EndpointProvider',
 | 
			
		||||
          '$state',
 | 
			
		||||
          function (EndpointProvider, $state) {
 | 
			
		||||
            const id = EndpointProvider.endpointID();
 | 
			
		||||
            if (!id) {
 | 
			
		||||
              return $state.go('portainer.home');
 | 
			
		||||
      /* @ngInject */
 | 
			
		||||
      async onEnter($state, endpoint, EndpointProvider, KubernetesHealthService, Notifications, StateManager) {
 | 
			
		||||
        try {
 | 
			
		||||
          if (endpoint.Type === 7) {
 | 
			
		||||
            try {
 | 
			
		||||
              await KubernetesHealthService.ping();
 | 
			
		||||
              endpoint.Status = 1;
 | 
			
		||||
            } catch (e) {
 | 
			
		||||
              endpoint.Status = 2;
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
        ],
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          EndpointProvider.setEndpointID(endpoint.Id);
 | 
			
		||||
          await StateManager.updateEndpointState(endpoint, []);
 | 
			
		||||
        } catch (e) {
 | 
			
		||||
          Notifications.error('Failed loading endpoint', e);
 | 
			
		||||
          $state.go('portainer.home', {}, { reload: true });
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -75,6 +75,35 @@ angular.module('portainer.app', []).config([
 | 
			
		|||
      },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    var endpointRoot = {
 | 
			
		||||
      name: 'endpoint',
 | 
			
		||||
      url: '/:endpointId',
 | 
			
		||||
      parent: 'root',
 | 
			
		||||
      abstract: true,
 | 
			
		||||
      resolve: {
 | 
			
		||||
        /* @ngInject */
 | 
			
		||||
        endpoint($async, $state, $transition$, EndpointService, Notifications) {
 | 
			
		||||
          return $async(async () => {
 | 
			
		||||
            try {
 | 
			
		||||
              const endpointId = +$transition$.params().endpointId;
 | 
			
		||||
 | 
			
		||||
              const endpoint = await EndpointService.endpoint(endpointId);
 | 
			
		||||
              if ((endpoint.Type === 4 || endpoint.Type === 7) && !endpoint.EdgeID) {
 | 
			
		||||
                $state.go('portainer.endpoints.endpoint', { id: endpoint.Id });
 | 
			
		||||
                return;
 | 
			
		||||
              }
 | 
			
		||||
 | 
			
		||||
              return endpoint;
 | 
			
		||||
            } catch (e) {
 | 
			
		||||
              Notifications.error('Failed loading endpoint', e);
 | 
			
		||||
              $state.go('portainer.home', {}, { reload: true });
 | 
			
		||||
              return;
 | 
			
		||||
            }
 | 
			
		||||
          });
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    var portainer = {
 | 
			
		||||
      name: 'portainer',
 | 
			
		||||
      parent: 'root',
 | 
			
		||||
| 
						 | 
				
			
			@ -366,51 +395,6 @@ angular.module('portainer.app', []).config([
 | 
			
		|||
      },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    var stacks = {
 | 
			
		||||
      name: 'portainer.stacks',
 | 
			
		||||
      url: '/stacks',
 | 
			
		||||
      views: {
 | 
			
		||||
        'content@': {
 | 
			
		||||
          templateUrl: './views/stacks/stacks.html',
 | 
			
		||||
          controller: 'StacksController',
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
      resolve: {
 | 
			
		||||
        endpointID: [
 | 
			
		||||
          'EndpointProvider',
 | 
			
		||||
          '$state',
 | 
			
		||||
          function (EndpointProvider, $state) {
 | 
			
		||||
            var id = EndpointProvider.endpointID();
 | 
			
		||||
            if (!id) {
 | 
			
		||||
              return $state.go('portainer.home');
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
        ],
 | 
			
		||||
      },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    var stack = {
 | 
			
		||||
      name: 'portainer.stacks.stack',
 | 
			
		||||
      url: '/:name?id&type&external',
 | 
			
		||||
      views: {
 | 
			
		||||
        'content@': {
 | 
			
		||||
          templateUrl: './views/stacks/edit/stack.html',
 | 
			
		||||
          controller: 'StackController',
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    var stackCreation = {
 | 
			
		||||
      name: 'portainer.stacks.newstack',
 | 
			
		||||
      url: '/newstack',
 | 
			
		||||
      views: {
 | 
			
		||||
        'content@': {
 | 
			
		||||
          templateUrl: './views/stacks/create/createstack.html',
 | 
			
		||||
          controller: 'CreateStackController',
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    var support = {
 | 
			
		||||
      name: 'portainer.support',
 | 
			
		||||
      url: '/support',
 | 
			
		||||
| 
						 | 
				
			
			@ -491,67 +475,8 @@ angular.module('portainer.app', []).config([
 | 
			
		|||
      },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    var templates = {
 | 
			
		||||
      name: 'portainer.templates',
 | 
			
		||||
      url: '/templates',
 | 
			
		||||
      resolve: {
 | 
			
		||||
        endpointID: [
 | 
			
		||||
          'EndpointProvider',
 | 
			
		||||
          '$state',
 | 
			
		||||
          function (EndpointProvider, $state) {
 | 
			
		||||
            var id = EndpointProvider.endpointID();
 | 
			
		||||
            if (!id) {
 | 
			
		||||
              return $state.go('portainer.home');
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
        ],
 | 
			
		||||
      },
 | 
			
		||||
      views: {
 | 
			
		||||
        'content@': {
 | 
			
		||||
          templateUrl: './views/templates/templates.html',
 | 
			
		||||
          controller: 'TemplatesController',
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const customTemplates = {
 | 
			
		||||
      name: 'portainer.templates.custom',
 | 
			
		||||
      url: '/custom',
 | 
			
		||||
 | 
			
		||||
      views: {
 | 
			
		||||
        'content@': {
 | 
			
		||||
          component: 'customTemplatesView',
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const customTemplatesNew = {
 | 
			
		||||
      name: 'portainer.templates.custom.new',
 | 
			
		||||
      url: '/new?fileContent&type',
 | 
			
		||||
 | 
			
		||||
      views: {
 | 
			
		||||
        'content@': {
 | 
			
		||||
          component: 'createCustomTemplateView',
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
      params: {
 | 
			
		||||
        fileContent: '',
 | 
			
		||||
        type: '',
 | 
			
		||||
      },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const customTemplatesEdit = {
 | 
			
		||||
      name: 'portainer.templates.custom.edit',
 | 
			
		||||
      url: '/:id',
 | 
			
		||||
 | 
			
		||||
      views: {
 | 
			
		||||
        'content@': {
 | 
			
		||||
          component: 'editCustomTemplateView',
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    $stateRegistryProvider.register(root);
 | 
			
		||||
    $stateRegistryProvider.register(endpointRoot);
 | 
			
		||||
    $stateRegistryProvider.register(portainer);
 | 
			
		||||
    $stateRegistryProvider.register(about);
 | 
			
		||||
    $stateRegistryProvider.register(account);
 | 
			
		||||
| 
						 | 
				
			
			@ -578,9 +503,6 @@ angular.module('portainer.app', []).config([
 | 
			
		|||
    $stateRegistryProvider.register(registryCreation);
 | 
			
		||||
    $stateRegistryProvider.register(settings);
 | 
			
		||||
    $stateRegistryProvider.register(settingsAuthentication);
 | 
			
		||||
    $stateRegistryProvider.register(stacks);
 | 
			
		||||
    $stateRegistryProvider.register(stack);
 | 
			
		||||
    $stateRegistryProvider.register(stackCreation);
 | 
			
		||||
    $stateRegistryProvider.register(support);
 | 
			
		||||
    $stateRegistryProvider.register(supportProduct);
 | 
			
		||||
    $stateRegistryProvider.register(tags);
 | 
			
		||||
| 
						 | 
				
			
			@ -588,9 +510,5 @@ angular.module('portainer.app', []).config([
 | 
			
		|||
    $stateRegistryProvider.register(user);
 | 
			
		||||
    $stateRegistryProvider.register(teams);
 | 
			
		||||
    $stateRegistryProvider.register(team);
 | 
			
		||||
    $stateRegistryProvider.register(templates);
 | 
			
		||||
    $stateRegistryProvider.register(customTemplates);
 | 
			
		||||
    $stateRegistryProvider.register(customTemplatesNew);
 | 
			
		||||
    $stateRegistryProvider.register(customTemplatesEdit);
 | 
			
		||||
  },
 | 
			
		||||
]);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,7 +52,7 @@
 | 
			
		|||
        >
 | 
			
		||||
          <i class="fa fa-trash-alt space-right" aria-hidden="true"></i>Remove
 | 
			
		||||
        </button>
 | 
			
		||||
        <button type="button" class="btn btn-sm btn-primary" ui-sref="portainer.stacks.newstack" authorization="PortainerStackCreate">
 | 
			
		||||
        <button type="button" class="btn btn-sm btn-primary" ui-sref="docker.stacks.newstack" authorization="PortainerStackCreate">
 | 
			
		||||
          <i class="fa fa-plus space-right" aria-hidden="true"></i>Add stack
 | 
			
		||||
        </button>
 | 
			
		||||
      </div>
 | 
			
		||||
| 
						 | 
				
			
			@ -110,7 +110,7 @@
 | 
			
		|||
                  <input id="select_{{ $index }}" type="checkbox" ng-model="item.Checked" ng-click="$ctrl.selectItem(item, $event)" ng-disabled="!$ctrl.allowSelection(item)" />
 | 
			
		||||
                  <label for="select_{{ $index }}"></label>
 | 
			
		||||
                </span>
 | 
			
		||||
                <a ng-if="!$ctrl.offlineMode" ui-sref="portainer.stacks.stack({ name: item.Name, id: item.Id, type: item.Type, external: item.External })">{{ item.Name }}</a>
 | 
			
		||||
                <a ng-if="!$ctrl.offlineMode" ui-sref="docker.stacks.stack({ name: item.Name, id: item.Id, type: item.Type, external: item.External })">{{ item.Name }}</a>
 | 
			
		||||
                <span ng-if="$ctrl.offlineMode">{{ item.Name }}</span>
 | 
			
		||||
              </td>
 | 
			
		||||
              <td>{{ item.Type === 1 ? 'Swarm' : 'Compose' }}</td>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,7 +7,7 @@
 | 
			
		|||
 | 
			
		||||
      <div class="actionBar">
 | 
			
		||||
        <div>
 | 
			
		||||
          <button type="button" class="btn btn-sm btn-primary" ui-sref="portainer.templates.new" ng-if="$ctrl.showAddAction">
 | 
			
		||||
          <button type="button" class="btn btn-sm btn-primary" ui-sref="docker.templates.new" ng-if="$ctrl.showAddAction">
 | 
			
		||||
            <i class="fa fa-plus space-right" aria-hidden="true"></i>Add template
 | 
			
		||||
          </button>
 | 
			
		||||
          <span ng-class="{ 'pull-right': $ctrl.showAddAction }" style="width: 25%;">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -181,9 +181,11 @@ angular.module('portainer.app').factory('StateManager', [
 | 
			
		|||
        return deferred.promise;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const reload = endpoint.Status === 1 || !endpoint.Snaphosts || !endpoint.Snaphosts.length || !endpoint.Snapshots[0].SnapshotRaw;
 | 
			
		||||
 | 
			
		||||
      $q.all({
 | 
			
		||||
        version: endpoint.Status === 1 ? SystemService.version() : $q.when(endpoint.Snapshots[0].SnapshotRaw.Version),
 | 
			
		||||
        info: endpoint.Status === 1 ? SystemService.info() : $q.when(endpoint.Snapshots[0].SnapshotRaw.Info),
 | 
			
		||||
        version: reload ? SystemService.version() : $q.when(endpoint.Snapshots[0].SnapshotRaw.Version),
 | 
			
		||||
        info: reload ? SystemService.info() : $q.when(endpoint.Snapshots[0].SnapshotRaw.Info),
 | 
			
		||||
      })
 | 
			
		||||
        .then(function success(data) {
 | 
			
		||||
          var endpointMode = InfoHelper.determineEndpointMode(data.info, endpoint.Type);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,11 +12,8 @@ angular
 | 
			
		|||
    Notifications,
 | 
			
		||||
    EndpointProvider,
 | 
			
		||||
    StateManager,
 | 
			
		||||
    LegacyExtensionManager,
 | 
			
		||||
    ModalService,
 | 
			
		||||
    MotdService,
 | 
			
		||||
    SystemService,
 | 
			
		||||
    KubernetesHealthService
 | 
			
		||||
    MotdService
 | 
			
		||||
  ) {
 | 
			
		||||
    $scope.state = {
 | 
			
		||||
      connectingToEdgeEndpoint: false,
 | 
			
		||||
| 
						 | 
				
			
			@ -28,23 +25,21 @@ angular
 | 
			
		|||
 | 
			
		||||
    $scope.goToDashboard = function (endpoint) {
 | 
			
		||||
      if (endpoint.Type === 3) {
 | 
			
		||||
        return switchToAzureEndpoint(endpoint);
 | 
			
		||||
      } else if (endpoint.Type === 4) {
 | 
			
		||||
        return switchToEdgeEndpoint(endpoint);
 | 
			
		||||
      } else if (endpoint.Type === 5 || endpoint.Type === 6) {
 | 
			
		||||
        return switchToKubernetesEndpoint(endpoint);
 | 
			
		||||
      } else if (endpoint.Type === 7) {
 | 
			
		||||
        return switchToKubernetesEdgeEndpoint(endpoint);
 | 
			
		||||
        $state.go('azure.dashboard', { endpointId: endpoint.Id });
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      checkEndpointStatus(endpoint)
 | 
			
		||||
        .then(function success(data) {
 | 
			
		||||
          endpoint = data;
 | 
			
		||||
          return switchToDockerEndpoint(endpoint);
 | 
			
		||||
        })
 | 
			
		||||
        .catch(function error(err) {
 | 
			
		||||
          Notifications.error('Failure', err, 'Unable to verify endpoint status');
 | 
			
		||||
        });
 | 
			
		||||
      if (endpoint.Type === 4 || endpoint.Type === 7) {
 | 
			
		||||
        if (!endpoint.EdgeID) {
 | 
			
		||||
          $state.go('portainer.endpoints.endpoint', { id: endpoint.Id });
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
        $scope.state.connectingToEdgeEndpoint = true;
 | 
			
		||||
      }
 | 
			
		||||
      if (endpoint.Type === 5 || endpoint.Type === 6 || endpoint.Type === 7) {
 | 
			
		||||
        $state.go('kubernetes.dashboard', { endpointId: endpoint.Id });
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      $state.go('docker.dashboard', { endpointId: endpoint.Id });
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    $scope.dismissImportantInformation = function (hash) {
 | 
			
		||||
| 
						 | 
				
			
			@ -64,130 +59,6 @@ angular
 | 
			
		|||
      });
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    function checkEndpointStatus(endpoint) {
 | 
			
		||||
      var deferred = $q.defer();
 | 
			
		||||
 | 
			
		||||
      var status = 1;
 | 
			
		||||
      SystemService.ping(endpoint.Id)
 | 
			
		||||
        .then(function success() {
 | 
			
		||||
          status = 1;
 | 
			
		||||
        })
 | 
			
		||||
        .catch(function error() {
 | 
			
		||||
          status = 2;
 | 
			
		||||
        })
 | 
			
		||||
        .finally(function () {
 | 
			
		||||
          if (endpoint.Status === status) {
 | 
			
		||||
            deferred.resolve(endpoint);
 | 
			
		||||
            return deferred.promise;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          EndpointService.updateEndpoint(endpoint.Id, { Status: status })
 | 
			
		||||
            .then(function success() {
 | 
			
		||||
              endpoint.Status = status;
 | 
			
		||||
              deferred.resolve(endpoint);
 | 
			
		||||
            })
 | 
			
		||||
            .catch(function error(err) {
 | 
			
		||||
              deferred.reject({ msg: 'Unable to update endpoint status', err: err });
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
      return deferred.promise;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function switchToAzureEndpoint(endpoint) {
 | 
			
		||||
      EndpointProvider.setEndpointID(endpoint.Id);
 | 
			
		||||
      EndpointProvider.setEndpointPublicURL(endpoint.PublicURL);
 | 
			
		||||
      EndpointProvider.setOfflineModeFromStatus(endpoint.Status);
 | 
			
		||||
      StateManager.updateEndpointState(endpoint, [])
 | 
			
		||||
        .then(function success() {
 | 
			
		||||
          $state.go('azure.dashboard');
 | 
			
		||||
        })
 | 
			
		||||
        .catch(function error(err) {
 | 
			
		||||
          Notifications.error('Failure', err, 'Unable to connect to the Azure endpoint');
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function switchToKubernetesEndpoint(endpoint) {
 | 
			
		||||
      EndpointProvider.setEndpointID(endpoint.Id);
 | 
			
		||||
      StateManager.updateEndpointState(endpoint, [])
 | 
			
		||||
        .then(function success() {
 | 
			
		||||
          $state.go('kubernetes.dashboard');
 | 
			
		||||
        })
 | 
			
		||||
        .catch(function error(err) {
 | 
			
		||||
          Notifications.error('Failure', err, 'Unable to connect to the Kubernetes endpoint');
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function switchToEdgeEndpoint(endpoint) {
 | 
			
		||||
      if (!endpoint.EdgeID) {
 | 
			
		||||
        $state.go('portainer.endpoints.endpoint', { id: endpoint.Id });
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      $scope.state.connectingToEdgeEndpoint = true;
 | 
			
		||||
      SystemService.ping(endpoint.Id)
 | 
			
		||||
        .then(function success() {
 | 
			
		||||
          endpoint.Status = 1;
 | 
			
		||||
        })
 | 
			
		||||
        .catch(function error() {
 | 
			
		||||
          endpoint.Status = 2;
 | 
			
		||||
        })
 | 
			
		||||
        .finally(function final() {
 | 
			
		||||
          switchToDockerEndpoint(endpoint);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function switchToKubernetesEdgeEndpoint(endpoint) {
 | 
			
		||||
      if (!endpoint.EdgeID) {
 | 
			
		||||
        $state.go('portainer.endpoints.endpoint', { id: endpoint.Id });
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      EndpointProvider.setEndpointID(endpoint.Id);
 | 
			
		||||
      $scope.state.connectingToEdgeEndpoint = true;
 | 
			
		||||
      KubernetesHealthService.ping()
 | 
			
		||||
        .then(function success() {
 | 
			
		||||
          endpoint.Status = 1;
 | 
			
		||||
        })
 | 
			
		||||
        .catch(function error() {
 | 
			
		||||
          endpoint.Status = 2;
 | 
			
		||||
        })
 | 
			
		||||
        .finally(function final() {
 | 
			
		||||
          switchToKubernetesEndpoint(endpoint);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function switchToDockerEndpoint(endpoint) {
 | 
			
		||||
      if (endpoint.Status === 2 && endpoint.Snapshots[0] && endpoint.Snapshots[0].Swarm === true) {
 | 
			
		||||
        $scope.state.connectingToEdgeEndpoint = false;
 | 
			
		||||
        Notifications.error('Failure', '', 'Endpoint is unreachable. Connect to another swarm manager.');
 | 
			
		||||
        return;
 | 
			
		||||
      } else if (endpoint.Status === 2 && !endpoint.Snapshots[0]) {
 | 
			
		||||
        $scope.state.connectingToEdgeEndpoint = false;
 | 
			
		||||
        Notifications.error('Failure', '', 'Endpoint is unreachable and there is no snapshot available for offline browsing.');
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      EndpointProvider.setEndpointID(endpoint.Id);
 | 
			
		||||
      EndpointProvider.setEndpointPublicURL(endpoint.PublicURL);
 | 
			
		||||
      EndpointProvider.setOfflineModeFromStatus(endpoint.Status);
 | 
			
		||||
      LegacyExtensionManager.initEndpointExtensions(endpoint)
 | 
			
		||||
        .then(function success(data) {
 | 
			
		||||
          var extensions = data;
 | 
			
		||||
          return StateManager.updateEndpointState(endpoint, extensions);
 | 
			
		||||
        })
 | 
			
		||||
        .then(function success() {
 | 
			
		||||
          $state.go('docker.dashboard');
 | 
			
		||||
        })
 | 
			
		||||
        .catch(function error(err) {
 | 
			
		||||
          Notifications.error('Failure', err, 'Unable to connect to the Docker endpoint');
 | 
			
		||||
          $state.reload();
 | 
			
		||||
        })
 | 
			
		||||
        .finally(function final() {
 | 
			
		||||
          $scope.state.connectingToEdgeEndpoint = false;
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function triggerSnapshot() {
 | 
			
		||||
      EndpointService.snapshotEndpoints()
 | 
			
		||||
        .then(function success() {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,7 +14,6 @@ angular
 | 
			
		|||
    FormValidator,
 | 
			
		||||
    ResourceControlService,
 | 
			
		||||
    FormHelper,
 | 
			
		||||
    EndpointProvider,
 | 
			
		||||
    CustomTemplateService
 | 
			
		||||
  ) {
 | 
			
		||||
    $scope.formValues = {
 | 
			
		||||
| 
						 | 
				
			
			@ -60,7 +59,7 @@ angular
 | 
			
		|||
 | 
			
		||||
    function createSwarmStack(name, method) {
 | 
			
		||||
      var env = FormHelper.removeInvalidEnvVars($scope.formValues.Env);
 | 
			
		||||
      var endpointId = EndpointProvider.endpointID();
 | 
			
		||||
      const endpointId = +$state.params.endpointId;
 | 
			
		||||
 | 
			
		||||
      if (method === 'template' || method === 'editor') {
 | 
			
		||||
        var stackFileContent = $scope.formValues.StackFileContent;
 | 
			
		||||
| 
						 | 
				
			
			@ -87,7 +86,7 @@ angular
 | 
			
		|||
 | 
			
		||||
    function createComposeStack(name, method) {
 | 
			
		||||
      var env = FormHelper.removeInvalidEnvVars($scope.formValues.Env);
 | 
			
		||||
      var endpointId = EndpointProvider.endpointID();
 | 
			
		||||
      const endpointId = +$state.params.endpointId;
 | 
			
		||||
 | 
			
		||||
      if (method === 'editor' || method === 'template') {
 | 
			
		||||
        var stackFileContent = $scope.formValues.StackFileContent;
 | 
			
		||||
| 
						 | 
				
			
			@ -142,7 +141,7 @@ angular
 | 
			
		|||
        })
 | 
			
		||||
        .then(function success() {
 | 
			
		||||
          Notifications.success('Stack successfully deployed');
 | 
			
		||||
          $state.go('portainer.stacks');
 | 
			
		||||
          $state.go('docker.stacks');
 | 
			
		||||
        })
 | 
			
		||||
        .catch(function error(err) {
 | 
			
		||||
          Notifications.error('Deployment error', err, 'Unable to deploy stack');
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<rd-header>
 | 
			
		||||
  <rd-header-title title-text="Create stack"></rd-header-title>
 | 
			
		||||
  <rd-header-content> <a ui-sref="portainer.stacks">Stacks</a> > Add stack </rd-header-content>
 | 
			
		||||
  <rd-header-content> <a ui-sref="docker.stacks">Stacks</a> > Add stack </rd-header-content>
 | 
			
		||||
</rd-header>
 | 
			
		||||
 | 
			
		||||
<div class="row">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,10 +1,10 @@
 | 
			
		|||
<rd-header>
 | 
			
		||||
  <rd-header-title title-text="Stack details">
 | 
			
		||||
    <a data-toggle="tooltip" title-text="Refresh" ui-sref="portainer.stacks.stack({id: stack.Id})" ui-sref-opts="{reload: true}">
 | 
			
		||||
    <a data-toggle="tooltip" title-text="Refresh" ui-sref="docker.stacks.stack({id: stack.Id})" ui-sref-opts="{reload: true}">
 | 
			
		||||
      <i class="fa fa-sync" aria-hidden="true"></i>
 | 
			
		||||
    </a>
 | 
			
		||||
  </rd-header-title>
 | 
			
		||||
  <rd-header-content> <a ui-sref="portainer.stacks">Stacks</a> > {{ stackName }} </rd-header-content>
 | 
			
		||||
  <rd-header-content> <a ui-sref="docker.stacks">Stacks</a> > {{ stackName }} </rd-header-content>
 | 
			
		||||
</rd-header>
 | 
			
		||||
 | 
			
		||||
<div class="row">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -56,7 +56,7 @@ angular.module('portainer.app').controller('StackController', [
 | 
			
		|||
 | 
			
		||||
      function onDuplicationSuccess() {
 | 
			
		||||
        Notifications.success('Stack successfully duplicated');
 | 
			
		||||
        $state.go('portainer.stacks', {}, { reload: true });
 | 
			
		||||
        $state.go('docker.stacks', {}, { reload: true });
 | 
			
		||||
        EndpointProvider.setEndpointID(stack.EndpointId);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -122,7 +122,7 @@ angular.module('portainer.app').controller('StackController', [
 | 
			
		|||
      return migrateRequest(stack, targetEndpointId, name)
 | 
			
		||||
        .then(function success() {
 | 
			
		||||
          Notifications.success('Stack successfully migrated', stack.Name);
 | 
			
		||||
          $state.go('portainer.stacks', {}, { reload: true });
 | 
			
		||||
          $state.go('docker.stacks', {}, { reload: true });
 | 
			
		||||
        })
 | 
			
		||||
        .catch(function error(err) {
 | 
			
		||||
          Notifications.error('Failure', err, 'Unable to migrate stack');
 | 
			
		||||
| 
						 | 
				
			
			@ -133,13 +133,13 @@ angular.module('portainer.app').controller('StackController', [
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    function deleteStack() {
 | 
			
		||||
      var endpointId = EndpointProvider.endpointID();
 | 
			
		||||
      var endpointId = +$state.params.endpointId;
 | 
			
		||||
      var stack = $scope.stack;
 | 
			
		||||
 | 
			
		||||
      StackService.remove(stack, $transition$.params().external, endpointId)
 | 
			
		||||
        .then(function success() {
 | 
			
		||||
          Notifications.success('Stack successfully removed', stack.Name);
 | 
			
		||||
          $state.go('portainer.stacks');
 | 
			
		||||
          $state.go('docker.stacks');
 | 
			
		||||
        })
 | 
			
		||||
        .catch(function error(err) {
 | 
			
		||||
          Notifications.error('Failure', err, 'Unable to remove stack ' + stack.Name);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<rd-header>
 | 
			
		||||
  <rd-header-title title-text="Stacks list">
 | 
			
		||||
    <a data-toggle="tooltip" title="Refresh" ui-sref="portainer.stacks" ui-sref-opts="{reload: true}">
 | 
			
		||||
    <a data-toggle="tooltip" title="Refresh" ui-sref="docker.stacks" ui-sref-opts="{reload: true}">
 | 
			
		||||
      <i class="fa fa-sync" aria-hidden="true"></i>
 | 
			
		||||
    </a>
 | 
			
		||||
  </rd-header-title>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<rd-header id="view-top">
 | 
			
		||||
  <rd-header-title title-text="Application templates list">
 | 
			
		||||
    <a data-toggle="tooltip" title="Refresh" ui-sref="portainer.templates" ui-sref-opts="{reload: true}">
 | 
			
		||||
    <a data-toggle="tooltip" title="Refresh" ui-sref="docker.templates" ui-sref-opts="{reload: true}">
 | 
			
		||||
      <i class="fa fa-sync" aria-hidden="true"></i>
 | 
			
		||||
    </a>
 | 
			
		||||
  </rd-header-title>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,7 +5,6 @@ angular.module('portainer.app').controller('TemplatesController', [
 | 
			
		|||
  '$scope',
 | 
			
		||||
  '$q',
 | 
			
		||||
  '$state',
 | 
			
		||||
  '$transition$',
 | 
			
		||||
  '$anchorScroll',
 | 
			
		||||
  'ContainerService',
 | 
			
		||||
  'ImageService',
 | 
			
		||||
| 
						 | 
				
			
			@ -19,12 +18,10 @@ angular.module('portainer.app').controller('TemplatesController', [
 | 
			
		|||
  'FormValidator',
 | 
			
		||||
  'SettingsService',
 | 
			
		||||
  'StackService',
 | 
			
		||||
  'EndpointProvider',
 | 
			
		||||
  function (
 | 
			
		||||
    $scope,
 | 
			
		||||
    $q,
 | 
			
		||||
    $state,
 | 
			
		||||
    $transition$,
 | 
			
		||||
    $anchorScroll,
 | 
			
		||||
    ContainerService,
 | 
			
		||||
    ImageService,
 | 
			
		||||
| 
						 | 
				
			
			@ -37,8 +34,7 @@ angular.module('portainer.app').controller('TemplatesController', [
 | 
			
		|||
    Authentication,
 | 
			
		||||
    FormValidator,
 | 
			
		||||
    SettingsService,
 | 
			
		||||
    StackService,
 | 
			
		||||
    EndpointProvider
 | 
			
		||||
    StackService
 | 
			
		||||
  ) {
 | 
			
		||||
    $scope.state = {
 | 
			
		||||
      selectedTemplate: null,
 | 
			
		||||
| 
						 | 
				
			
			@ -144,7 +140,7 @@ angular.module('portainer.app').controller('TemplatesController', [
 | 
			
		|||
        ComposeFilePathInRepository: template.Repository.stackfile,
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      var endpointId = EndpointProvider.endpointID();
 | 
			
		||||
      const endpointId = +$state.params.endpointId;
 | 
			
		||||
      StackService.createComposeStackFromGitRepository(stackName, repositoryOptions, template.Env, endpointId)
 | 
			
		||||
        .then(function success(data) {
 | 
			
		||||
          const resourceControl = data.ResourceControl;
 | 
			
		||||
| 
						 | 
				
			
			@ -152,7 +148,7 @@ angular.module('portainer.app').controller('TemplatesController', [
 | 
			
		|||
        })
 | 
			
		||||
        .then(function success() {
 | 
			
		||||
          Notifications.success('Stack successfully deployed');
 | 
			
		||||
          $state.go('portainer.stacks');
 | 
			
		||||
          $state.go('docker.stacks');
 | 
			
		||||
        })
 | 
			
		||||
        .catch(function error(err) {
 | 
			
		||||
          Notifications.warning('Deployment error', err.data.err);
 | 
			
		||||
| 
						 | 
				
			
			@ -181,7 +177,8 @@ angular.module('portainer.app').controller('TemplatesController', [
 | 
			
		|||
        ComposeFilePathInRepository: template.Repository.stackfile,
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      var endpointId = EndpointProvider.endpointID();
 | 
			
		||||
      const endpointId = +$state.params.endpointId;
 | 
			
		||||
 | 
			
		||||
      StackService.createSwarmStackFromGitRepository(stackName, repositoryOptions, env, endpointId)
 | 
			
		||||
        .then(function success(data) {
 | 
			
		||||
          const resourceControl = data.ResourceControl;
 | 
			
		||||
| 
						 | 
				
			
			@ -189,7 +186,7 @@ angular.module('portainer.app').controller('TemplatesController', [
 | 
			
		|||
        })
 | 
			
		||||
        .then(function success() {
 | 
			
		||||
          Notifications.success('Stack successfully deployed');
 | 
			
		||||
          $state.go('portainer.stacks');
 | 
			
		||||
          $state.go('docker.stacks');
 | 
			
		||||
        })
 | 
			
		||||
        .catch(function error(err) {
 | 
			
		||||
          Notifications.warning('Deployment error', err.data.err);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue