Add invite by email (WIP)

This commit is contained in:
Joseph Schorr 2014-08-28 20:49:11 -04:00
parent f15b3f345e
commit ae92098b23
5 changed files with 91 additions and 7 deletions

View file

@ -3544,6 +3544,12 @@ p.editable:hover i {
white-space: nowrap;
}
.tt-message {
padding: 10px;
font-size: 12px;
white-space: nowrap;
}
.tt-suggestion p {
margin: 0;
}

View file

@ -2,10 +2,13 @@
<div class="entity-search"
namespace="orgname" placeholder="'Add a registered user or robot...'"
entity-selected="addNewMember(entity)"
email-selected="inviteEmail(email)"
current-entity="selectedMember"
auto-clear="true"
allowed-entities="['user', 'robot']"
pull-right="true"
allow-emails="true"
email-message="Press enter to invite the entered e-mail address to this team"
ng-show="!addingMember"></div>
<div class="quay-spinner" ng-show="addingMember"></div>
<div class="help-text" ng-show="!addingMember">

View file

@ -399,6 +399,11 @@ quayApp = angular.module('quay', quayDependencies, function($provide, cfpLoading
$provide.factory('UtilService', ['$sanitize', function($sanitize) {
var utilService = {};
utilService.isEmailAddress = function(val) {
var emailRegex = /^[a-zA-Z0-9.!#$%&*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
return emailRegex.test(val);
};
utilService.escapeHtmlString = function(text) {
var adjusted = text.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
@ -3478,7 +3483,9 @@ quayApp.directive('entitySearch', function () {
'allowedEntities': '=allowedEntities',
'currentEntity': '=currentEntity',
'entitySelected': '&entitySelected',
'emailSelected': '&emailSelected',
// When set to true, the contents of the control will be cleared as soon
// as an entity is selected.
@ -3487,9 +3494,14 @@ quayApp.directive('entitySearch', function () {
// Set this property to immediately clear the contents of the control.
'clearValue': '=clearValue',
// Whether e-mail addresses are allowed.
'allowEmails': '@allowEmails',
'emailMessage': '@emailMessage',
// True if the menu should pull right.
'pullRight': '@pullRight'
},
controller: function($rootScope, $scope, $element, Restangular, UserService, ApiService, Config) {
controller: function($rootScope, $scope, $element, Restangular, UserService, ApiService, UtilService, Config) {
$scope.lazyLoading = true;
$scope.teams = null;
@ -3686,8 +3698,12 @@ quayApp.directive('entitySearch', function () {
return null;
}
if (val.indexOf('@') > 0) {
return '<div class="tt-empty">A ' + Config.REGISTRY_TITLE_SHORT + ' username (not an e-mail address) must be specified</div>';
if (UtilService.isEmailAddress(val)) {
if ($scope.allowEmails) {
return '<div class="tt-message">' + $scope.emailMessage + '</div>';
} else {
return '<div class="tt-empty">A ' + Config.REGISTRY_TITLE_SHORT + ' username (not an e-mail address) must be specified</div>';
}
}
var classes = [];
@ -3743,6 +3759,16 @@ quayApp.directive('entitySearch', function () {
}}
});
$(input).on('keypress', function(e) {
var val = $(input).val();
var code = e.keyCode || e.which;
if (code == 13 && $scope.allowEmails && UtilService.isEmailAddress(val)) {
$scope.$apply(function() {
$scope.emailSelected({'email': val});
});
}
});
$(input).on('input', function(e) {
$scope.$apply(function() {
$scope.clearEntityInternal();

View file

@ -2371,6 +2371,28 @@ function TeamViewCtrl($rootScope, $scope, Restangular, ApiService, $routeParams)
};
};
$scope.inviteEmail = function(email) {
if (!email || $scope.memberMap[email]) { return; }
$scope.addingMember = true;
var params = {
'orgname': orgname,
'teamname': teamname,
'email': email
};
var errorHandler = ApiService.errorDisplay('Cannot invite team member', function() {
$scope.addingMember = false;
});
ApiService.inviteTeamMemberEmail(null, params).then(function(resp) {
$scope.members.push(resp);
$scope.memberMap[resp.name] = resp;
$scope.addingMember = false;
}, errorHandler);
};
$scope.addNewMember = function(member) {
if (!member || $scope.memberMap[member.name]) { return; }
@ -2380,15 +2402,16 @@ function TeamViewCtrl($rootScope, $scope, Restangular, ApiService, $routeParams)
'membername': member.name
};
var errorHandler = ApiService.errorDisplay('Cannot add team member', function() {
$scope.addingMember = false;
});
$scope.addingMember = true;
ApiService.updateOrganizationTeamMember(null, params).then(function(resp) {
$scope.members.push(resp);
$scope.memberMap[resp.name] = resp;
$scope.addingMember = false;
}, function() {
$('#cannotChangeMembersModal').modal({});
$scope.addingMember = false;
});
}, errorHandler);
};
$scope.removeMember = function(username) {