mirror of
https://github.com/bitwarden/browser.git
synced 2024-12-18 15:47:57 +01:00
[PM-13470] Allow creating clients for multi-org providers (#11890)
This commit is contained in:
parent
e91741b146
commit
2bbe4d2cba
@ -9017,6 +9017,12 @@
|
||||
"providerPlan": {
|
||||
"message": "Managed Service Provider"
|
||||
},
|
||||
"managedServiceProvider": {
|
||||
"message": "Managed service provider"
|
||||
},
|
||||
"multiOrganizationEnterprise": {
|
||||
"message": "Multi-organization enterprise"
|
||||
},
|
||||
"orgSeats": {
|
||||
"message": "Organization Seats"
|
||||
},
|
||||
|
@ -12,7 +12,7 @@
|
||||
}}</span>
|
||||
</div>
|
||||
<ng-container>
|
||||
<div class="tw-grid tw-grid-flow-col tw-grid-cols-2 tw-gap-4 tw-mb-4">
|
||||
<div class="tw-grid tw-grid-flow-col tw-auto-cols-[minmax(0,_2fr)] tw-gap-4 tw-mb-4">
|
||||
<div
|
||||
*ngFor="let planCard of planCards"
|
||||
[ngClass]="getPlanCardContainerClasses(planCard.selected)"
|
||||
|
@ -3,7 +3,7 @@ import { Component, Inject, OnInit } from "@angular/core";
|
||||
import { FormControl, FormGroup, Validators } from "@angular/forms";
|
||||
|
||||
import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions/billing-api.service.abstraction";
|
||||
import { PlanType } from "@bitwarden/common/billing/enums";
|
||||
import { PlanType, ProductTierType } from "@bitwarden/common/billing/enums";
|
||||
import { PlanResponse } from "@bitwarden/common/billing/models/response/plan.response";
|
||||
import { ProviderPlanResponse } from "@bitwarden/common/billing/models/response/provider-subscription-response";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
@ -103,30 +103,35 @@ export class CreateClientDialogComponent implements OnInit {
|
||||
|
||||
this.providerPlans = response?.plans ?? [];
|
||||
|
||||
const teamsPlan = this.dialogParams.plans.find((plan) => plan.type === PlanType.TeamsMonthly);
|
||||
const enterprisePlan = this.dialogParams.plans.find(
|
||||
(plan) => plan.type === PlanType.EnterpriseMonthly,
|
||||
);
|
||||
|
||||
this.discountPercentage = response.discountPercentage;
|
||||
const discountFactor = this.discountPercentage ? (100 - this.discountPercentage) / 100 : 1;
|
||||
|
||||
this.planCards = [
|
||||
{
|
||||
name: this.i18nService.t("planNameTeams"),
|
||||
cost: teamsPlan.PasswordManager.providerPortalSeatPrice * discountFactor,
|
||||
type: teamsPlan.type,
|
||||
plan: teamsPlan,
|
||||
selected: true,
|
||||
},
|
||||
{
|
||||
name: this.i18nService.t("planNameEnterprise"),
|
||||
cost: enterprisePlan.PasswordManager.providerPortalSeatPrice * discountFactor,
|
||||
type: enterprisePlan.type,
|
||||
plan: enterprisePlan,
|
||||
selected: false,
|
||||
},
|
||||
];
|
||||
this.planCards = [];
|
||||
|
||||
for (let i = 0; i < this.providerPlans.length; i++) {
|
||||
const providerPlan = this.providerPlans[i];
|
||||
const plan = this.dialogParams.plans.find((plan) => plan.type === providerPlan.type);
|
||||
|
||||
let planName: string;
|
||||
switch (plan.productTier) {
|
||||
case ProductTierType.Teams: {
|
||||
planName = this.i18nService.t("planNameTeams");
|
||||
break;
|
||||
}
|
||||
case ProductTierType.Enterprise: {
|
||||
planName = this.i18nService.t("planNameEnterprise");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.planCards.push({
|
||||
name: planName,
|
||||
cost: plan.PasswordManager.providerPortalSeatPrice * discountFactor,
|
||||
type: plan.type,
|
||||
plan: plan,
|
||||
selected: i === 0,
|
||||
});
|
||||
}
|
||||
|
||||
this.loading = false;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
</bit-callout>
|
||||
<dl class="tw-grid tw-grid-flow-col tw-grid-rows-2">
|
||||
<dt>{{ "billingPlan" | i18n }}</dt>
|
||||
<dd>{{ "providerPlan" | i18n }}</dd>
|
||||
<dd>{{ plan | i18n }}</dd>
|
||||
<ng-container *ngIf="data.status && data.date">
|
||||
<dt>{{ data.status.label }}</dt>
|
||||
<dd>
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { DatePipe } from "@angular/common";
|
||||
import { Component, Input } from "@angular/core";
|
||||
|
||||
import { ProviderType } from "@bitwarden/common/admin-console/enums";
|
||||
import { ProviderSubscriptionResponse } from "@bitwarden/common/billing/models/response/provider-subscription-response";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
|
||||
@ -32,6 +33,15 @@ export class ProviderSubscriptionStatusComponent {
|
||||
private i18nService: I18nService,
|
||||
) {}
|
||||
|
||||
get plan(): string {
|
||||
switch (this.subscription.providerType) {
|
||||
case ProviderType.Msp:
|
||||
return "managedServiceProvider";
|
||||
case ProviderType.MultiOrganizationEnterprise:
|
||||
return "multiOrganizationEnterprise";
|
||||
}
|
||||
}
|
||||
|
||||
get status(): string {
|
||||
if (this.subscription.cancelAt && this.subscription.status === "active") {
|
||||
return "pending_cancellation";
|
||||
|
@ -1,4 +1,5 @@
|
||||
export enum ProviderType {
|
||||
Msp = 0,
|
||||
Reseller = 1,
|
||||
MultiOrganizationEnterprise = 2,
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { ProviderType } from "@bitwarden/common/admin-console/enums";
|
||||
import { PlanType, ProductTierType } from "@bitwarden/common/billing/enums";
|
||||
import { SubscriptionSuspensionResponse } from "@bitwarden/common/billing/models/response/subscription-suspension.response";
|
||||
import { TaxInfoResponse } from "@bitwarden/common/billing/models/response/tax-info.response";
|
||||
|
||||
@ -13,6 +15,7 @@ export class ProviderSubscriptionResponse extends BaseResponse {
|
||||
taxInformation?: TaxInfoResponse;
|
||||
cancelAt?: string;
|
||||
suspension?: SubscriptionSuspensionResponse;
|
||||
providerType: ProviderType;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
@ -34,6 +37,7 @@ export class ProviderSubscriptionResponse extends BaseResponse {
|
||||
if (suspension != null) {
|
||||
this.suspension = new SubscriptionSuspensionResponse(suspension);
|
||||
}
|
||||
this.providerType = this.getResponseProperty("providerType");
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,6 +48,8 @@ export class ProviderPlanResponse extends BaseResponse {
|
||||
purchasedSeats: number;
|
||||
cost: number;
|
||||
cadence: string;
|
||||
type: PlanType;
|
||||
productTier: ProductTierType;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
@ -53,5 +59,7 @@ export class ProviderPlanResponse extends BaseResponse {
|
||||
this.purchasedSeats = this.getResponseProperty("PurchasedSeats");
|
||||
this.cost = this.getResponseProperty("Cost");
|
||||
this.cadence = this.getResponseProperty("Cadence");
|
||||
this.type = this.getResponseProperty("Type");
|
||||
this.productTier = this.getResponseProperty("ProductTier");
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user