Skip to content

Commit

Permalink
Split invoice history table into two tables for paid and open (#11459)
Browse files Browse the repository at this point in the history
(cherry picked from commit 49b26db)
  • Loading branch information
cturnbull-bitwarden committed Oct 9, 2024
1 parent 1e84d49 commit 44401b3
Show file tree
Hide file tree
Showing 11 changed files with 157 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@ <h2 bitTypography="h2">
></i>
<span class="tw-sr-only">{{ "loading" | i18n }}</span>
</ng-container>
<ng-container *ngIf="invoices || transactions">
<app-billing-history [invoices]="invoices" [transactions]="transactions"></app-billing-history>
<ng-container *ngIf="openInvoices || paidInvoices || transactions">
<app-billing-history
[openInvoices]="openInvoices"
[paidInvoices]="paidInvoices"
[transactions]="transactions"
></app-billing-history>
<button
type="button"
bitButton
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl
export class BillingHistoryViewComponent implements OnInit {
loading = false;
firstLoaded = false;
invoices: BillingInvoiceResponse[] = [];
openInvoices: BillingInvoiceResponse[] = [];
paidInvoices: BillingInvoiceResponse[] = [];
transactions: BillingTransactionResponse[] = [];
hasAdditionalHistory: boolean = false;

Expand All @@ -41,8 +42,14 @@ export class BillingHistoryViewComponent implements OnInit {
}
this.loading = true;

const invoicesPromise = this.accountBillingApiService.getBillingInvoices(
this.invoices.length > 0 ? this.invoices[this.invoices.length - 1].id : null,
const openInvoicesPromise = this.accountBillingApiService.getBillingInvoices(
"open",
this.openInvoices.length > 0 ? this.openInvoices[this.openInvoices.length - 1].id : null,
);

const paidInvoicesPromise = this.accountBillingApiService.getBillingInvoices(
"paid",
this.paidInvoices.length > 0 ? this.paidInvoices[this.paidInvoices.length - 1].id : null,
);

const transactionsPromise = this.accountBillingApiService.getBillingTransactions(
Expand All @@ -51,15 +58,20 @@ export class BillingHistoryViewComponent implements OnInit {
: null,
);

const accountInvoices = await invoicesPromise;
const accountTransactions = await transactionsPromise;
const openInvoices = await openInvoicesPromise;
const paidInvoices = await paidInvoicesPromise;
const transactions = await transactionsPromise;

const pageSize = 5;

this.invoices = [...this.invoices, ...accountInvoices];
this.transactions = [...this.transactions, ...accountTransactions];
this.hasAdditionalHistory = !(
accountInvoices.length < pageSize && accountTransactions.length < pageSize
);
this.openInvoices = [...this.openInvoices, ...openInvoices];
this.paidInvoices = [...this.paidInvoices, ...paidInvoices];
this.transactions = [...this.transactions, ...transactions];

this.hasAdditionalHistory =
openInvoices.length >= pageSize ||
paidInvoices.length >= pageSize ||
transactions.length >= pageSize;

this.loading = false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,12 @@
></i>
<span class="tw-sr-only">{{ "loading" | i18n }}</span>
</ng-container>
<ng-container *ngIf="invoices || transactions">
<app-billing-history [invoices]="invoices" [transactions]="transactions"></app-billing-history>
<ng-container *ngIf="openInvoices || paidInvoices || transactions">
<app-billing-history
[openInvoices]="openInvoices"
[paidInvoices]="paidInvoices"
[transactions]="transactions"
></app-billing-history>
<button
type="button"
bitButton
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import {
export class OrgBillingHistoryViewComponent implements OnInit, OnDestroy {
loading = false;
firstLoaded = false;
invoices: BillingInvoiceResponse[] = [];
openInvoices: BillingInvoiceResponse[] = [];
paidInvoices: BillingInvoiceResponse[] = [];
transactions: BillingTransactionResponse[] = [];
organizationId: string;
hasAdditionalHistory: boolean = false;
Expand Down Expand Up @@ -51,9 +52,16 @@ export class OrgBillingHistoryViewComponent implements OnInit, OnDestroy {

this.loading = true;

const invoicesPromise = this.organizationBillingApiService.getBillingInvoices(
const openInvoicesPromise = this.organizationBillingApiService.getBillingInvoices(
this.organizationId,
this.invoices.length > 0 ? this.invoices[this.invoices.length - 1].id : null,
"open",
this.openInvoices.length > 0 ? this.openInvoices[this.openInvoices.length - 1].id : null,
);

const paidInvoicesPromise = this.organizationBillingApiService.getBillingInvoices(
this.organizationId,
"paid",
this.paidInvoices.length > 0 ? this.paidInvoices[this.paidInvoices.length - 1].id : null,
);

const transactionsPromise = this.organizationBillingApiService.getBillingTransactions(
Expand All @@ -63,13 +71,21 @@ export class OrgBillingHistoryViewComponent implements OnInit, OnDestroy {
: null,
);

const invoices = await invoicesPromise;
const openInvoices = await openInvoicesPromise;
const paidInvoices = await paidInvoicesPromise;
const transactions = await transactionsPromise;

const pageSize = 5;

this.invoices = [...this.invoices, ...invoices];
this.openInvoices = [...this.openInvoices, ...openInvoices];
this.paidInvoices = [...this.paidInvoices, ...paidInvoices];
this.transactions = [...this.transactions, ...transactions];
this.hasAdditionalHistory = !(invoices.length < pageSize && transactions.length < pageSize);

this.hasAdditionalHistory =
openInvoices.length <= pageSize ||
paidInvoices.length <= pageSize ||
transactions.length <= pageSize;

this.loading = false;
}
}
52 changes: 49 additions & 3 deletions apps/web/src/app/billing/shared/billing-history.component.html
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
<bit-section>
<h3 bitTypography="h3">{{ "invoices" | i18n }}</h3>
<p bitTypography="body1" *ngIf="!invoices || !invoices.length">{{ "noInvoices" | i18n }}</p>
<h3 bitTypography="h3">{{ "unpaid" | i18n }} {{ "invoices" | i18n }}</h3>
<p bitTypography="body1" *ngIf="!openInvoices || !openInvoices.length">
{{ "noUnpaidInvoices" | i18n }}
</p>
<bit-table>
<ng-template body>
<tr bitRow *ngFor="let i of invoices">
<tr bitRow *ngFor="let i of openInvoices">
<td bitCell>{{ i.date | date: "mediumDate" }}</td>
<td bitCell>
<a
Expand All @@ -26,7 +28,51 @@ <h3 bitTypography="h3">{{ "invoices" | i18n }}</h3>
>
</td>
<td bitCell>{{ i.amount | currency: "$" }}</td>
<td bitCell class="tw-w-28">
<span *ngIf="i.paid">
<i class="bwi bwi-check tw-text-success" aria-hidden="true"></i>
{{ "paid" | i18n }}
</span>
<span *ngIf="!i.paid">
<i class="bwi bwi-exclamation-circle tw-text-muted" aria-hidden="true"></i>
{{ "unpaid" | i18n }}
</span>
</td>
</tr>
</ng-template>
</bit-table>
</bit-section>
<bit-section>
<h3 bitTypography="h3">{{ "paid" | i18n }} {{ "invoices" | i18n }}</h3>
<p bitTypography="body1" *ngIf="!paidInvoices || !paidInvoices.length">
{{ "noPaidInvoices" | i18n }}
</p>
<bit-table>
<ng-template body>
<tr bitRow *ngFor="let i of paidInvoices">
<td bitCell>{{ i.date | date: "mediumDate" }}</td>
<td bitCell>
<a
href="{{ i.pdfUrl }}"
target="_blank"
rel="noreferrer"
class="tw-mr-2"
appA11yTitle="{{ 'downloadInvoice' | i18n }}"
>
<i class="bwi bwi-file-pdf" aria-hidden="true"></i
></a>
<a
bitLink
href="{{ i.url }}"
target="_blank"
rel="noreferrer"
title="{{ 'viewInvoice' | i18n }}"
>
{{ "invoiceNumber" | i18n: i.number }}</a
>
</td>
<td bitCell>{{ i.amount | currency: "$" }}</td>
<td bitCell class="tw-w-28">
<span *ngIf="i.paid">
<i class="bwi bwi-check tw-text-success" aria-hidden="true"></i>
{{ "paid" | i18n }}
Expand Down
5 changes: 4 additions & 1 deletion apps/web/src/app/billing/shared/billing-history.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ import {
})
export class BillingHistoryComponent {
@Input()
invoices: BillingInvoiceResponse[];
openInvoices: BillingInvoiceResponse[];

@Input()
paidInvoices: BillingInvoiceResponse[];

@Input()
transactions: BillingTransactionResponse[];
Expand Down
7 changes: 5 additions & 2 deletions apps/web/src/locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -2616,8 +2616,11 @@
"invoices": {
"message": "Invoices"
},
"noInvoices": {
"message": "No invoices."
"noUnpaidInvoices": {
"message": "No unpaid invoices."
},
"noPaidInvoices": {
"message": "No paid invoices."
},
"paid": {
"message": "Paid",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ import {
} from "@bitwarden/common/billing/models/response/billing.response";

export class AccountBillingApiServiceAbstraction {
getBillingInvoices: (id: string, startAfter?: string) => Promise<BillingInvoiceResponse[]>;
getBillingTransactions: (
id: string,
startAfter?: string,
) => Promise<BillingTransactionResponse[]>;
getBillingInvoices: (status?: string, startAfter?: string) => Promise<BillingInvoiceResponse[]>;
getBillingTransactions: (startAfter?: string) => Promise<BillingTransactionResponse[]>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ import {
} from "@bitwarden/common/billing/models/response/billing.response";

export class OrganizationBillingApiServiceAbstraction {
getBillingInvoices: (id: string, startAfter?: string) => Promise<BillingInvoiceResponse[]>;
getBillingInvoices: (
id: string,
status?: string,
startAfter?: string,
) => Promise<BillingInvoiceResponse[]>;

getBillingTransactions: (
id: string,
startAfter?: string,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,25 @@ import {
export class AccountBillingApiService implements AccountBillingApiServiceAbstraction {
constructor(private apiService: ApiService) {}

async getBillingInvoices(startAfter?: string): Promise<BillingInvoiceResponse[]> {
const queryParams = startAfter ? `?startAfter=${startAfter}` : "";
async getBillingInvoices(
status?: string,
startAfter?: string,
): Promise<BillingInvoiceResponse[]> {
const params = new URLSearchParams();

if (status) {
params.append("status", status);
}

if (startAfter) {
params.append("startAfter", startAfter);
}

const queryString = `?${params.toString()}`;

const r = await this.apiService.send(
"GET",
`/accounts/billing/invoices${queryParams}`,
`/accounts/billing/invoices${queryString}`,
null,
true,
true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,26 @@ import {
export class OrganizationBillingApiService implements OrganizationBillingApiServiceAbstraction {
constructor(private apiService: ApiService) {}

async getBillingInvoices(id: string, startAfter?: string): Promise<BillingInvoiceResponse[]> {
const queryParams = startAfter ? `?startAfter=${startAfter}` : "";
async getBillingInvoices(
id: string,
status?: string,
startAfter?: string,
): Promise<BillingInvoiceResponse[]> {
const params = new URLSearchParams();

if (status) {
params.append("status", status);
}

if (startAfter) {
params.append("startAfter", startAfter);
}

const queryString = `?${params.toString()}`;

const r = await this.apiService.send(
"GET",
`/organizations/${id}/billing/invoices${queryParams}`,
`/organizations/${id}/billing/invoices${queryString}`,
null,
true,
true,
Expand Down

0 comments on commit 44401b3

Please sign in to comment.