[PM-4395] Block reseller org invites if they outnumber available seats (#6698)

* Add Toast when reseller org invites over seat limit

* Set validation error when reseller org invited members outnumber seats

* Thomas' feedback
This commit is contained in:
Alex Morask 2023-11-20 10:10:47 -05:00 committed by GitHub
parent 1dbff31d20
commit 6f9c6d07af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 33 additions and 0 deletions

View File

@ -54,6 +54,7 @@ export interface MemberDialogParams {
allOrganizationUserEmails: string[]; allOrganizationUserEmails: string[];
usesKeyConnector: boolean; usesKeyConnector: boolean;
initialTab?: MemberDialogTab; initialTab?: MemberDialogTab;
numConfirmedMembers: number;
} }
export enum MemberDialogResult { export enum MemberDialogResult {
@ -383,6 +384,15 @@ export class MemberDialogComponent implements OnInit, OnDestroy {
}); });
return; return;
} }
if (
this.organization.hasReseller &&
this.params.numConfirmedMembers + emails.length > this.organization.seats
) {
this.formGroup.controls.emails.setErrors({
tooManyEmails: { message: this.i18nService.t("seatLimitReachedContactYourProvider") },
});
return;
}
await this.userService.invite(emails, userView); await this.userService.invite(emails, userView);
} }

View File

@ -427,6 +427,15 @@ export class PeopleComponent
} }
async edit(user: OrganizationUserView, initialTab: MemberDialogTab = MemberDialogTab.Role) { async edit(user: OrganizationUserView, initialTab: MemberDialogTab = MemberDialogTab.Role) {
if (!user && this.organization.hasReseller && this.organization.seats === this.confirmedCount) {
this.platformUtilsService.showToast(
"error",
this.i18nService.t("seatLimitReached"),
this.i18nService.t("contactYourProvider")
);
return;
}
// Invite User: Add Flow // Invite User: Add Flow
// Click on user email: Edit Flow // Click on user email: Edit Flow
@ -450,6 +459,7 @@ export class PeopleComponent
allOrganizationUserEmails: this.allUsers?.map((user) => user.email) ?? [], allOrganizationUserEmails: this.allUsers?.map((user) => user.email) ?? [],
usesKeyConnector: user?.usesKeyConnector, usesKeyConnector: user?.usesKeyConnector,
initialTab: initialTab, initialTab: initialTab,
numConfirmedMembers: this.confirmedCount,
}, },
}); });

View File

@ -7398,5 +7398,14 @@
}, },
"unexpectedErrorSend": { "unexpectedErrorSend": {
"message": "An unexpected error has occurred while loading this Send. Try again later." "message": "An unexpected error has occurred while loading this Send. Try again later."
},
"seatLimitReached": {
"message": "Seat limit has been reached"
},
"contactYourProvider": {
"message": "Contact your provider to purchase additional seats."
},
"seatLimitReachedContactYourProvider": {
"message": "Seat limit has been reached. Contact your provider to purchase additional seats."
} }
} }

View File

@ -258,6 +258,10 @@ export class Organization {
return this.providerId != null || this.providerName != null; return this.providerId != null || this.providerName != null;
} }
get hasReseller() {
return this.hasProvider && this.providerType === ProviderType.Reseller;
}
get canAccessSecretsManager() { get canAccessSecretsManager() {
return this.useSecretsManager && this.accessSecretsManager; return this.useSecretsManager && this.accessSecretsManager;
} }