- Add API for returning the user’s used private repos and available private repos
- Fix the same API for orgs - Change the chosen plan in the create repo view to use the API - Add an account indicator if the user is over their plan
This commit is contained in:
parent
95a8915546
commit
ed82d65dd1
5 changed files with 74 additions and 14 deletions
|
@ -118,6 +118,26 @@ def get_logged_in_user():
|
|||
return jsonify(user_view(user))
|
||||
|
||||
|
||||
@app.route('/api/user/private', methods=['GET'])
|
||||
@api_login_required
|
||||
def get_user_private_count():
|
||||
user = current_user.db_user()
|
||||
private_repos = model.get_private_repo_count(user.username)
|
||||
repos_allowed = 0
|
||||
|
||||
if user.stripe_id:
|
||||
cus = stripe.Customer.retrieve(user.stripe_id)
|
||||
if cus.subscription:
|
||||
plan = get_plan(cus.subscription.plan.id)
|
||||
if plan:
|
||||
repos_allowed = plan['privateRepos']
|
||||
|
||||
return jsonify({
|
||||
'privateCount': private_repos,
|
||||
'reposAllowed': repos_allowed
|
||||
})
|
||||
|
||||
|
||||
@app.route('/api/user/convert', methods=['POST'])
|
||||
@api_login_required
|
||||
def convert_user_to_organization():
|
||||
|
@ -485,7 +505,11 @@ def get_organization_private_allowed(orgname):
|
|||
if organization.stripe_id:
|
||||
cus = stripe.Customer.retrieve(organization.stripe_id)
|
||||
if cus.subscription:
|
||||
repos_allowed = get_plan(cus.subscription.plan.id)
|
||||
repos_allowed = 0
|
||||
plan = get_plan(cus.subscription.plan.id)
|
||||
if plan:
|
||||
repos_allowed = plan['privateRepos']
|
||||
|
||||
return jsonify({
|
||||
'privateAllowed': (private_repos < repos_allowed)
|
||||
})
|
||||
|
|
|
@ -38,14 +38,18 @@
|
|||
<a href="javascript:void(0)" class="dropdown-toggle user-dropdown" data-toggle="dropdown">
|
||||
<img src="//www.gravatar.com/avatar/{{ user.gravatar }}?s=32&d=identicon" />
|
||||
{{ user.username }}
|
||||
<span class="badge user-notification notification-animated" ng-show="user.askForPassword">1</span>
|
||||
<span class="badge user-notification notification-animated" ng-show="user.askForPassword || overPlan">
|
||||
{{ (user.askForPassword ? 1 : 0) + (overPlan ? 1 : 0) }}
|
||||
</span>
|
||||
<b class="caret"></b>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li>
|
||||
<a href="/user/" target="{{ appLinkTarget() }}">
|
||||
Account Settings
|
||||
<span class="badge user-notification" ng-show="user.askForPassword">1</span>
|
||||
<span class="badge user-notification" ng-show="user.askForPassword || overPlan">
|
||||
{{ (user.askForPassword ? 1 : 0) + (overPlan ? 1 : 0) }}
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li><a ng-href="/organizations/" target="{{ appLinkTarget() }}">Organizations</a></li>
|
||||
|
|
|
@ -1493,10 +1493,26 @@ quayApp.directive('headerBar', function () {
|
|||
restrict: 'C',
|
||||
scope: {
|
||||
},
|
||||
controller: function($scope, $element, $location, UserService, Restangular) {
|
||||
$scope.$watch( function () { return UserService.currentUser(); }, function (currentUser) {
|
||||
$scope.user = currentUser;
|
||||
}, true);
|
||||
controller: function($scope, $element, $location, UserService, PlanService, Restangular) {
|
||||
$scope.overPlan = false;
|
||||
|
||||
var checkOverPlan = function() {
|
||||
if ($scope.user.anonymous) {
|
||||
$scope.overPlan = false;
|
||||
return;
|
||||
}
|
||||
|
||||
var checkPrivate = Restangular.one('user/private');
|
||||
checkPrivate.customGET().then(function(resp) {
|
||||
$scope.overPlan = resp.privateCount >= resp.reposAllowed;
|
||||
});
|
||||
};
|
||||
|
||||
// Monitor any user changes and place the current user into the scope.
|
||||
UserService.updateUserIn($scope, checkOverPlan);
|
||||
|
||||
// Monitor any plan changes.
|
||||
PlanService.registerListener(this, checkOverPlan);
|
||||
|
||||
$scope.signout = function() {
|
||||
var signoutPost = Restangular.one('signout');
|
||||
|
@ -1511,7 +1527,7 @@ quayApp.directive('headerBar', function () {
|
|||
return "_self";
|
||||
}
|
||||
return "";
|
||||
};
|
||||
};
|
||||
}
|
||||
};
|
||||
return directiveDefinitionObject;
|
||||
|
|
|
@ -810,23 +810,34 @@ function NewRepoCtrl($scope, $location, $http, $timeout, UserService, Restangula
|
|||
|
||||
var isUserNamespace = (namespace == $scope.user.username);
|
||||
|
||||
$scope.checkingPlan = true;
|
||||
$scope.planRequired = null;
|
||||
$scope.isUserNamespace = isUserNamespace;
|
||||
|
||||
if (isUserNamespace) {
|
||||
// Load the user's subscription information in case they want to create a private
|
||||
// repository.
|
||||
PlanService.getSubscription(null, subscribedToPlan, function() {
|
||||
PlanService.getMinimumPlan(1, false, function(minimum) { $scope.planRequired = minimum; });
|
||||
var checkPrivateAllowed = Restangular.one('user/private');
|
||||
checkPrivateAllowed.get().then(function(resp) {
|
||||
if (resp.privateCount + 1 > resp.reposAllowed) {
|
||||
PlanService.getMinimumPlan(resp.privateCount + 1, false, function(minimum) {
|
||||
$scope.planRequired = minimum;
|
||||
});
|
||||
}
|
||||
|
||||
$scope.checkingPlan = false;
|
||||
}, function() {
|
||||
$scope.planRequired = {};
|
||||
$scope.checkingPlan = false;
|
||||
});
|
||||
} else {
|
||||
$scope.planRequired = null;
|
||||
|
||||
var checkPrivateAllowed = Restangular.one('organization/' + namespace + '/private');
|
||||
checkPrivateAllowed.get().then(function(resp) {
|
||||
$scope.planRequired = resp.privateAllowed ? null : {};
|
||||
$scope.checkingPlan = false;
|
||||
}, function() {
|
||||
$scope.planRequired = {};
|
||||
$scope.checkingPlan = false;
|
||||
});
|
||||
|
||||
// Auto-set to private repo.
|
||||
|
|
|
@ -74,12 +74,14 @@
|
|||
<!-- Payment -->
|
||||
<div class="required-plan" ng-show="repo.is_public == '0' && planRequired && isUserNamespace">
|
||||
<div class="alert alert-warning">
|
||||
In order to make this repository private, you’ll need to upgrade your plan from <b>{{ subscribedPlan.title }}</b> to <b>{{ planRequired.title }}</b>. This will cost $<span>{{ planRequired.price / 100 }}</span>/month.
|
||||
In order to make this repository private, you’ll need to upgrade your plan to <b>{{ planRequired.title }}</b>. This will cost $<span>{{ planRequired.price / 100 }}</span>/month.
|
||||
</div>
|
||||
<a class="btn btn-primary" ng-click="upgradePlan()" ng-show="!planChanging">Upgrade now</a>
|
||||
<div class="quay-spinner" ng-show="planChanging"></div>
|
||||
</div>
|
||||
|
||||
<div class="quay-spinner" ng-show="repo.is_public == '0' && checkingPlan"></div>
|
||||
|
||||
<div class="required-plan" ng-show="repo.is_public == '0' && planRequired && !isUserNamespace">
|
||||
<div class="alert alert-warning">
|
||||
This organization has reached its private repository limit. Please contact your administrator.
|
||||
|
@ -114,7 +116,10 @@
|
|||
<div class="row">
|
||||
<div class="col-md-1"></div>
|
||||
<div class="col-md-8">
|
||||
<button class="btn btn-large btn-success" type="submit" ng-disabled="newRepoForm.$invalid || (repo.is_public == '0' && planRequired)">Create Repository</button>
|
||||
<button class="btn btn-large btn-success" type="submit"
|
||||
ng-disabled="newRepoForm.$invalid || (repo.is_public == '0' && (planRequired || checkingPlan))">
|
||||
Create Repository
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
Reference in a new issue