Code cleanup part #1: move all the services and directive JS code in the app.js file into its own files
This commit is contained in:
parent
3cae6609a7
commit
9b87999c1c
97 changed files with 7076 additions and 6870 deletions
357
static/js/services/plan-service.js
Normal file
357
static/js/services/plan-service.js
Normal file
|
@ -0,0 +1,357 @@
|
|||
/**
|
||||
* Helper service for loading, changing and working with subscription plans.
|
||||
*/
|
||||
angular.module('quay')
|
||||
.factory('PlanService', ['KeyService', 'UserService', 'CookieService', 'ApiService', 'Features', 'Config',
|
||||
|
||||
function(KeyService, UserService, CookieService, ApiService, Features, Config) {
|
||||
var plans = null;
|
||||
var planDict = {};
|
||||
var planService = {};
|
||||
var listeners = [];
|
||||
|
||||
var previousSubscribeFailure = false;
|
||||
|
||||
planService.getFreePlan = function() {
|
||||
return 'free';
|
||||
};
|
||||
|
||||
planService.registerListener = function(obj, callback) {
|
||||
listeners.push({'obj': obj, 'callback': callback});
|
||||
};
|
||||
|
||||
planService.unregisterListener = function(obj) {
|
||||
for (var i = 0; i < listeners.length; ++i) {
|
||||
if (listeners[i].obj == obj) {
|
||||
listeners.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
planService.notePlan = function(planId) {
|
||||
if (Features.BILLING) {
|
||||
CookieService.putSession('quay.notedplan', planId);
|
||||
}
|
||||
};
|
||||
|
||||
planService.isOrgCompatible = function(plan) {
|
||||
return plan['stripeId'] == planService.getFreePlan() || plan['bus_features'];
|
||||
};
|
||||
|
||||
planService.getMatchingBusinessPlan = function(callback) {
|
||||
planService.getPlans(function() {
|
||||
planService.getSubscription(null, function(sub) {
|
||||
var plan = planDict[sub.plan];
|
||||
if (!plan) {
|
||||
planService.getMinimumPlan(0, true, callback);
|
||||
return;
|
||||
}
|
||||
|
||||
var count = Math.max(sub.usedPrivateRepos, plan.privateRepos);
|
||||
planService.getMinimumPlan(count, true, callback);
|
||||
}, function() {
|
||||
planService.getMinimumPlan(0, true, callback);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
planService.handleNotedPlan = function() {
|
||||
var planId = planService.getAndResetNotedPlan();
|
||||
if (!planId || !Features.BILLING) { return false; }
|
||||
|
||||
UserService.load(function() {
|
||||
if (UserService.currentUser().anonymous) {
|
||||
return;
|
||||
}
|
||||
|
||||
planService.getPlan(planId, function(plan) {
|
||||
if (planService.isOrgCompatible(plan)) {
|
||||
document.location = '/organizations/new/?plan=' + planId;
|
||||
} else {
|
||||
document.location = '/user?plan=' + planId;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
planService.getAndResetNotedPlan = function() {
|
||||
var planId = CookieService.get('quay.notedplan');
|
||||
CookieService.clear('quay.notedplan');
|
||||
return planId;
|
||||
};
|
||||
|
||||
planService.handleCardError = function(resp) {
|
||||
if (!planService.isCardError(resp)) { return; }
|
||||
|
||||
bootbox.dialog({
|
||||
"message": resp.data.carderror,
|
||||
"title": "Credit card issue",
|
||||
"buttons": {
|
||||
"close": {
|
||||
"label": "Close",
|
||||
"className": "btn-primary"
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
planService.isCardError = function(resp) {
|
||||
return resp && resp.data && resp.data.carderror;
|
||||
};
|
||||
|
||||
planService.verifyLoaded = function(callback) {
|
||||
if (!Features.BILLING) { return; }
|
||||
|
||||
if (plans && plans.length) {
|
||||
callback(plans);
|
||||
return;
|
||||
}
|
||||
|
||||
ApiService.listPlans().then(function(data) {
|
||||
plans = data.plans || [];
|
||||
for(var i = 0; i < plans.length; i++) {
|
||||
planDict[plans[i].stripeId] = plans[i];
|
||||
}
|
||||
callback(plans);
|
||||
}, function() { callback([]); });
|
||||
};
|
||||
|
||||
planService.getPlans = function(callback, opt_includePersonal) {
|
||||
planService.verifyLoaded(function() {
|
||||
var filtered = [];
|
||||
for (var i = 0; i < plans.length; ++i) {
|
||||
var plan = plans[i];
|
||||
if (plan['deprecated']) { continue; }
|
||||
if (!opt_includePersonal && !planService.isOrgCompatible(plan)) { continue; }
|
||||
filtered.push(plan);
|
||||
}
|
||||
callback(filtered);
|
||||
});
|
||||
};
|
||||
|
||||
planService.getPlan = function(planId, callback) {
|
||||
planService.getPlanIncludingDeprecated(planId, function(plan) {
|
||||
if (!plan['deprecated']) {
|
||||
callback(plan);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
planService.getPlanIncludingDeprecated = function(planId, callback) {
|
||||
planService.verifyLoaded(function() {
|
||||
if (planDict[planId]) {
|
||||
callback(planDict[planId]);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
planService.getMinimumPlan = function(privateCount, isBusiness, callback) {
|
||||
planService.getPlans(function(plans) {
|
||||
for (var i = 0; i < plans.length; i++) {
|
||||
var plan = plans[i];
|
||||
if (plan.privateRepos >= privateCount) {
|
||||
callback(plan);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
callback(null);
|
||||
}, /* include personal */!isBusiness);
|
||||
};
|
||||
|
||||
planService.getSubscription = function(orgname, success, failure) {
|
||||
if (!Features.BILLING) { return; }
|
||||
|
||||
ApiService.getSubscription(orgname).then(success, failure);
|
||||
};
|
||||
|
||||
planService.setSubscription = function(orgname, planId, success, failure, opt_token) {
|
||||
if (!Features.BILLING) { return; }
|
||||
|
||||
var subscriptionDetails = {
|
||||
plan: planId
|
||||
};
|
||||
|
||||
if (opt_token) {
|
||||
subscriptionDetails['token'] = opt_token.id;
|
||||
}
|
||||
|
||||
ApiService.updateSubscription(orgname, subscriptionDetails).then(function(resp) {
|
||||
success(resp);
|
||||
planService.getPlan(planId, function(plan) {
|
||||
for (var i = 0; i < listeners.length; ++i) {
|
||||
listeners[i]['callback'](plan);
|
||||
}
|
||||
});
|
||||
}, failure);
|
||||
};
|
||||
|
||||
planService.getCardInfo = function(orgname, callback) {
|
||||
if (!Features.BILLING) { return; }
|
||||
|
||||
ApiService.getCard(orgname).then(function(resp) {
|
||||
callback(resp.card);
|
||||
}, function() {
|
||||
callback({'is_valid': false});
|
||||
});
|
||||
};
|
||||
|
||||
planService.changePlan = function($scope, orgname, planId, callbacks, opt_async) {
|
||||
if (!Features.BILLING) { return; }
|
||||
|
||||
if (callbacks['started']) {
|
||||
callbacks['started']();
|
||||
}
|
||||
|
||||
planService.getPlan(planId, function(plan) {
|
||||
if (orgname && !planService.isOrgCompatible(plan)) { return; }
|
||||
|
||||
planService.getCardInfo(orgname, function(cardInfo) {
|
||||
if (plan.price > 0 && (previousSubscribeFailure || !cardInfo.last4)) {
|
||||
var title = cardInfo.last4 ? 'Subscribe' : 'Start Trial ({{amount}} plan)';
|
||||
planService.showSubscribeDialog($scope, orgname, planId, callbacks, title, /* async */true);
|
||||
return;
|
||||
}
|
||||
|
||||
previousSubscribeFailure = false;
|
||||
|
||||
planService.setSubscription(orgname, planId, callbacks['success'], function(resp) {
|
||||
previousSubscribeFailure = true;
|
||||
planService.handleCardError(resp);
|
||||
callbacks['failure'](resp);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
planService.changeCreditCard = function($scope, orgname, callbacks) {
|
||||
if (!Features.BILLING) { return; }
|
||||
|
||||
if (callbacks['opening']) {
|
||||
callbacks['opening']();
|
||||
}
|
||||
|
||||
var submitted = false;
|
||||
var submitToken = function(token) {
|
||||
if (submitted) { return; }
|
||||
submitted = true;
|
||||
$scope.$apply(function() {
|
||||
if (callbacks['started']) {
|
||||
callbacks['started']();
|
||||
}
|
||||
|
||||
var cardInfo = {
|
||||
'token': token.id
|
||||
};
|
||||
|
||||
ApiService.setCard(orgname, cardInfo).then(callbacks['success'], function(resp) {
|
||||
planService.handleCardError(resp);
|
||||
callbacks['failure'](resp);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
var email = planService.getEmail(orgname);
|
||||
StripeCheckout.open({
|
||||
key: KeyService.stripePublishableKey,
|
||||
address: false,
|
||||
email: email,
|
||||
currency: 'usd',
|
||||
name: 'Update credit card',
|
||||
description: 'Enter your credit card number',
|
||||
panelLabel: 'Update',
|
||||
token: submitToken,
|
||||
image: 'static/img/quay-icon-stripe.png',
|
||||
opened: function() { $scope.$apply(function() { callbacks['opened']() }); },
|
||||
closed: function() { $scope.$apply(function() { callbacks['closed']() }); }
|
||||
});
|
||||
};
|
||||
|
||||
planService.getEmail = function(orgname) {
|
||||
var email = null;
|
||||
if (UserService.currentUser()) {
|
||||
email = UserService.currentUser().email;
|
||||
|
||||
if (orgname) {
|
||||
org = UserService.getOrganization(orgname);
|
||||
if (org) {
|
||||
emaiil = org.email;
|
||||
}
|
||||
}
|
||||
}
|
||||
return email;
|
||||
};
|
||||
|
||||
planService.showSubscribeDialog = function($scope, orgname, planId, callbacks, opt_title, opt_async) {
|
||||
if (!Features.BILLING) { return; }
|
||||
|
||||
// If the async parameter is true and this is a browser that does not allow async popup of the
|
||||
// Stripe dialog (such as Mobile Safari or IE), show a bootbox to show the dialog instead.
|
||||
var isIE = navigator.appName.indexOf("Internet Explorer") != -1;
|
||||
var isMobileSafari = navigator.userAgent.match(/(iPod|iPhone|iPad)/) && navigator.userAgent.match(/AppleWebKit/);
|
||||
|
||||
if (opt_async && (isIE || isMobileSafari)) {
|
||||
bootbox.dialog({
|
||||
"message": "Please click 'Subscribe' to continue",
|
||||
"buttons": {
|
||||
"subscribe": {
|
||||
"label": "Subscribe",
|
||||
"className": "btn-primary",
|
||||
"callback": function() {
|
||||
planService.showSubscribeDialog($scope, orgname, planId, callbacks, opt_title, false);
|
||||
}
|
||||
},
|
||||
"close": {
|
||||
"label": "Cancel",
|
||||
"className": "btn-default"
|
||||
}
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (callbacks['opening']) {
|
||||
callbacks['opening']();
|
||||
}
|
||||
|
||||
var submitted = false;
|
||||
var submitToken = function(token) {
|
||||
if (submitted) { return; }
|
||||
submitted = true;
|
||||
|
||||
if (Config.MIXPANEL_KEY) {
|
||||
mixpanel.track('plan_subscribe');
|
||||
}
|
||||
|
||||
$scope.$apply(function() {
|
||||
if (callbacks['started']) {
|
||||
callbacks['started']();
|
||||
}
|
||||
planService.setSubscription(orgname, planId, callbacks['success'], callbacks['failure'], token);
|
||||
});
|
||||
};
|
||||
|
||||
planService.getPlan(planId, function(planDetails) {
|
||||
var email = planService.getEmail(orgname);
|
||||
StripeCheckout.open({
|
||||
key: KeyService.stripePublishableKey,
|
||||
address: false,
|
||||
email: email,
|
||||
amount: planDetails.price,
|
||||
currency: 'usd',
|
||||
name: 'Quay.io ' + planDetails.title + ' Subscription',
|
||||
description: 'Up to ' + planDetails.privateRepos + ' private repositories',
|
||||
panelLabel: opt_title || 'Subscribe',
|
||||
token: submitToken,
|
||||
image: 'static/img/quay-icon-stripe.png',
|
||||
opened: function() { $scope.$apply(function() { callbacks['opened']() }); },
|
||||
closed: function() { $scope.$apply(function() { callbacks['closed']() }); }
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return planService;
|
||||
}]);
|
Reference in a new issue