mirror of
https://github.com/bitwarden/browser
synced 2026-02-07 20:24:01 +00:00
[PM-30677] Convert SendSearchComponent to OnPush (#18322)
Converts SendSearchComponent to use OnPush change detection.
This commit is contained in:
@@ -1,14 +1,6 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import {
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
computed,
|
||||
effect,
|
||||
inject,
|
||||
signal,
|
||||
viewChild,
|
||||
} from "@angular/core";
|
||||
import { Component, computed, inject, signal, viewChild } from "@angular/core";
|
||||
import { toSignal } from "@angular/core/rxjs-interop";
|
||||
import { combineLatest, map, switchMap, lastValueFrom } from "rxjs";
|
||||
|
||||
@@ -92,7 +84,6 @@ export class SendV2Component {
|
||||
private dialogService = inject(DialogService);
|
||||
private toastService = inject(ToastService);
|
||||
private logService = inject(LogService);
|
||||
private cdr = inject(ChangeDetectorRef);
|
||||
|
||||
protected readonly useDrawerEditMode = toSignal(
|
||||
this.configService.getFeatureFlag$(FeatureFlag.DesktopUiMigrationMilestone2),
|
||||
@@ -137,17 +128,6 @@ export class SendV2Component {
|
||||
{ initialValue: null },
|
||||
);
|
||||
|
||||
constructor() {
|
||||
// WORKAROUND: Force change detection when data updates
|
||||
// This is needed because SendSearchComponent (shared lib) hasn't migrated to OnPush yet
|
||||
// and doesn't trigger CD properly when search/add operations complete
|
||||
// TODO: Remove this once SendSearchComponent migrates to OnPush (tracked in CL-764)
|
||||
effect(() => {
|
||||
this.filteredSends();
|
||||
this.cdr.markForCheck();
|
||||
});
|
||||
}
|
||||
|
||||
protected readonly selectedSendType = computed(() => {
|
||||
const action = this.action();
|
||||
|
||||
@@ -171,8 +151,6 @@ export class SendV2Component {
|
||||
} else {
|
||||
this.action.set(Action.Add);
|
||||
this.sendId.set(null);
|
||||
|
||||
this.cdr.detectChanges();
|
||||
void this.addEditComponent()?.resetAndLoad();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1 @@
|
||||
<bit-search
|
||||
[placeholder]="'search' | i18n"
|
||||
[(ngModel)]="searchText"
|
||||
(ngModelChange)="onSearchTextChanged()"
|
||||
appAutofocus
|
||||
>
|
||||
</bit-search>
|
||||
<bit-search [placeholder]="'search' | i18n" [(ngModel)]="searchText" appAutofocus />
|
||||
|
||||
@@ -1,50 +1,55 @@
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { Component } from "@angular/core";
|
||||
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
||||
import { ChangeDetectionStrategy, Component, inject, model } from "@angular/core";
|
||||
import { takeUntilDestroyed, toObservable } from "@angular/core/rxjs-interop";
|
||||
import { FormsModule } from "@angular/forms";
|
||||
import { Subject, Subscription, debounceTime, filter } from "rxjs";
|
||||
import { debounceTime, filter } from "rxjs";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import { SearchModule } from "@bitwarden/components";
|
||||
import { I18nPipe } from "@bitwarden/ui-common";
|
||||
|
||||
import { SendItemsService } from "../services/send-items.service";
|
||||
|
||||
const SearchTextDebounceInterval = 200;
|
||||
|
||||
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
|
||||
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
|
||||
/**
|
||||
* Search component for filtering Send items.
|
||||
*
|
||||
* Provides a search input that filters the Send list with debounced updates.
|
||||
* Syncs with the service's latest search text to maintain state across navigation.
|
||||
*/
|
||||
@Component({
|
||||
imports: [CommonModule, SearchModule, JslibModule, FormsModule],
|
||||
selector: "tools-send-search",
|
||||
templateUrl: "send-search.component.html",
|
||||
imports: [FormsModule, I18nPipe, SearchModule],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class SendSearchComponent {
|
||||
searchText: string = "";
|
||||
private sendListItemService = inject(SendItemsService);
|
||||
|
||||
private searchText$ = new Subject<string>();
|
||||
/** The current search text entered by the user. */
|
||||
protected readonly searchText = model("");
|
||||
|
||||
constructor(private sendListItemService: SendItemsService) {
|
||||
constructor() {
|
||||
this.subscribeToLatestSearchText();
|
||||
this.subscribeToApplyFilter();
|
||||
}
|
||||
|
||||
onSearchTextChanged() {
|
||||
this.searchText$.next(this.searchText);
|
||||
}
|
||||
|
||||
subscribeToLatestSearchText(): Subscription {
|
||||
return this.sendListItemService.latestSearchText$
|
||||
private subscribeToLatestSearchText(): void {
|
||||
this.sendListItemService.latestSearchText$
|
||||
.pipe(
|
||||
takeUntilDestroyed(),
|
||||
filter((data) => !!data),
|
||||
)
|
||||
.subscribe((text) => {
|
||||
this.searchText = text;
|
||||
this.searchText.set(text);
|
||||
});
|
||||
}
|
||||
|
||||
subscribeToApplyFilter(): Subscription {
|
||||
return this.searchText$
|
||||
/**
|
||||
* Applies the search filter to the Send list with a debounce delay.
|
||||
* This prevents excessive filtering while the user is still typing.
|
||||
*/
|
||||
private subscribeToApplyFilter(): void {
|
||||
toObservable(this.searchText)
|
||||
.pipe(debounceTime(SearchTextDebounceInterval), takeUntilDestroyed())
|
||||
.subscribe((data) => {
|
||||
this.sendListItemService.applyFilter(data);
|
||||
|
||||
Reference in New Issue
Block a user