();
constructor(private searchService: SearchService) { }
- ngOnChanges() {
- if (this.queryModel) {
- this.fromIndex = 0;
- this.search();
- this.queryModel.update.subscribe(() => this.search());
+ ngOnChanges(changes: SimpleChanges) {
+ if (changes.queryModel) {
+ this.pageResults?.complete();
+ this.pageResults = new PageResults(this.searchService, this.queryModel);
+ this.error$ = this.pageResults.error$.pipe(
+ map(this.parseError)
+ );
+ this.pageResults.result$.pipe(
+ takeUntil(this.destroy$)
+ ).subscribe(result => {
+ this.searchedEvent.emit({ queryText: this.queryModel.queryText, resultsCount: result.total });
+ });
}
}
+ ngOnDestroy(): void {
+ this.pageResults?.complete();
+ this.destroy$.next();
+ this.destroy$.complete();
+ }
+
+ setParameters(parameters: PageResultsParameters) {
+ this.pageResults?.setParameters(parameters);
+ }
+
+ totalDisplayed(totalResults: number) {
+ return Math.min(totalResults, MAXIMUM_DISPLAYED);
+ }
+
+ goToScan(page: DocumentPage, document: FoundDocument, event: Event) {
+ page.focus(document, 'scan');
+ event.stopPropagation();
+ };
+
@HostListener('window:scroll', [])
onWindowScroll() {
// mark that the search results were scrolled down beyond 68 pixels from top (position underneath sticky search bar)
@@ -91,95 +95,13 @@ export class SearchResultsComponent implements OnChanges {
}
}
- private search() {
- this.isLoading = true;
- this.searchService.search(this.queryModel).then(results => {
- this.results = results;
- this.results.documents.map((d, i) => d.position = i + 1);
- this.searched(this.queryModel.queryText, this.results.total.value);
- this.totalResults = this.results.total.value <= MAXIMUM_DISPLAYED ? this.results.total.value : MAXIMUM_DISPLAYED;
- }, error => {
- this.showError = {
+ private parseError(error): ShowError {
+ if (error) {
+ return {
date: (new Date()).toISOString(),
href: location.href,
message: error.message || 'An unknown error occurred'
};
- console.trace(error);
- // if an error occurred, return query text and 0 results
- this.searched(this.queryModel.queryText, 0);
- });
- }
-
- public async loadResults(searchParameters: SearchParameters) {
- this.isLoading = true;
- this.fromIndex = searchParameters.from;
- this.resultsPerPage = searchParameters.size;
- this.results = await this.searchService.loadResults(this.queryModel, searchParameters.from, searchParameters.size);
- this.results.documents.map( (d, i) => d.position = i + searchParameters.from + 1 );
- this.isLoading = false;
- }
-
- public searched(queryText: string, resultsCount: number) {
- // emit searchedEvent to search component
- this.searchedEvent.next({ queryText, resultsCount });
- this.isLoading = false;
- }
-
- public goToScan(document: FoundDocument, event: any) {
- this.onViewDocument(document);
- this.documentTabIndex = 1;
- event.stopPropagation();
- }
-
- public onViewDocument(document: FoundDocument) {
- this.showDocument = true;
- this.viewDocument = document;
- this.documentTabIndex = 0;
- }
-
- get contextDisplayName(): string {
- if (this.corpus && this.corpus.documentContext) {
- return this.corpus.documentContext.displayName;
}
}
-
- public async nextDocument(document: FoundDocument) {
- const newPosition = document.position + 1;
- const maxPosition = this.fromIndex + this.results.documents.length;
-
- if (newPosition > maxPosition) {
- this.fromIndex = maxPosition + 1;
- await this.loadResults({
- from: maxPosition,
- size: this.resultsPerPage,
- });
- this.viewDocumentAtPosition(newPosition);
- } else {
- this.viewDocumentAtPosition(newPosition);
- }
- }
-
- public async prevDocument(document: FoundDocument) {
- const newPosition = document.position - 1;
- const minPosition = this.fromIndex + 1;
-
- if (newPosition < minPosition) {
- this.fromIndex = this.fromIndex - this.resultsPerPage;
- await this.loadResults({
- from: this.fromIndex,
- size: this.resultsPerPage,
- });
- this.viewDocumentAtPosition(newPosition);
- } else {
- this.viewDocumentAtPosition(newPosition);
- }
- }
-
- viewDocumentAtPosition(position: number) {
- const document = this.results.documents.find(doc =>
- doc.position === position
- );
- this.onViewDocument(document);
- }
-
}
diff --git a/frontend/src/app/search/search.component.html b/frontend/src/app/search/search.component.html
index 7e95bfefe..e3e782532 100644
--- a/frontend/src/app/search/search.component.html
+++ b/frontend/src/app/search/search.component.html
@@ -55,10 +55,8 @@
-
-
-
diff --git a/frontend/src/app/search/search.module.ts b/frontend/src/app/search/search.module.ts
index c4e62a79e..b1f72d613 100644
--- a/frontend/src/app/search/search.module.ts
+++ b/frontend/src/app/search/search.module.ts
@@ -9,7 +9,6 @@ import { CorpusModule } from '../corpus-header/corpus.module';
import { SearchSortingComponent } from './search-sorting.component';
import { FilterModule } from '../filter/filter.module';
import { DownloadModule } from '../download/download.module';
-import { DialogModule } from 'primeng/dialog';
import { QueryService, SearchService } from '../services';
import { VisualizationModule } from '../visualization/visualization.module';
@@ -28,7 +27,6 @@ import { VisualizationModule } from '../visualization/visualization.module';
SearchSortingComponent,
],
imports: [
- DialogModule,
CorpusModule,
DocumentModule,
DownloadModule,
diff --git a/frontend/src/app/services/elastic-search.service.spec.ts b/frontend/src/app/services/elastic-search.service.spec.ts
index b24021381..bc806258c 100644
--- a/frontend/src/app/services/elastic-search.service.spec.ts
+++ b/frontend/src/app/services/elastic-search.service.spec.ts
@@ -79,7 +79,7 @@ describe('ElasticSearchService', () => {
it('should make a search request', async () => {
const queryModel = new QueryModel(mockCorpus);
const size = 2;
- const response = service.search(queryModel, size);
+ const response = service.loadResults(queryModel, 0, size);
const searchUrl = `/api/es/${mockCorpus.name}/_search?size=${size}`;
httpTestingController.expectOne(searchUrl).flush(mockResponse);
diff --git a/frontend/src/app/services/elastic-search.service.ts b/frontend/src/app/services/elastic-search.service.ts
index be8d30354..2ba4d6d5e 100644
--- a/frontend/src/app/services/elastic-search.service.ts
+++ b/frontend/src/app/services/elastic-search.service.ts
@@ -9,13 +9,12 @@ import {
import * as _ from 'lodash';
import { TagService } from './tag.service';
import { QueryParameters } from '../models/search-requests';
+import { RESULTS_PER_PAGE } from '../models/page-results';
@Injectable()
export class ElasticSearchService {
- private resultsPerPage = 20;
-
constructor(private http: HttpClient, private tagService: TagService) {
}
@@ -79,29 +78,17 @@ export class ElasticSearchService {
};
}
-
-
- public async search(
- queryModel: QueryModel,
- size?: number,
- ): Promise {
- const esQuery = queryModel.toEsQuery();
-
- // Perform the search
- const response = await this.execute(queryModel.corpus, esQuery, size || this.resultsPerPage);
- return this.parseResponse(queryModel.corpus, response);
- }
-
-
/**
* Load results for requested page
*/
public async loadResults(
- queryModel: QueryModel, from: number,
- size: number): Promise {
+ queryModel: QueryModel,
+ from: number,
+ size: number = RESULTS_PER_PAGE
+ ): Promise {
const esQuery = queryModel.toEsQuery();
// Perform the search
- const response = await this.execute(queryModel.corpus, esQuery, size || this.resultsPerPage, from);
+ const response = await this.execute(queryModel.corpus, esQuery, size, from);
return this.parseResponse(queryModel.corpus, response);
}
diff --git a/frontend/src/app/services/search.service.spec.ts b/frontend/src/app/services/search.service.spec.ts
index 0b4e67275..fe20957c1 100644
--- a/frontend/src/app/services/search.service.spec.ts
+++ b/frontend/src/app/services/search.service.spec.ts
@@ -45,7 +45,7 @@ describe('SearchService', () => {
it('should search', inject([SearchService], async (service: SearchService) => {
const queryModel = new QueryModel(mockCorpus);
- const results = await service.search(queryModel);
+ const results = await service.loadResults(queryModel, 0, 20);
expect(results).toBeTruthy();
expect(results.total.value).toBeGreaterThan(0);
}));
diff --git a/frontend/src/app/services/search.service.ts b/frontend/src/app/services/search.service.ts
index 455fe48eb..8d04a08a0 100644
--- a/frontend/src/app/services/search.service.ts
+++ b/frontend/src/app/services/search.service.ts
@@ -30,16 +30,7 @@ export class SearchService {
from,
size
);
- results.fields = queryModel.corpus.fields.filter((field) => field.resultsOverview);
- return results;
- }
-
- public async search(queryModel: QueryModel
- ): Promise {
- const request = this.elasticSearchService.search(queryModel);
- return request.then(results =>
- this.filterResultsFields(results, queryModel)
- );
+ return this.filterResultsFields(results, queryModel);
}
public async aggregateSearch(
diff --git a/frontend/src/mock-data/elastic-search.ts b/frontend/src/mock-data/elastic-search.ts
index 4a983a201..c584514ad 100644
--- a/frontend/src/mock-data/elastic-search.ts
+++ b/frontend/src/mock-data/elastic-search.ts
@@ -12,7 +12,7 @@ export class ElasticSearchServiceMock {
return Promise.resolve(makeDocument({content: 'Hello world!'}));
}
- search(): Promise {
+ loadResults(): Promise {
return Promise.resolve({
total: {
relation: 'eq',