1
0
mirror of https://github.com/bitwarden/browser synced 2026-01-05 10:03:21 +00:00

[PM-10323] Add delete option to managed members (#11655)

* Add managedByOrganization property to OrganizationUserUserDetailsResponse and OrganizationUserView

* Add managedByOrganization property to OrganizationUserDetailsResponse and OrganizationUserAdminView

* Add deleteOrganizationUser method to OrganizationUserApiService

* Add copy strings for organization user delete dialog

* Add copy string for organization user deleted toast

* Add delete organization user dialog component

* Add the option to delete managed organization users from the members list

* Refactor delete user confirmation dialog in MembersComponent to use DialogService

* Delete DeleteOrganizationUserDialogComponent

* Refactor delete button in member dialog component to change the icon and tooltip text to 'Remove'

* Add delete button to members dialog if the user is managed by the organization
This commit is contained in:
Rui Tomé
2024-11-04 16:19:30 +00:00
committed by GitHub
parent 2d0460eb15
commit d669d2003f
7 changed files with 134 additions and 1 deletions

View File

@@ -264,6 +264,16 @@
<button
*ngIf="editMode"
type="button"
bitIconButton="bwi-close"
buttonType="danger"
bitFormButton
[appA11yTitle]="'remove' | i18n"
[bitAction]="remove"
[disabled]="loading"
></button>
<button
*ngIf="editMode && params.managedByOrganization === true"
type="button"
bitIconButton="bwi-trash"
buttonType="danger"
bitFormButton

View File

@@ -65,6 +65,7 @@ export interface MemberDialogParams {
isOnSecretsManagerStandalone: boolean;
initialTab?: MemberDialogTab;
numConfirmedMembers: number;
managedByOrganization?: boolean;
}
export enum MemberDialogResult {
@@ -464,7 +465,7 @@ export class MemberDialogComponent implements OnDestroy {
this.close(MemberDialogResult.Saved);
};
delete = async () => {
remove = async () => {
if (!this.editMode) {
return;
}
@@ -561,6 +562,39 @@ export class MemberDialogComponent implements OnDestroy {
this.close(MemberDialogResult.Restored);
};
delete = async () => {
if (!this.editMode) {
return;
}
const confirmed = await this.dialogService.openSimpleDialog({
title: {
key: "deleteOrganizationUser",
placeholders: [this.params.name],
},
content: { key: "deleteOrganizationUserWarning" },
type: "warning",
acceptButtonText: { key: "delete" },
cancelButtonText: { key: "cancel" },
});
if (!confirmed) {
return false;
}
await this.organizationUserApiService.deleteOrganizationUser(
this.params.organizationId,
this.params.organizationUserId,
);
this.toastService.showToast({
variant: "success",
title: null,
message: this.i18nService.t("organizationUserDeleted", this.params.name),
});
this.close(MemberDialogResult.Deleted);
};
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();

View File

@@ -320,6 +320,17 @@
<i aria-hidden="true" class="bwi bwi-close"></i> {{ "remove" | i18n }}
</span>
</button>
<button
*ngIf="u.managedByOrganization === true"
type="button"
bitMenuItem
(click)="deleteUser(u)"
>
<span class="tw-text-danger">
<i class="bwi bwi-fw bwi-trash" aria-hidden="true"></i>
{{ "delete" | i18n }}
</span>
</button>
</bit-menu>
</td>
</tr>

View File

@@ -518,6 +518,7 @@ export class MembersComponent extends BaseMembersComponent<OrganizationUserView>
isOnSecretsManagerStandalone: this.orgIsOnSecretsManagerStandalone,
initialTab: initialTab,
numConfirmedMembers: this.dataSource.confirmedUserCount,
managedByOrganization: user?.managedByOrganization,
},
});
@@ -725,6 +726,40 @@ export class MembersComponent extends BaseMembersComponent<OrganizationUserView>
return true;
}
async deleteUser(user: OrganizationUserView) {
const confirmed = await this.dialogService.openSimpleDialog({
title: {
key: "deleteOrganizationUser",
placeholders: [this.userNamePipe.transform(user)],
},
content: { key: "deleteOrganizationUserWarning" },
type: "warning",
acceptButtonText: { key: "delete" },
cancelButtonText: { key: "cancel" },
});
if (!confirmed) {
return false;
}
this.actionPromise = this.organizationUserApiService.deleteOrganizationUser(
this.organization.id,
user.id,
);
try {
await this.actionPromise;
this.toastService.showToast({
variant: "success",
title: null,
message: this.i18nService.t("organizationUserDeleted", this.userNamePipe.transform(user)),
});
this.dataSource.removeUser(user);
} catch (e) {
this.validationService.showError(e);
}
this.actionPromise = null;
}
private async noMasterPasswordConfirmationDialog(user: OrganizationUserView) {
return this.dialogService.openSimpleDialog({
title: {