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 onEnter
pull/4029/head
Chaim Lev-Ari 2020-07-14 23:46:38 +03:00 committed by GitHub
parent 1b3e2c8f69
commit 3c34fbd8f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 245 additions and 316 deletions

View File

@ -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 = {

View File

@ -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);

View File

@ -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>

View File

@ -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;

View File

@ -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;

View File

@ -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">

View File

@ -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),

View File

@ -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 });
}
},
};

View File

@ -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);
},
]);

View File

@ -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>

View File

@ -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%;">

View File

@ -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);

View File

@ -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() {

View File

@ -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');

View File

@ -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> &gt; Add stack </rd-header-content>
<rd-header-content> <a ui-sref="docker.stacks">Stacks</a> &gt; Add stack </rd-header-content>
</rd-header>
<div class="row">

View File

@ -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> &gt; {{ stackName }} </rd-header-content>
<rd-header-content> <a ui-sref="docker.stacks">Stacks</a> &gt; {{ stackName }} </rd-header-content>
</rd-header>
<div class="row">

View File

@ -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);

View File

@ -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>

View File

@ -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>

View File

@ -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);