adjust storage implementation

This commit is contained in:
Kyle Spearrin 2018-06-29 23:41:35 -04:00
parent f7b9416460
commit 37026e556f
7 changed files with 133 additions and 7 deletions

2
jslib

@ -1 +1 @@
Subproject commit ef897695e9b5bfecbfcbbd4ad3aec62b4ecdca25
Subproject commit c0e7e588ed59832a6f579ff63d85bfcdfb400d78

View File

@ -33,6 +33,7 @@ import { TwoFactorOptionsComponent } from './accounts/two-factor-options.compone
import { TwoFactorComponent } from './accounts/two-factor.component';
import { AccountComponent } from './settings/account.component';
import { AdjustStorageComponent } from './settings/adjust-storage.component';
import { ChangeEmailComponent } from './settings/change-email.component';
import { ChangePasswordComponent } from './settings/change-password.component';
import { DeauthorizeSessionsComponent } from './settings/deauthorize-sessions.component';
@ -106,6 +107,7 @@ import { SearchCiphersPipe } from 'jslib/angular/pipes/search-ciphers.pipe';
declarations: [
AccountComponent,
AddEditComponent,
AdjustStorageComponent,
ApiActionDirective,
AppComponent,
AttachmentsComponent,

View File

@ -0,0 +1,25 @@
<form #form class="card" (ngSubmit)="submit()" [appApiAction]="formPromise" ngNativeValidate>
<div class="card-body">
<div class="row">
<div class="form-group col-6">
<label for="storageAdjustment">{{(add ? 'gbStorageAdd' : 'gbStorageRemove') | i18n}}</label>
<input id="storageAdjustment" class="form-control" type="number" name="StroageGbAdjustment" [(ngModel)]="storageAdjustment"
min="0" max="99" step="1">
</div>
</div>
<div *ngIf="add" class="mb-3">
<strong>{{'total' | i18n}}:</strong> {{storageAdjustment || 0}} GB &times; {{storageGbPrice | currency:'$'}} = {{adjustedStorageTotal
| currency:'$'}} /{{interval | i18n}}
</div>
<button type="submit" class="btn btn-primary btn-submit" [disabled]="form.loading">
<i class="fa fa-spinner fa-spin"></i>
<span>{{'submit' | i18n}}</span>
</button>
<button type="button" class="btn btn-outline-secondary" (click)="cancel()">
{{'cancel' | i18n}}
</button>
<small class="d-block text-muted mt-3">
{{(add ? 'storageAddNote' : 'storageRemoveNote') | i18n}}
</small>
</div>
</form>

View File

@ -0,0 +1,60 @@
import {
Component,
EventEmitter,
Input,
Output,
} from '@angular/core';
import { ToasterService } from 'angular2-toaster';
import { Angulartics2 } from 'angulartics2';
import { ApiService } from 'jslib/abstractions/api.service';
import { I18nService } from 'jslib/abstractions/i18n.service';
import { StorageRequest } from 'jslib/models/request/storageRequest';
@Component({
selector: 'app-adjust-storage',
templateUrl: 'adjust-storage.component.html',
})
export class AdjustStorageComponent {
@Input() storageGbPrice = 0;
@Input() add = true;
@Input() user = true;
@Input() interval = 'year';
@Output() onAdjusted = new EventEmitter<number>();
@Output() onCanceled = new EventEmitter();
storageAdjustment = 0;
formPromise: Promise<any>;
constructor(private apiService: ApiService, private i18nService: I18nService,
private analytics: Angulartics2, private toasterService: ToasterService) { }
async submit() {
try {
const request = new StorageRequest();
request.storageGbAdjustment = this.storageAdjustment;
if (!this.add) {
request.storageGbAdjustment *= -1;
}
if (this.user) {
this.formPromise = this.apiService.postAccountStorage(request);
}
await this.formPromise;
this.analytics.eventTrack.next({ action: this.add ? 'Added Storage' : 'Removed Storage' });
this.toasterService.popAsync('success', null,
this.i18nService.t('adjustedStorage', request.storageGbAdjustment.toString()));
this.onAdjusted.emit(this.storageAdjustment);
} catch { }
}
cancel() {
this.onCanceled.emit();
}
get adjustedStorageTotal(): number {
return this.storageGbPrice * this.storageAdjustment;
}
}

View File

@ -69,12 +69,16 @@
</div>
<ng-container *ngIf="subscription && !subscription.cancelled && !subscriptionMarkedForCancel && paymentSource">
<div class="mt-3">
<button type="button" class="btn btn-outline-secondary" (click)="adjustStorage(true)">
{{'addStorage' | i18n}}
</button>
<button type="button" class="btn btn-outline-secondary" (click)="adjustStorage(false)">
{{'removeStorage' | i18n}}
</button>
<ng-container *ngIf="!showAdjustStorage">
<button type="button" class="btn btn-outline-secondary" (click)="adjustStorage(true)">
{{'addStorage' | i18n}}
</button>
<button type="button" class="btn btn-outline-secondary" (click)="adjustStorage(false)">
{{'removeStorage' | i18n}}
</button>
</ng-container>
<app-adjust-storage [storageGbPrice]="4" [add]="adjustStorageAdd" [user]="true" (onAdjusted)="adjustedStorage($event)" (onCanceled)="canceledAdjustStorage()"
*ngIf="showAdjustStorage"></app-adjust-storage>
</div>
</ng-container>
<h2 class="spaced-header">{{'paymentMethod' | i18n}}</h2>

View File

@ -15,6 +15,8 @@ import { TokenService } from 'jslib/abstractions/token.service';
import { PaymentMethodType } from 'jslib/enums/paymentMethodType';
import { AdjustStorageComponent } from './adjust-storage.component';
@Component({
selector: 'app-user-billing',
templateUrl: 'user-billing.component.html',
@ -23,6 +25,8 @@ export class UserBillingComponent implements OnInit {
premium = false;
loading = false;
firstLoaded = false;
adjustStorageAdd = true;
showAdjustStorage = false;
billing: BillingResponse;
paymentMethodType = PaymentMethodType;
@ -101,7 +105,17 @@ export class UserBillingComponent implements OnInit {
}
adjustStorage(add: boolean) {
this.adjustStorageAdd = add;
this.showAdjustStorage = true;
}
adjustedStorage(gbAmount: number) {
this.showAdjustStorage = false;
this.load();
}
canceledAdjustStorage() {
this.showAdjustStorage = false;
}
changePayment() {

View File

@ -1383,5 +1383,26 @@
"example": "BITWARDEN"
}
}
},
"gbStorageAdd": {
"message": "GB of Storage To Add"
},
"gbStorageRemove": {
"message": "GB of Storage To Remove"
},
"storageAddNote": {
"message": "Adding storage to your plan will result in adjustments to your billing totals and immediately charge your payment method on file. The first charge will be prorated for the remainder of the current billing cycle."
},
"storageRemoveNote": {
"message": "Removing storage will result in adjustments to your billing totals that will be prorated as credits to your next billing charge."
},
"adjustedStorage": {
"message": "Adjusted $AMOUNT$ GB of storage.",
"placeholders": {
"amount": {
"content": "$1",
"example": "5"
}
}
}
}