mirror of
https://github.com/bitwarden/browser
synced 2026-02-04 10:43:47 +00:00
created VaultStateService
This commit is contained in:
108
apps/desktop/src/services/vault-state.service.ts
Normal file
108
apps/desktop/src/services/vault-state.service.ts
Normal file
@@ -0,0 +1,108 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
import { Subject } from "rxjs";
|
||||
|
||||
import { VaultFilter } from "@bitwarden/angular/vault/vault-filter/models/vault-filter.model";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
|
||||
import { SearchBarService } from "../app/layout/search/search-bar.service";
|
||||
|
||||
/**
|
||||
* Service to coordinate vault state, including filter state and folder actions,
|
||||
* between the navigation component and the vault component.
|
||||
*/
|
||||
@Injectable({ providedIn: "root" })
|
||||
export class VaultStateService {
|
||||
private filterChangeSubject = new Subject<VaultFilter>();
|
||||
private addFolderSubject = new Subject<void>();
|
||||
private editFolderSubject = new Subject<string>();
|
||||
|
||||
/**
|
||||
* The currently active vault filter.
|
||||
*/
|
||||
activeFilter: VaultFilter = new VaultFilter();
|
||||
|
||||
/**
|
||||
* Observable stream of vault filter changes.
|
||||
* Subscribe to this to react to filter changes from the navigation.
|
||||
*/
|
||||
readonly filterChange$ = this.filterChangeSubject.asObservable();
|
||||
|
||||
/**
|
||||
* Observable stream of add folder requests.
|
||||
* Subscribe to this to handle folder creation.
|
||||
*/
|
||||
readonly addFolder$ = this.addFolderSubject.asObservable();
|
||||
|
||||
/**
|
||||
* Observable stream of edit folder requests.
|
||||
* Subscribe to this to handle folder editing.
|
||||
* Emits the folder ID to edit.
|
||||
*/
|
||||
readonly editFolder$ = this.editFolderSubject.asObservable();
|
||||
|
||||
constructor(
|
||||
private i18nService: I18nService,
|
||||
private searchBarService: SearchBarService,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Apply a new vault filter.
|
||||
* This updates the search bar placeholder and notifies all subscribers.
|
||||
*/
|
||||
applyFilter(filter: VaultFilter): void {
|
||||
// Store the active filter
|
||||
this.activeFilter = filter;
|
||||
|
||||
// Update search bar placeholder text based on the filter
|
||||
this.searchBarService.setPlaceholderText(
|
||||
this.i18nService.t(this.calculateSearchBarLocalizationString(filter)),
|
||||
);
|
||||
|
||||
// Emit the filter change to subscribers
|
||||
this.filterChangeSubject.next(filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Request to add a new folder.
|
||||
* This will notify subscribers to show the folder creation dialog.
|
||||
*/
|
||||
requestAddFolder(): void {
|
||||
this.addFolderSubject.next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Request to edit an existing folder.
|
||||
* This will notify subscribers to show the folder edit dialog.
|
||||
*/
|
||||
requestEditFolder(folderId: string): void {
|
||||
this.editFolderSubject.next(folderId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the appropriate search bar localization string based on the active filter.
|
||||
*/
|
||||
private calculateSearchBarLocalizationString(vaultFilter: VaultFilter): string {
|
||||
if (vaultFilter.status === "favorites") {
|
||||
return "searchFavorites";
|
||||
}
|
||||
if (vaultFilter.status === "trash") {
|
||||
return "searchTrash";
|
||||
}
|
||||
if (vaultFilter.cipherType != null) {
|
||||
return "searchType";
|
||||
}
|
||||
if (vaultFilter.selectedFolderId != null && vaultFilter.selectedFolderId !== "none") {
|
||||
return "searchFolder";
|
||||
}
|
||||
if (vaultFilter.selectedCollectionId != null) {
|
||||
return "searchCollection";
|
||||
}
|
||||
if (vaultFilter.selectedOrganizationId != null) {
|
||||
return "searchOrganization";
|
||||
}
|
||||
if (vaultFilter.myVaultOnly) {
|
||||
return "searchMyVault";
|
||||
}
|
||||
return "searchVault";
|
||||
}
|
||||
}
|
||||
@@ -1 +1,9 @@
|
||||
<bit-nav-group icon="bwi-vault" [text]="'vault' | i18n" route="new-vault"></bit-nav-group>
|
||||
<bit-nav-group icon="bwi-vault" [text]="'vault' | i18n" route="new-vault">
|
||||
<app-vault-filter
|
||||
class="vault-filters"
|
||||
[activeFilter]="vaultStateService.activeFilter"
|
||||
(onFilterChange)="vaultStateService.applyFilter($event)"
|
||||
(onAddFolder)="vaultStateService.requestAddFolder()"
|
||||
(onEditFolder)="vaultStateService.requestEditFolder($event.id)"
|
||||
></app-vault-filter>
|
||||
</bit-nav-group>
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
import { ChangeDetectionStrategy, Component } from "@angular/core";
|
||||
|
||||
import { NavigationModule } from "@bitwarden/components";
|
||||
import { I18nPipe } from "@bitwarden/ui-common";
|
||||
import { VaultStateService } from "../../../../services/vault-state.service";
|
||||
import { VaultFilterModule } from "../vault-filter/vault-filter.module";
|
||||
|
||||
@Component({
|
||||
selector: "app-vault-nav",
|
||||
imports: [I18nPipe, NavigationModule],
|
||||
imports: [I18nPipe, NavigationModule, VaultFilterModule],
|
||||
templateUrl: "./vault-nav.component.html",
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class VaultNavComponent {}
|
||||
export class VaultNavComponent {
|
||||
constructor(protected vaultStateService: VaultStateService) {}
|
||||
}
|
||||
|
||||
@@ -83,6 +83,7 @@ import {
|
||||
import { SearchBarService } from "../../../app/layout/search/search-bar.service";
|
||||
import { DesktopCredentialGenerationService } from "../../../services/desktop-cipher-form-generator.service";
|
||||
import { DesktopPremiumUpgradePromptService } from "../../../services/desktop-premium-upgrade-prompt.service";
|
||||
import { VaultStateService } from "../../../services/vault-state.service";
|
||||
import { invokeMenu, RendererMenuItem } from "../../../utils";
|
||||
import { AssignCollectionsDesktopComponent } from "../vault/assign-collections";
|
||||
import { ItemFooterComponent } from "../vault/item-footer.component";
|
||||
@@ -225,6 +226,7 @@ export class VaultComponent<C extends CipherViewLike>
|
||||
private cipherArchiveService: CipherArchiveService,
|
||||
private policyService: PolicyService,
|
||||
private archiveCipherUtilitiesService: ArchiveCipherUtilitiesService,
|
||||
private vaultStateService: VaultStateService,
|
||||
) {}
|
||||
|
||||
async ngOnInit() {
|
||||
@@ -240,6 +242,30 @@ export class VaultComponent<C extends CipherViewLike>
|
||||
this.userHasPremiumAccess = canAccessPremium;
|
||||
});
|
||||
|
||||
// Subscribe to filter changes from VaultNavComponent
|
||||
this.vaultStateService.filterChange$
|
||||
.pipe(
|
||||
switchMap((vaultFilter: VaultFilter) => this.applyVaultFilter(vaultFilter)),
|
||||
takeUntil(this.componentIsDestroyed$),
|
||||
)
|
||||
.subscribe();
|
||||
|
||||
// Subscribe to add folder requests from VaultNavComponent
|
||||
this.vaultStateService.addFolder$
|
||||
.pipe(
|
||||
switchMap(() => this.addFolder()),
|
||||
takeUntil(this.componentIsDestroyed$),
|
||||
)
|
||||
.subscribe();
|
||||
|
||||
// Subscribe to edit folder requests from VaultNavComponent
|
||||
this.vaultStateService.editFolder$
|
||||
.pipe(
|
||||
switchMap((folderId: string) => this.editFolder(folderId)),
|
||||
takeUntil(this.componentIsDestroyed$),
|
||||
)
|
||||
.subscribe();
|
||||
|
||||
this.broadcasterService.subscribe(BroadcasterSubscriptionId, (message: any) => {
|
||||
this.ngZone
|
||||
.run(async () => {
|
||||
|
||||
Reference in New Issue
Block a user