1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-06 00:13:28 +00:00

[PM-21109] Resend invitation button not responsive when clicked (#14603)

* Resolve the resend email bug

* Resolve the resend invite option for Active sponsorship

* Resolve the lint error

* Rename the o variable  properly
This commit is contained in:
cyprain-okeke
2025-05-05 16:19:11 +01:00
committed by GitHub
parent af40ff26a2
commit 28f00e5533
7 changed files with 38 additions and 19 deletions

View File

@@ -39,12 +39,14 @@
</tr>
</ng-container>
<ng-template body alignContent="middle">
@for (o of sponsoredFamilies; let i = $index; track i) {
@for (sponsoredFamily of sponsoredFamilies; let i = $index; track i) {
<ng-container>
<tr bitRow>
<td bitCell>{{ o.friendlyName }}</td>
<td bitCell [class]="o.statusClass">{{ o.statusMessage }}</td>
<td bitCell>{{ o.notes }}</td>
<td bitCell>{{ sponsoredFamily.friendlyName }}</td>
<td bitCell [class]="sponsoredFamily.statusClass">
{{ sponsoredFamily.statusMessage }}
</td>
<td bitCell>{{ sponsoredFamily.notes }}</td>
<td bitCell>
<button
type="button"
@@ -58,7 +60,8 @@
type="button"
bitMenuItem
[attr.aria-label]="'resendEmailLabel' | i18n"
(click)="resendEmail(o)"
*ngIf="!isSelfHosted && !sponsoredFamily.validUntil"
(click)="resendEmail(sponsoredFamily)"
>
<i aria-hidden="true" class="bwi bwi-envelope"></i>
{{ "resendInvitation" | i18n }}
@@ -70,7 +73,7 @@
type="button"
bitMenuItem
[attr.aria-label]="'revokeAccountMessage' | i18n"
(click)="removeSponsorship(o)"
(click)="removeSponsorship(sponsoredFamily)"
>
<i aria-hidden="true" class="bwi bwi-close tw-text-danger"></i>
<span class="tw-text-danger pl-1">{{ "remove" | i18n }}</span>

View File

@@ -145,7 +145,10 @@ export class FreeBitwardenFamiliesComponent implements OnInit {
}
async resendEmail(sponsorship: OrganizationSponsorshipInvitesResponse) {
await this.apiService.postResendSponsorshipOffer(sponsorship.sponsoringOrganizationUserId);
await this.organizationSponsorshipApiService.postResendSponsorshipOffer(
this.organizationId,
sponsorship.friendlyName,
);
this.toastService.showToast({
variant: "success",
title: undefined,

View File

@@ -10,6 +10,7 @@ import { PolicyType } from "@bitwarden/common/admin-console/enums";
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { getUserId } from "@bitwarden/common/auth/services/account.service";
import { OrganizationSponsorshipApiServiceAbstraction } from "@bitwarden/common/billing/abstractions/organizations/organization-sponsorship-api.service.abstraction";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { DialogService, ToastService } from "@bitwarden/components";
@@ -37,6 +38,7 @@ export class SponsoringOrgRowComponent implements OnInit {
private toastService: ToastService,
private policyService: PolicyService,
private accountService: AccountService,
private organizationSponsorshipApiService: OrganizationSponsorshipApiServiceAbstraction,
) {}
async ngOnInit() {
@@ -73,7 +75,10 @@ export class SponsoringOrgRowComponent implements OnInit {
}
async resendEmail() {
await this.apiService.postResendSponsorshipOffer(this.sponsoringOrg.id);
await this.organizationSponsorshipApiService.postResendSponsorshipOffer(
this.sponsoringOrg.id,
this.sponsoringOrg.familySponsorshipFriendlyName,
);
this.toastService.showToast({
variant: "success",
title: null,

View File

@@ -490,7 +490,6 @@ export abstract class ApiService {
sponsorshipToken: string,
request: OrganizationSponsorshipRedeemRequest,
) => Promise<void>;
postResendSponsorshipOffer: (sponsoringOrgId: string) => Promise<void>;
getMasterKeyFromKeyConnector: (keyConnectorUrl: string) => Promise<KeyConnectorUserKeyResponse>;
postUserKeyToKeyConnector: (

View File

@@ -5,4 +5,9 @@ export abstract class OrganizationSponsorshipApiServiceAbstraction {
abstract getOrganizationSponsorship(
sponsoredOrgId: string,
): Promise<ListResponse<OrganizationSponsorshipInvitesResponse>>;
abstract postResendSponsorshipOffer(
sponsoringOrgId: string,
friendlyName?: string,
): Promise<void>;
}

View File

@@ -19,4 +19,18 @@ export class OrganizationSponsorshipApiService
);
return new ListResponse(r, OrganizationSponsorshipInvitesResponse);
}
async postResendSponsorshipOffer(
sponsoringOrgId: string,
sponsoredFriendlyName?: string,
): Promise<void> {
let url = "/organization/sponsorship/" + sponsoringOrgId + "/families-for-enterprise/resend";
// Add the query parameter if sponsoredOrgUserId is provided
if (sponsoredFriendlyName) {
url += `?sponsoredFriendlyName=${encodeURIComponent(sponsoredFriendlyName)}`;
}
return await this.apiService.send("POST", url, null, true, false);
}
}

View File

@@ -1682,16 +1682,6 @@ export class ApiService implements ApiServiceAbstraction {
);
}
async postResendSponsorshipOffer(sponsoringOrgId: string): Promise<void> {
return await this.send(
"POST",
"/organization/sponsorship/" + sponsoringOrgId + "/families-for-enterprise/resend",
null,
true,
false,
);
}
// Keep the running refreshTokenPromise to prevent parallel calls.
protected refreshToken(): Promise<string> {
if (this.refreshTokenPromise === undefined) {