1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-11 22:03:36 +00:00

Migrate vault filter service from active user state to single user state (#15089)

This commit is contained in:
SmithThe4th
2025-06-30 13:02:18 -04:00
committed by GitHub
parent 80116c7e54
commit 62981a1bec
3 changed files with 41 additions and 19 deletions

View File

@@ -6,6 +6,7 @@ import { Observable } from "rxjs";
// eslint-disable-next-line no-restricted-imports
import { CollectionView } from "@bitwarden/admin-console/common";
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { UserId } from "@bitwarden/common/types/guid";
import { FolderView } from "@bitwarden/common/vault/models/view/folder.view";
import { DynamicTreeNode } from "../vault-filter/models/dynamic-tree-node.model";
@@ -14,11 +15,14 @@ import { DynamicTreeNode } from "../vault-filter/models/dynamic-tree-node.model"
* @deprecated August 30 2022: Use new VaultFilterService with observables
*/
export abstract class DeprecatedVaultFilterService {
buildOrganizations: () => Promise<Organization[]>;
buildNestedFolders: (organizationId?: string) => Observable<DynamicTreeNode<FolderView>>;
buildCollections: (organizationId?: string) => Promise<DynamicTreeNode<CollectionView>>;
buildCollapsedFilterNodes: () => Promise<Set<string>>;
storeCollapsedFilterNodes: (collapsedFilterNodes: Set<string>) => Promise<void>;
checkForSingleOrganizationPolicy: () => Promise<boolean>;
checkForOrganizationDataOwnershipPolicy: () => Promise<boolean>;
abstract buildOrganizations(): Promise<Organization[]>;
abstract buildNestedFolders(organizationId?: string): Observable<DynamicTreeNode<FolderView>>;
abstract buildCollections(organizationId?: string): Promise<DynamicTreeNode<CollectionView>>;
abstract buildCollapsedFilterNodes(userId: UserId): Promise<Set<string>>;
abstract storeCollapsedFilterNodes(
collapsedFilterNodes: Set<string>,
userId: UserId,
): Promise<void>;
abstract checkForSingleOrganizationPolicy(): Promise<boolean>;
abstract checkForOrganizationDataOwnershipPolicy(): Promise<boolean>;
}

View File

@@ -7,6 +7,9 @@ import { firstValueFrom, Observable } from "rxjs";
// eslint-disable-next-line no-restricted-imports
import { CollectionView } from "@bitwarden/admin-console/common";
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 { UserId } from "@bitwarden/common/types/guid";
import { ITreeNodeObject } from "@bitwarden/common/vault/models/domain/tree-node";
import { FolderView } from "@bitwarden/common/vault/models/view/folder.view";
@@ -29,6 +32,8 @@ export class VaultFilterComponent implements OnInit {
@Output() onAddFolder = new EventEmitter<never>();
@Output() onEditFolder = new EventEmitter<FolderView>();
private activeUserId: UserId;
isLoaded = false;
collapsedFilterNodes: Set<string>;
organizations: Organization[];
@@ -37,14 +42,20 @@ export class VaultFilterComponent implements OnInit {
collections: DynamicTreeNode<CollectionView>;
folders$: Observable<DynamicTreeNode<FolderView>>;
constructor(protected vaultFilterService: DeprecatedVaultFilterService) {}
constructor(
protected vaultFilterService: DeprecatedVaultFilterService,
protected accountService: AccountService,
) {}
get displayCollections() {
return this.collections?.fullList != null && this.collections.fullList.length > 0;
}
async ngOnInit(): Promise<void> {
this.collapsedFilterNodes = await this.vaultFilterService.buildCollapsedFilterNodes();
this.activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId));
this.collapsedFilterNodes = await this.vaultFilterService.buildCollapsedFilterNodes(
this.activeUserId,
);
this.organizations = await this.vaultFilterService.buildOrganizations();
if (this.organizations != null && this.organizations.length > 0) {
this.activeOrganizationDataOwnershipPolicy =
@@ -68,7 +79,10 @@ export class VaultFilterComponent implements OnInit {
} else {
this.collapsedFilterNodes.add(node.id);
}
await this.vaultFilterService.storeCollapsedFilterNodes(this.collapsedFilterNodes);
await this.vaultFilterService.storeCollapsedFilterNodes(
this.collapsedFilterNodes,
this.activeUserId,
);
}
async applyFilter(filter: VaultFilter) {

View File

@@ -12,7 +12,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 { ActiveUserState, StateProvider } from "@bitwarden/common/platform/state";
import { SingleUserState, StateProvider } from "@bitwarden/common/platform/state";
import { UserId } from "@bitwarden/common/types/guid";
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
@@ -28,10 +28,9 @@ const NestingDelimiter = "/";
@Injectable()
export class VaultFilterService implements DeprecatedVaultFilterServiceAbstraction {
private collapsedGroupingsState: ActiveUserState<string[]> =
this.stateProvider.getActive(COLLAPSED_GROUPINGS);
private readonly collapsedGroupings$: Observable<Set<string>> =
this.collapsedGroupingsState.state$.pipe(map((c) => new Set(c)));
private collapsedGroupingsState(userId: UserId): SingleUserState<string[]> {
return this.stateProvider.getUser(userId, COLLAPSED_GROUPINGS);
}
constructor(
protected organizationService: OrganizationService,
@@ -43,12 +42,17 @@ export class VaultFilterService implements DeprecatedVaultFilterServiceAbstracti
protected accountService: AccountService,
) {}
async storeCollapsedFilterNodes(collapsedFilterNodes: Set<string>): Promise<void> {
await this.collapsedGroupingsState.update(() => Array.from(collapsedFilterNodes));
async storeCollapsedFilterNodes(
collapsedFilterNodes: Set<string>,
userId: UserId,
): Promise<void> {
await this.collapsedGroupingsState(userId).update(() => Array.from(collapsedFilterNodes));
}
async buildCollapsedFilterNodes(): Promise<Set<string>> {
return await firstValueFrom(this.collapsedGroupings$);
async buildCollapsedFilterNodes(userId: UserId): Promise<Set<string>> {
return await firstValueFrom(
this.collapsedGroupingsState(userId).state$.pipe(map((c) => new Set(c))),
);
}
async buildOrganizations(): Promise<Organization[]> {