mirror of
https://github.com/bitwarden/browser
synced 2026-01-09 20:13:42 +00:00
We currently duplicate some logic between our layouts. In an effort to streamline our experience I'm exploring if we can create a web specific layout that handles some of this.
64 lines
2.7 KiB
TypeScript
64 lines
2.7 KiB
TypeScript
import { CommonModule } from "@angular/common";
|
|
import { Component, OnInit } from "@angular/core";
|
|
import { RouterModule } from "@angular/router";
|
|
import { Observable, combineLatest, concatMap } from "rxjs";
|
|
|
|
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
|
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
|
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
|
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
|
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
|
import { SyncService } from "@bitwarden/common/platform/sync";
|
|
import { IconModule } from "@bitwarden/components";
|
|
|
|
import { PasswordManagerLogo } from "./password-manager-logo";
|
|
import { WebLayoutModule } from "./web-layout.module";
|
|
|
|
@Component({
|
|
selector: "app-user-layout",
|
|
templateUrl: "user-layout.component.html",
|
|
standalone: true,
|
|
imports: [CommonModule, RouterModule, JslibModule, WebLayoutModule, IconModule],
|
|
})
|
|
export class UserLayoutComponent implements OnInit {
|
|
protected readonly logo = PasswordManagerLogo;
|
|
protected hasFamilySponsorshipAvailable$: Observable<boolean>;
|
|
protected showSubscription$: Observable<boolean>;
|
|
|
|
constructor(
|
|
private platformUtilsService: PlatformUtilsService,
|
|
private organizationService: OrganizationService,
|
|
private apiService: ApiService,
|
|
private syncService: SyncService,
|
|
private billingAccountProfileStateService: BillingAccountProfileStateService,
|
|
) {}
|
|
|
|
async ngOnInit() {
|
|
document.body.classList.remove("layout_frontend");
|
|
|
|
await this.syncService.fullSync(false);
|
|
|
|
this.hasFamilySponsorshipAvailable$ = this.organizationService.canManageSponsorships$;
|
|
|
|
// We want to hide the subscription menu for organizations that provide premium.
|
|
// Except if the user has premium personally or has a billing history.
|
|
this.showSubscription$ = combineLatest([
|
|
this.billingAccountProfileStateService.hasPremiumPersonally$,
|
|
this.billingAccountProfileStateService.hasPremiumFromAnyOrganization$,
|
|
]).pipe(
|
|
concatMap(async ([hasPremiumPersonally, hasPremiumFromOrg]) => {
|
|
const isCloud = !this.platformUtilsService.isSelfHost();
|
|
|
|
let billing = null;
|
|
if (isCloud) {
|
|
// TODO: We should remove the need to call this!
|
|
billing = await this.apiService.getUserBillingHistory();
|
|
}
|
|
|
|
const cloudAndBillingHistory = isCloud && !billing?.hasNoHistory;
|
|
return hasPremiumPersonally || !hasPremiumFromOrg || cloudAndBillingHistory;
|
|
}),
|
|
);
|
|
}
|
|
}
|