mirror of
https://github.com/bitwarden/browser
synced 2026-01-06 10:33:57 +00:00
[PM-12048] Wire up vNextCollectionService (#14871)
* remove derived state, add cache in service. Fix ts strict errors
* cleanup
* promote vNextCollectionService
* wip
* replace callers in web WIP
* refactor tests for web
* update callers to use vNextCollectionServcie methods in CLI
* WIP make decryptMany public again, fix callers, imports
* wip cli
* wip desktop
* update callers in browser, fix tests
* remove in service cache
* cleanup
* fix test
* clean up
* address cr feedback
* remove duplicate userId
* clean up
* remove unused import
* fix vault-settings-import-nudge.service
* fix caching issue
* clean up
* refactor decryption, cleanup, update callers
* clean up
* Use in-memory statedefinition
* Ac/pm 12048 v next collection service pairing (#15239)
* Draft from pairing with Gibson
* Add todos
* Add comment
* wip
* refactor upsert
---------
Co-authored-by: Brandon <btreston@bitwarden.com>
* clean up
* fix state definitions
* fix linter error
* cleanup
* add test, fix shareReplay
* fix item-more-options component
* fix desktop build
* refactor state to account for null as an initial value, remove caching
* add proper cache, add unit test, update callers
* clean up
* fix routing when deleting collections
* cleanup
* use combineLatest
* fix ts-strict errors, fix error handling
* refactor Collection and CollectionView properties for ts-strict
* Revert "refactor Collection and CollectionView properties for ts-strict"
This reverts commit a5c63aab76.
---------
Co-authored-by: Thomas Rittson <trittson@bitwarden.com>
Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com>
This commit is contained in:
@@ -9,7 +9,7 @@ import { Organization } from "@bitwarden/common/admin-console/models/domain/orga
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { CollectionId } from "@bitwarden/common/types/guid";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
import { CipherBulkDeleteRequest } from "@bitwarden/common/vault/models/request/cipher-bulk-delete.request";
|
||||
import { UnionOfValues } from "@bitwarden/common/vault/types/union-of-values";
|
||||
@@ -68,7 +68,6 @@ export class BulkDeleteDialogComponent {
|
||||
@Inject(DIALOG_DATA) params: BulkDeleteDialogParams,
|
||||
private dialogRef: DialogRef<BulkDeleteDialogResult>,
|
||||
private cipherService: CipherService,
|
||||
private platformUtilsService: PlatformUtilsService,
|
||||
private i18nService: I18nService,
|
||||
private apiService: ApiService,
|
||||
private collectionService: CollectionService,
|
||||
@@ -116,7 +115,11 @@ export class BulkDeleteDialogComponent {
|
||||
});
|
||||
}
|
||||
if (this.collections.length) {
|
||||
await this.collectionService.delete(this.collections.map((c) => c.id));
|
||||
const userId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId));
|
||||
await this.collectionService.delete(
|
||||
this.collections.map((c) => c.id as CollectionId),
|
||||
userId,
|
||||
);
|
||||
this.toastService.showToast({
|
||||
variant: "success",
|
||||
title: null,
|
||||
|
||||
@@ -78,7 +78,7 @@ describe("vault filter service", () => {
|
||||
configService.getFeatureFlag$.mockReturnValue(of(true));
|
||||
organizationService.memberOrganizations$.mockReturnValue(organizations);
|
||||
folderService.folderViews$.mockReturnValue(folderViews);
|
||||
collectionService.decryptedCollections$ = collectionViews;
|
||||
collectionService.decryptedCollections$.mockReturnValue(collectionViews);
|
||||
policyService.policyAppliesToUser$
|
||||
.calledWith(PolicyType.OrganizationDataOwnership, mockUserId)
|
||||
.mockReturnValue(organizationDataOwnershipPolicy);
|
||||
|
||||
@@ -4,7 +4,6 @@ import { Injectable } from "@angular/core";
|
||||
import {
|
||||
BehaviorSubject,
|
||||
combineLatest,
|
||||
combineLatestWith,
|
||||
filter,
|
||||
firstValueFrom,
|
||||
map,
|
||||
@@ -100,13 +99,13 @@ export class VaultFilterService implements VaultFilterServiceAbstraction {
|
||||
map((folders) => this.buildFolderTree(folders)),
|
||||
);
|
||||
|
||||
filteredCollections$: Observable<CollectionView[]> =
|
||||
this.collectionService.decryptedCollections$.pipe(
|
||||
combineLatestWith(this._organizationFilter),
|
||||
switchMap(([collections, org]) => {
|
||||
return this.filterCollections(collections, org);
|
||||
}),
|
||||
);
|
||||
filteredCollections$: Observable<CollectionView[]> = combineLatest([
|
||||
this.accountService.activeAccount$.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) => this.collectionService.decryptedCollections$(userId)),
|
||||
),
|
||||
this._organizationFilter,
|
||||
]).pipe(switchMap(([collections, org]) => this.filterCollections(collections, org)));
|
||||
|
||||
collectionTree$: Observable<TreeNode<CollectionFilter>> = combineLatest([
|
||||
this.filteredCollections$,
|
||||
|
||||
@@ -334,7 +334,8 @@ export class VaultComponent<C extends CipherViewLike> implements OnInit, OnDestr
|
||||
});
|
||||
|
||||
const filter$ = this.routedVaultFilterService.filter$;
|
||||
const allCollections$ = this.collectionService.decryptedCollections$;
|
||||
|
||||
const allCollections$ = this.collectionService.decryptedCollections$(activeUserId);
|
||||
const nestedCollections$ = allCollections$.pipe(
|
||||
map((collections) => getNestedCollectionTree(collections)),
|
||||
);
|
||||
@@ -861,7 +862,10 @@ export class VaultComponent<C extends CipherViewLike> implements OnInit, OnDestr
|
||||
if (result.collection) {
|
||||
// Update CollectionService with the new collection
|
||||
const c = new CollectionData(result.collection as CollectionDetailsResponse);
|
||||
await this.collectionService.upsert(c);
|
||||
const activeUserId = await firstValueFrom(
|
||||
this.accountService.activeAccount$.pipe(getUserId),
|
||||
);
|
||||
await this.collectionService.upsert(c, activeUserId);
|
||||
}
|
||||
this.refresh();
|
||||
}
|
||||
@@ -878,20 +882,23 @@ export class VaultComponent<C extends CipherViewLike> implements OnInit, OnDestr
|
||||
});
|
||||
|
||||
const result = await lastValueFrom(dialog.closed);
|
||||
const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId));
|
||||
if (result.action === CollectionDialogAction.Saved) {
|
||||
if (result.collection) {
|
||||
// Update CollectionService with the new collection
|
||||
const c = new CollectionData(result.collection as CollectionDetailsResponse);
|
||||
await this.collectionService.upsert(c);
|
||||
await this.collectionService.upsert(c, activeUserId);
|
||||
}
|
||||
this.refresh();
|
||||
} else if (result.action === CollectionDialogAction.Deleted) {
|
||||
await this.collectionService.delete(result.collection?.id);
|
||||
this.refresh();
|
||||
const parent = this.selectedCollection?.parent;
|
||||
// Navigate away if we deleted the collection we were viewing
|
||||
if (this.selectedCollection?.node.id === c?.id) {
|
||||
const navigateAway = this.selectedCollection && this.selectedCollection.node.id === c.id;
|
||||
await this.collectionService.delete([result.collection?.id as CollectionId], activeUserId);
|
||||
this.refresh();
|
||||
if (navigateAway) {
|
||||
await this.router.navigate([], {
|
||||
queryParams: { collectionId: this.selectedCollection.parent?.node.id ?? null },
|
||||
queryParams: { collectionId: parent?.node.id ?? null },
|
||||
queryParamsHandling: "merge",
|
||||
replaceUrl: true,
|
||||
});
|
||||
@@ -916,18 +923,22 @@ export class VaultComponent<C extends CipherViewLike> implements OnInit, OnDestr
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const parent = this.selectedCollection?.parent;
|
||||
// Navigate away if we deleted the collection we were viewing
|
||||
const navigateAway =
|
||||
this.selectedCollection && this.selectedCollection.node.id === collection.id;
|
||||
await this.apiService.deleteCollection(collection.organizationId, collection.id);
|
||||
await this.collectionService.delete(collection.id);
|
||||
const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId));
|
||||
await this.collectionService.delete([collection.id as CollectionId], activeUserId);
|
||||
|
||||
this.toastService.showToast({
|
||||
variant: "success",
|
||||
title: null,
|
||||
message: this.i18nService.t("deletedCollectionId", collection.name),
|
||||
});
|
||||
// Navigate away if we deleted the collection we were viewing
|
||||
if (this.selectedCollection?.node.id === collection.id) {
|
||||
if (navigateAway) {
|
||||
await this.router.navigate([], {
|
||||
queryParams: { collectionId: this.selectedCollection.parent?.node.id ?? null },
|
||||
queryParams: { collectionId: parent?.node.id ?? null },
|
||||
queryParamsHandling: "merge",
|
||||
replaceUrl: true,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user