mirror of
https://github.com/bitwarden/browser
synced 2025-12-16 08:13:42 +00:00
[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
This commit is contained in:
@@ -8564,5 +8564,8 @@
|
|||||||
"example": "Organization name"
|
"example": "Organization name"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"purchasedSeatsRemoved": {
|
||||||
|
"message": "purchased seats removed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,13 +58,16 @@
|
|||||||
</bit-label>
|
</bit-label>
|
||||||
<input type="number" bitInput formControlName="seats" min="1" />
|
<input type="number" bitInput formControlName="seats" min="1" />
|
||||||
<bit-hint
|
<bit-hint
|
||||||
class="tw-text-muted tw-grid tw-grid-flow-col tw-gap-1 tw-grid-cols-1 tw-grid-rows-2"
|
class="tw-text-muted tw-grid tw-grid-flow-col tw-gap-1 tw-grid-cols-1"
|
||||||
*ngIf="openSeats > 0"
|
[ngClass]="{
|
||||||
|
'tw-grid-rows-1': additionalSeatsPurchased <= 0,
|
||||||
|
'tw-grid-rows-2': additionalSeatsPurchased > 0
|
||||||
|
}"
|
||||||
>
|
>
|
||||||
<span class="tw-col-span-1"
|
<span class="tw-col-span-1"
|
||||||
>{{ unassignedSeats }} {{ "unassignedSeatsDescription" | i18n | lowercase }}</span
|
>{{ unassignedSeats }} {{ "unassignedSeatsDescription" | i18n | lowercase }}</span
|
||||||
>
|
>
|
||||||
<span class="tw-col-span-1"
|
<span class="tw-col-span-1" *ngIf="additionalSeatsPurchased > 0"
|
||||||
>{{ additionalSeatsPurchased }}
|
>{{ additionalSeatsPurchased }}
|
||||||
{{ "purchaseSeatDescription" | i18n | lowercase }}</span
|
{{ "purchaseSeatDescription" | i18n | lowercase }}</span
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -162,18 +162,16 @@ export class CreateClientDialogComponent implements OnInit {
|
|||||||
this.dialogRef.close(this.ResultType.Submitted);
|
this.dialogRef.close(this.ResultType.Submitted);
|
||||||
};
|
};
|
||||||
|
|
||||||
protected get openSeats(): number {
|
protected get unassignedSeats(): number {
|
||||||
const selectedProviderPlan = this.getSelectedProviderPlan();
|
const selectedProviderPlan = this.getSelectedProviderPlan();
|
||||||
|
|
||||||
if (selectedProviderPlan === null) {
|
if (selectedProviderPlan === null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return selectedProviderPlan.seatMinimum - selectedProviderPlan.assignedSeats;
|
const openSeats = selectedProviderPlan.seatMinimum - selectedProviderPlan.assignedSeats;
|
||||||
}
|
|
||||||
|
|
||||||
protected get unassignedSeats(): number {
|
const unassignedSeats = openSeats - this.formGroup.value.seats;
|
||||||
const unassignedSeats = this.openSeats - this.formGroup.value.seats;
|
|
||||||
|
|
||||||
return unassignedSeats > 0 ? unassignedSeats : 0;
|
return unassignedSeats > 0 ? unassignedSeats : 0;
|
||||||
}
|
}
|
||||||
@@ -185,11 +183,16 @@ export class CreateClientDialogComponent implements OnInit {
|
|||||||
return 0;
|
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 {
|
private getSelectedProviderPlan(): ProviderPlanResponse {
|
||||||
|
|||||||
@@ -16,21 +16,27 @@
|
|||||||
formControlName="assignedSeats"
|
formControlName="assignedSeats"
|
||||||
[min]="dialogParams.organization.occupiedSeats"
|
[min]="dialogParams.organization.occupiedSeats"
|
||||||
/>
|
/>
|
||||||
<bit-hint class="tw-text-muted" *ngIf="openSeats > 0 || isServiceUserWithPurchasedSeats">
|
<bit-hint class="tw-text-muted" *ngIf="!isServiceUserWithPurchasedSeats">
|
||||||
<div
|
<div
|
||||||
*ngIf="!this.isServiceUserWithPurchasedSeats"
|
|
||||||
class="tw-grid tw-grid-flow-col tw-gap-1 tw-grid-cols-1"
|
class="tw-grid tw-grid-flow-col tw-gap-1 tw-grid-cols-1"
|
||||||
[ngClass]="{ 'tw-grid-rows-2': this.isProviderAdmin }"
|
[ngClass]="{
|
||||||
|
'tw-grid-rows-1': additionalSeatsPurchased === 0,
|
||||||
|
'tw-grid-rows-2': purchasingSeats || sellingSeats
|
||||||
|
}"
|
||||||
>
|
>
|
||||||
<span class="tw-col-span-1">
|
<span class="tw-col-span-1">
|
||||||
{{ unassignedSeats }} {{ "unassignedSeatsDescription" | i18n | lowercase }}
|
{{ unassignedSeats }} {{ "unassignedSeatsDescription" | i18n | lowercase }}
|
||||||
</span>
|
</span>
|
||||||
<span *ngIf="this.isProviderAdmin" class="tw-col-span-1"
|
<span *ngIf="purchasingSeats" class="tw-col-span-1"
|
||||||
>{{ additionalSeatsPurchased }}
|
>{{ additionalSeatsPurchased }}
|
||||||
{{ "purchaseSeatDescription" | i18n | lowercase }}</span
|
{{ "purchaseSeatDescription" | i18n | lowercase }}</span
|
||||||
>
|
>
|
||||||
|
<span *ngIf="sellingSeats" class="tw-col-span-1"
|
||||||
|
>{{ purchasedSeatsRemoved }} {{ "purchasedSeatsRemoved" | i18n | lowercase }}</span
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</bit-hint>
|
</bit-hint>
|
||||||
|
<bit-hint *ngIf="isServiceUserWithPurchasedSeats"></bit-hint>
|
||||||
</bit-form-field>
|
</bit-form-field>
|
||||||
</div>
|
</div>
|
||||||
<ng-container bitDialogFooter>
|
<ng-container bitDialogFooter>
|
||||||
|
|||||||
@@ -36,7 +36,10 @@ export const openManageClientSubscriptionDialog = (
|
|||||||
export class ManageClientSubscriptionDialogComponent implements OnInit {
|
export class ManageClientSubscriptionDialogComponent implements OnInit {
|
||||||
protected loading = true;
|
protected loading = true;
|
||||||
protected providerPlan: ProviderPlanResponse;
|
protected providerPlan: ProviderPlanResponse;
|
||||||
|
protected assignedSeats: number;
|
||||||
protected openSeats: number;
|
protected openSeats: number;
|
||||||
|
protected purchasedSeats: number;
|
||||||
|
protected seatMinimum: number;
|
||||||
protected readonly ResultType = ManageClientSubscriptionDialogResultType;
|
protected readonly ResultType = ManageClientSubscriptionDialogResultType;
|
||||||
|
|
||||||
protected formGroup = new FormGroup({
|
protected formGroup = new FormGroup({
|
||||||
@@ -63,7 +66,10 @@ export class ManageClientSubscriptionDialogComponent implements OnInit {
|
|||||||
(plan) => plan.planName === this.dialogParams.organization.plan,
|
(plan) => plan.planName === this.dialogParams.organization.plan,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.assignedSeats = this.providerPlan.assignedSeats;
|
||||||
this.openSeats = this.providerPlan.seatMinimum - 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.formGroup.controls.assignedSeats.addValidators(
|
||||||
this.isServiceUserWithPurchasedSeats
|
this.isServiceUserWithPurchasedSeats
|
||||||
@@ -165,9 +171,22 @@ export class ManageClientSubscriptionDialogComponent implements OnInit {
|
|||||||
const seatDifference =
|
const seatDifference =
|
||||||
this.formGroup.value.assignedSeats - this.dialogParams.organization.seats;
|
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 {
|
get isProviderAdmin(): boolean {
|
||||||
@@ -177,4 +196,12 @@ export class ManageClientSubscriptionDialogComponent implements OnInit {
|
|||||||
get isServiceUserWithPurchasedSeats(): boolean {
|
get isServiceUserWithPurchasedSeats(): boolean {
|
||||||
return !this.isProviderAdmin && this.providerPlan && this.providerPlan.purchasedSeats > 0;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user