diff --git a/app/app.js b/app/app.js
index 3c31d9274..8325bd523 100644
--- a/app/app.js
+++ b/app/app.js
@@ -1,75 +1,75 @@
-angular.module('portainer.filters', []);
-angular.module('portainer.rest', ['ngResource']);
-angular.module('portainer.services', []);
-angular.module('portainer.helpers', []);
-angular.module('portainer', [
- 'ui.bootstrap',
- 'ui.router',
- 'ui.select',
- 'ngCookies',
- 'ngSanitize',
- 'ngFileUpload',
- 'angularUtils.directives.dirPagination',
- 'LocalStorageModule',
- 'angular-jwt',
- 'angular-google-analytics',
- 'portainer.templates',
- 'portainer.filters',
- 'portainer.rest',
- 'portainer.helpers',
- 'portainer.services',
- 'auth',
- 'dashboard',
- 'container',
- 'containerConsole',
- 'containerLogs',
- 'containers',
- 'createContainer',
- 'createNetwork',
- 'createService',
- 'createVolume',
- 'docker',
- 'endpoint',
- 'endpointInit',
- 'endpoints',
- 'events',
- 'image',
- 'images',
- 'main',
- 'network',
- 'networks',
- 'node',
- 'service',
- 'services',
- 'settings',
- 'sidebar',
- 'stats',
- 'swarm',
- 'task',
- 'templates',
- 'volumes'])
- .config(['$stateProvider', '$urlRouterProvider', '$httpProvider', 'localStorageServiceProvider', 'jwtOptionsProvider', 'AnalyticsProvider', function ($stateProvider, $urlRouterProvider, $httpProvider, localStorageServiceProvider, jwtOptionsProvider, AnalyticsProvider) {
- 'use strict';
-
- localStorageServiceProvider
- .setStorageType('sessionStorage')
- .setPrefix('portainer');
-
- jwtOptionsProvider.config({
- tokenGetter: ['LocalStorage', function(LocalStorage) {
- return LocalStorage.getJWT();
- }],
- unauthenticatedRedirector: ['$state', function($state) {
- $state.go('auth', {error: 'Your session has expired'});
- }]
- });
- $httpProvider.interceptors.push('jwtInterceptor');
-
- AnalyticsProvider.setAccount('@@CONFIG_GA_ID');
- AnalyticsProvider.startOffline(true);
-
- $urlRouterProvider.otherwise('/auth');
-
+angular.module('portainer.filters', []);
+angular.module('portainer.rest', ['ngResource']);
+angular.module('portainer.services', []);
+angular.module('portainer.helpers', []);
+angular.module('portainer', [
+ 'ui.bootstrap',
+ 'ui.router',
+ 'ui.select',
+ 'ngCookies',
+ 'ngSanitize',
+ 'ngFileUpload',
+ 'angularUtils.directives.dirPagination',
+ 'LocalStorageModule',
+ 'angular-jwt',
+ 'angular-google-analytics',
+ 'portainer.templates',
+ 'portainer.filters',
+ 'portainer.rest',
+ 'portainer.helpers',
+ 'portainer.services',
+ 'auth',
+ 'dashboard',
+ 'container',
+ 'containerConsole',
+ 'containerLogs',
+ 'containers',
+ 'createContainer',
+ 'createNetwork',
+ 'createService',
+ 'createVolume',
+ 'docker',
+ 'endpoint',
+ 'endpointInit',
+ 'endpoints',
+ 'events',
+ 'image',
+ 'images',
+ 'main',
+ 'network',
+ 'networks',
+ 'node',
+ 'service',
+ 'services',
+ 'settings',
+ 'sidebar',
+ 'stats',
+ 'swarm',
+ 'task',
+ 'templates',
+ 'volumes'])
+ .config(['$stateProvider', '$urlRouterProvider', '$httpProvider', 'localStorageServiceProvider', 'jwtOptionsProvider', 'AnalyticsProvider', function ($stateProvider, $urlRouterProvider, $httpProvider, localStorageServiceProvider, jwtOptionsProvider, AnalyticsProvider) {
+ 'use strict';
+
+ localStorageServiceProvider
+ .setStorageType('sessionStorage')
+ .setPrefix('portainer');
+
+ jwtOptionsProvider.config({
+ tokenGetter: ['LocalStorage', function(LocalStorage) {
+ return LocalStorage.getJWT();
+ }],
+ unauthenticatedRedirector: ['$state', function($state) {
+ $state.go('auth', {error: 'Your session has expired'});
+ }]
+ });
+ $httpProvider.interceptors.push('jwtInterceptor');
+
+ AnalyticsProvider.setAccount('@@CONFIG_GA_ID');
+ AnalyticsProvider.startOffline(true);
+
+ $urlRouterProvider.otherwise('/auth');
+
$stateProvider
.state('root', {
abstract: true,
@@ -83,444 +83,444 @@ angular.module('portainer', [
.state('auth', {
parent: 'root',
url: '/auth',
- params: {
- logout: false,
- error: ''
- },
- views: {
- "content@": {
- templateUrl: 'app/components/auth/auth.html',
- controller: 'AuthenticationController'
- }
- },
- data: {
- requiresLogin: false
- }
- })
- .state('containers', {
- parent: 'root',
- url: '/containers/',
- views: {
- "content@": {
- templateUrl: 'app/components/containers/containers.html',
- controller: 'ContainersController'
- },
- "sidebar@": {
- templateUrl: 'app/components/sidebar/sidebar.html',
- controller: 'SidebarController'
- }
- }
- })
- .state('container', {
- url: "^/containers/:id",
- views: {
- "content@": {
- templateUrl: 'app/components/container/container.html',
- controller: 'ContainerController'
- },
- "sidebar@": {
- templateUrl: 'app/components/sidebar/sidebar.html',
- controller: 'SidebarController'
- }
- }
- })
- .state('stats', {
- url: "^/containers/:id/stats",
- views: {
- "content@": {
- templateUrl: 'app/components/stats/stats.html',
- controller: 'StatsController'
- },
- "sidebar@": {
- templateUrl: 'app/components/sidebar/sidebar.html',
- controller: 'SidebarController'
- }
- }
- })
- .state('logs', {
- url: "^/containers/:id/logs",
- views: {
- "content@": {
- templateUrl: 'app/components/containerLogs/containerlogs.html',
- controller: 'ContainerLogsController'
- },
- "sidebar@": {
- templateUrl: 'app/components/sidebar/sidebar.html',
- controller: 'SidebarController'
- }
- }
- })
- .state('console', {
- url: "^/containers/:id/console",
- views: {
- "content@": {
- templateUrl: 'app/components/containerConsole/containerConsole.html',
- controller: 'ContainerConsoleController'
- },
- "sidebar@": {
- templateUrl: 'app/components/sidebar/sidebar.html',
- controller: 'SidebarController'
- }
- }
- })
- .state('dashboard', {
- parent: 'root',
- url: '/dashboard',
- views: {
- "content@": {
- templateUrl: 'app/components/dashboard/dashboard.html',
- controller: 'DashboardController'
- },
- "sidebar@": {
- templateUrl: 'app/components/sidebar/sidebar.html',
- controller: 'SidebarController'
- }
- }
- })
- .state('actions', {
- abstract: true,
- url: "/actions",
- views: {
- "content@": {
- template: '
'
- },
- "sidebar@": {
- template: ''
- }
- }
- })
- .state('actions.create', {
- abstract: true,
- url: "/create",
- views: {
- "content@": {
- template: ''
- },
- "sidebar@": {
- template: ''
- }
- }
- })
- .state('actions.create.container', {
- url: "/container",
- views: {
- "content@": {
- templateUrl: 'app/components/createContainer/createcontainer.html',
- controller: 'CreateContainerController'
- },
- "sidebar@": {
- templateUrl: 'app/components/sidebar/sidebar.html',
- controller: 'SidebarController'
- }
- }
- })
- .state('actions.create.network', {
- url: "/network",
- views: {
- "content@": {
- templateUrl: 'app/components/createNetwork/createnetwork.html',
- controller: 'CreateNetworkController'
- },
- "sidebar@": {
- templateUrl: 'app/components/sidebar/sidebar.html',
- controller: 'SidebarController'
- }
- }
- })
- .state('actions.create.service', {
- url: "/service",
- views: {
- "content@": {
- templateUrl: 'app/components/createService/createservice.html',
- controller: 'CreateServiceController'
- },
- "sidebar@": {
- templateUrl: 'app/components/sidebar/sidebar.html',
- controller: 'SidebarController'
- }
- }
- })
- .state('actions.create.volume', {
- url: "/volume",
- views: {
- "content@": {
- templateUrl: 'app/components/createVolume/createvolume.html',
- controller: 'CreateVolumeController'
- },
- "sidebar@": {
- templateUrl: 'app/components/sidebar/sidebar.html',
- controller: 'SidebarController'
- }
- }
- })
- .state('docker', {
- url: '/docker/',
- views: {
- "content@": {
- templateUrl: 'app/components/docker/docker.html',
- controller: 'DockerController'
- },
- "sidebar@": {
- templateUrl: 'app/components/sidebar/sidebar.html',
- controller: 'SidebarController'
- }
- }
- })
- .state('endpoints', {
- url: '/endpoints/',
- views: {
- "content@": {
- templateUrl: 'app/components/endpoints/endpoints.html',
- controller: 'EndpointsController'
- },
- "sidebar@": {
- templateUrl: 'app/components/sidebar/sidebar.html',
- controller: 'SidebarController'
- }
- }
- })
- .state('endpoint', {
- url: '^/endpoints/:id',
- views: {
- "content@": {
- templateUrl: 'app/components/endpoint/endpoint.html',
- controller: 'EndpointController'
- },
- "sidebar@": {
- templateUrl: 'app/components/sidebar/sidebar.html',
- controller: 'SidebarController'
- }
- }
- })
- .state('endpointInit', {
- url: '/init/endpoint',
- views: {
- "content@": {
- templateUrl: 'app/components/endpointInit/endpointInit.html',
- controller: 'EndpointInitController'
- }
- }
- })
- .state('events', {
- url: '/events/',
- views: {
- "content@": {
- templateUrl: 'app/components/events/events.html',
- controller: 'EventsController'
- },
- "sidebar@": {
- templateUrl: 'app/components/sidebar/sidebar.html',
- controller: 'SidebarController'
- }
- }
- })
- .state('images', {
- url: '/images/',
- views: {
- "content@": {
- templateUrl: 'app/components/images/images.html',
- controller: 'ImagesController'
- },
- "sidebar@": {
- templateUrl: 'app/components/sidebar/sidebar.html',
- controller: 'SidebarController'
- }
- }
- })
- .state('image', {
- url: '^/images/:id/',
- views: {
- "content@": {
- templateUrl: 'app/components/image/image.html',
- controller: 'ImageController'
- },
- "sidebar@": {
- templateUrl: 'app/components/sidebar/sidebar.html',
- controller: 'SidebarController'
- }
- }
- })
- .state('networks', {
- url: '/networks/',
- views: {
- "content@": {
- templateUrl: 'app/components/networks/networks.html',
- controller: 'NetworksController'
- },
- "sidebar@": {
- templateUrl: 'app/components/sidebar/sidebar.html',
- controller: 'SidebarController'
- }
- }
- })
- .state('network', {
- url: '^/networks/:id/',
- views: {
- "content@": {
- templateUrl: 'app/components/network/network.html',
- controller: 'NetworkController'
- },
- "sidebar@": {
- templateUrl: 'app/components/sidebar/sidebar.html',
- controller: 'SidebarController'
- }
- }
- })
- .state('node', {
- url: '^/nodes/:id/',
- views: {
- "content@": {
- templateUrl: 'app/components/node/node.html',
- controller: 'NodeController'
- },
- "sidebar@": {
- templateUrl: 'app/components/sidebar/sidebar.html',
- controller: 'SidebarController'
- }
- }
- })
- .state('services', {
- url: '/services/',
- views: {
- "content@": {
- templateUrl: 'app/components/services/services.html',
- controller: 'ServicesController'
- },
- "sidebar@": {
- templateUrl: 'app/components/sidebar/sidebar.html',
- controller: 'SidebarController'
- }
- }
- })
- .state('service', {
- url: '^/service/:id/',
- views: {
- "content@": {
- templateUrl: 'app/components/service/service.html',
- controller: 'ServiceController'
- },
- "sidebar@": {
- templateUrl: 'app/components/sidebar/sidebar.html',
- controller: 'SidebarController'
- }
- }
- })
- .state('settings', {
- url: '/settings/',
- views: {
- "content@": {
- templateUrl: 'app/components/settings/settings.html',
- controller: 'SettingsController'
- },
- "sidebar@": {
- templateUrl: 'app/components/sidebar/sidebar.html',
- controller: 'SidebarController'
- }
- }
- })
- .state('task', {
- url: '^/task/:id',
- views: {
- "content@": {
- templateUrl: 'app/components/task/task.html',
- controller: 'TaskController'
- },
- "sidebar@": {
- templateUrl: 'app/components/sidebar/sidebar.html',
- controller: 'SidebarController'
- }
- }
- })
- .state('templates', {
- url: '/templates/',
- views: {
- "content@": {
- templateUrl: 'app/components/templates/templates.html',
- controller: 'TemplatesController'
- },
- "sidebar@": {
- templateUrl: 'app/components/sidebar/sidebar.html',
- controller: 'SidebarController'
- }
- }
- })
- .state('volumes', {
- url: '/volumes/',
- views: {
- "content@": {
- templateUrl: 'app/components/volumes/volumes.html',
- controller: 'VolumesController'
- },
- "sidebar@": {
- templateUrl: 'app/components/sidebar/sidebar.html',
- controller: 'SidebarController'
- }
- }
- })
- .state('swarm', {
- url: '/swarm/',
- views: {
- "content@": {
- templateUrl: 'app/components/swarm/swarm.html',
- controller: 'SwarmController'
- },
- "sidebar@": {
- templateUrl: 'app/components/sidebar/sidebar.html',
- controller: 'SidebarController'
- }
- }
- });
-
- // The Docker API likes to return plaintext errors, this catches them and disp
- $httpProvider.interceptors.push(function() {
- return {
- 'response': function(response) {
- if (typeof(response.data) === 'string' &&
- (response.data.startsWith('Conflict.') || response.data.startsWith('conflict:'))) {
- $.gritter.add({
- title: 'Error',
- text: $('').text(response.data).html(),
- time: 10000
- });
- }
- return response;
- }
- };
- });
- }])
- .run(['$rootScope', '$state', 'Authentication', 'authManager', 'StateManager', 'Messages', 'Analytics', function ($rootScope, $state, Authentication, authManager, StateManager, Messages, Analytics) {
- StateManager.initialize().then(function success(state) {
- if (state.application.authentication) {
- authManager.checkAuthOnRefresh();
- authManager.redirectWhenUnauthenticated();
- Authentication.init();
- $rootScope.$on('tokenHasExpired', function($state) {
- $state.go('auth', {error: 'Your session has expired'});
- });
- }
- if (state.application.analytics) {
- Analytics.offline(false);
- Analytics.registerScriptTags();
- Analytics.registerTrackers();
- $rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) {
- Analytics.trackPage(toState.url);
- Analytics.pageView();
- });
- }
- }, function error(err) {
- Messages.error("Failure", err, 'Unable to retrieve application settings');
- });
-
- $rootScope.$state = $state;
- }])
- // This is your docker url that the api will use to make requests
- // You need to set this to the api endpoint without the port i.e. http://192.168.1.9
- .constant('DOCKER_PORT', '') // Docker port, leave as an empty string if no port is required. If you have a port, prefix it with a ':' i.e. :4243
- .constant('DOCKER_ENDPOINT', 'api/docker')
- .constant('CONFIG_ENDPOINT', 'api/settings')
+ params: {
+ logout: false,
+ error: ''
+ },
+ views: {
+ "content@": {
+ templateUrl: 'app/components/auth/auth.html',
+ controller: 'AuthenticationController'
+ }
+ },
+ data: {
+ requiresLogin: false
+ }
+ })
+ .state('containers', {
+ parent: 'root',
+ url: '/containers/',
+ views: {
+ "content@": {
+ templateUrl: 'app/components/containers/containers.html',
+ controller: 'ContainersController'
+ },
+ "sidebar@": {
+ templateUrl: 'app/components/sidebar/sidebar.html',
+ controller: 'SidebarController'
+ }
+ }
+ })
+ .state('container', {
+ url: "^/containers/:id",
+ views: {
+ "content@": {
+ templateUrl: 'app/components/container/container.html',
+ controller: 'ContainerController'
+ },
+ "sidebar@": {
+ templateUrl: 'app/components/sidebar/sidebar.html',
+ controller: 'SidebarController'
+ }
+ }
+ })
+ .state('stats', {
+ url: "^/containers/:id/stats",
+ views: {
+ "content@": {
+ templateUrl: 'app/components/stats/stats.html',
+ controller: 'StatsController'
+ },
+ "sidebar@": {
+ templateUrl: 'app/components/sidebar/sidebar.html',
+ controller: 'SidebarController'
+ }
+ }
+ })
+ .state('logs', {
+ url: "^/containers/:id/logs",
+ views: {
+ "content@": {
+ templateUrl: 'app/components/containerLogs/containerlogs.html',
+ controller: 'ContainerLogsController'
+ },
+ "sidebar@": {
+ templateUrl: 'app/components/sidebar/sidebar.html',
+ controller: 'SidebarController'
+ }
+ }
+ })
+ .state('console', {
+ url: "^/containers/:id/console",
+ views: {
+ "content@": {
+ templateUrl: 'app/components/containerConsole/containerConsole.html',
+ controller: 'ContainerConsoleController'
+ },
+ "sidebar@": {
+ templateUrl: 'app/components/sidebar/sidebar.html',
+ controller: 'SidebarController'
+ }
+ }
+ })
+ .state('dashboard', {
+ parent: 'root',
+ url: '/dashboard',
+ views: {
+ "content@": {
+ templateUrl: 'app/components/dashboard/dashboard.html',
+ controller: 'DashboardController'
+ },
+ "sidebar@": {
+ templateUrl: 'app/components/sidebar/sidebar.html',
+ controller: 'SidebarController'
+ }
+ }
+ })
+ .state('actions', {
+ abstract: true,
+ url: "/actions",
+ views: {
+ "content@": {
+ template: '
'
+ },
+ "sidebar@": {
+ template: '
'
+ }
+ }
+ })
+ .state('actions.create', {
+ abstract: true,
+ url: "/create",
+ views: {
+ "content@": {
+ template: '
'
+ },
+ "sidebar@": {
+ template: '
'
+ }
+ }
+ })
+ .state('actions.create.container', {
+ url: "/container",
+ views: {
+ "content@": {
+ templateUrl: 'app/components/createContainer/createcontainer.html',
+ controller: 'CreateContainerController'
+ },
+ "sidebar@": {
+ templateUrl: 'app/components/sidebar/sidebar.html',
+ controller: 'SidebarController'
+ }
+ }
+ })
+ .state('actions.create.network', {
+ url: "/network",
+ views: {
+ "content@": {
+ templateUrl: 'app/components/createNetwork/createnetwork.html',
+ controller: 'CreateNetworkController'
+ },
+ "sidebar@": {
+ templateUrl: 'app/components/sidebar/sidebar.html',
+ controller: 'SidebarController'
+ }
+ }
+ })
+ .state('actions.create.service', {
+ url: "/service",
+ views: {
+ "content@": {
+ templateUrl: 'app/components/createService/createservice.html',
+ controller: 'CreateServiceController'
+ },
+ "sidebar@": {
+ templateUrl: 'app/components/sidebar/sidebar.html',
+ controller: 'SidebarController'
+ }
+ }
+ })
+ .state('actions.create.volume', {
+ url: "/volume",
+ views: {
+ "content@": {
+ templateUrl: 'app/components/createVolume/createvolume.html',
+ controller: 'CreateVolumeController'
+ },
+ "sidebar@": {
+ templateUrl: 'app/components/sidebar/sidebar.html',
+ controller: 'SidebarController'
+ }
+ }
+ })
+ .state('docker', {
+ url: '/docker/',
+ views: {
+ "content@": {
+ templateUrl: 'app/components/docker/docker.html',
+ controller: 'DockerController'
+ },
+ "sidebar@": {
+ templateUrl: 'app/components/sidebar/sidebar.html',
+ controller: 'SidebarController'
+ }
+ }
+ })
+ .state('endpoints', {
+ url: '/endpoints/',
+ views: {
+ "content@": {
+ templateUrl: 'app/components/endpoints/endpoints.html',
+ controller: 'EndpointsController'
+ },
+ "sidebar@": {
+ templateUrl: 'app/components/sidebar/sidebar.html',
+ controller: 'SidebarController'
+ }
+ }
+ })
+ .state('endpoint', {
+ url: '^/endpoints/:id',
+ views: {
+ "content@": {
+ templateUrl: 'app/components/endpoint/endpoint.html',
+ controller: 'EndpointController'
+ },
+ "sidebar@": {
+ templateUrl: 'app/components/sidebar/sidebar.html',
+ controller: 'SidebarController'
+ }
+ }
+ })
+ .state('endpointInit', {
+ url: '/init/endpoint',
+ views: {
+ "content@": {
+ templateUrl: 'app/components/endpointInit/endpointInit.html',
+ controller: 'EndpointInitController'
+ }
+ }
+ })
+ .state('events', {
+ url: '/events/',
+ views: {
+ "content@": {
+ templateUrl: 'app/components/events/events.html',
+ controller: 'EventsController'
+ },
+ "sidebar@": {
+ templateUrl: 'app/components/sidebar/sidebar.html',
+ controller: 'SidebarController'
+ }
+ }
+ })
+ .state('images', {
+ url: '/images/',
+ views: {
+ "content@": {
+ templateUrl: 'app/components/images/images.html',
+ controller: 'ImagesController'
+ },
+ "sidebar@": {
+ templateUrl: 'app/components/sidebar/sidebar.html',
+ controller: 'SidebarController'
+ }
+ }
+ })
+ .state('image', {
+ url: '^/images/:id/',
+ views: {
+ "content@": {
+ templateUrl: 'app/components/image/image.html',
+ controller: 'ImageController'
+ },
+ "sidebar@": {
+ templateUrl: 'app/components/sidebar/sidebar.html',
+ controller: 'SidebarController'
+ }
+ }
+ })
+ .state('networks', {
+ url: '/networks/',
+ views: {
+ "content@": {
+ templateUrl: 'app/components/networks/networks.html',
+ controller: 'NetworksController'
+ },
+ "sidebar@": {
+ templateUrl: 'app/components/sidebar/sidebar.html',
+ controller: 'SidebarController'
+ }
+ }
+ })
+ .state('network', {
+ url: '^/networks/:id/',
+ views: {
+ "content@": {
+ templateUrl: 'app/components/network/network.html',
+ controller: 'NetworkController'
+ },
+ "sidebar@": {
+ templateUrl: 'app/components/sidebar/sidebar.html',
+ controller: 'SidebarController'
+ }
+ }
+ })
+ .state('node', {
+ url: '^/nodes/:id/',
+ views: {
+ "content@": {
+ templateUrl: 'app/components/node/node.html',
+ controller: 'NodeController'
+ },
+ "sidebar@": {
+ templateUrl: 'app/components/sidebar/sidebar.html',
+ controller: 'SidebarController'
+ }
+ }
+ })
+ .state('services', {
+ url: '/services/',
+ views: {
+ "content@": {
+ templateUrl: 'app/components/services/services.html',
+ controller: 'ServicesController'
+ },
+ "sidebar@": {
+ templateUrl: 'app/components/sidebar/sidebar.html',
+ controller: 'SidebarController'
+ }
+ }
+ })
+ .state('service', {
+ url: '^/service/:id/',
+ views: {
+ "content@": {
+ templateUrl: 'app/components/service/service.html',
+ controller: 'ServiceController'
+ },
+ "sidebar@": {
+ templateUrl: 'app/components/sidebar/sidebar.html',
+ controller: 'SidebarController'
+ }
+ }
+ })
+ .state('settings', {
+ url: '/settings/',
+ views: {
+ "content@": {
+ templateUrl: 'app/components/settings/settings.html',
+ controller: 'SettingsController'
+ },
+ "sidebar@": {
+ templateUrl: 'app/components/sidebar/sidebar.html',
+ controller: 'SidebarController'
+ }
+ }
+ })
+ .state('task', {
+ url: '^/task/:id',
+ views: {
+ "content@": {
+ templateUrl: 'app/components/task/task.html',
+ controller: 'TaskController'
+ },
+ "sidebar@": {
+ templateUrl: 'app/components/sidebar/sidebar.html',
+ controller: 'SidebarController'
+ }
+ }
+ })
+ .state('templates', {
+ url: '/templates/',
+ views: {
+ "content@": {
+ templateUrl: 'app/components/templates/templates.html',
+ controller: 'TemplatesController'
+ },
+ "sidebar@": {
+ templateUrl: 'app/components/sidebar/sidebar.html',
+ controller: 'SidebarController'
+ }
+ }
+ })
+ .state('volumes', {
+ url: '/volumes/',
+ views: {
+ "content@": {
+ templateUrl: 'app/components/volumes/volumes.html',
+ controller: 'VolumesController'
+ },
+ "sidebar@": {
+ templateUrl: 'app/components/sidebar/sidebar.html',
+ controller: 'SidebarController'
+ }
+ }
+ })
+ .state('swarm', {
+ url: '/swarm/',
+ views: {
+ "content@": {
+ templateUrl: 'app/components/swarm/swarm.html',
+ controller: 'SwarmController'
+ },
+ "sidebar@": {
+ templateUrl: 'app/components/sidebar/sidebar.html',
+ controller: 'SidebarController'
+ }
+ }
+ });
+
+ // The Docker API likes to return plaintext errors, this catches them and disp
+ $httpProvider.interceptors.push(function() {
+ return {
+ 'response': function(response) {
+ if (typeof(response.data) === 'string' &&
+ (response.data.startsWith('Conflict.') || response.data.startsWith('conflict:'))) {
+ $.gritter.add({
+ title: 'Error',
+ text: $('
').text(response.data).html(),
+ time: 10000
+ });
+ }
+ return response;
+ }
+ };
+ });
+ }])
+ .run(['$rootScope', '$state', 'Authentication', 'authManager', 'StateManager', 'Messages', 'Analytics', function ($rootScope, $state, Authentication, authManager, StateManager, Messages, Analytics) {
+ StateManager.initialize().then(function success(state) {
+ if (state.application.authentication) {
+ authManager.checkAuthOnRefresh();
+ authManager.redirectWhenUnauthenticated();
+ Authentication.init();
+ $rootScope.$on('tokenHasExpired', function($state) {
+ $state.go('auth', {error: 'Your session has expired'});
+ });
+ }
+ if (state.application.analytics) {
+ Analytics.offline(false);
+ Analytics.registerScriptTags();
+ Analytics.registerTrackers();
+ $rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) {
+ Analytics.trackPage(toState.url);
+ Analytics.pageView();
+ });
+ }
+ }, function error(err) {
+ Messages.error("Failure", err, 'Unable to retrieve application settings');
+ });
+
+ $rootScope.$state = $state;
+ }])
+ // This is your docker url that the api will use to make requests
+ // You need to set this to the api endpoint without the port i.e. http://192.168.1.9
+ .constant('DOCKER_PORT', '') // Docker port, leave as an empty string if no port is required. If you have a port, prefix it with a ':' i.e. :4243
+ .constant('DOCKER_ENDPOINT', 'api/docker')
+ .constant('CONFIG_ENDPOINT', 'api/settings')
.constant('AUTH_ENDPOINT', 'api/auth')
.constant('USERS_ENDPOINT', 'api/users')
.constant('ENDPOINTS_ENDPOINT', 'api/endpoints')
.constant('TEMPLATES_ENDPOINT', 'api/templates')
.constant('PAGINATION_MAX_ITEMS', 10)
- .constant('UI_VERSION', 'v1.11.3');
+ .constant('UI_VERSION', 'v1.11.3');
diff --git a/app/filters/filters.js b/app/filters/filters.js
index 3e6881cbe..ddfda05f1 100644
--- a/app/filters/filters.js
+++ b/app/filters/filters.js
@@ -1,231 +1,231 @@
-angular.module('portainer.filters', [])
-.filter('truncate', function () {
- 'use strict';
- return function (text, length, end) {
- if (isNaN(length)) {
- length = 10;
- }
-
- if (end === undefined) {
- end = '...';
- }
-
- if (text.length <= length || text.length - end.length <= length) {
- return text;
- }
- else {
- return String(text).substring(0, length - end.length) + end;
- }
- };
-})
-.filter('taskstatusbadge', function () {
- 'use strict';
- return function (text) {
- var status = _.toLower(text);
- if (status.indexOf('new') !== -1 || status.indexOf('allocated') !== -1 ||
- status.indexOf('assigned') !== -1 || status.indexOf('accepted') !== -1) {
- return 'info';
- } else if (status.indexOf('pending') !== -1) {
- return 'warning';
- } else if (status.indexOf('shutdown') !== -1 || status.indexOf('failed') !== -1 ||
- status.indexOf('rejected') !== -1) {
- return 'danger';
- } else if (status.indexOf('complete') !== -1) {
- return 'primary';
- }
- return 'success';
- };
-})
-.filter('containerstatusbadge', function () {
- 'use strict';
- return function (text) {
- var status = _.toLower(text);
- if (status.indexOf('paused') !== -1) {
- return 'warning';
- } else if (status.indexOf('created') !== -1) {
- return 'info';
- } else if (status.indexOf('stopped') !== -1) {
- return 'danger';
- }
- return 'success';
- };
-})
-.filter('containerstatus', function () {
- 'use strict';
- return function (text) {
- var status = _.toLower(text);
- if (status.indexOf('paused') !== -1) {
- return 'paused';
- } else if (status.indexOf('created') !== -1) {
- return 'created';
- } else if (status.indexOf('exited') !== -1) {
- return 'stopped';
- }
- return 'running';
- };
-})
-.filter('nodestatusbadge', function () {
- 'use strict';
- return function (text) {
- if (text === 'down' || text === 'Unhealthy') {
- return 'danger';
- }
- return 'success';
- };
-})
-.filter('trimcontainername', function () {
- 'use strict';
- return function (name) {
- if (name) {
- return (name.indexOf('/') === 0 ? name.replace('/','') : name);
- }
- return '';
- };
-})
-.filter('capitalize', function () {
- 'use strict';
- return function (text) {
- return _.capitalize(text);
- };
-})
-.filter('getstatetext', function () {
- 'use strict';
- return function (state) {
- if (state === undefined) {
- return '';
- }
- if (state.Ghost && state.Running) {
- return 'Ghost';
- }
- if (state.Running && state.Paused) {
- return 'Running (Paused)';
- }
- if (state.Running) {
- return 'Running';
- }
- return 'Stopped';
- };
-})
-.filter('stripprotocol', function() {
- 'use strict';
- return function (url) {
- return url.replace(/.*?:\/\//g, '');
- };
-})
-.filter('getstatelabel', function () {
- 'use strict';
- return function (state) {
- if (state === undefined) {
- return 'label-default';
- }
- if (state.Ghost && state.Running) {
- return 'label-important';
- }
- if (state.Running) {
- return 'label-success';
- }
- return 'label-default';
- };
-})
-.filter('humansize', function () {
- 'use strict';
- return function (bytes, round) {
- if (!round) {
- round = 1;
- }
- if (bytes || bytes === 0) {
- return filesize(bytes, {base: 10, round: round});
- }
- };
-})
-.filter('containername', function () {
- 'use strict';
- return function (container) {
- var name = container.Names[0];
- return name.substring(1, name.length);
- };
-})
-.filter('swarmcontainername', function () {
- 'use strict';
- return function (container) {
- return _.split(container.Names[0], '/')[2];
- };
-})
-.filter('swarmversion', function () {
- 'use strict';
- return function (text) {
- return _.split(text, '/')[1];
- };
-})
-.filter('swarmhostname', function () {
- 'use strict';
- return function (container) {
- return _.split(container.Names[0], '/')[1];
- };
-})
-.filter('repotags', function () {
- 'use strict';
- return function (image) {
- if (image.RepoTags && image.RepoTags.length > 0) {
- var tag = image.RepoTags[0];
- if (tag === ':') {
- return [];
- }
- return image.RepoTags;
- }
- return [];
- };
-})
-.filter('getisodatefromtimestamp', function () {
- 'use strict';
- return function (timestamp) {
- return moment.unix(timestamp).format('YYYY-MM-DD HH:mm:ss');
- };
-})
-.filter('getisodate', function () {
- 'use strict';
- return function (date) {
- return moment(date).format('YYYY-MM-DD HH:mm:ss');
- };
-})
-.filter('command', function () {
- 'use strict';
- return function (command) {
- if (command) {
- return command.join(' ');
- }
- };
-})
-.filter('key', function () {
- 'use strict';
- return function (pair, separator) {
- return pair.slice(0, pair.indexOf(separator));
- };
-})
-.filter('value', function () {
- 'use strict';
- return function (pair, separator) {
- return pair.slice(pair.indexOf(separator) + 1);
- };
-})
-.filter('emptyobject', function () {
- 'use strict';
- return function (obj) {
- return _.isEmpty(obj);
- };
-})
-.filter('ipaddress', function () {
- 'use strict';
- return function (ip) {
- return ip.slice(0, ip.indexOf('/'));
- };
-})
-.filter('arraytostr', function () {
- 'use strict';
- return function (arr, separator) {
- if (arr) {
- return _.join(arr, separator);
- }
- return '';
- };
-});
+angular.module('portainer.filters', [])
+.filter('truncate', function () {
+ 'use strict';
+ return function (text, length, end) {
+ if (isNaN(length)) {
+ length = 10;
+ }
+
+ if (end === undefined) {
+ end = '...';
+ }
+
+ if (text.length <= length || text.length - end.length <= length) {
+ return text;
+ }
+ else {
+ return String(text).substring(0, length - end.length) + end;
+ }
+ };
+})
+.filter('taskstatusbadge', function () {
+ 'use strict';
+ return function (text) {
+ var status = _.toLower(text);
+ if (status.indexOf('new') !== -1 || status.indexOf('allocated') !== -1 ||
+ status.indexOf('assigned') !== -1 || status.indexOf('accepted') !== -1) {
+ return 'info';
+ } else if (status.indexOf('pending') !== -1) {
+ return 'warning';
+ } else if (status.indexOf('shutdown') !== -1 || status.indexOf('failed') !== -1 ||
+ status.indexOf('rejected') !== -1) {
+ return 'danger';
+ } else if (status.indexOf('complete') !== -1) {
+ return 'primary';
+ }
+ return 'success';
+ };
+})
+.filter('containerstatusbadge', function () {
+ 'use strict';
+ return function (text) {
+ var status = _.toLower(text);
+ if (status.indexOf('paused') !== -1) {
+ return 'warning';
+ } else if (status.indexOf('created') !== -1) {
+ return 'info';
+ } else if (status.indexOf('stopped') !== -1) {
+ return 'danger';
+ }
+ return 'success';
+ };
+})
+.filter('containerstatus', function () {
+ 'use strict';
+ return function (text) {
+ var status = _.toLower(text);
+ if (status.indexOf('paused') !== -1) {
+ return 'paused';
+ } else if (status.indexOf('created') !== -1) {
+ return 'created';
+ } else if (status.indexOf('exited') !== -1) {
+ return 'stopped';
+ }
+ return 'running';
+ };
+})
+.filter('nodestatusbadge', function () {
+ 'use strict';
+ return function (text) {
+ if (text === 'down' || text === 'Unhealthy') {
+ return 'danger';
+ }
+ return 'success';
+ };
+})
+.filter('trimcontainername', function () {
+ 'use strict';
+ return function (name) {
+ if (name) {
+ return (name.indexOf('/') === 0 ? name.replace('/','') : name);
+ }
+ return '';
+ };
+})
+.filter('capitalize', function () {
+ 'use strict';
+ return function (text) {
+ return _.capitalize(text);
+ };
+})
+.filter('getstatetext', function () {
+ 'use strict';
+ return function (state) {
+ if (state === undefined) {
+ return '';
+ }
+ if (state.Ghost && state.Running) {
+ return 'Ghost';
+ }
+ if (state.Running && state.Paused) {
+ return 'Running (Paused)';
+ }
+ if (state.Running) {
+ return 'Running';
+ }
+ return 'Stopped';
+ };
+})
+.filter('stripprotocol', function() {
+ 'use strict';
+ return function (url) {
+ return url.replace(/.*?:\/\//g, '');
+ };
+})
+.filter('getstatelabel', function () {
+ 'use strict';
+ return function (state) {
+ if (state === undefined) {
+ return 'label-default';
+ }
+ if (state.Ghost && state.Running) {
+ return 'label-important';
+ }
+ if (state.Running) {
+ return 'label-success';
+ }
+ return 'label-default';
+ };
+})
+.filter('humansize', function () {
+ 'use strict';
+ return function (bytes, round) {
+ if (!round) {
+ round = 1;
+ }
+ if (bytes || bytes === 0) {
+ return filesize(bytes, {base: 10, round: round});
+ }
+ };
+})
+.filter('containername', function () {
+ 'use strict';
+ return function (container) {
+ var name = container.Names[0];
+ return name.substring(1, name.length);
+ };
+})
+.filter('swarmcontainername', function () {
+ 'use strict';
+ return function (container) {
+ return _.split(container.Names[0], '/')[2];
+ };
+})
+.filter('swarmversion', function () {
+ 'use strict';
+ return function (text) {
+ return _.split(text, '/')[1];
+ };
+})
+.filter('swarmhostname', function () {
+ 'use strict';
+ return function (container) {
+ return _.split(container.Names[0], '/')[1];
+ };
+})
+.filter('repotags', function () {
+ 'use strict';
+ return function (image) {
+ if (image.RepoTags && image.RepoTags.length > 0) {
+ var tag = image.RepoTags[0];
+ if (tag === ':') {
+ return [];
+ }
+ return image.RepoTags;
+ }
+ return [];
+ };
+})
+.filter('getisodatefromtimestamp', function () {
+ 'use strict';
+ return function (timestamp) {
+ return moment.unix(timestamp).format('YYYY-MM-DD HH:mm:ss');
+ };
+})
+.filter('getisodate', function () {
+ 'use strict';
+ return function (date) {
+ return moment(date).format('YYYY-MM-DD HH:mm:ss');
+ };
+})
+.filter('command', function () {
+ 'use strict';
+ return function (command) {
+ if (command) {
+ return command.join(' ');
+ }
+ };
+})
+.filter('key', function () {
+ 'use strict';
+ return function (pair, separator) {
+ return pair.slice(0, pair.indexOf(separator));
+ };
+})
+.filter('value', function () {
+ 'use strict';
+ return function (pair, separator) {
+ return pair.slice(pair.indexOf(separator) + 1);
+ };
+})
+.filter('emptyobject', function () {
+ 'use strict';
+ return function (obj) {
+ return _.isEmpty(obj);
+ };
+})
+.filter('ipaddress', function () {
+ 'use strict';
+ return function (ip) {
+ return ip.slice(0, ip.indexOf('/'));
+ };
+})
+.filter('arraytostr', function () {
+ 'use strict';
+ return function (arr, separator) {
+ if (arr) {
+ return _.join(arr, separator);
+ }
+ return '';
+ };
+});