From e27d698d4b4564944fda9865f5be9a62ba8f2f26 Mon Sep 17 00:00:00 2001 From: Alex Morask <144709477+amorask-bitwarden@users.noreply.github.com> Date: Wed, 17 Jul 2024 10:12:40 -0400 Subject: [PATCH] [AC-2860] Revise unassigned and purchased seat warning for CB (#10077) * Rework create-client-dialog seat warning * Rework manage-client-subscription-dialog seat warning * Fix create client purchased seats label * Fix manage client subscription purchased seats label logic * Another manage subscription purchased seats fix --- apps/web/src/locales/en/messages.json | 3 ++ .../create-client-dialog.component.html | 9 ++++-- .../clients/create-client-dialog.component.ts | 19 +++++++----- ...-client-subscription-dialog.component.html | 14 ++++++--- ...ge-client-subscription-dialog.component.ts | 31 +++++++++++++++++-- 5 files changed, 59 insertions(+), 17 deletions(-) diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index 8b8c265653..73396c39c1 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -8564,5 +8564,8 @@ "example": "Organization name" } } + }, + "purchasedSeatsRemoved": { + "message": "purchased seats removed" } } 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 662cd8a69f..66ac422441 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 @@ -58,13 +58,16 @@ {{ unassignedSeats }} {{ "unassignedSeatsDescription" | i18n | lowercase }} - {{ additionalSeatsPurchased }} {{ "purchaseSeatDescription" | i18n | lowercase }} diff --git a/bitwarden_license/bit-web/src/app/billing/providers/clients/create-client-dialog.component.ts b/bitwarden_license/bit-web/src/app/billing/providers/clients/create-client-dialog.component.ts index 987b7cc698..c0ee21d2ab 100644 --- a/bitwarden_license/bit-web/src/app/billing/providers/clients/create-client-dialog.component.ts +++ b/bitwarden_license/bit-web/src/app/billing/providers/clients/create-client-dialog.component.ts @@ -162,18 +162,16 @@ export class CreateClientDialogComponent implements OnInit { this.dialogRef.close(this.ResultType.Submitted); }; - protected get openSeats(): number { + protected get unassignedSeats(): number { const selectedProviderPlan = this.getSelectedProviderPlan(); if (selectedProviderPlan === null) { return 0; } - return selectedProviderPlan.seatMinimum - selectedProviderPlan.assignedSeats; - } + const openSeats = selectedProviderPlan.seatMinimum - selectedProviderPlan.assignedSeats; - protected get unassignedSeats(): number { - const unassignedSeats = this.openSeats - this.formGroup.value.seats; + const unassignedSeats = openSeats - this.formGroup.value.seats; return unassignedSeats > 0 ? unassignedSeats : 0; } @@ -185,11 +183,16 @@ export class CreateClientDialogComponent implements OnInit { return 0; } - const selectedSeats = this.formGroup.value.seats ?? 0; + if (selectedProviderPlan.purchasedSeats > 0) { + return this.formGroup.value.seats; + } - const purchased = selectedSeats - this.openSeats; + const additionalSeatsPurchased = + this.formGroup.value.seats + + selectedProviderPlan.assignedSeats - + selectedProviderPlan.seatMinimum; - return purchased > 0 ? purchased : 0; + return additionalSeatsPurchased > 0 ? additionalSeatsPurchased : 0; } private getSelectedProviderPlan(): ProviderPlanResponse { diff --git a/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-client-subscription-dialog.component.html b/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-client-subscription-dialog.component.html index 0d2d22eadd..2c911b2cb1 100644 --- a/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-client-subscription-dialog.component.html +++ b/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-client-subscription-dialog.component.html @@ -16,21 +16,27 @@ formControlName="assignedSeats" [min]="dialogParams.organization.occupiedSeats" /> - +
{{ unassignedSeats }} {{ "unassignedSeatsDescription" | i18n | lowercase }} - {{ additionalSeatsPurchased }} {{ "purchaseSeatDescription" | i18n | lowercase }} + {{ purchasedSeatsRemoved }} {{ "purchasedSeatsRemoved" | i18n | lowercase }}
+ diff --git a/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-client-subscription-dialog.component.ts b/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-client-subscription-dialog.component.ts index e97e4ea959..f92223d1b5 100644 --- a/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-client-subscription-dialog.component.ts +++ b/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-client-subscription-dialog.component.ts @@ -36,7 +36,10 @@ export const openManageClientSubscriptionDialog = ( export class ManageClientSubscriptionDialogComponent implements OnInit { protected loading = true; protected providerPlan: ProviderPlanResponse; + protected assignedSeats: number; protected openSeats: number; + protected purchasedSeats: number; + protected seatMinimum: number; protected readonly ResultType = ManageClientSubscriptionDialogResultType; protected formGroup = new FormGroup({ @@ -63,7 +66,10 @@ export class ManageClientSubscriptionDialogComponent implements OnInit { (plan) => plan.planName === this.dialogParams.organization.plan, ); + this.assignedSeats = this.providerPlan.assignedSeats; this.openSeats = this.providerPlan.seatMinimum - this.providerPlan.assignedSeats; + this.purchasedSeats = this.providerPlan.purchasedSeats; + this.seatMinimum = this.providerPlan.seatMinimum; this.formGroup.controls.assignedSeats.addValidators( this.isServiceUserWithPurchasedSeats @@ -165,9 +171,22 @@ export class ManageClientSubscriptionDialogComponent implements OnInit { const seatDifference = this.formGroup.value.assignedSeats - this.dialogParams.organization.seats; - const purchasedSeats = seatDifference - this.openSeats; + if (this.purchasedSeats > 0) { + return seatDifference; + } - return purchasedSeats > 0 ? purchasedSeats : 0; + return seatDifference - this.openSeats; + } + + get purchasedSeatsRemoved(): number { + const seatDifference = + this.dialogParams.organization.seats - this.formGroup.value.assignedSeats; + + if (this.purchasedSeats >= seatDifference) { + return seatDifference; + } + + return this.purchasedSeats; } get isProviderAdmin(): boolean { @@ -177,4 +196,12 @@ export class ManageClientSubscriptionDialogComponent implements OnInit { get isServiceUserWithPurchasedSeats(): boolean { return !this.isProviderAdmin && this.providerPlan && this.providerPlan.purchasedSeats > 0; } + + get purchasingSeats(): boolean { + return this.additionalSeatsPurchased > 0; + } + + get sellingSeats(): boolean { + return this.purchasedSeats > 0 && this.additionalSeatsPurchased < 0; + } }