1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-16 08:13:42 +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

@@ -13,6 +13,7 @@ import {
Subject,
} from "rxjs";
import {
catchError,
concatMap,
debounceTime,
distinctUntilChanged,
@@ -23,7 +24,6 @@ import {
switchMap,
takeUntil,
tap,
catchError,
} from "rxjs/operators";
import {
@@ -44,6 +44,7 @@ import { getUserId } from "@bitwarden/common/auth/services/account.service";
import { OrganizationBillingServiceAbstraction } from "@bitwarden/common/billing/abstractions";
import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions/billing-api.service.abstraction";
import { EventType } from "@bitwarden/common/enums";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
@@ -61,8 +62,8 @@ import { TreeNode } from "@bitwarden/common/vault/models/domain/tree-node";
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
import { ServiceUtils } from "@bitwarden/common/vault/service-utils";
import {
DialogRef,
BannerModule,
DialogRef,
DialogService,
Icons,
NoItemsModule,
@@ -77,6 +78,8 @@ import {
DecryptionFailureDialogComponent,
PasswordRepromptService,
} from "@bitwarden/vault";
import { OrganizationWarningsService } from "@bitwarden/web-vault/app/billing/services/organization-warnings.service";
import { ResellerRenewalWarningComponent } from "@bitwarden/web-vault/app/billing/warnings/reseller-renewal-warning.component";
import { BillingNotificationService } from "../../../billing/services/billing-notification.service";
import {
@@ -85,6 +88,7 @@ import {
} from "../../../billing/services/reseller-warning.service";
import { TrialFlowService } from "../../../billing/services/trial-flow.service";
import { FreeTrial } from "../../../billing/types/free-trial";
import { FreeTrialWarningComponent } from "../../../billing/warnings/free-trial-warning.component";
import { SharedModule } from "../../../shared";
import { AssignCollectionsWebComponent } from "../../../vault/components/assign-collections";
import {
@@ -145,6 +149,8 @@ enum AddAccessStatusType {
SharedModule,
BannerModule,
NoItemsModule,
FreeTrialWarningComponent,
ResellerRenewalWarningComponent,
],
providers: [
RoutedVaultFilterService,
@@ -174,8 +180,9 @@ export class VaultComponent implements OnInit, OnDestroy {
protected showCollectionAccessRestricted: boolean;
private hasSubscription$ = new BehaviorSubject<boolean>(false);
protected currentSearchText$: Observable<string>;
protected freeTrial$: Observable<FreeTrial>;
protected resellerWarning$: Observable<ResellerWarning | null>;
protected useOrganizationWarningsService$: Observable<boolean>;
protected freeTrialWhenWarningsServiceDisabled$: Observable<FreeTrial>;
protected resellerWarningWhenWarningsServiceDisabled$: Observable<ResellerWarning | null>;
protected prevCipherId: string | null = null;
protected userId: UserId;
/**
@@ -255,6 +262,7 @@ export class VaultComponent implements OnInit, OnDestroy {
private resellerWarningService: ResellerWarningService,
private accountService: AccountService,
private billingNotificationService: BillingNotificationService,
private organizationWarningsService: OrganizationWarningsService,
) {}
async ngOnInit() {
@@ -628,9 +636,23 @@ export class VaultComponent implements OnInit, OnDestroy {
)
.subscribe();
this.unpaidSubscriptionDialog$.pipe(takeUntil(this.destroy$)).subscribe();
// Billing Warnings
this.useOrganizationWarningsService$ = this.configService.getFeatureFlag$(
FeatureFlag.UseOrganizationWarningsService,
);
this.freeTrial$ = combineLatest([
this.useOrganizationWarningsService$
.pipe(
switchMap((enabled) =>
enabled
? this.organizationWarningsService.showInactiveSubscriptionDialog$(this.organization)
: this.unpaidSubscriptionDialog$,
),
takeUntil(this.destroy$),
)
.subscribe();
const freeTrial$ = combineLatest([
organization$,
this.hasSubscription$.pipe(filter((hasSubscription) => hasSubscription !== null)),
]).pipe(
@@ -655,7 +677,12 @@ export class VaultComponent implements OnInit, OnDestroy {
filter((result) => result !== null),
);
this.resellerWarning$ = organization$.pipe(
this.freeTrialWhenWarningsServiceDisabled$ = this.useOrganizationWarningsService$.pipe(
filter((enabled) => !enabled),
switchMap(() => freeTrial$),
);
const resellerWarning$ = organization$.pipe(
filter((org) => org.isOwner),
switchMap((org) =>
from(this.billingApiService.getOrganizationBillingMetadata(org.id)).pipe(
@@ -665,6 +692,12 @@ export class VaultComponent implements OnInit, OnDestroy {
map(({ org, metadata }) => this.resellerWarningService.getWarning(org, metadata)),
);
this.resellerWarningWhenWarningsServiceDisabled$ = this.useOrganizationWarningsService$.pipe(
filter((enabled) => !enabled),
switchMap(() => resellerWarning$),
);
// End Billing Warnings
firstSetup$
.pipe(
switchMap(() => this.refresh$),