diff --git a/static/directives/signin-form.html b/static/directives/signin-form.html
index ef0b5f795..cf982f08b 100644
--- a/static/directives/signin-form.html
+++ b/static/directives/signin-form.html
@@ -4,19 +4,17 @@
placeholder="Username" ng-model="user.username" autofocus>
-
-
+
+
OR
-
-
+
+
Sign In with GitHub
-
+
Invalid username or password.
diff --git a/static/js/app.js b/static/js/app.js
index 85893934e..cd4a9ad70 100644
--- a/static/js/app.js
+++ b/static/js/app.js
@@ -174,7 +174,8 @@ quayApp = angular.module('quay', ['ngRoute', 'restangular', 'angularMoment', 'an
return keyService;
}]);
- $provide.factory('PlanService', ['Restangular', 'KeyService', 'UserService', function(Restangular, KeyService, UserService) {
+ $provide.factory('PlanService', ['Restangular', 'KeyService', 'UserService', '$cookieStore',
+ function(Restangular, KeyService, UserService, $cookieStore) {
var plans = null;
var planDict = {};
var planService = {};
@@ -192,6 +193,29 @@ quayApp = angular.module('quay', ['ngRoute', 'restangular', 'angularMoment', 'an
}
}
};
+
+ planService.notePlan = function(planId) {
+ $cookieStore.put('quay.notedplan', planId);
+ };
+
+ planService.handleNotedPlan = function() {
+ var planId = planService.getAndResetNotedPlan();
+ if (!planId) { return; }
+
+ planService.isBusinessPlan(planId, function(bus) {
+ if (bus) {
+ document.location = '/organizations/new/?plan=' + planId;
+ } else {
+ document.location = '/user?plan=' + planId;
+ }
+ });
+ };
+
+ planService.getAndResetNotedPlan = function() {
+ var planId = $cookieStore.get('quay.notedplan');
+ $cookieStore.put('quay.notedplan', '');
+ return planId;
+ };
planService.handleCardError = function(resp) {
if (!planService.isCardError(resp)) { return; }
@@ -249,6 +273,20 @@ quayApp = angular.module('quay', ['ngRoute', 'restangular', 'angularMoment', 'an
});
};
+ planService.isBusinessPlan = function(planId, callback) {
+ planService.verifyLoaded(function() {
+ planSource = plans.business;
+ for (var i = 0; i < planSource.length; i++) {
+ var plan = planSource[i];
+ if (plan.stripeId == planId) {
+ callback(true);
+ return;
+ }
+ }
+ callback(false);
+ });
+ };
+
planService.getPlans = function(callback) {
planService.verifyLoaded(callback);
};
@@ -602,31 +640,57 @@ quayApp.directive('signinForm', function () {
transclude: true,
restrict: 'C',
scope: {
- 'redirectUrl': '=redirectUrl'
+ 'redirectUrl': '=redirectUrl',
+ 'signInStarted': '&signInStarted',
+ 'signedIn': '&signedIn'
},
controller: function($scope, $location, $timeout, Restangular, KeyService, UserService) {
- $scope.githubClientId = KeyService.githubClientId;
+ $scope.showGithub = function() {
+ $scope.markStarted();
- var appendMixpanelId = function() {
+ var mixpanelDistinctIdClause = '';
if (mixpanel.get_distinct_id !== undefined) {
- $scope.mixpanelDistinctIdClause = "&state=" + mixpanel.get_distinct_id();
- } else {
- // Mixpanel not yet loaded, try again later
- $timeout(appendMixpanelId, 200);
+ $scope.mixpanelDistinctIdClause = "&state=" + encodeURIComponent(mixpanel.get_distinct_id());
}
+
+ // Needed to ensure that UI work done by the started callback is finished before the location
+ // changes.
+ $timeout(function() {
+ var url = 'https://github.com/login/oauth/authorize?client_id=' + encodeURIComponent(KeyService.githubClientId) +
+ '&scope=user:email' + mixpanelDistinctIdClause;
+ document.location = url;
+ }, 250);
};
- appendMixpanelId();
+ $scope.markStarted = function() {
+ if ($scope.signInStarted != null) {
+ $scope.signInStarted();
+ }
+ };
$scope.signin = function() {
+ $scope.markStarted();
+
var signinPost = Restangular.one('signin');
signinPost.customPOST($scope.user).then(function() {
$scope.needsEmailVerification = false;
$scope.invalidCredentials = false;
- // Redirect to the specified page or the landing page
+ if ($scope.signedIn != null) {
+ $scope.signedIn();
+ }
+
UserService.load();
- $location.path($scope.redirectUrl ? $scope.redirectUrl : '/');
+
+ // Redirect to the specified page or the landing page
+ // Note: The timeout of 500ms is needed to ensure dialogs containing sign in
+ // forms get removed before the location changes.
+ $timeout(function() {
+ if ($scope.redirectUrl == $location.path()) {
+ return;
+ }
+ $location.path($scope.redirectUrl ? $scope.redirectUrl : '/');
+ }, 500);
}, function(result) {
$scope.needsEmailVerification = result.data.needsEmailVerification;
$scope.invalidCredentials = result.data.invalidCredentials;
@@ -1850,8 +1914,9 @@ quayApp.directive('ngBlur', function() {
};
});
-quayApp.run(['$location', '$rootScope', 'Restangular', 'UserService', '$http', '$cookieStore', '$timeout',
- function($location, $rootScope, Restangular, UserService, $http, $cookieStore, $timeout) {
+quayApp.run(['$location', '$rootScope', 'Restangular', 'UserService', 'PlanService', '$http', '$cookieStore', '$timeout',
+ function($location, $rootScope, Restangular, UserService, PlanService, $http, $cookieStore, $timeout) {
+ // Handle session expiration.
Restangular.setErrorInterceptor(function(response) {
if (response.status == 401) {
$('#sessionexpiredModal').modal({});
@@ -1861,6 +1926,9 @@ quayApp.run(['$location', '$rootScope', 'Restangular', 'UserService', '$http', '
return true;
});
+ // Check if we need to redirect based on a previously chosen plan.
+ PlanService.handleNotedPlan();
+
var changeTab = function(activeTab) {
$timeout(function() {
$('a[data-toggle="tab"]').each(function(index) {
diff --git a/static/js/controllers.js b/static/js/controllers.js
index 8c362d1c7..ba0b31855 100644
--- a/static/js/controllers.js
+++ b/static/js/controllers.js
@@ -38,10 +38,17 @@ function PlansCtrl($scope, $location, UserService, PlanService) {
$scope.user = currentUser;
}, true);
+ $scope.signedIn = function() {
+ $('#signinModal').modal('hide');
+ PlanService.handleNotedPlan();
+
+ };
+
$scope.buyNow = function(plan) {
if ($scope.user && !$scope.user.anonymous) {
document.location = '/user?plan=' + plan;
} else {
+ PlanService.notePlan(plan);
$('#signinModal').modal({});
}
};
@@ -50,6 +57,7 @@ function PlansCtrl($scope, $location, UserService, PlanService) {
if ($scope.user && !$scope.user.anonymous) {
document.location = '/organizations/new/?plan=' + plan;
} else {
+ PlanService.notePlan(plan);
$('#signinModal').modal({});
}
};
@@ -106,7 +114,7 @@ function RepoListCtrl($scope, Restangular, UserService) {
});
}
-function LandingCtrl($scope, $timeout, $location, Restangular, UserService, KeyService) {
+function LandingCtrl($scope, $timeout, $location, Restangular, UserService, KeyService, PlanService) {
$scope.namespace = null;
$scope.$watch('namespace', function(namespace) {
@@ -1270,7 +1278,7 @@ function OrgsCtrl($scope, UserService) {
function NewOrgCtrl($scope, $routeParams, $timeout, $location, UserService, PlanService, Restangular) {
$scope.loading = true;
- $scope.$watch( function () { return UserService.currentUser(); }, function (currentUser) {
+ $scope.$watch(function () { return UserService.currentUser(); }, function (currentUser) {
$scope.user = currentUser;
$scope.loading = false;
}, true);
@@ -1288,6 +1296,16 @@ function NewOrgCtrl($scope, $routeParams, $timeout, $location, UserService, Plan
}
});
+ $scope.signedIn = function() {
+ PlanService.handleNotedPlan();
+ };
+
+ $scope.signinStarted = function() {
+ PlanService.getMinimumPlan(1, true, function(plan) {
+ PlanService.notePlan(plan.stripeId);
+ });
+ };
+
$scope.setPlan = function(plan) {
$scope.currentPlan = plan;
};
diff --git a/static/partials/new-organization.html b/static/partials/new-organization.html
index 955c0d2d0..2180834c4 100644
--- a/static/partials/new-organization.html
+++ b/static/partials/new-organization.html
@@ -43,7 +43,8 @@
Sign In
diff --git a/static/partials/plans.html b/static/partials/plans.html
index 178169b79..2172d15bf 100644
--- a/static/partials/plans.html
+++ b/static/partials/plans.html
@@ -83,7 +83,7 @@
Please Sign In
- Please sign into Quay in order to continue
+