Debouncedly use a search term in console domain list (#2242)

This commit is contained in:
gbrodman 2023-12-08 15:37:30 -05:00 committed by GitHub
parent b3b0efd47e
commit e5e2370923
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 39 additions and 9 deletions

View file

@ -1,7 +1,13 @@
<div class="console-domains"> <div class="console-domains">
<mat-form-field> <mat-form-field>
<mat-label>Filter</mat-label> <mat-label>Filter</mat-label>
<input matInput (keyup)="applyFilter($event)" #input /> <input
type="search"
matInput
[(ngModel)]="searchTerm"
(ngModelChange)="sendInput()"
#input
/>
</mat-form-field> </mat-form-field>
<div *ngIf="isLoading; else domains_content" class="console-domains__loading"> <div *ngIf="isLoading; else domains_content" class="console-domains__loading">

View file

@ -18,6 +18,7 @@ import { BackendService } from '../shared/services/backend.service';
import { MatPaginator, PageEvent } from '@angular/material/paginator'; import { MatPaginator, PageEvent } from '@angular/material/paginator';
import { RegistrarService } from '../registrar/registrar.service'; import { RegistrarService } from '../registrar/registrar.service';
import { Domain, DomainListService } from './domainList.service'; import { Domain, DomainListService } from './domainList.service';
import { Subject, debounceTime } from 'rxjs';
@Component({ @Component({
selector: 'app-domain-list', selector: 'app-domain-list',
@ -27,6 +28,7 @@ import { Domain, DomainListService } from './domainList.service';
}) })
export class DomainListComponent { export class DomainListComponent {
public static PATH = 'domain-list'; public static PATH = 'domain-list';
private readonly DEBOUNCE_MS = 500;
displayedColumns: string[] = [ displayedColumns: string[] = [
'domainName', 'domainName',
@ -38,6 +40,9 @@ export class DomainListComponent {
dataSource: MatTableDataSource<Domain> = new MatTableDataSource(); dataSource: MatTableDataSource<Domain> = new MatTableDataSource();
isLoading = true; isLoading = true;
searchTermSubject = new Subject<string>();
searchTerm?: string;
pageNumber?: number; pageNumber?: number;
resultsPerPage = 50; resultsPerPage = 50;
totalResults?: number; totalResults?: number;
@ -52,13 +57,28 @@ export class DomainListComponent {
ngOnInit() { ngOnInit() {
this.dataSource.paginator = this.paginator; this.dataSource.paginator = this.paginator;
// Don't spam the server unnecessarily while the user is typing
this.searchTermSubject
.pipe(debounceTime(this.DEBOUNCE_MS))
.subscribe((searchTermValue) => {
this.reloadData();
});
this.reloadData(); this.reloadData();
} }
ngOnDestroy() {
this.searchTermSubject.complete();
}
reloadData() { reloadData() {
this.isLoading = true; this.isLoading = true;
this.domainListService this.domainListService
.retrieveDomains(this.pageNumber, this.resultsPerPage, this.totalResults) .retrieveDomains(
this.pageNumber,
this.resultsPerPage,
this.totalResults,
this.searchTerm
)
.subscribe((domainListResult) => { .subscribe((domainListResult) => {
this.dataSource.data = domainListResult.domains; this.dataSource.data = domainListResult.domains;
this.totalResults = domainListResult.totalResults; this.totalResults = domainListResult.totalResults;
@ -66,10 +86,8 @@ export class DomainListComponent {
}); });
} }
/** TODO: the backend will need to accept a filter string. */ sendInput() {
applyFilter(event: KeyboardEvent) { this.searchTermSubject.next(this.searchTerm!);
// const filterValue = (event.target as HTMLInputElement).value;
this.reloadData();
} }
onPageChange(event: PageEvent) { onPageChange(event: PageEvent) {

View file

@ -47,7 +47,8 @@ export class DomainListService {
retrieveDomains( retrieveDomains(
pageNumber?: number, pageNumber?: number,
resultsPerPage?: number, resultsPerPage?: number,
totalResults?: number totalResults?: number,
searchTerm?: string
) { ) {
return this.backendService return this.backendService
.getDomains( .getDomains(
@ -55,7 +56,8 @@ export class DomainListService {
this.checkpointTime, this.checkpointTime,
pageNumber, pageNumber,
resultsPerPage, resultsPerPage,
totalResults totalResults,
searchTerm
) )
.pipe( .pipe(
tap((domainListResult: DomainListResult) => { tap((domainListResult: DomainListResult) => {

View file

@ -69,7 +69,8 @@ export class BackendService {
checkpointTime?: string, checkpointTime?: string,
pageNumber?: number, pageNumber?: number,
resultsPerPage?: number, resultsPerPage?: number,
totalResults?: number totalResults?: number,
searchTerm?: string
): Observable<DomainListResult> { ): Observable<DomainListResult> {
var url = `/console-api/domain-list?registrarId=${registrarId}`; var url = `/console-api/domain-list?registrarId=${registrarId}`;
if (checkpointTime) { if (checkpointTime) {
@ -84,6 +85,9 @@ export class BackendService {
if (totalResults) { if (totalResults) {
url += `&totalResults=${totalResults}`; url += `&totalResults=${totalResults}`;
} }
if (searchTerm) {
url += `&searchTerm=${searchTerm}`;
}
return this.http return this.http
.get<DomainListResult>(url) .get<DomainListResult>(url)
.pipe(catchError((err) => this.errorCatcher<DomainListResult>(err))); .pipe(catchError((err) => this.errorCatcher<DomainListResult>(err)));