1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-16 08:13:42 +00:00

[PM-8161] Payment optional trial MVP (#10872)

* Initial comment

* Add changes for the create org with payment method

* Add the secrets manager trail flow

* Add the banners

* Add changes for the Disabled Org

* Add banner to payment method page

* Refactoring changes

* Resolve the bug on tha payment method

* Resolve lint error

* Resolve Pr comments

* resolve the lint issue

* Resolve the lint wrong file issue

* Rename object properly

* Resolve pr comments from sm team

* Resolve the pr comments from sm team

* Fix the failing test

* Resolve some issue with vault

* Resolve the comments from sm team

* Resolve some pr comments from vault team

* Resolve pr comments from auth team

* Exported ValidOrgParams enum

* Removed unnecessary interpolation

* Corrected bit-banner id for trial

* Resolve pr comments from auth team

* Resolve pr comments from auth team

* Removed unnecessary method

* Made OrganizationCreateRequest a subtype of OrganizationNoPaymentMethodCreateRequest

* Resolve review changes from sm

* Resolve review changes from dm

* Resolve the pr comments from billing

* move the free-trial to core

* Move free-trial change to right file

* Revert changes on the free trial  page

* Resolve the comment on protected trial page

* Resolve the comment on protected trial page

* Revert the next async change

* resolve pr comment fro vault team

* resolve the default message comments

* remove unused method

* resolve email sending issue

* Fix the pop issue on payment method

* Fix some console errors

* Fix the pop refresh page

* move the trial services to billing folder

* resolve pr comments

* Resolve the import issues

* Move the observable up

* Resolve blank payment method for trialing org

* Changes to  disable icon is removed onsubmit

* Remove unused references

* add a missing a period at the end of it

* resolve the reload issue

* Resolve the disable icon issue

* Fix the admin access bug

* Resolve the lint issue

* Fix the message incorrect format

* Formatting fixed

* Resolve the access issue of other users role
This commit is contained in:
cyprain-okeke
2024-11-11 17:05:37 +01:00
committed by GitHub
parent 888b9e346c
commit f593269133
39 changed files with 971 additions and 81 deletions

View File

@@ -1,3 +1,24 @@
<ng-container *ngIf="freeTrial$ | async as freeTrial">
<bit-banner
id="update-browser-banner"
class="-tw-m-6 tw-flex tw-flex-col tw-pb-6"
bannerType="premium"
icon="bwi-billing"
[showClose]="false"
*ngIf="!loading && freeTrial.shownBanner"
>
{{ freeTrial.message }}
<a
bitLink
linkType="contrast"
class="tw-cursor-pointer"
(click)="navigateToPaymentMethod()"
rel="noreferrer noopener"
>
{{ "routeToPaymentMethodTrigger" | i18n }}
</a>
</bit-banner>
</ng-container>
<app-header [title]="organizationName">
<sm-new-menu></sm-new-menu>
</app-header>

View File

@@ -1,5 +1,5 @@
import { Component, OnDestroy, OnInit } from "@angular/core";
import { ActivatedRoute } from "@angular/router";
import { ActivatedRoute, Router } from "@angular/router";
import {
map,
Observable,
@@ -12,14 +12,20 @@ import {
take,
share,
firstValueFrom,
concatMap,
of,
filter,
} from "rxjs";
import { I18nPipe } from "@bitwarden/angular/platform/pipes/i18n.pipe";
import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction";
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { DialogService } from "@bitwarden/components";
import { TrialFlowService } from "@bitwarden/web-vault/app/billing/services/trial-flow.service";
import { FreeTrial } from "@bitwarden/web-vault/app/core/types/free-trial";
import { OrganizationCounts } from "../models/view/counts.view";
import { ProjectListView } from "../models/view/project-list.view";
@@ -81,6 +87,8 @@ export class OverviewComponent implements OnInit, OnDestroy {
protected showOnboarding = false;
protected loading = true;
protected organizationEnabled = false;
protected organization: Organization;
protected i18n: I18nPipe;
protected onboardingTasks$: Observable<SMOnboardingTasks>;
protected view$: Observable<{
@@ -91,6 +99,7 @@ export class OverviewComponent implements OnInit, OnDestroy {
tasks: OrganizationTasks;
counts: OrganizationCounts;
}>;
protected freeTrial$: Observable<FreeTrial>;
constructor(
private route: ActivatedRoute,
@@ -104,6 +113,10 @@ export class OverviewComponent implements OnInit, OnDestroy {
private i18nService: I18nService,
private smOnboardingTasksService: SMOnboardingTasksService,
private logService: LogService,
private router: Router,
private organizationApiService: OrganizationApiServiceAbstraction,
private trialFlowService: TrialFlowService,
) {}
ngOnInit() {
@@ -114,18 +127,35 @@ export class OverviewComponent implements OnInit, OnDestroy {
distinctUntilChanged(),
);
orgId$
.pipe(
concatMap(async (orgId) => await this.organizationService.get(orgId)),
takeUntil(this.destroy$),
)
.subscribe((org) => {
this.organizationId = org.id;
this.organizationName = org.name;
this.userIsAdmin = org.isAdmin;
this.loading = true;
this.organizationEnabled = org.enabled;
});
const org$ = orgId$.pipe(switchMap((orgId) => this.organizationService.get(orgId)));
org$.pipe(takeUntil(this.destroy$)).subscribe((org) => {
this.organizationId = org.id;
this.organization = org;
this.organizationName = org.name;
this.userIsAdmin = org.isAdmin;
this.loading = true;
this.organizationEnabled = org.enabled;
});
this.freeTrial$ = org$.pipe(
filter((org) => org.isOwner),
switchMap((org) =>
combineLatest([
of(org),
this.organizationApiService.getSubscription(org.id),
this.organizationApiService.getBilling(org.id),
]),
),
map(([org, sub, billing]) => {
return this.trialFlowService.checkForOrgsWithUpcomingPaymentIssues(
org,
sub,
billing?.paymentSource,
);
}),
takeUntil(this.destroy$),
);
const projects$ = combineLatest([
orgId$,
@@ -197,6 +227,15 @@ export class OverviewComponent implements OnInit, OnDestroy {
});
}
async navigateToPaymentMethod() {
await this.router.navigate(
["organizations", `${this.organizationId}`, "billing", "payment-method"],
{
state: { launchPaymentModalAutomatically: true },
},
);
}
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();

View File

@@ -1,5 +1,7 @@
import { NgModule } from "@angular/core";
import { BannerModule } from "@bitwarden/components";
import { OnboardingModule } from "../../../../../../apps/web/src/app/shared/components/onboarding/onboarding.module";
import { SecretsManagerSharedModule } from "../shared/sm-shared.module";
@@ -8,7 +10,7 @@ import { OverviewComponent } from "./overview.component";
import { SectionComponent } from "./section.component";
@NgModule({
imports: [SecretsManagerSharedModule, OverviewRoutingModule, OnboardingModule],
imports: [SecretsManagerSharedModule, OverviewRoutingModule, OnboardingModule, BannerModule],
declarations: [OverviewComponent, SectionComponent],
providers: [],
})