mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-22 11:45:59 +01:00
[PM-14554] Condition the display of members bulk actions based on selection (#11922)
* Refactor organization user API service to support bulk deletion of users
* Add copy for bulk user delete dialog
* Add bulk user delete dialog component
* Add bulk user delete functionality to members component
* Make bulk user actions in the members component conditional based on the selected members
* Refactor members component to only display bulk user deletion option if the Account Deprovisioning flag is enabled
* Refactor bulk action visibility in members component based on Account Deprovisioning flag
* Patch build process
* Refactor bulk action visibility conditions in members component
* Simplify status checks in members component by using loose equality and removing redundant boolean comparisons
* Refactor bulk action visibility logic in members component to use computed properties for improved readability and maintainability
* Refactor bulk action visibility logic in members component to eliminate redundant methods and improve readability
* Revert "Patch build process"
This reverts commit 917c969f00
.
* Refactor bulk action visibility logic in members component
---------
Co-authored-by: Matt Bishop <mbishop@bitwarden.com>
This commit is contained in:
parent
587327bc4a
commit
773bdd2167
@ -123,25 +123,40 @@
|
||||
{{ "confirmSelected" | i18n }}
|
||||
</span>
|
||||
</button>
|
||||
<button type="button" bitMenuItem (click)="bulkRestore()">
|
||||
<button
|
||||
type="button"
|
||||
bitMenuItem
|
||||
(click)="bulkRestore()"
|
||||
*ngIf="showBulkRestoreUsers"
|
||||
>
|
||||
<i class="bwi bwi-fw bwi-plus-circle" aria-hidden="true"></i>
|
||||
{{ "restoreAccess" | i18n }}
|
||||
</button>
|
||||
<button type="button" bitMenuItem (click)="bulkRevoke()">
|
||||
<button
|
||||
type="button"
|
||||
bitMenuItem
|
||||
(click)="bulkRevoke()"
|
||||
*ngIf="showBulkRevokeUsers"
|
||||
>
|
||||
<i class="bwi bwi-fw bwi-minus-circle" aria-hidden="true"></i>
|
||||
{{ "revokeAccess" | i18n }}
|
||||
</button>
|
||||
<button type="button" bitMenuItem (click)="bulkRemove()">
|
||||
<button
|
||||
type="button"
|
||||
bitMenuItem
|
||||
(click)="bulkRemove()"
|
||||
*ngIf="showBulkRemoveUsers"
|
||||
>
|
||||
<span class="tw-text-danger">
|
||||
<i aria-hidden="true" class="bwi bwi-close"></i>
|
||||
{{ "remove" | i18n }}
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
*ngIf="accountDeprovisioningEnabled$ | async"
|
||||
type="button"
|
||||
bitMenuItem
|
||||
(click)="bulkDelete()"
|
||||
*ngIf="showBulkDeleteUsers"
|
||||
>
|
||||
<span class="tw-text-danger">
|
||||
<i aria-hidden="true" class="bwi bwi-trash"></i>
|
||||
@ -327,7 +342,7 @@
|
||||
{{ "revokeAccess" | i18n }}
|
||||
</button>
|
||||
<button
|
||||
*ngIf="!(accountDeprovisioningEnabled$ | async) || !u.managedByOrganization"
|
||||
*ngIf="!accountDeprovisioningEnabled || !u.managedByOrganization"
|
||||
type="button"
|
||||
bitMenuItem
|
||||
(click)="remove(u)"
|
||||
@ -337,7 +352,7 @@
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
*ngIf="(accountDeprovisioningEnabled$ | async) && u.managedByOrganization"
|
||||
*ngIf="accountDeprovisioningEnabled && u.managedByOrganization"
|
||||
type="button"
|
||||
bitMenuItem
|
||||
(click)="deleteUser(u)"
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Component, ViewChild, ViewContainerRef } from "@angular/core";
|
||||
import { Component, OnInit, ViewChild, ViewContainerRef } from "@angular/core";
|
||||
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
||||
import { ActivatedRoute, Router } from "@angular/router";
|
||||
import {
|
||||
@ -83,7 +83,7 @@ class MembersTableDataSource extends PeopleTableDataSource<OrganizationUserView>
|
||||
@Component({
|
||||
templateUrl: "members.component.html",
|
||||
})
|
||||
export class MembersComponent extends BaseMembersComponent<OrganizationUserView> {
|
||||
export class MembersComponent extends BaseMembersComponent<OrganizationUserView> implements OnInit {
|
||||
@ViewChild("resetPasswordTemplate", { read: ViewContainerRef, static: true })
|
||||
resetPasswordModalRef: ViewContainerRef;
|
||||
|
||||
@ -96,13 +96,10 @@ export class MembersComponent extends BaseMembersComponent<OrganizationUserView>
|
||||
status: OrganizationUserStatusType = null;
|
||||
orgResetPasswordPolicyEnabled = false;
|
||||
orgIsOnSecretsManagerStandalone = false;
|
||||
accountDeprovisioningEnabled = false;
|
||||
|
||||
protected canUseSecretsManager$: Observable<boolean>;
|
||||
|
||||
protected accountDeprovisioningEnabled$: Observable<boolean> = this.configService.getFeatureFlag$(
|
||||
FeatureFlag.AccountDeprovisioning,
|
||||
);
|
||||
|
||||
// Fixed sizes used for cdkVirtualScroll
|
||||
protected rowHeight = 69;
|
||||
protected rowHeightClass = `tw-h-[69px]`;
|
||||
@ -216,6 +213,12 @@ export class MembersComponent extends BaseMembersComponent<OrganizationUserView>
|
||||
.subscribe();
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
this.accountDeprovisioningEnabled = await this.configService.getFeatureFlag(
|
||||
FeatureFlag.AccountDeprovisioning,
|
||||
);
|
||||
}
|
||||
|
||||
async getUsers(): Promise<OrganizationUserView[]> {
|
||||
let groupsPromise: Promise<Map<string, string>>;
|
||||
let collectionsPromise: Promise<Map<string, string>>;
|
||||
@ -779,4 +782,65 @@ export class MembersComponent extends BaseMembersComponent<OrganizationUserView>
|
||||
type: "warning",
|
||||
});
|
||||
}
|
||||
|
||||
get showBulkConfirmUsers(): boolean {
|
||||
if (!this.accountDeprovisioningEnabled) {
|
||||
return super.showBulkConfirmUsers;
|
||||
}
|
||||
|
||||
return this.dataSource
|
||||
.getCheckedUsers()
|
||||
.every((member) => member.status == this.userStatusType.Accepted);
|
||||
}
|
||||
|
||||
get showBulkReinviteUsers(): boolean {
|
||||
if (!this.accountDeprovisioningEnabled) {
|
||||
return super.showBulkReinviteUsers;
|
||||
}
|
||||
|
||||
return this.dataSource
|
||||
.getCheckedUsers()
|
||||
.every((member) => member.status == this.userStatusType.Invited);
|
||||
}
|
||||
|
||||
get showBulkRestoreUsers(): boolean {
|
||||
return (
|
||||
!this.accountDeprovisioningEnabled ||
|
||||
this.dataSource
|
||||
.getCheckedUsers()
|
||||
.every((member) => member.status == this.userStatusType.Revoked)
|
||||
);
|
||||
}
|
||||
|
||||
get showBulkRevokeUsers(): boolean {
|
||||
return (
|
||||
!this.accountDeprovisioningEnabled ||
|
||||
this.dataSource
|
||||
.getCheckedUsers()
|
||||
.every((member) => member.status != this.userStatusType.Revoked)
|
||||
);
|
||||
}
|
||||
|
||||
get showBulkRemoveUsers(): boolean {
|
||||
return (
|
||||
!this.accountDeprovisioningEnabled ||
|
||||
this.dataSource.getCheckedUsers().every((member) => !member.managedByOrganization)
|
||||
);
|
||||
}
|
||||
|
||||
get showBulkDeleteUsers(): boolean {
|
||||
if (!this.accountDeprovisioningEnabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const validStatuses = [
|
||||
this.userStatusType.Accepted,
|
||||
this.userStatusType.Confirmed,
|
||||
this.userStatusType.Revoked,
|
||||
];
|
||||
|
||||
return this.dataSource
|
||||
.getCheckedUsers()
|
||||
.every((member) => member.managedByOrganization && validStatuses.includes(member.status));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user