Merge pull request #2066 from coreos-inc/select-username
Add support for temp usernames and an interstitial to confirm username
This commit is contained in:
commit
233b2be5c2
18 changed files with 388 additions and 24 deletions
25
static/css/pages/update-user.css
Normal file
25
static/css/pages/update-user.css
Normal file
|
@ -0,0 +1,25 @@
|
|||
.update-user p {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.update-user .username-status {
|
||||
margin-left: 10px;
|
||||
font-size: 125%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.update-user .username-status .fa {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.update-user i.fa-exclamation-triangle {
|
||||
color: #FCA657;
|
||||
}
|
||||
|
||||
.update-user i.fa-check-circle {
|
||||
color: #2FC98E;
|
||||
}
|
||||
|
||||
.update-user i.fa-ban {
|
||||
color: #D64456;
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
<span class="namespace-input-element">
|
||||
<input type="text" class="form-control" placeholder="{{ namespaceTitle }}" ng-model="binding"
|
||||
required autofocus ng-pattern="usernamePattern"
|
||||
name="namespaceField">
|
||||
ng-model-options="{'debounce': 200}"
|
||||
name="namespaceField"
|
||||
ng-class="hasExternalError ? 'ng-invalid' : ''">
|
||||
</span>
|
|
@ -191,6 +191,9 @@ quayApp.config(['$routeProvider', '$locationProvider', 'pages', function($routeP
|
|||
// Privacy
|
||||
.route('/privacy', 'privacy')
|
||||
|
||||
// Change username
|
||||
.route('/updateuser', 'update-user')
|
||||
|
||||
// Landing Page
|
||||
.route('/', 'landing')
|
||||
|
||||
|
|
|
@ -11,13 +11,14 @@ angular.module('quay').directive('namespaceInput', function () {
|
|||
scope: {
|
||||
'binding': '=binding',
|
||||
'isBackIncompat': '=isBackIncompat',
|
||||
'hasExternalError': '=?hasExternalError',
|
||||
|
||||
'namespaceTitle': '@namespaceTitle',
|
||||
},
|
||||
controller: function($scope, $element) {
|
||||
$scope.USERNAME_PATTERN = USERNAME_PATTERN;
|
||||
$scope.usernamePattern = new RegExp(USERNAME_PATTERN);
|
||||
|
||||
|
||||
$scope.$watch('binding', function(binding) {
|
||||
if (!binding) {
|
||||
$scope.isBackIncompat = false;
|
||||
|
|
80
static/js/pages/update-user.js
Normal file
80
static/js/pages/update-user.js
Normal file
|
@ -0,0 +1,80 @@
|
|||
(function() {
|
||||
/**
|
||||
* Update user page.
|
||||
*/
|
||||
angular.module('quayPages').config(['pages', function(pages) {
|
||||
pages.create('update-user', 'update-user.html', UpdateUserCtrl, {
|
||||
'title': 'Confirm Username'
|
||||
});
|
||||
}]);
|
||||
|
||||
function UpdateUserCtrl($scope, UserService, $location, ApiService) {
|
||||
$scope.state = 'loading';
|
||||
|
||||
UserService.updateUserIn($scope, function(user) {
|
||||
if (!user.prompts || !user.prompts.length) {
|
||||
$location.path('/');
|
||||
return;
|
||||
}
|
||||
|
||||
$scope.state = 'editing';
|
||||
$scope.username = user.username;
|
||||
});
|
||||
|
||||
var confirmUsername = function(username) {
|
||||
if (username == $scope.user.username) {
|
||||
$scope.state = 'confirmed';
|
||||
return;
|
||||
}
|
||||
|
||||
$scope.state = 'confirming';
|
||||
var params = {
|
||||
'username': username
|
||||
};
|
||||
|
||||
ApiService.getUserInformation(null, params).then(function() {
|
||||
$scope.state = 'existing';
|
||||
}, function(resp) {
|
||||
if (resp.status == 404) {
|
||||
$scope.state = 'confirmed';
|
||||
} else {
|
||||
$scope.state = 'error';
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$scope.updateUsername = function(username) {
|
||||
$scope.state = 'updating';
|
||||
var data = {
|
||||
'username': username
|
||||
};
|
||||
|
||||
ApiService.changeUserDetails(data).then(function() {
|
||||
window.location = '/';
|
||||
}, ApiService.errorDisplay('Could not update username'));
|
||||
};
|
||||
|
||||
$scope.hasPrompt = function(user, prompt_name) {
|
||||
if (!user.prompts) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < user.prompts.length; ++i) {
|
||||
if (user.prompts[i] == prompt_name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
$scope.$watch('username', function(username) {
|
||||
if (!username) {
|
||||
$scope.state = 'editing';
|
||||
return;
|
||||
}
|
||||
|
||||
confirmUsername(username);
|
||||
});
|
||||
}
|
||||
})();
|
|
@ -91,8 +91,14 @@ function(ApiService, CookieService, $rootScope, Config, $location) {
|
|||
}
|
||||
}
|
||||
|
||||
// If the loaded user has a prompt, redirect them to the update page.
|
||||
if (loadedUser.prompts && loadedUser.prompts.length) {
|
||||
$location.path('/updateuser');
|
||||
return;
|
||||
}
|
||||
|
||||
if (opt_callback) {
|
||||
opt_callback();
|
||||
opt_callback(loadedUser);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
36
static/partials/update-user.html
Normal file
36
static/partials/update-user.html
Normal file
|
@ -0,0 +1,36 @@
|
|||
<div class="cor-loader-inline" ng-if="user.anonymous || state == 'updating'"></div>
|
||||
<!-- TODO: Support additional kinds of prompts here -->
|
||||
|
||||
<div class="update-user" ng-show="hasPrompt(user, 'confirm_username') && state != 'updating'">
|
||||
<h2>Confirm Username</h2>
|
||||
<p>
|
||||
The username <strong>{{ user.username }}</strong> was automatically generated to conform to the
|
||||
Docker CLI guidelines for use as a namespace in <span class="registry-title"></span>.
|
||||
</p>
|
||||
<p>Please confirm the selected username or enter a different username below:</p>
|
||||
<form name="usernameForm" ng-submit="updateUsername(username)">
|
||||
<div class="namespace-input" binding="username" is-back-incompat="isBackIncompat"
|
||||
namespace-title="Username" style="margin-bottom: 20px;"
|
||||
has-external-error="state == 'existing'"></div>
|
||||
|
||||
<input type="submit" class="btn btn-primary"
|
||||
ng-disabled="usernameForm.$invalid || state != 'confirmed'"
|
||||
value="Confirm Username">
|
||||
<span class="cor-loader-inline" ng-show="state == 'confirming'"></span>
|
||||
<span class="username-status" ng-show="state == 'confirmed' && !isBackIncompat">
|
||||
<i class="fa fa-check-circle"></i> Username valid
|
||||
</span>
|
||||
<span class="username-status" ng-show="state == 'existing'">
|
||||
<i class="fa fa-ban"></i> Username already taken
|
||||
</span>
|
||||
<span class="username-status" ng-show="state == 'error'">
|
||||
<i class="fa fa-exclamation-triangle"></i> Could not check username
|
||||
</span>
|
||||
<span class="username-status" ng-show="state == 'editing' && usernameForm.$invalid">
|
||||
Usernames must be alphanumeric and be at least four characters in length
|
||||
</span>
|
||||
<span class="username-status" ng-show="state == 'confirmed' && isBackIncompat">
|
||||
<i class="fa fa-exclamation-triangle"></i> Note: Usernames with dots or dashes are incompatible with Docker verion 1.8 or older
|
||||
</span>
|
||||
</form>
|
||||
</div>
|
Reference in a new issue