1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-15 07:43:35 +00:00

[PM-18955] Use OrganizationWarningsService on AC Collections Page behind FF (#14437)

* Add getWarnings to OrganizationBillingApiService

* Add OrganizationWarningsService

* Add feature flag

* Add standalone warning components that consume new service

* Add new components to AC collections vault when FF is enabled

* Add OrganizationWarningsService spec

* Run prettier on spec file

* Thomas' feedback
This commit is contained in:
Alex Morask
2025-05-01 17:13:18 -04:00
committed by GitHub
parent 23e7f120fd
commit c8d6e48996
10 changed files with 828 additions and 9 deletions

View File

@@ -1,3 +1,5 @@
import { OrganizationWarningsResponse } from "@bitwarden/common/billing/models/response/organization-warnings.response";
import {
BillingInvoiceResponse,
BillingTransactionResponse,
@@ -15,6 +17,8 @@ export abstract class OrganizationBillingApiServiceAbstraction {
startAfter?: string,
) => Promise<BillingTransactionResponse[]>;
abstract getWarnings: (id: string) => Promise<OrganizationWarningsResponse>;
abstract setupBusinessUnit: (
id: string,
request: {

View File

@@ -0,0 +1,97 @@
import { BaseResponse } from "../../../models/response/base.response";
export class OrganizationWarningsResponse extends BaseResponse {
freeTrial?: FreeTrialWarningResponse;
inactiveSubscription?: InactiveSubscriptionWarningResponse;
resellerRenewal?: ResellerRenewalWarningResponse;
constructor(response: any) {
super(response);
const freeTrialWarning = this.getResponseProperty("FreeTrial");
if (freeTrialWarning) {
this.freeTrial = new FreeTrialWarningResponse(freeTrialWarning);
}
const inactiveSubscriptionWarning = this.getResponseProperty("InactiveSubscription");
if (inactiveSubscriptionWarning) {
this.inactiveSubscription = new InactiveSubscriptionWarningResponse(
inactiveSubscriptionWarning,
);
}
const resellerWarning = this.getResponseProperty("ResellerRenewal");
if (resellerWarning) {
this.resellerRenewal = new ResellerRenewalWarningResponse(resellerWarning);
}
}
}
class FreeTrialWarningResponse extends BaseResponse {
remainingTrialDays: number;
constructor(response: any) {
super(response);
this.remainingTrialDays = this.getResponseProperty("RemainingTrialDays");
}
}
class InactiveSubscriptionWarningResponse extends BaseResponse {
resolution: string;
constructor(response: any) {
super(response);
this.resolution = this.getResponseProperty("Resolution");
}
}
class ResellerRenewalWarningResponse extends BaseResponse {
type: "upcoming" | "issued" | "past_due";
upcoming?: UpcomingRenewal;
issued?: IssuedRenewal;
pastDue?: PastDueRenewal;
constructor(response: any) {
super(response);
this.type = this.getResponseProperty("Type");
switch (this.type) {
case "upcoming": {
this.upcoming = new UpcomingRenewal(this.getResponseProperty("Upcoming"));
break;
}
case "issued": {
this.issued = new IssuedRenewal(this.getResponseProperty("Issued"));
break;
}
case "past_due": {
this.pastDue = new PastDueRenewal(this.getResponseProperty("PastDue"));
}
}
}
}
class UpcomingRenewal extends BaseResponse {
renewalDate: Date;
constructor(response: any) {
super(response);
this.renewalDate = new Date(this.getResponseProperty("RenewalDate"));
}
}
class IssuedRenewal extends BaseResponse {
issuedDate: Date;
dueDate: Date;
constructor(response: any) {
super(response);
this.issuedDate = new Date(this.getResponseProperty("IssuedDate"));
this.dueDate = new Date(this.getResponseProperty("DueDate"));
}
}
class PastDueRenewal extends BaseResponse {
suspensionDate: Date;
constructor(response: any) {
super(response);
this.suspensionDate = new Date(this.getResponseProperty("SuspensionDate"));
}
}

View File

@@ -1,3 +1,5 @@
import { OrganizationWarningsResponse } from "@bitwarden/common/billing/models/response/organization-warnings.response";
import { ApiService } from "../../../abstractions/api.service";
import { OrganizationBillingApiServiceAbstraction } from "../../abstractions/organizations/organization-billing-api.service.abstraction";
import {
@@ -50,6 +52,18 @@ export class OrganizationBillingApiService implements OrganizationBillingApiServ
return r?.map((i: any) => new BillingTransactionResponse(i)) || [];
}
async getWarnings(id: string): Promise<OrganizationWarningsResponse> {
const response = await this.apiService.send(
"GET",
`/organizations/${id}/billing/warnings`,
null,
true,
true,
);
return new OrganizationWarningsResponse(response);
}
async setupBusinessUnit(
id: string,
request: {

View File

@@ -35,6 +35,7 @@ export enum FeatureFlag {
PM18794_ProviderPaymentMethod = "pm-18794-provider-payment-method",
PM17772_AdminInitiatedSponsorships = "pm-17772-admin-initiated-sponsorships",
PM19956_RequireProviderPaymentMethodDuringSetup = "pm-19956-require-provider-payment-method-during-setup",
UseOrganizationWarningsService = "use-organization-warnings-service",
/* Data Insights and Reporting */
CriticalApps = "pm-14466-risk-insights-critical-application",
@@ -123,6 +124,7 @@ export const DefaultFeatureFlagValue = {
[FeatureFlag.PM18794_ProviderPaymentMethod]: FALSE,
[FeatureFlag.PM17772_AdminInitiatedSponsorships]: FALSE,
[FeatureFlag.PM19956_RequireProviderPaymentMethodDuringSetup]: FALSE,
[FeatureFlag.UseOrganizationWarningsService]: FALSE,
/* Key Management */
[FeatureFlag.PrivateKeyRegeneration]: FALSE,