1
0
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:
Oscar Hinton
2022-07-12 20:25:18 +02:00
committed by GitHub
parent a43aa9612c
commit 23253b3882
32 changed files with 421 additions and 180 deletions

View File

@@ -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(

View File

@@ -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);

View File

@@ -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"),

View File

@@ -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>

View File

@@ -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) {

View File

@@ -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>

View File

@@ -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 =

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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));

View File

@@ -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);

View File

@@ -32,7 +32,7 @@
[hide]="hideFolders"
[activeFilter]="activeFilter"
[collapsedFilterNodes]="collapsedFilterNodes"
[folderNodes]="folders"
[folderNodes]="folders$ | async"
(onNodeCollapseStateChange)="toggleFilterNodeCollapseState($event)"
(onFilterChange)="applyFilter($event)"
(onAddFolder)="addFolder()"

View File

@@ -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>

View File

@@ -57,7 +57,7 @@
[hide]="hideFolders"
[activeFilter]="activeFilter"
[collapsedFilterNodes]="collapsedFilterNodes"
[folderNodes]="folders"
[folderNodes]="folders$ | async"
(onNodeCollapseStateChange)="toggleFilterNodeCollapseState($event)"
(onFilterChange)="applyFilter($event)"
(onAddFolder)="addFolder()"

View File

@@ -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;

View File

@@ -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;

View File

@@ -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>

View File

@@ -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>

View File

@@ -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() {