mirror of
https://github.com/bitwarden/browser
synced 2025-12-11 13:53:34 +00:00
[PS-1078] Refactor FolderService to use Observables (#3022)
This commit is contained in:
@@ -44,6 +44,7 @@ import { ApiService } from "@bitwarden/common/services/api.service";
|
||||
import { AppIdService } from "@bitwarden/common/services/appId.service";
|
||||
import { AuditService } from "@bitwarden/common/services/audit.service";
|
||||
import { AuthService } from "@bitwarden/common/services/auth.service";
|
||||
import { BroadcasterService } from "@bitwarden/common/services/broadcaster.service";
|
||||
import { CipherService } from "@bitwarden/common/services/cipher.service";
|
||||
import { CollectionService } from "@bitwarden/common/services/collection.service";
|
||||
import { ConsoleLogService } from "@bitwarden/common/services/consoleLog.service";
|
||||
@@ -149,6 +150,7 @@ export default class MainBackground {
|
||||
vaultFilterService: VaultFilterService;
|
||||
usernameGenerationService: UsernameGenerationServiceAbstraction;
|
||||
encryptService: EncryptService;
|
||||
broadcasterService: BroadcasterService;
|
||||
folderApiService: FolderApiServiceAbstraction;
|
||||
|
||||
onUpdatedRan: boolean;
|
||||
@@ -267,11 +269,13 @@ export default class MainBackground {
|
||||
this.logService,
|
||||
this.stateService
|
||||
);
|
||||
this.broadcasterService = new BroadcasterService();
|
||||
this.folderService = new FolderService(
|
||||
this.cryptoService,
|
||||
this.i18nService,
|
||||
this.cipherService,
|
||||
this.stateService
|
||||
this.stateService,
|
||||
this.broadcasterService
|
||||
);
|
||||
this.folderApiService = new FolderApiService(this.folderService, this.apiService);
|
||||
this.collectionService = new CollectionService(
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { firstValueFrom } from "rxjs";
|
||||
|
||||
import { AuthService } from "@bitwarden/common/abstractions/auth.service";
|
||||
import { CipherService } from "@bitwarden/common/abstractions/cipher.service";
|
||||
import { FolderService } from "@bitwarden/common/abstractions/folder/folder.service.abstraction";
|
||||
@@ -385,7 +387,7 @@ export default class NotificationBackground {
|
||||
model.login = loginModel;
|
||||
|
||||
if (!Utils.isNullOrWhitespace(folderId)) {
|
||||
const folders = await this.folderService.getAllDecrypted();
|
||||
const folders = await firstValueFrom(this.folderService.folderViews$);
|
||||
if (folders.some((x) => x.id === folderId)) {
|
||||
model.folderId = folderId;
|
||||
}
|
||||
@@ -437,7 +439,7 @@ export default class NotificationBackground {
|
||||
private async getDataForTab(tab: chrome.tabs.Tab, responseCommand: string) {
|
||||
const responseData: any = {};
|
||||
if (responseCommand === "notificationBarGetFoldersList") {
|
||||
responseData.folders = await this.folderService.getAllDecrypted();
|
||||
responseData.folders = await firstValueFrom(this.folderService.folderViews$);
|
||||
}
|
||||
|
||||
await BrowserApi.tabSendMessageData(tab, responseCommand, responseData);
|
||||
|
||||
@@ -11,6 +11,7 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { AppIdService } from "@bitwarden/common/abstractions/appId.service";
|
||||
import { AuditService } from "@bitwarden/common/abstractions/audit.service";
|
||||
import { AuthService as AuthServiceAbstraction } from "@bitwarden/common/abstractions/auth.service";
|
||||
import { BroadcasterService as BroadcasterServiceAbstraction } from "@bitwarden/common/abstractions/broadcaster.service";
|
||||
import { CipherService } from "@bitwarden/common/abstractions/cipher.service";
|
||||
import { CollectionService } from "@bitwarden/common/abstractions/collection.service";
|
||||
import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
|
||||
@@ -111,6 +112,10 @@ function getBgService<T>(service: keyof MainBackground) {
|
||||
: new BrowserMessagingService();
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: BroadcasterServiceAbstraction,
|
||||
useFactory: getBgService<BroadcasterServiceAbstraction>("broadcasterService"),
|
||||
},
|
||||
{
|
||||
provide: TwoFactorService,
|
||||
useFactory: getBgService<TwoFactorService>("twoFactorService"),
|
||||
|
||||
@@ -20,20 +20,20 @@
|
||||
</div>
|
||||
</header>
|
||||
<main tabindex="-1">
|
||||
<div class="box list full-list" *ngIf="folders && folders.length">
|
||||
<div class="box list full-list" *ngIf="(folders$ | async)?.length">
|
||||
<div class="box-content">
|
||||
<button
|
||||
type="button"
|
||||
appStopClick
|
||||
(click)="folderSelected(f)"
|
||||
class="box-content-row padded"
|
||||
*ngFor="let f of folders"
|
||||
*ngFor="let f of folders$ | async"
|
||||
>
|
||||
{{ f.name }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="no-items" *ngIf="!folders || !folders.length">
|
||||
<div class="no-items" *ngIf="!(folders$ | async)?.length">
|
||||
<p>{{ "noFolders" | i18n }}</p>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { Component } from "@angular/core";
|
||||
import { Router } from "@angular/router";
|
||||
import { map, Observable } from "rxjs";
|
||||
|
||||
import { FolderService } from "@bitwarden/common/abstractions/folder/folder.service.abstraction";
|
||||
import { FolderView } from "@bitwarden/common/models/view/folderView";
|
||||
@@ -8,17 +9,19 @@ import { FolderView } from "@bitwarden/common/models/view/folderView";
|
||||
selector: "app-folders",
|
||||
templateUrl: "folders.component.html",
|
||||
})
|
||||
export class FoldersComponent implements OnInit {
|
||||
folders: FolderView[];
|
||||
export class FoldersComponent {
|
||||
folders$: Observable<FolderView[]>;
|
||||
|
||||
constructor(private folderService: FolderService, private router: Router) {}
|
||||
constructor(private folderService: FolderService, private router: Router) {
|
||||
this.folders$ = this.folderService.folderViews$.pipe(
|
||||
map((folders) => {
|
||||
if (folders.length > 0) {
|
||||
folders = folders.slice(0, folders.length - 1);
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
this.folders = await this.folderService.getAllDecrypted();
|
||||
// Remove "No Folder"
|
||||
if (this.folders.length > 0) {
|
||||
this.folders = this.folders.slice(0, this.folders.length - 1);
|
||||
}
|
||||
return folders;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
folderSelected(folder: FolderView) {
|
||||
|
||||
@@ -515,7 +515,7 @@
|
||||
<div class="box-content-row" appBoxRow>
|
||||
<label for="folder">{{ "folder" | i18n }}</label>
|
||||
<select id="folder" name="FolderId" [(ngModel)]="cipher.folderId">
|
||||
<option *ngFor="let f of folders" [ngValue]="f.id">{{ f.name }}</option>
|
||||
<option *ngFor="let f of folders$ | async" [ngValue]="f.id">{{ f.name }}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="box-content-row box-content-row-checkbox" appBoxRow>
|
||||
|
||||
@@ -120,7 +120,7 @@ export class CiphersComponent extends BaseCiphersComponent implements OnInit, On
|
||||
this.searchPlaceholder = this.i18nService.t("searchFolder");
|
||||
if (this.folderId != null) {
|
||||
this.showOrganizations = false;
|
||||
const folderNode = await this.folderService.getNested(this.folderId);
|
||||
const folderNode = await this.vaultFilterService.getFolderNested(this.folderId);
|
||||
if (folderNode != null && folderNode.node != null) {
|
||||
this.groupingTitle = folderNode.node.name;
|
||||
this.nestedFolders =
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Location } from "@angular/common";
|
||||
import { ChangeDetectorRef, Component, NgZone, OnDestroy, OnInit } from "@angular/core";
|
||||
import { ActivatedRoute, Router } from "@angular/router";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
import { first } from "rxjs/operators";
|
||||
|
||||
import { VaultFilter } from "@bitwarden/angular/modules/vault-filter/models/vault-filter.model";
|
||||
@@ -182,9 +183,11 @@ export class VaultFilterComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
async loadFolders() {
|
||||
const allFolders = await this.vaultFilterService.buildFolders(this.selectedOrganization);
|
||||
const allFolders = await firstValueFrom(
|
||||
this.vaultFilterService.buildNestedFolders(this.selectedOrganization)
|
||||
);
|
||||
this.folders = allFolders.fullList;
|
||||
this.nestedFolders = await allFolders.nestedList;
|
||||
this.nestedFolders = allFolders.nestedList;
|
||||
}
|
||||
|
||||
async search(timeout: number = null) {
|
||||
|
||||
@@ -14,6 +14,7 @@ import { GlobalState } from "@bitwarden/common/models/domain/globalState";
|
||||
import { AppIdService } from "@bitwarden/common/services/appId.service";
|
||||
import { AuditService } from "@bitwarden/common/services/audit.service";
|
||||
import { AuthService } from "@bitwarden/common/services/auth.service";
|
||||
import { BroadcasterService } from "@bitwarden/common/services/broadcaster.service";
|
||||
import { CipherService } from "@bitwarden/common/services/cipher.service";
|
||||
import { CollectionService } from "@bitwarden/common/services/collection.service";
|
||||
import { ContainerService } from "@bitwarden/common/services/container.service";
|
||||
@@ -103,6 +104,7 @@ export class Main {
|
||||
organizationService: OrganizationService;
|
||||
providerService: ProviderService;
|
||||
twoFactorService: TwoFactorService;
|
||||
broadcasterService: BroadcasterService;
|
||||
folderApiService: FolderApiService;
|
||||
|
||||
constructor() {
|
||||
@@ -198,11 +200,14 @@ export class Main {
|
||||
this.stateService
|
||||
);
|
||||
|
||||
this.broadcasterService = new BroadcasterService();
|
||||
|
||||
this.folderService = new FolderService(
|
||||
this.cryptoService,
|
||||
this.i18nService,
|
||||
this.cipherService,
|
||||
this.stateService
|
||||
this.stateService,
|
||||
this.broadcasterService
|
||||
);
|
||||
|
||||
this.folderApiService = new FolderApiService(this.folderService, this.apiService);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { firstValueFrom } from "rxjs";
|
||||
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { AuditService } from "@bitwarden/common/abstractions/audit.service";
|
||||
import { CipherService } from "@bitwarden/common/abstractions/cipher.service";
|
||||
@@ -358,7 +360,7 @@ export class GetCommand extends DownloadCommand {
|
||||
decFolder = await folder.decrypt();
|
||||
}
|
||||
} else if (id.trim() !== "") {
|
||||
let folders = await this.folderService.getAllDecrypted();
|
||||
let folders = await firstValueFrom(this.folderService.folderViews$);
|
||||
folders = CliUtils.searchFolders(folders, id);
|
||||
if (folders.length > 1) {
|
||||
return Response.multipleResults(folders.map((f) => f.id));
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { firstValueFrom } from "rxjs";
|
||||
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { CipherService } from "@bitwarden/common/abstractions/cipher.service";
|
||||
import { CollectionService } from "@bitwarden/common/abstractions/collection.service";
|
||||
@@ -126,7 +128,7 @@ export class ListCommand {
|
||||
}
|
||||
|
||||
private async listFolders(options: Options) {
|
||||
let folders = await this.folderService.getAllDecrypted();
|
||||
let folders = await firstValueFrom(this.folderService.folderViews$);
|
||||
|
||||
if (options.search != null && options.search.trim() !== "") {
|
||||
folders = CliUtils.searchFolders(folders, options.search);
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
[hide]="hideFolders"
|
||||
[activeFilter]="activeFilter"
|
||||
[collapsedFilterNodes]="collapsedFilterNodes"
|
||||
[folderNodes]="folders"
|
||||
[folderNodes]="folders$ | async"
|
||||
(onNodeCollapseStateChange)="toggleFilterNodeCollapseState($event)"
|
||||
(onFilterChange)="applyFilter($event)"
|
||||
(onAddFolder)="addFolder()"
|
||||
|
||||
@@ -455,7 +455,7 @@
|
||||
<div class="box-content-row" appBoxRow>
|
||||
<label for="folder">{{ "folder" | i18n }}</label>
|
||||
<select id="folder" name="FolderId" [(ngModel)]="cipher.folderId">
|
||||
<option *ngFor="let f of folders" [ngValue]="f.id">{{ f.name }}</option>
|
||||
<option *ngFor="let f of folders$ | async" [ngValue]="f.id">{{ f.name }}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="box-content-row box-content-row-checkbox" appBoxRow>
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
[hide]="hideFolders"
|
||||
[activeFilter]="activeFilter"
|
||||
[collapsedFilterNodes]="collapsedFilterNodes"
|
||||
[folderNodes]="folders"
|
||||
[folderNodes]="folders$ | async"
|
||||
(onNodeCollapseStateChange)="toggleFilterNodeCollapseState($event)"
|
||||
(onFilterChange)="applyFilter($event)"
|
||||
(onAddFolder)="addFolder()"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Component } from "@angular/core";
|
||||
import { Router } from "@angular/router";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
|
||||
import { ChangePasswordComponent as BaseChangePasswordComponent } from "@bitwarden/angular/components/change-password.component";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
@@ -192,7 +193,7 @@ export class ChangePasswordComponent extends BaseChangePasswordComponent {
|
||||
request.key = encKey[1].encryptedString;
|
||||
request.masterPasswordHash = masterPasswordHash;
|
||||
|
||||
const folders = await this.folderService.getAllDecrypted();
|
||||
const folders = await firstValueFrom(this.folderService.folderViews$);
|
||||
for (let i = 0; i < folders.length; i++) {
|
||||
if (folders[i].id == null) {
|
||||
continue;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Component } from "@angular/core";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { CipherService } from "@bitwarden/common/abstractions/cipher.service";
|
||||
@@ -81,7 +82,7 @@ export class UpdateKeyComponent {
|
||||
|
||||
await this.syncService.fullSync(true);
|
||||
|
||||
const folders = await this.folderService.getAllDecrypted();
|
||||
const folders = await firstValueFrom(this.folderService.folderViews$);
|
||||
for (let i = 0; i < folders.length; i++) {
|
||||
if (folders[i].id == null) {
|
||||
continue;
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
class="form-control"
|
||||
[disabled]="cipher.isDeleted || viewOnly"
|
||||
>
|
||||
<option *ngFor="let f of folders" [ngValue]="f.id">{{ f.name }}</option>
|
||||
<option *ngFor="let f of folders$ | async" [ngValue]="f.id">{{ f.name }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<div class="form-group">
|
||||
<label for="folder">{{ "folder" | i18n }}</label>
|
||||
<select id="folder" name="FolderId" [(ngModel)]="folderId" class="form-control">
|
||||
<option *ngFor="let f of folders" [ngValue]="f.id">{{ f.name }}</option>
|
||||
<option *ngFor="let f of folders$ | async" [ngValue]="f.id">{{ f.name }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from "@angular/core";
|
||||
import { firstValueFrom, Observable } from "rxjs";
|
||||
|
||||
import { CipherService } from "@bitwarden/common/abstractions/cipher.service";
|
||||
import { FolderService } from "@bitwarden/common/abstractions/folder/folder.service.abstraction";
|
||||
@@ -15,7 +16,7 @@ export class BulkMoveComponent implements OnInit {
|
||||
@Output() onMoved = new EventEmitter();
|
||||
|
||||
folderId: string = null;
|
||||
folders: FolderView[] = [];
|
||||
folders$: Observable<FolderView[]>;
|
||||
formPromise: Promise<any>;
|
||||
|
||||
constructor(
|
||||
@@ -26,8 +27,8 @@ export class BulkMoveComponent implements OnInit {
|
||||
) {}
|
||||
|
||||
async ngOnInit() {
|
||||
this.folders = await this.folderService.getAllDecrypted();
|
||||
this.folderId = this.folders[0].id;
|
||||
this.folders$ = this.folderService.folderViews$;
|
||||
this.folderId = (await firstValueFrom(this.folders$))[0].id;
|
||||
}
|
||||
|
||||
async submit() {
|
||||
|
||||
Reference in New Issue
Block a user