2015-02-19 21:21:54 +00:00
|
|
|
/**
|
|
|
|
* Element for managing subscriptions.
|
|
|
|
*/
|
|
|
|
angular.module('quay').directive('planManager', function () {
|
|
|
|
var directiveDefinitionObject = {
|
|
|
|
priority: 0,
|
|
|
|
templateUrl: '/static/directives/plan-manager.html',
|
|
|
|
replace: false,
|
|
|
|
transclude: false,
|
|
|
|
restrict: 'C',
|
|
|
|
scope: {
|
|
|
|
'user': '=user',
|
|
|
|
'organization': '=organization',
|
2015-05-07 20:43:45 +00:00
|
|
|
|
|
|
|
'hasSubscription': '=hasSubscription',
|
|
|
|
|
2015-02-19 21:21:54 +00:00
|
|
|
'readyForPlan': '&readyForPlan',
|
|
|
|
'planChanged': '&planChanged'
|
|
|
|
},
|
|
|
|
controller: function($scope, $element, PlanService, ApiService) {
|
|
|
|
$scope.isExistingCustomer = false;
|
|
|
|
|
|
|
|
$scope.parseDate = function(timestamp) {
|
|
|
|
return new Date(timestamp * 1000);
|
|
|
|
};
|
|
|
|
|
|
|
|
$scope.isPlanVisible = function(plan, subscribedPlan) {
|
2015-08-13 03:42:40 +00:00
|
|
|
if ($scope.organization && !PlanService.isOrgCompatible(plan)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-08-12 14:48:40 +00:00
|
|
|
// A plan is visible if it is not deprecated, or if it is both not superseded
|
|
|
|
// by another plan, and also the active plan for the user.
|
2015-02-19 21:21:54 +00:00
|
|
|
if (plan['deprecated']) {
|
2015-08-13 03:42:40 +00:00
|
|
|
var superseded = PlanService.getPlanImmediately(plan['superseded_by']);
|
2015-08-12 14:48:40 +00:00
|
|
|
if (superseded) {
|
|
|
|
return !$scope.isPlanVisible(superseded, subscribedPlan);
|
|
|
|
}
|
2015-02-19 21:21:54 +00:00
|
|
|
|
2015-08-13 16:25:21 +00:00
|
|
|
return subscribedPlan && plan.stripeId === subscribedPlan.stripeId;
|
2015-02-19 21:21:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
2015-08-12 14:48:40 +00:00
|
|
|
$scope.isPlanActive = function(plan, subscribedPlan) {
|
|
|
|
// A plan is active if it is either the plan directly subscribed to by the user
|
|
|
|
// or the plan which supersedes the plan to which the user is subscribed.
|
|
|
|
if (!subscribedPlan) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (subscribedPlan['deprecated'] && subscribedPlan['superseded_by']) {
|
|
|
|
return $scope.isPlanActive(plan, PlanService.getPlanImmediately(subscribedPlan['superseded_by']));
|
|
|
|
}
|
|
|
|
|
2015-08-13 03:42:40 +00:00
|
|
|
return plan.stripeId === subscribedPlan.stripeId;
|
2015-08-12 14:48:40 +00:00
|
|
|
};
|
|
|
|
|
2015-02-19 21:21:54 +00:00
|
|
|
$scope.changeSubscription = function(planId, opt_async) {
|
|
|
|
if ($scope.planChanging) { return; }
|
|
|
|
|
|
|
|
var callbacks = {
|
|
|
|
'opening': function() { $scope.planChanging = true; },
|
|
|
|
'started': function() { $scope.planChanging = true; },
|
|
|
|
'opened': function() { $scope.planChanging = true; },
|
|
|
|
'closed': function() { $scope.planChanging = false; },
|
|
|
|
'success': subscribedToPlan,
|
|
|
|
'failure': function(resp) {
|
|
|
|
$scope.planChanging = false;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
PlanService.changePlan($scope, $scope.organization, planId, callbacks, opt_async);
|
|
|
|
};
|
|
|
|
|
|
|
|
$scope.cancelSubscription = function() {
|
|
|
|
$scope.changeSubscription(PlanService.getFreePlan());
|
|
|
|
};
|
|
|
|
|
|
|
|
var subscribedToPlan = function(sub) {
|
|
|
|
$scope.subscription = sub;
|
|
|
|
$scope.isExistingCustomer = !!sub['isExistingCustomer'];
|
|
|
|
|
|
|
|
PlanService.getPlanIncludingDeprecated(sub.plan, function(subscribedPlan) {
|
|
|
|
$scope.subscribedPlan = subscribedPlan;
|
|
|
|
$scope.planUsagePercent = sub.usedPrivateRepos * 100 / $scope.subscribedPlan.privateRepos;
|
|
|
|
|
|
|
|
if ($scope.planChanged) {
|
|
|
|
$scope.planChanged({ 'plan': subscribedPlan });
|
|
|
|
}
|
|
|
|
|
|
|
|
$scope.planChanging = false;
|
|
|
|
$scope.planLoading = false;
|
2015-05-07 20:43:45 +00:00
|
|
|
$scope.hasSubscription = subscribedPlan.stripeId != PlanService.getFreePlan();
|
2015-02-19 21:21:54 +00:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
var update = function() {
|
|
|
|
$scope.planLoading = true;
|
|
|
|
if (!$scope.plans) { return; }
|
|
|
|
|
|
|
|
PlanService.getSubscription($scope.organization, subscribedToPlan, function() {
|
|
|
|
$scope.isExistingCustomer = false;
|
|
|
|
subscribedToPlan({ 'plan': PlanService.getFreePlan() });
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
var loadPlans = function() {
|
|
|
|
if ($scope.plans || $scope.loadingPlans) { return; }
|
|
|
|
if (!$scope.user && !$scope.organization) { return; }
|
|
|
|
|
|
|
|
$scope.loadingPlans = true;
|
|
|
|
PlanService.verifyLoaded(function(plans) {
|
|
|
|
$scope.plans = plans;
|
|
|
|
update();
|
|
|
|
|
|
|
|
if ($scope.readyForPlan) {
|
|
|
|
var planRequested = $scope.readyForPlan();
|
|
|
|
if (planRequested && planRequested != PlanService.getFreePlan()) {
|
|
|
|
$scope.changeSubscription(planRequested, /* async */true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
// Start the initial download.
|
|
|
|
$scope.planLoading = true;
|
|
|
|
loadPlans();
|
|
|
|
|
|
|
|
$scope.$watch('organization', loadPlans);
|
|
|
|
$scope.$watch('user', loadPlans);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
return directiveDefinitionObject;
|
|
|
|
});
|
|
|
|
|