1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-14 15:23:33 +00:00

[PM-8553] browser v2 search bar defects (#9506)

* update no results icon and no results scrolling
* update v2 search so the term persist when the user clicks into an item and exits the item
This commit is contained in:
Jason Ng
2024-06-05 10:06:52 -04:00
committed by GitHub
parent 7e86c0afd4
commit cb0927ac5d
6 changed files with 56 additions and 25 deletions

View File

@@ -1,12 +1,14 @@
import { CommonModule } from "@angular/common";
import { Component, Output, EventEmitter } from "@angular/core";
import { Component } from "@angular/core";
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
import { FormsModule } from "@angular/forms";
import { Subject, debounceTime } from "rxjs";
import { Subject, Subscription, debounceTime, filter } from "rxjs";
import { JslibModule } from "@bitwarden/angular/jslib.module";
import { SearchModule } from "@bitwarden/components";
import { VaultPopupItemsService } from "../../../services/vault-popup-items.service";
const SearchTextDebounceInterval = 200;
@Component({
@@ -17,19 +19,34 @@ const SearchTextDebounceInterval = 200;
})
export class VaultV2SearchComponent {
searchText: string;
@Output() searchTextChanged = new EventEmitter<string>();
private searchText$ = new Subject<string>();
constructor() {
this.searchText$
.pipe(debounceTime(SearchTextDebounceInterval), takeUntilDestroyed())
.subscribe((data) => {
this.searchTextChanged.emit(data);
});
constructor(private vaultPopupItemsService: VaultPopupItemsService) {
this.subscribeToLatestSearchText();
this.subscribeToApplyFilter();
}
onSearchTextChanged() {
this.searchText$.next(this.searchText);
}
subscribeToLatestSearchText(): Subscription {
return this.vaultPopupItemsService.latestSearchText$
.pipe(
takeUntilDestroyed(),
filter((data) => !!data),
)
.subscribe((text) => {
this.searchText = text;
});
}
subscribeToApplyFilter(): Subscription {
return this.searchText$
.pipe(debounceTime(SearchTextDebounceInterval), takeUntilDestroyed())
.subscribe((data) => {
this.vaultPopupItemsService.applyFilter(data);
});
}
}

View File

@@ -22,18 +22,15 @@
</div>
<ng-container *ngIf="!(showEmptyState$ | async)">
<div class="tw-fixed">
<app-vault-v2-search (searchTextChanged)="handleSearchTextChange($event)">
</app-vault-v2-search>
<app-vault-v2-search> </app-vault-v2-search>
<app-vault-list-filters></app-vault-list-filters>
</div>
<app-vault-list-filters></app-vault-list-filters>
<div
*ngIf="(showNoResultsState$ | async) && !(showDeactivatedOrg$ | async)"
class="tw-flex tw-flex-col tw-h-full tw-justify-center"
class="tw-flex tw-flex-col tw-justify-center tw-h-auto tw-pt-12"
>
<bit-no-items>
<bit-no-items [icon]="noResultsIcon">
<ng-container slot="title">{{ "noItemsMatchSearch" | i18n }}</ng-container>
<ng-container slot="description">{{ "clearFiltersOrTryAnother" | i18n }}</ng-container>
</bit-no-items>
@@ -41,7 +38,7 @@
<div
*ngIf="showDeactivatedOrg$ | async"
class="tw-flex tw-flex-col tw-h-full tw-justify-center"
class="tw-flex tw-flex-col tw-justify-center tw-h-auto tw-pt-12"
>
<bit-no-items [icon]="deactivatedIcon">
<ng-container slot="title">{{ "organizationIsDeactivated" | i18n }}</ng-container>

View File

@@ -44,6 +44,7 @@ export class VaultV2Component implements OnInit, OnDestroy {
protected vaultIcon = Icons.Vault;
protected deactivatedIcon = Icons.DeactivatedOrg;
protected noResultsIcon = Icons.NoResults;
constructor(
private vaultPopupItemsService: VaultPopupItemsService,
@@ -54,10 +55,6 @@ export class VaultV2Component implements OnInit, OnDestroy {
ngOnDestroy(): void {}
handleSearchTextChange(searchText: string) {
this.vaultPopupItemsService.applyFilter(searchText);
}
addCipher() {
// TODO: Add currently filtered organization to query params if available
void this.router.navigate(["/add-cipher"], {});

View File

@@ -38,7 +38,8 @@ import { MY_VAULT_ID, VaultPopupListFiltersService } from "./vault-popup-list-fi
})
export class VaultPopupItemsService {
private _refreshCurrentTab$ = new Subject<void>();
private searchText$ = new BehaviorSubject<string>("");
private _searchText$ = new BehaviorSubject<string>("");
latestSearchText$: Observable<string> = this._searchText$.asObservable();
/**
* Observable that contains the list of other cipher types that should be shown
@@ -105,7 +106,7 @@ export class VaultPopupItemsService {
private _filteredCipherList$: Observable<PopupCipherView[]> = combineLatest([
this._cipherList$,
this.searchText$,
this._searchText$,
this.vaultPopupListFiltersService.filterFunction$,
]).pipe(
map(([ciphers, searchText, filterFunction]): [CipherView[], string] => [
@@ -179,7 +180,7 @@ export class VaultPopupItemsService {
* Observable that indicates whether a filter is currently applied to the ciphers.
*/
hasFilterApplied$ = combineLatest([
this.searchText$,
this._searchText$,
this.vaultPopupListFiltersService.filters$,
]).pipe(
switchMap(([searchText, filters]) => {
@@ -242,7 +243,7 @@ export class VaultPopupItemsService {
}
applyFilter(newSearchText: string) {
this.searchText$.next(newSearchText);
this._searchText$.next(newSearchText);
}
/**