Refactored the clear input field handling for search to new observable
This commit is contained in:
parent
7263a561d9
commit
a9ca770307
4 changed files with 36 additions and 33 deletions
|
|
@ -1,6 +1,5 @@
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { Subject } from '@microsoft/signalr';
|
|
||||||
import { distinctUntilChanged, filter, map, Observable, of, ReplaySubject, startWith, switchMap } from 'rxjs';
|
import { distinctUntilChanged, filter, map, Observable, of, ReplaySubject, startWith, switchMap } from 'rxjs';
|
||||||
import { environment } from 'src/environments/environment';
|
import { environment } from 'src/environments/environment';
|
||||||
import { SearchResultGroup } from '../_models/search/search-result-group';
|
import { SearchResultGroup } from '../_models/search/search-result-group';
|
||||||
|
|
@ -13,27 +12,23 @@ export class SearchService {
|
||||||
|
|
||||||
baseUrl = environment.apiUrl;
|
baseUrl = environment.apiUrl;
|
||||||
|
|
||||||
private searchSubject: ReplaySubject<string> = new ReplaySubject();
|
private searchSubject: ReplaySubject<string> = new ReplaySubject(1);
|
||||||
searchResults$: Observable<SearchResultGroup>;
|
searchResults$: Observable<SearchResultGroup>;
|
||||||
|
|
||||||
constructor(private httpClient: HttpClient) {
|
constructor(private httpClient: HttpClient) {
|
||||||
this.searchResults$ = this.searchSubject.pipe(
|
this.searchResults$ = this.searchSubject.pipe(
|
||||||
startWith(''),
|
startWith(''),
|
||||||
map(val => val.trim()),
|
map(val => val.trim()),
|
||||||
filter(term => term !== '' && term !== null && term !== undefined),
|
|
||||||
distinctUntilChanged(),
|
distinctUntilChanged(),
|
||||||
switchMap(term => {
|
switchMap(term => {
|
||||||
return this.httpClient.get<SearchResultGroup>(this.baseUrl + 'search/search?queryString=' + encodeURIComponent(term));
|
if (term === '' || term === null || term === undefined) return of(new SearchResultGroup());
|
||||||
|
return this.httpClient.get<SearchResultGroup>(this.baseUrl + 'search/search?queryString=' + encodeURIComponent(term))
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
search(term: string) {
|
search(term: string) {
|
||||||
this.searchSubject.next(term);
|
this.searchSubject.next(term);
|
||||||
if (term === '') {
|
|
||||||
return of(new SearchResultGroup());
|
|
||||||
}
|
|
||||||
return this.httpClient.get<SearchResultGroup>(this.baseUrl + 'search/search?queryString=' + encodeURIComponent(term));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getSeriesForMangaFile(mangaFileId: number) {
|
getSeriesForMangaFile(mangaFileId: number) {
|
||||||
|
|
|
||||||
|
|
@ -129,11 +129,14 @@ export class EditSeriesRelationComponent implements OnInit, OnDestroy {
|
||||||
seriesSettings.id = 'relation--' + index;
|
seriesSettings.id = 'relation--' + index;
|
||||||
seriesSettings.unique = true;
|
seriesSettings.unique = true;
|
||||||
seriesSettings.addIfNonExisting = false;
|
seriesSettings.addIfNonExisting = false;
|
||||||
seriesSettings.fetchFn = (searchFilter: string) => this.searchService.search(searchFilter).pipe(
|
seriesSettings.fetchFn = (searchFilter: string) => {
|
||||||
|
this.searchService.search(searchFilter);
|
||||||
|
return this.searchService.searchResults$.pipe(
|
||||||
map(group => group.series),
|
map(group => group.series),
|
||||||
map(items => seriesSettings.compareFn(items, searchFilter)),
|
map(items => seriesSettings.compareFn(items, searchFilter)),
|
||||||
map(series => series.filter(s => s.seriesId !== this.series.id)),
|
map(series => series.filter(s => s.seriesId !== this.series.id)),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
seriesSettings.compareFn = (options: SearchResult[], filter: string) => {
|
seriesSettings.compareFn = (options: SearchResult[], filter: string) => {
|
||||||
return options.filter(m => this.utilityService.filter(m.name, filter));
|
return options.filter(m => this.utilityService.filter(m.name, filter));
|
||||||
|
|
@ -144,7 +147,8 @@ export class EditSeriesRelationComponent implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (series !== undefined) {
|
if (series !== undefined) {
|
||||||
return this.searchService.search(series.name).pipe(
|
this.searchService.search(series.name)
|
||||||
|
return this.searchService.searchResults$.pipe(
|
||||||
map(group => group.series), map(results => {
|
map(group => group.series), map(results => {
|
||||||
seriesSettings.savedData = results.filter(s => s.seriesId === series.id);
|
seriesSettings.savedData = results.filter(s => s.seriesId === series.id);
|
||||||
return seriesSettings;
|
return seriesSettings;
|
||||||
|
|
|
||||||
|
|
@ -192,7 +192,7 @@ NZ0ZV4zm4/L1dfnYNCrjTFq9G03rmj5D+Y4i0OHuL3GFPJytaM54AAAAAElFTkSuQmCC
|
||||||
[minQueryLength]="2"
|
[minQueryLength]="2"
|
||||||
initialValue=""
|
initialValue=""
|
||||||
placeholder="Search…"
|
placeholder="Search…"
|
||||||
[grouppedData]="(searchService.searchResults$ | async) || searchResults"
|
[grouppedData]="(search$ | async) || emptyResult"
|
||||||
(inputChanged)="onChangeSearch($event)"
|
(inputChanged)="onChangeSearch($event)"
|
||||||
(clearField)="clearSearch()"
|
(clearField)="clearSearch()"
|
||||||
(focusChanged)="focusUpdate($event)"
|
(focusChanged)="focusUpdate($event)"
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import { DOCUMENT } from '@angular/common';
|
import { DOCUMENT } from '@angular/common';
|
||||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, Inject, OnDestroy, OnInit, ViewChild } from '@angular/core';
|
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, Inject, OnDestroy, OnInit, ViewChild } from '@angular/core';
|
||||||
import { NavigationEnd, Router } from '@angular/router';
|
import { NavigationEnd, Router } from '@angular/router';
|
||||||
import { fromEvent, Subject } from 'rxjs';
|
import { fromEvent, Observable, of, Subject } from 'rxjs';
|
||||||
import { debounceTime, distinctUntilChanged, filter, takeUntil, tap } from 'rxjs/operators';
|
import { catchError, debounceTime, distinctUntilChanged, filter, startWith, takeUntil, tap } from 'rxjs/operators';
|
||||||
import { Chapter } from 'src/app/_models/chapter';
|
import { Chapter } from 'src/app/_models/chapter';
|
||||||
import { MangaFile } from 'src/app/_models/manga-file';
|
import { MangaFile } from 'src/app/_models/manga-file';
|
||||||
import { ScrollService } from 'src/app/_services/scroll.service';
|
import { ScrollService } from 'src/app/_services/scroll.service';
|
||||||
|
|
@ -31,7 +31,8 @@ export class NavHeaderComponent implements OnInit, OnDestroy {
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
debounceTime = 300;
|
debounceTime = 300;
|
||||||
imageStyles = {width: '24px', 'margin-top': '5px'};
|
imageStyles = {width: '24px', 'margin-top': '5px'};
|
||||||
searchResults: SearchResultGroup = new SearchResultGroup();
|
emptyResult: SearchResultGroup = new SearchResultGroup();
|
||||||
|
search$!: Observable<SearchResultGroup>;
|
||||||
searchTerm = '';
|
searchTerm = '';
|
||||||
customFilter: (items: SearchResult[], query: string) => SearchResult[] = (items: SearchResult[], query: string) => {
|
customFilter: (items: SearchResult[], query: string) => SearchResult[] = (items: SearchResult[], query: string) => {
|
||||||
const normalizedQuery = query.trim().toLowerCase();
|
const normalizedQuery = query.trim().toLowerCase();
|
||||||
|
|
@ -54,6 +55,21 @@ export class NavHeaderComponent implements OnInit, OnDestroy {
|
||||||
public imageService: ImageService, @Inject(DOCUMENT) private document: Document,
|
public imageService: ImageService, @Inject(DOCUMENT) private document: Document,
|
||||||
private scrollService: ScrollService, public searchService: SearchService, private readonly cdRef: ChangeDetectorRef) {
|
private scrollService: ScrollService, public searchService: SearchService, private readonly cdRef: ChangeDetectorRef) {
|
||||||
this.scrollElem = this.document.body;
|
this.scrollElem = this.document.body;
|
||||||
|
|
||||||
|
this.search$ = this.searchService.searchResults$.pipe(
|
||||||
|
startWith(new SearchResultGroup()),
|
||||||
|
takeUntil(this.onDestroy),
|
||||||
|
tap((_) => {
|
||||||
|
this.isLoading = false;
|
||||||
|
this.cdRef.markForCheck();
|
||||||
|
}),
|
||||||
|
catchError(() => {
|
||||||
|
this.isLoading = false;
|
||||||
|
this.searchTerm = '';
|
||||||
|
this.cdRef.markForCheck();
|
||||||
|
return of();
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
|
@ -107,20 +123,8 @@ export class NavHeaderComponent implements OnInit, OnDestroy {
|
||||||
onChangeSearch(val: string) {
|
onChangeSearch(val: string) {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
this.searchTerm = val.trim();
|
this.searchTerm = val.trim();
|
||||||
|
this.searchService.search(val);
|
||||||
this.cdRef.markForCheck();
|
this.cdRef.markForCheck();
|
||||||
|
|
||||||
this.searchService.search(val.trim());
|
|
||||||
|
|
||||||
this.searchService.search(val.trim()).pipe(takeUntil(this.onDestroy)).subscribe((results: SearchResultGroup) => {
|
|
||||||
//this.searchResults = results;
|
|
||||||
this.isLoading = false;
|
|
||||||
this.cdRef.markForCheck();
|
|
||||||
}, err => {
|
|
||||||
this.searchResults.reset();
|
|
||||||
this.isLoading = false;
|
|
||||||
this.searchTerm = '';
|
|
||||||
this.cdRef.markForCheck();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
goTo(queryParamName: string, filter: any) {
|
goTo(queryParamName: string, filter: any) {
|
||||||
|
|
@ -173,7 +177,7 @@ export class NavHeaderComponent implements OnInit, OnDestroy {
|
||||||
clearSearch() {
|
clearSearch() {
|
||||||
this.searchViewRef.clear();
|
this.searchViewRef.clear();
|
||||||
this.searchTerm = '';
|
this.searchTerm = '';
|
||||||
this.searchResults = new SearchResultGroup();
|
this.searchService.search('');
|
||||||
this.cdRef.markForCheck();
|
this.cdRef.markForCheck();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue