From 2bbe4d2cba94ea2acd0a9a84f9d38ed73efb2764 Mon Sep 17 00:00:00 2001 From: Jonas Hendrickx Date: Mon, 11 Nov 2024 07:57:09 +0100 Subject: [PATCH] [PM-13470] Allow creating clients for multi-org providers (#11890) --- apps/web/src/locales/en/messages.json | 6 +++ .../create-client-dialog.component.html | 2 +- .../clients/create-client-dialog.component.ts | 49 ++++++++++--------- ...rovider-subscription-status.component.html | 2 +- .../provider-subscription-status.component.ts | 10 ++++ .../admin-console/enums/provider-type.enum.ts | 1 + .../provider-subscription-response.ts | 8 +++ 7 files changed, 54 insertions(+), 24 deletions(-) diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index 09feaadcc1c..f4baf8273dc 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -9017,6 +9017,12 @@ "providerPlan": { "message": "Managed Service Provider" }, + "managedServiceProvider": { + "message": "Managed service provider" + }, + "multiOrganizationEnterprise": { + "message": "Multi-organization enterprise" + }, "orgSeats": { "message": "Organization Seats" }, diff --git a/bitwarden_license/bit-web/src/app/billing/providers/clients/create-client-dialog.component.html b/bitwarden_license/bit-web/src/app/billing/providers/clients/create-client-dialog.component.html index ed58650f211..e72b9ed661a 100644 --- a/bitwarden_license/bit-web/src/app/billing/providers/clients/create-client-dialog.component.html +++ b/bitwarden_license/bit-web/src/app/billing/providers/clients/create-client-dialog.component.html @@ -12,7 +12,7 @@ }} -
+
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; } diff --git a/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription-status.component.html b/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription-status.component.html index 6c4bf422f7a..f08dbf0c37a 100644 --- a/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription-status.component.html +++ b/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription-status.component.html @@ -4,7 +4,7 @@
{{ "billingPlan" | i18n }}
-
{{ "providerPlan" | i18n }}
+
{{ plan | i18n }}
{{ data.status.label }}
diff --git a/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription-status.component.ts b/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription-status.component.ts index c3ad875136e..dea7d4ca197 100644 --- a/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription-status.component.ts +++ b/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription-status.component.ts @@ -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"; diff --git a/libs/common/src/admin-console/enums/provider-type.enum.ts b/libs/common/src/admin-console/enums/provider-type.enum.ts index 5f81c338f0e..d802c659f6f 100644 --- a/libs/common/src/admin-console/enums/provider-type.enum.ts +++ b/libs/common/src/admin-console/enums/provider-type.enum.ts @@ -1,4 +1,5 @@ export enum ProviderType { Msp = 0, Reseller = 1, + MultiOrganizationEnterprise = 2, } diff --git a/libs/common/src/billing/models/response/provider-subscription-response.ts b/libs/common/src/billing/models/response/provider-subscription-response.ts index 2dc9d4281de..2ecf988addd 100644 --- a/libs/common/src/billing/models/response/provider-subscription-response.ts +++ b/libs/common/src/billing/models/response/provider-subscription-response.ts @@ -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"); } }