1
0
mirror of https://github.com/bitwarden/web synced 2025-12-18 09:13:17 +00:00

shared org plans component

This commit is contained in:
Kyle Spearrin
2019-03-21 13:11:40 -04:00
parent 5dc00a8bc6
commit 0f3d71a504
8 changed files with 495 additions and 445 deletions

View File

@@ -3,243 +3,27 @@ import {
OnInit,
ViewChild,
} from '@angular/core';
import {
ActivatedRoute,
Router,
} from '@angular/router';
import { ActivatedRoute } from '@angular/router';
import { ToasterService } from 'angular2-toaster';
import { Angulartics2 } from 'angulartics2';
import { ApiService } from 'jslib/abstractions/api.service';
import { CryptoService } from 'jslib/abstractions/crypto.service';
import { I18nService } from 'jslib/abstractions/i18n.service';
import { PlatformUtilsService } from 'jslib/abstractions/platformUtils.service';
import { SyncService } from 'jslib/abstractions/sync.service';
import { PaymentComponent } from './payment.component';
import { PlanType } from 'jslib/enums/planType';
import { OrganizationCreateRequest } from 'jslib/models/request/organizationCreateRequest';
import { OrganizationPlansComponent } from './organization-plans.component';
@Component({
selector: 'app-create-organization',
templateUrl: 'create-organization.component.html',
})
export class CreateOrganizationComponent implements OnInit {
@ViewChild(PaymentComponent) paymentComponent: PaymentComponent;
@ViewChild(OrganizationPlansComponent) orgPlansComponent: OrganizationPlansComponent;
selfHosted = false;
ownedBusiness = false;
premiumAccessAddon = false;
storageGbPriceMonthly = 0.33;
additionalStorage = 0;
additionalSeats = 0;
plan = 'free';
interval = 'year';
name: string;
billingEmail: string;
businessName: string;
storageGb: any = {
price: 0.33,
monthlyPrice: 0.50,
yearlyPrice: 4,
};
plans: any = {
free: {
basePrice: 0,
noAdditionalSeats: true,
noPayment: true,
},
families: {
basePrice: 1,
annualBasePrice: 12,
baseSeats: 5,
noAdditionalSeats: true,
annualPlanType: PlanType.FamiliesAnnually,
canBuyPremiumAccessAddon: true,
},
teams: {
basePrice: 5,
annualBasePrice: 60,
monthlyBasePrice: 8,
baseSeats: 5,
seatPrice: 2,
annualSeatPrice: 24,
monthlySeatPrice: 2.5,
monthPlanType: PlanType.TeamsMonthly,
annualPlanType: PlanType.TeamsAnnually,
},
enterprise: {
seatPrice: 3,
annualSeatPrice: 36,
monthlySeatPrice: 4,
monthPlanType: PlanType.EnterpriseMonthly,
annualPlanType: PlanType.EnterpriseAnnually,
},
};
formPromise: Promise<any>;
constructor(private apiService: ApiService, private i18nService: I18nService,
private analytics: Angulartics2, private toasterService: ToasterService,
platformUtilsService: PlatformUtilsService, private cryptoService: CryptoService,
private router: Router, private syncService: SyncService,
private route: ActivatedRoute) {
this.selfHosted = platformUtilsService.isSelfHost();
}
constructor(private route: ActivatedRoute) { }
ngOnInit() {
const queryParamsSub = this.route.queryParams.subscribe(async (qParams) => {
if (qParams.plan === 'families' || qParams.plan === 'teams' || qParams.plan === 'enterprise') {
this.plan = qParams.plan;
this.orgPlansComponent.plan = qParams.plan;
}
if (queryParamsSub != null) {
queryParamsSub.unsubscribe();
}
});
}
async submit() {
let files: FileList = null;
if (this.selfHosted) {
const fileEl = document.getElementById('file') as HTMLInputElement;
files = fileEl.files;
if (files == null || files.length === 0) {
this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'),
this.i18nService.t('selectFile'));
return;
}
}
let key: string = null;
let collectionCt: string = null;
try {
this.formPromise = this.cryptoService.makeShareKey().then((shareKey) => {
key = shareKey[0].encryptedString;
return this.cryptoService.encrypt(this.i18nService.t('defaultCollection'), shareKey[1]);
}).then((collection) => {
collectionCt = collection.encryptedString;
if (this.selfHosted || this.plan === 'free') {
return null;
} else {
return this.paymentComponent.createPaymentToken();
}
}).then((tokenResult) => {
if (this.selfHosted) {
const fd = new FormData();
fd.append('license', files[0]);
fd.append('key', key);
fd.append('collectionName', collectionCt);
return this.apiService.postOrganizationLicense(fd);
} else {
const request = new OrganizationCreateRequest();
request.key = key;
request.collectionName = collectionCt;
request.name = this.name;
request.billingEmail = this.billingEmail;
if (this.plan === 'free') {
request.planType = PlanType.Free;
} else {
request.paymentToken = tokenResult[0];
request.paymentMethodType = tokenResult[1];
request.businessName = this.ownedBusiness ? this.businessName : null;
request.additionalSeats = this.additionalSeats;
request.additionalStorageGb = this.additionalStorage;
request.premiumAccessAddon = this.plans[this.plan].canBuyPremiumAccessAddon &&
this.premiumAccessAddon;
if (this.interval === 'month') {
request.planType = this.plans[this.plan].monthPlanType;
} else {
request.planType = this.plans[this.plan].annualPlanType;
}
}
return this.apiService.postOrganization(request);
}
}).then((response) => {
return this.finalize(response.id);
});
await this.formPromise;
} catch { }
}
async finalize(orgId: string) {
await this.apiService.refreshIdentityToken();
await this.syncService.fullSync(true);
this.analytics.eventTrack.next({ action: 'Created Organization' });
this.toasterService.popAsync('success', this.i18nService.t('organizationCreated'),
this.i18nService.t('organizationReadyToGo'));
this.router.navigate(['/organizations/' + orgId]);
}
changedPlan() {
if (!this.plans[this.plan].canBuyPremiumAccessAddon) {
this.premiumAccessAddon = false;
}
if (this.plans[this.plan].monthPlanType == null) {
this.interval = 'year';
}
if (this.plans[this.plan].noAdditionalSeats) {
this.additionalSeats = 0;
} else if (!this.additionalSeats && !this.plans[this.plan].baseSeats &&
!this.plans[this.plan].noAdditionalSeats) {
this.additionalSeats = 1;
}
}
changedOwnedBusiness() {
if (!this.ownedBusiness || this.plan === 'teams' || this.plan === 'enterprise') {
return;
}
this.plan = 'teams';
}
additionalStorageTotal(annual: boolean): number {
if (annual) {
return (this.additionalStorage || 0) * this.storageGb.yearlyPrice;
} else {
return (this.additionalStorage || 0) * this.storageGb.monthlyPrice;
}
}
seatTotal(annual: boolean): number {
if (this.plans[this.plan].noAdditionalSeats) {
return 0;
}
if (annual) {
return this.plans[this.plan].annualSeatPrice * (this.additionalSeats || 0);
} else {
return this.plans[this.plan].monthlySeatPrice * (this.additionalSeats || 0);
}
}
baseTotal(annual: boolean): number {
if (annual) {
return (this.plans[this.plan].annualBasePrice || 0);
} else {
return (this.plans[this.plan].monthlyBasePrice || 0);
}
}
premiumAccessTotal(annual: boolean): number {
if (this.plans[this.plan].canBuyPremiumAccessAddon && this.premiumAccessAddon) {
if (annual) {
return 40;
}
}
return 0;
}
get total(): number {
const annual = this.interval === 'year';
return this.baseTotal(annual) + this.seatTotal(annual) + this.additionalStorageTotal(annual) +
this.premiumAccessTotal(annual);
}
}