1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-08-07 23:05:26 +02:00

Merge branch 'develop' into oath-poc

This commit is contained in:
Anthony Lapenna 2019-02-04 09:19:12 +13:00
commit 508352f4ea
53 changed files with 626 additions and 452 deletions

View file

@ -48,7 +48,7 @@ angular.module('portainer.app', [])
var authentication = {
name: 'portainer.auth',
url: '/auth',
url: '/auth?redirect',
params: {
logout: false,
error: ''
@ -87,7 +87,7 @@ angular.module('portainer.app', [])
}
};
var endpointCreation = {
var endpointCreation = {
name: 'portainer.endpoints.new',
url: '/new',
views: {
@ -242,7 +242,7 @@ angular.module('portainer.app', [])
}
};
var registryCreation = {
var registryCreation = {
name: 'portainer.registries.new',
url: '/new',
views: {
@ -286,7 +286,7 @@ angular.module('portainer.app', [])
}
};
var scheduleCreation = {
var scheduleCreation = {
name: 'portainer.schedules.new',
url: '/new',
views: {
@ -327,6 +327,16 @@ angular.module('portainer.app', [])
templateUrl: 'app/portainer/views/stacks/stacks.html',
controller: 'StacksController'
}
},
resolve: {
endpointID: ['EndpointProvider', '$state',
function (EndpointProvider, $state) {
var id = EndpointProvider.endpointID();
if (!id) {
return $state.go('portainer.home');
}
}
]
}
};
@ -342,7 +352,7 @@ angular.module('portainer.app', [])
};
var stackCreation = {
name: 'portainer.newstack',
name: 'portainer.stacks.newstack',
url: '/newstack',
views: {
'content@': {

View file

@ -11,7 +11,7 @@
ng-disabled="$ctrl.state.selectedItemCount === 0" ng-click="$ctrl.removeAction($ctrl.state.selectedItems)">
<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.newstack">
<button type="button" class="btn btn-sm btn-primary" ui-sref="portainer.stacks.newstack">
<i class="fa fa-plus space-right" aria-hidden="true"></i>Add stack
</button>
</div>

View file

@ -23,11 +23,11 @@
</span>
<span>
<span class="small">
<span class="small" ng-if="$ctrl.model.GroupName">
Group: {{ $ctrl.model.GroupName }}
</span>
<button
ng-if="$ctrl.isAdmin"
ng-if="$ctrl.isAdmin"
class="btn btn-link btn-xs"
ng-click="$ctrl.editEndpoint($event)"><i class="fa fa-pencil-alt"></i>
</button>

View file

@ -21,10 +21,10 @@
</span>
<span>
<span class="label label-primary" ng-if="!$ctrl.model.Enabled && !$ctrl.model.Available">coming soon</span>
<span class="label label-warning" ng-if="!$ctrl.model.Enabled && $ctrl.model.Deal">deal</span>
<span class="label label-danger" ng-if="$ctrl.model.Enabled && $ctrl.model.Expired">expired</span>
<span class="label label-success" ng-if="$ctrl.model.Enabled && !$ctrl.model.Expired">enabled</span>
<span class="label label-primary" ng-if="$ctrl.model.Enabled && $ctrl.model.UpdateAvailable && !$ctrl.model.Expired">update available</span>
<span class="label label-warning" ng-if="!$ctrl.model.Enabled && $ctrl.model.Deal && !$ctrl.model.License.Expiration">deal</span>
<span class="label label-danger" ng-if="!$ctrl.model.Enabled && $ctrl.model.License.Expiration && !$ctrl.model.License.Valid">expired</span>
<span class="label label-success" ng-if="$ctrl.model.Enabled && $ctrl.model.License.Valid">enabled</span>
<span class="label label-primary" ng-if="$ctrl.model.Enabled && $ctrl.model.License.Valid && $ctrl.model.UpdateAvailable">update available</span>
</span>
</div>
<!-- !blocklist-item-line1 -->

View file

@ -3,7 +3,6 @@ angular.module('portainer.app')
function($state) {
var ctrl = this;
ctrl.$onInit = $onInit;
ctrl.goToExtensionView = goToExtensionView;
function goToExtensionView() {
@ -11,10 +10,4 @@ angular.module('portainer.app')
$state.go('portainer.extensions.extension', { id: ctrl.model.Id });
}
}
function $onInit() {
if (ctrl.currentDate === ctrl.model.License.Expiration) {
ctrl.model.Expired = true;
}
}
}]);

View file

@ -3,7 +3,7 @@
<div class="blocklist-item-box">
<!-- extension-image -->
<span class="blocklist-item-logo">
<img class="blocklist-item-logo" src="images/support_{{ $ctrl.model.Id }}.png" />
<img class="blocklist-item-logo" ng-src="images/support_{{ $ctrl.model.Id }}.png" />
</span>
<!-- !extension-image -->
<!-- extension-details -->
@ -15,11 +15,6 @@
{{ $ctrl.model.Name }}
</span>
</span>
<span>
<span class="label label-danger" ng-if="$ctrl.model.Enabled && $ctrl.model.Expired">expired</span>
<span class="label label-success" ng-if="$ctrl.model.Enabled && !$ctrl.model.Expired">enabled</span>
<span class="label label-primary" ng-if="$ctrl.model.Enabled && $ctrl.model.UpdateAvailable && !$ctrl.model.Expired">update available</span>
</span>
</div>
<!-- !blocklist-item-line1 -->
<!-- blocklist-item-line2 -->
@ -29,9 +24,6 @@
{{ $ctrl.model.ShortDescription }}
</span>
</span>
<span ng-if="$ctrl.model.License.Company">
<span class="small text-muted">Licensed to {{ $ctrl.model.License.Company }} - Expires on {{ $ctrl.model.License.Expiration }}</span>
</span>
</div>
<!-- !blocklist-item-line2 -->
</span>

View file

@ -1,5 +1,5 @@
angular.module('portainer.app')
.factory('EndpointStatusInterceptor', ['$q', '$injector', 'EndpointProvider', function ($q, $injector, EndpointProvider) {
.factory('EndpointStatusInterceptor', ['$q', 'EndpointProvider', function ($q, EndpointProvider) {
'use strict';
var interceptor = {};
@ -18,21 +18,17 @@ angular.module('portainer.app')
}
function responseInterceptor(response) {
var EndpointService = $injector.get('EndpointService');
var url = response.config.url;
if (response.status === 200 && canBeOffline(url) && EndpointProvider.offlineMode()) {
EndpointProvider.setOfflineMode(false);
EndpointService.updateEndpoint(EndpointProvider.endpointID(), {Status: EndpointProvider.endpointStatusFromOfflineMode(false)});
}
return response || $q.when(response);
}
function responseErrorInterceptor(rejection) {
var EndpointService = $injector.get('EndpointService');
var url = rejection.config.url;
if ((rejection.status === 502 || rejection.status === 503 || rejection.status === -1) && canBeOffline(url) && !EndpointProvider.offlineMode()) {
EndpointProvider.setOfflineMode(true);
EndpointService.updateEndpoint(EndpointProvider.endpointID(), {Status: EndpointProvider.endpointStatusFromOfflineMode(true)});
}
return $q.reject(rejection);
}

View file

@ -64,10 +64,6 @@ angular.module('portainer.app')
return endpoint.OfflineMode;
};
service.endpointStatusFromOfflineMode = function(isOffline) {
return isOffline ? 2 : 1;
};
service.setOfflineMode = function(isOffline) {
endpoint.OfflineMode = isOffline;
LocalStorage.storeOfflineMode(isOffline);

View file

@ -5,6 +5,7 @@ angular.module('portainer.app')
var service = {};
var headers = {};
headers.agentTargetQueue = [];
headers.agentManagerOperation = false;
service.registryAuthenticationHeader = function() {
return headers.registryAuthentication;
@ -36,9 +37,18 @@ angular.module('portainer.app')
}
};
service.resetAgentTargetQueue = function() {
service.setPortainerAgentManagerOperation = function(set) {
headers.agentManagerOperation = set;
};
service.portainerAgentManagerOperation = function() {
return headers.agentManagerOperation;
};
service.resetAgentHeaders = function() {
headers.agentTargetQueue = [];
delete headers.agentTargetLastValue;
headers.agentManagerOperation = false;
};
return service;

View file

@ -1,126 +1,125 @@
angular.module('portainer.app')
.controller('AuthenticationController', ['urlHelper','$q', '$scope', '$state', '$stateParams', '$sanitize', 'Authentication', 'UserService', 'EndpointService', 'StateManager', 'Notifications', 'SettingsService',
function (urlHelper, $q, $scope, $state, $stateParams, $sanitize, Authentication, UserService, EndpointService, StateManager, Notifications, SettingsService) {
$scope.logo = StateManager.getState().application.logo;
angular.module('portainer.app').controller('AuthenticationController', ['$q', '$scope', '$state', '$stateParams', '$sanitize', 'Authentication', 'UserService', 'EndpointService', 'StateManager', 'Notifications', 'SettingsService', 'urlHelper',
function($q, $scope, $state, $stateParams, $sanitize, Authentication, UserService, EndpointService, StateManager, Notifications, SettingsService, urlHelper) {
$scope.logo = StateManager.getState().application.logo;
$scope.formValues = {
Username: '',
Password: ''
};
$scope.formValues = {
Username: '',
Password: ''
};
$scope.state = {
AuthenticationError: ''
};
$scope.state = {
AuthenticationError: ''
};
$scope.authenticateUser = function() {
var username = $scope.formValues.Username;
var password = $scope.formValues.Password;
$scope.authenticateUser = function() {
var username = $scope.formValues.Username;
var password = $scope.formValues.Password;
Authentication.login(username, password)
.then(function success() {
checkForEndpoints();
})
.catch(function error() {
Authentication.login(username, password)
.then(function success() {
checkForEndpoints();
})
.catch(function error() {
SettingsService.publicSettings()
.then(function success(settings) {
if (settings.AuthenticationMethod === 1) {
return Authentication.login($sanitize(username), $sanitize(password));
}
return $q.reject();
})
.then(function success() {
$state.go('portainer.updatePassword');
})
.catch(function error() {
$scope.state.AuthenticationError = 'Invalid credentials';
});
});
};
function unauthenticatedFlow() {
EndpointService.endpoints()
.then(function success(endpoints) {
if (endpoints.length === 0) {
$state.go('portainer.init.endpoint');
} else {
$state.go($stateParams.redirect || 'portainer.home');
}
})
.catch(function error(err) {
Notifications.error('Failure', err, 'Unable to retrieve endpoints');
});
}
function authenticatedFlow() {
UserService.administratorExists()
.then(function success(exists) {
if (!exists) {
$state.go('portainer.init.admin');
}
})
.catch(function error(err) {
Notifications.error('Failure', err, 'Unable to verify administrator account existence');
});
}
function checkForEndpoints() {
EndpointService.endpoints()
.then(function success(data) {
var endpoints = data;
var userDetails = Authentication.getUserDetails();
if (endpoints.length === 0 && userDetails.role === 1) {
$state.go('portainer.init.endpoint');
} else {
$state.go($stateParams.redirect || 'portainer.home');
}
})
.catch(function error(err) {
Notifications.error('Failure', err, 'Unable to retrieve endpoints');
});
}
function initView() {
SettingsService.publicSettings()
.then(function success(settings) {
if (settings.AuthenticationMethod === 1) {
return Authentication.login($sanitize(username), $sanitize(password));
}
return $q.reject();
})
.then(function success() {
$state.go('portainer.updatePassword');
})
.catch(function error() {
$scope.state.AuthenticationError = 'Invalid credentials';
});
});
};
.then(function success(settings) {
$scope.AuthenticationMethod = settings.AuthenticationMethod;
$scope.OAuthLoginURI = settings.OAuthLoginURI;
});
function unauthenticatedFlow() {
EndpointService.endpoints()
.then(function success(endpoints) {
if (endpoints.length === 0) {
$state.go('portainer.init.endpoint');
} else {
if ($stateParams.logout || $stateParams.error) {
Authentication.logout();
$scope.state.AuthenticationError = $stateParams.error;
return;
}
if (Authentication.isAuthenticated()) {
$state.go('portainer.home');
}
})
.catch(function error(err) {
Notifications.error('Failure', err, 'Unable to retrieve endpoints');
});
}
function authenticatedFlow() {
UserService.administratorExists()
.then(function success(exists) {
if (!exists) {
$state.go('portainer.init.admin');
}
})
.catch(function error(err) {
Notifications.error('Failure', err, 'Unable to verify administrator account existence');
});
}
function checkForEndpoints() {
EndpointService.endpoints()
.then(function success(data) {
var endpoints = data;
var userDetails = Authentication.getUserDetails();
if (endpoints.length === 0 && userDetails.role === 1) {
$state.go('portainer.init.endpoint');
var authenticationEnabled = $scope.applicationState.application.authentication;
if (!authenticationEnabled) {
unauthenticatedFlow();
} else {
$state.go('portainer.home');
authenticatedFlow();
}
})
.catch(function error(err) {
Notifications.error('Failure', err, 'Unable to retrieve endpoints');
});
}
function initView() {
SettingsService.publicSettings()
.then(function success(settings) {
$scope.AuthenticationMethod = settings.AuthenticationMethod;
$scope.OAuthLoginURI = settings.OAuthLoginURI;
});
if ($stateParams.logout || $stateParams.error) {
Authentication.logout();
$scope.state.AuthenticationError = $stateParams.error;
return;
var code = urlHelper.getParameter('code');
if (code) {
oAuthLogin(code);
}
}
if (Authentication.isAuthenticated()) {
$state.go('portainer.home');
function oAuthLogin(code) {
return Authentication.OAuthLogin(code)
.then(function success() {
urlHelper.cleanParameters();
$state.go('portainer.home');
})
.catch(function error() {
$scope.state.AuthenticationError = 'Failed to authenticate with OAuth2 Provider';
});
}
var authenticationEnabled = $scope.applicationState.application.authentication;
if (!authenticationEnabled) {
unauthenticatedFlow();
} else {
authenticatedFlow();
}
var code = urlHelper.getParameter('code');
if (code) {
oAuthLogin(code);
}
}
function oAuthLogin(code) {
return Authentication.OAuthLogin(code)
.then(function success() {
urlHelper.cleanParameters();
$state.go('portainer.home');
})
.catch(function error() {
$scope.state.AuthenticationError = 'Failed to authenticate with OAuth2 Provider';
});
}
initView();
}]);
initView();
}]);

View file

@ -20,7 +20,7 @@ function ($q, $scope, $state, $filter, clipboard, EndpointService, GroupService,
};
$scope.copyAgentCommand = function() {
clipboard.copyText('curl -L https://portainer.io/download/agent-stack.yml -o agent-stack.yml && docker stack deploy --compose-file=agent-stack.yml portainer-agent');
clipboard.copyText('curl -L https://downloads.portainer.io/agent-stack.yml -o agent-stack.yml && docker stack deploy --compose-file=agent-stack.yml portainer-agent');
$('#copyNotification').show();
$('#copyNotification').fadeOut(2000);
};

View file

@ -67,7 +67,7 @@
Ensure that you have deployed the Portainer agent in your cluster first. You can use execute the following command on any manager node to deploy it.
<div style="margin-top: 10px;">
<code>
curl -L https://portainer.io/download/agent-stack.yml -o agent-stack.yml && docker stack deploy --compose-file=agent-stack.yml portainer-agent
curl -L https://downloads.portainer.io/agent-stack.yml -o agent-stack.yml && docker stack deploy --compose-file=agent-stack.yml portainer-agent
</code>
<span class="btn btn-primary btn-sm space-left" ng-click="copyAgentCommand()"><i class="fa fa-copy space-right" aria-hidden="true"></i>Copy</span>
<span>

View file

@ -36,7 +36,9 @@
<div class="form-group" style="margin-left: 40px;">
<div style="font-size: 125%; border-bottom: 2px solid #2d3e63; padding-bottom: 5px;">
{{ extension.Enabled ? 'Enabled' : extension.Price }}
<span ng-if="extension.Enabled">Enabled</span>
<span ng-if="!extension.Enabled && extension.License.Expiration && !extension.License.Valid">Expired</span>
<span ng-if="!extension.Enabled && !extension.License.Expiration">{{ extension.Price }}</span>
</div>
<div class="small text-muted col-sm-12" style="margin: 15px 0 15px 0;" ng-if="!extension.Enabled">

View file

@ -1,139 +1,139 @@
angular.module('portainer.app')
.controller('HomeController', ['$q', '$scope', '$state', 'Authentication', 'EndpointService', 'EndpointHelper', 'GroupService', 'Notifications', 'EndpointProvider', 'StateManager', 'LegacyExtensionManager', 'ModalService', 'MotdService', 'SystemService',
function ($q, $scope, $state, Authentication, EndpointService, EndpointHelper, GroupService, Notifications, EndpointProvider, StateManager, LegacyExtensionManager, ModalService, MotdService, SystemService) {
.controller('HomeController', ['$q', '$scope', '$state', 'Authentication', 'EndpointService', 'EndpointHelper', 'GroupService', 'Notifications', 'EndpointProvider', 'StateManager', 'LegacyExtensionManager', 'ModalService', 'MotdService', 'SystemService',
function($q, $scope, $state, Authentication, EndpointService, EndpointHelper, GroupService, Notifications, EndpointProvider, StateManager, LegacyExtensionManager, ModalService, MotdService, SystemService) {
$scope.goToEdit = function(id) {
$state.go('portainer.endpoints.endpoint', { id: id });
};
$scope.goToEdit = function(id) {
$state.go('portainer.endpoints.endpoint', { id: id });
};
$scope.goToDashboard = function (endpoint) {
if (endpoint.Type === 3) {
return switchToAzureEndpoint(endpoint);
}
$scope.goToDashboard = function(endpoint) {
if (endpoint.Type === 3) {
return switchToAzureEndpoint(endpoint);
}
checkEndpointStatus(endpoint)
.then(function sucess() {
return switchToDockerEndpoint(endpoint);
}).catch(function error(err) {
Notifications.error('Failure', err, 'Unable to verify endpoint status');
});
};
checkEndpointStatus(endpoint)
.then(function sucess() {
return switchToDockerEndpoint(endpoint);
}).catch(function error(err) {
Notifications.error('Failure', err, 'Unable to verify endpoint status');
});
};
$scope.dismissImportantInformation = function (hash) {
StateManager.dismissImportantInformation(hash);
};
$scope.dismissImportantInformation = function(hash) {
StateManager.dismissImportantInformation(hash);
};
$scope.dismissInformationPanel = function (id) {
StateManager.dismissInformationPanel(id);
};
$scope.dismissInformationPanel = function(id) {
StateManager.dismissInformationPanel(id);
};
$scope.triggerSnapshot = function () {
ModalService.confirmEndpointSnapshot(function (result) {
if (!result) {
return;
}
triggerSnapshot();
});
};
$scope.triggerSnapshot = function() {
ModalService.confirmEndpointSnapshot(function(result) {
if (!result) {
return;
}
triggerSnapshot();
});
};
function checkEndpointStatus(endpoint) {
var deferred = $q.defer();
function checkEndpointStatus(endpoint) {
var deferred = $q.defer();
var status = 1;
SystemService.ping(endpoint.Id)
.then(function sucess() {
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 sucess() {
deferred.resolve(endpoint);
}).catch(function error(err) {
deferred.reject({ msg: 'Unable to update endpoint status', err: err });
});
});
var status = 1;
SystemService.ping(endpoint.Id)
.then(function sucess() {
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 sucess() {
deferred.resolve(endpoint);
}).catch(function error(err) {
deferred.reject({msg: 'Unable to update endpoint status', err: err});
});
});
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');
});
}
return deferred.promise;
}
function switchToDockerEndpoint(endpoint) {
if (endpoint.Status === 2 && endpoint.Snapshots[0] && endpoint.Snapshots[0].Swarm === true) {
Notifications.error('Failure', '', 'Endpoint is unreachable. Connect to another swarm manager.');
return;
} else if (endpoint.Status === 2 && !endpoint.Snapshots[0]) {
Notifications.error('Failure', '', 'Endpoint is unreachable and there is no snapshot available for offline browsing.');
return;
}
function switchToAzureEndpoint(endpoint) {
EndpointProvider.setEndpointID(endpoint.Id);
EndpointProvider.setEndpointPublicURL(endpoint.PublicURL);
EndpointProvider.setOfflineModeFromStatus(endpoint.Status);
StateManager.updateEndpointState(endpoint.Name, endpoint.Type, [])
.then(function success() {
$state.go('azure.dashboard');
})
.catch(function error(err) {
Notifications.error('Failure', err, 'Unable to connect to the Azure endpoint');
});
}
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');
});
}
function switchToDockerEndpoint(endpoint) {
if (endpoint.Status === 2 && endpoint.Snapshots[0] && endpoint.Snapshots[0].Swarm === true) {
Notifications.error('Failure', '', 'Endpoint is unreachable. Connect to another swarm manager.');
return;
} else if (endpoint.Status === 2 && !endpoint.Snapshots[0]) {
Notifications.error('Failure', '', 'Endpoint is unreachable and there is no snapshot available for offline browsing.');
return;
}
function triggerSnapshot() {
EndpointService.snapshotEndpoints()
.then(function success() {
Notifications.success('Success', 'Endpoints updated');
$state.reload();
})
.catch(function error(err) {
Notifications.error('Failure', err, 'An error occured during endpoint snapshot');
});
}
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');
});
}
function initView() {
$scope.isAdmin = Authentication.getUserDetails().role === 1;
function triggerSnapshot() {
EndpointService.snapshotEndpoints()
.then(function success() {
Notifications.success('Success', 'Endpoints updated');
$state.reload();
})
.catch(function error(err) {
Notifications.error('Failure', err, 'An error occured during endpoint snapshot');
});
}
MotdService.motd()
.then(function success(data) {
$scope.motd = data;
});
function initView() {
$scope.isAdmin = Authentication.getUserDetails().role === 1;
$q.all({
endpoints: EndpointService.endpoints(),
groups: GroupService.groups()
})
.then(function success(data) {
var endpoints = data.endpoints;
var groups = data.groups;
EndpointHelper.mapGroupNameToEndpoint(endpoints, groups);
$scope.endpoints = endpoints;
EndpointProvider.setEndpoints(endpoints);
})
.catch(function error(err) {
Notifications.error('Failure', err, 'Unable to retrieve endpoint information');
});
}
MotdService.motd()
.then(function success(data) {
$scope.motd = data;
});
$q.all({
endpoints: EndpointService.endpoints(),
groups: GroupService.groups()
})
.then(function success(data) {
var endpoints = data.endpoints;
var groups = data.groups;
EndpointHelper.mapGroupNameToEndpoint(endpoints, groups);
$scope.endpoints = endpoints;
EndpointProvider.setEndpoints(endpoints);
})
.catch(function error(err) {
Notifications.error('Failure', err, 'Unable to retrieve endpoint information');
});
}
initView();
}]);
initView();
}]);

View file

@ -1,6 +1,6 @@
angular.module('portainer.app')
.controller('TeamsController', ['$q', '$scope', '$state', '$sanitize', 'TeamService', 'UserService', 'ModalService', 'Notifications', 'Authentication',
function ($q, $scope, $state, $sanitize, TeamService, UserService, ModalService, Notifications, Authentication) {
.controller('TeamsController', ['$q', '$scope', '$state', 'TeamService', 'UserService', 'ModalService', 'Notifications', 'Authentication',
function ($q, $scope, $state, TeamService, UserService, ModalService, Notifications, Authentication) {
$scope.state = {
actionInProgress: false
};
@ -22,7 +22,7 @@ function ($q, $scope, $state, $sanitize, TeamService, UserService, ModalService,
};
$scope.addTeam = function() {
var teamName = $sanitize($scope.formValues.Name);
var teamName = $scope.formValues.Name;
var leaderIds = [];
angular.forEach($scope.formValues.Leaders, function(user) {
leaderIds.push(user.Id);