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:
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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: {
|
||||
|
||||
Reference in New Issue
Block a user