mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-07-28 18:24:38 -05:00
lots of changes for the new unified search
This commit is contained in:
@@ -10,6 +10,8 @@ import { SearchService } from 'src/app/services/rest/search.service';
|
||||
import { environment } from 'src/environments/environment';
|
||||
import { DocumentDetailComponent } from '../document-detail/document-detail.component';
|
||||
import { Meta } from '@angular/platform-browser';
|
||||
import { DocumentListViewService } from 'src/app/services/document-list-view.service';
|
||||
import { FILTER_FULLTEXT_QUERY } from 'src/app/data/filter-rule-type';
|
||||
|
||||
@Component({
|
||||
selector: 'app-app-frame',
|
||||
@@ -24,6 +26,7 @@ export class AppFrameComponent implements OnInit {
|
||||
private openDocumentsService: OpenDocumentsService,
|
||||
private searchService: SearchService,
|
||||
public savedViewService: SavedViewService,
|
||||
private list: DocumentListViewService,
|
||||
private meta: Meta
|
||||
) {
|
||||
|
||||
@@ -74,7 +77,7 @@ export class AppFrameComponent implements OnInit {
|
||||
|
||||
search() {
|
||||
this.closeMenu()
|
||||
this.router.navigate(['search'], {queryParams: {query: this.searchField.value}})
|
||||
this.list.quickFilter([{rule_type: FILTER_FULLTEXT_QUERY, value: this.searchField.value}])
|
||||
}
|
||||
|
||||
closeDocument(d: PaperlessDocument) {
|
||||
|
@@ -20,6 +20,7 @@ import { ToastService } from 'src/app/services/toast.service';
|
||||
import { TextComponent } from '../common/input/text/text.component';
|
||||
import { SettingsService, SETTINGS_KEYS } from 'src/app/services/settings.service';
|
||||
import { PaperlessDocumentSuggestions } from 'src/app/data/paperless-document-suggestions';
|
||||
import { FILTER_FULLTEXT_MORELIKE } from 'src/app/data/filter-rule-type';
|
||||
|
||||
@Component({
|
||||
selector: 'app-document-detail',
|
||||
@@ -219,7 +220,7 @@ export class DocumentDetailComponent implements OnInit {
|
||||
}
|
||||
|
||||
moreLike() {
|
||||
this.router.navigate(["search"], {queryParams: {more_like:this.document.id}})
|
||||
this.documentListViewService.quickFilter([{rule_type: FILTER_FULLTEXT_MORELIKE, value: this.documentId.toString()}])
|
||||
}
|
||||
|
||||
hasNext() {
|
||||
|
@@ -25,14 +25,14 @@
|
||||
</h5>
|
||||
</div>
|
||||
<p class="card-text">
|
||||
<app-result-highlight *ngIf="getDetailsAsHighlight()" class="result-content" [highlights]="getDetailsAsHighlight()"></app-result-highlight>
|
||||
<span *ngIf="getDetailsAsString()" class="result-content">{{getDetailsAsString()}}</span>
|
||||
<span *ngIf="document.__search_hit__" [innerHtml]="document.__search_hit__.highlights"></span>
|
||||
<span *ngIf="!document.__search_hit__" class="result-content">{{contentTrimmed}}</span>
|
||||
</p>
|
||||
|
||||
|
||||
<div class="d-flex flex-column flex-md-row align-items-md-center">
|
||||
<div class="btn-group">
|
||||
<a routerLink="/search" [queryParams]="{'more_like': document.id}" class="btn btn-sm btn-outline-secondary" *ngIf="moreLikeThis">
|
||||
<a class="btn btn-sm btn-outline-secondary" (click)="clickMoreLike.emit()">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-three-dots" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd" d="M3 9.5a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z"/>
|
||||
</svg> <span class="d-block d-md-inline" i18n>More like this</span>
|
||||
@@ -62,9 +62,9 @@
|
||||
</div>
|
||||
|
||||
<div class="list-group list-group-horizontal border-0 card-info ml-md-auto mt-2 mt-md-0">
|
||||
<div *ngIf="searchScore" class="list-group-item bg-light text-dark p-1 mr-5 border-0 d-flex search-score">
|
||||
<div *ngIf="document.__search_hit__" class="list-group-item bg-light text-dark p-1 mr-5 border-0 d-flex search-score">
|
||||
<small class="text-muted" i18n>Score:</small>
|
||||
<ngb-progressbar [type]="searchScoreClass" [value]="searchScore" class="search-score-bar mx-2 mt-1" [max]="1"></ngb-progressbar>
|
||||
<ngb-progressbar [type]="searchScoreClass" [value]="document.__search_hit__.score" class="search-score-bar mx-2 mt-1" [max]="1"></ngb-progressbar>
|
||||
</div>
|
||||
<button *ngIf="document.document_type" type="button" class="list-group-item btn btn-sm bg-light text-dark p-1 border-0 mr-2" title="Filter by document type"
|
||||
(click)="clickDocumentType.emit(document.document_type);$event.stopPropagation()">
|
||||
|
@@ -60,3 +60,8 @@
|
||||
padding-top: 0.35rem !important;
|
||||
}
|
||||
}
|
||||
|
||||
span ::ng-deep .match {
|
||||
color: black;
|
||||
background-color: rgb(255, 211, 66);
|
||||
}
|
@@ -4,6 +4,8 @@ import { PaperlessDocument } from 'src/app/data/paperless-document';
|
||||
import { DocumentService } from 'src/app/services/rest/document.service';
|
||||
import { SettingsService, SETTINGS_KEYS } from 'src/app/services/settings.service';
|
||||
import { NgbPopover } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { DocumentListViewService } from 'src/app/services/document-list-view.service';
|
||||
import { FILTER_FULLTEXT_MORELIKE } from 'src/app/data/filter-rule-type';
|
||||
|
||||
@Component({
|
||||
selector: 'app-document-card-large',
|
||||
@@ -24,15 +26,9 @@ export class DocumentCardLargeComponent implements OnInit {
|
||||
return this.toggleSelected.observers.length > 0
|
||||
}
|
||||
|
||||
@Input()
|
||||
moreLikeThis: boolean = false
|
||||
|
||||
@Input()
|
||||
document: PaperlessDocument
|
||||
|
||||
@Input()
|
||||
details: any
|
||||
|
||||
@Output()
|
||||
clickTag = new EventEmitter<number>()
|
||||
|
||||
@@ -42,6 +38,9 @@ export class DocumentCardLargeComponent implements OnInit {
|
||||
@Output()
|
||||
clickDocumentType = new EventEmitter<number>()
|
||||
|
||||
@Output()
|
||||
clickMoreLike= new EventEmitter()
|
||||
|
||||
@Input()
|
||||
searchScore: number
|
||||
|
||||
@@ -67,19 +66,6 @@ export class DocumentCardLargeComponent implements OnInit {
|
||||
return this.settingsService.get(SETTINGS_KEYS.DARK_MODE_THUMB_INVERTED)
|
||||
}
|
||||
|
||||
getDetailsAsString() {
|
||||
if (typeof this.details === 'string') {
|
||||
return this.details.substring(0, 500)
|
||||
}
|
||||
}
|
||||
|
||||
getDetailsAsHighlight() {
|
||||
//TODO: this is not an exact typecheck, can we do better
|
||||
if (this.details instanceof Array) {
|
||||
return this.details
|
||||
}
|
||||
}
|
||||
|
||||
getThumbUrl() {
|
||||
return this.documentService.getThumbUrl(this.document.id)
|
||||
}
|
||||
@@ -116,4 +102,8 @@ export class DocumentCardLargeComponent implements OnInit {
|
||||
mouseLeaveCard() {
|
||||
this.popover.close()
|
||||
}
|
||||
|
||||
get contentTrimmed() {
|
||||
return this.document.content.substr(0, 500)
|
||||
}
|
||||
}
|
||||
|
@@ -90,7 +90,7 @@
|
||||
</div>
|
||||
|
||||
<div *ngIf="displayMode == 'largeCards'">
|
||||
<app-document-card-large [selected]="list.isSelected(d)" (toggleSelected)="toggleSelected(d, $event)" *ngFor="let d of list.documents; trackBy: trackByDocumentId" [document]="d" [details]="d.content" (clickTag)="clickTag($event)" (clickCorrespondent)="clickCorrespondent($event)" (clickDocumentType)="clickDocumentType($event)">
|
||||
<app-document-card-large [selected]="list.isSelected(d)" (toggleSelected)="toggleSelected(d, $event)" *ngFor="let d of list.documents; trackBy: trackByDocumentId" [document]="d" (clickTag)="clickTag($event)" (clickCorrespondent)="clickCorrespondent($event)" (clickDocumentType)="clickDocumentType($event)" (clickMoreLike)="clickMoreLike(d.id)">
|
||||
</app-document-card-large>
|
||||
</div>
|
||||
|
||||
|
@@ -207,6 +207,13 @@ export class DocumentListComponent implements OnInit, OnDestroy {
|
||||
})
|
||||
}
|
||||
|
||||
clickMoreLike(documentID: number) {
|
||||
this.list.selectNone()
|
||||
setTimeout(() => {
|
||||
//this.filterEditor.moreLikeThis(doc)
|
||||
})
|
||||
}
|
||||
|
||||
trackByDocumentId(index, item: PaperlessDocument) {
|
||||
return item.id
|
||||
}
|
||||
|
@@ -1,7 +1,6 @@
|
||||
<div class="row">
|
||||
<div class="col mb-2 mb-xl-0">
|
||||
<div class="form-inline d-flex align-items-center">
|
||||
<label class="text-muted mr-2 mb-0" i18n>Filter by:</label>
|
||||
<div class="input-group input-group-sm flex-fill w-auto">
|
||||
<div class="input-group-prepend" ngbDropdown>
|
||||
<button class="btn btn-outline-primary" ngbDropdownToggle>{{textFilterTargetName}}</button>
|
||||
@@ -9,7 +8,8 @@
|
||||
<button *ngFor="let t of textFilterTargets" ngbDropdownItem [class.active]="textFilterTarget == t.id" (click)="changeTextFilterTarget(t.id)">{{t.name}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<input class="form-control form-control-sm" type="text" [(ngModel)]="textFilter">
|
||||
<input class="form-control form-control-sm" type="text" [(ngModel)]="textFilter" *ngIf="textFilterTarget != 'fulltext-morelike'">
|
||||
<span class="form-control form-control-sm text-truncate" *ngIf="textFilterTarget == 'fulltext-morelike'">{{_moreLikeDoc?.title}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -8,13 +8,17 @@ import { DocumentTypeService } from 'src/app/services/rest/document-type.service
|
||||
import { TagService } from 'src/app/services/rest/tag.service';
|
||||
import { CorrespondentService } from 'src/app/services/rest/correspondent.service';
|
||||
import { FilterRule } from 'src/app/data/filter-rule';
|
||||
import { FILTER_ADDED_AFTER, FILTER_ADDED_BEFORE, FILTER_ASN, FILTER_CORRESPONDENT, FILTER_CREATED_AFTER, FILTER_CREATED_BEFORE, FILTER_DOCUMENT_TYPE, FILTER_HAS_ANY_TAG, FILTER_HAS_TAG, FILTER_TITLE, FILTER_TITLE_CONTENT } from 'src/app/data/filter-rule-type';
|
||||
import { FILTER_ADDED_AFTER, FILTER_ADDED_BEFORE, FILTER_ASN, FILTER_CORRESPONDENT, FILTER_CREATED_AFTER, FILTER_CREATED_BEFORE, FILTER_DOCUMENT_TYPE, FILTER_FULLTEXT_MORELIKE, FILTER_FULLTEXT_QUERY, FILTER_HAS_ANY_TAG, FILTER_HAS_TAG, FILTER_TITLE, FILTER_TITLE_CONTENT } from 'src/app/data/filter-rule-type';
|
||||
import { FilterableDropdownSelectionModel } from '../../common/filterable-dropdown/filterable-dropdown.component';
|
||||
import { ToggleableItemState } from '../../common/filterable-dropdown/toggleable-dropdown-button/toggleable-dropdown-button.component';
|
||||
import { DocumentService } from 'src/app/services/rest/document.service';
|
||||
import { PaperlessDocument } from 'src/app/data/paperless-document';
|
||||
|
||||
const TEXT_FILTER_TARGET_TITLE = "title"
|
||||
const TEXT_FILTER_TARGET_TITLE_CONTENT = "title-content"
|
||||
const TEXT_FILTER_TARGET_ASN = "asn"
|
||||
const TEXT_FILTER_TARGET_FULLTEXT_QUERY = "fulltext-query"
|
||||
const TEXT_FILTER_TARGET_FULLTEXT_MORELIKE = "fulltext-morelike"
|
||||
|
||||
@Component({
|
||||
selector: 'app-filter-editor',
|
||||
@@ -64,7 +68,8 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
||||
constructor(
|
||||
private documentTypeService: DocumentTypeService,
|
||||
private tagService: TagService,
|
||||
private correspondentService: CorrespondentService
|
||||
private correspondentService: CorrespondentService,
|
||||
private documentService: DocumentService
|
||||
) { }
|
||||
|
||||
tags: PaperlessTag[] = []
|
||||
@@ -72,12 +77,21 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
||||
documentTypes: PaperlessDocumentType[] = []
|
||||
|
||||
_textFilter = ""
|
||||
_moreLikeId: number
|
||||
_moreLikeDoc: PaperlessDocument
|
||||
|
||||
textFilterTargets = [
|
||||
{id: TEXT_FILTER_TARGET_TITLE, name: $localize`Title`},
|
||||
{id: TEXT_FILTER_TARGET_TITLE_CONTENT, name: $localize`Title & content`},
|
||||
{id: TEXT_FILTER_TARGET_ASN, name: $localize`ASN`}
|
||||
]
|
||||
get textFilterTargets() {
|
||||
let targets = [
|
||||
{id: TEXT_FILTER_TARGET_TITLE, name: $localize`Title`},
|
||||
{id: TEXT_FILTER_TARGET_TITLE_CONTENT, name: $localize`Title & content`},
|
||||
{id: TEXT_FILTER_TARGET_ASN, name: $localize`ASN`},
|
||||
{id: TEXT_FILTER_TARGET_FULLTEXT_QUERY, name: $localize`Fulltext search`}
|
||||
]
|
||||
if (this.textFilterTarget == TEXT_FILTER_TARGET_FULLTEXT_MORELIKE) {
|
||||
targets.push({id: TEXT_FILTER_TARGET_FULLTEXT_MORELIKE, name: $localize`More like`})
|
||||
}
|
||||
return targets
|
||||
}
|
||||
|
||||
textFilterTarget = TEXT_FILTER_TARGET_TITLE_CONTENT
|
||||
|
||||
@@ -101,6 +115,7 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
||||
this.tagSelectionModel.clear(false)
|
||||
this.correspondentSelectionModel.clear(false)
|
||||
this._textFilter = null
|
||||
this._moreLikeId = null
|
||||
this.dateAddedBefore = null
|
||||
this.dateAddedAfter = null
|
||||
this.dateCreatedBefore = null
|
||||
@@ -120,6 +135,17 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
||||
this._textFilter = rule.value
|
||||
this.textFilterTarget = TEXT_FILTER_TARGET_ASN
|
||||
break
|
||||
case FILTER_FULLTEXT_QUERY:
|
||||
this._textFilter = rule.value
|
||||
this.textFilterTarget = TEXT_FILTER_TARGET_FULLTEXT_QUERY
|
||||
break
|
||||
case FILTER_FULLTEXT_MORELIKE:
|
||||
this._moreLikeId = +rule.value
|
||||
this.textFilterTarget = TEXT_FILTER_TARGET_FULLTEXT_MORELIKE
|
||||
this.documentService.get(this._moreLikeId).subscribe(result => {
|
||||
this._moreLikeDoc = result
|
||||
})
|
||||
break
|
||||
case FILTER_CREATED_AFTER:
|
||||
this.dateCreatedAfter = rule.value
|
||||
break
|
||||
@@ -159,6 +185,12 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
||||
if (this._textFilter && this.textFilterTarget == TEXT_FILTER_TARGET_ASN) {
|
||||
filterRules.push({rule_type: FILTER_ASN, value: this._textFilter})
|
||||
}
|
||||
if (this._textFilter && this.textFilterTarget == TEXT_FILTER_TARGET_FULLTEXT_QUERY) {
|
||||
filterRules.push({rule_type: FILTER_FULLTEXT_QUERY, value: this._textFilter})
|
||||
}
|
||||
if (this._moreLikeId && this.textFilterTarget == TEXT_FILTER_TARGET_FULLTEXT_MORELIKE) {
|
||||
filterRules.push({rule_type: FILTER_FULLTEXT_MORELIKE, value: this._moreLikeId?.toString()})
|
||||
}
|
||||
if (this.tagSelectionModel.isNoneSelected()) {
|
||||
filterRules.push({rule_type: FILTER_HAS_ANY_TAG, value: "false"})
|
||||
} else {
|
||||
@@ -232,6 +264,7 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
resetSelected() {
|
||||
this.textFilterTarget = TEXT_FILTER_TARGET_TITLE_CONTENT
|
||||
this.reset.next()
|
||||
}
|
||||
|
||||
|
@@ -1,3 +0,0 @@
|
||||
... <span *ngFor="let fragment of highlights">
|
||||
<span *ngFor="let token of fragment" [class.match]="token.highlight">{{token.text}}</span> ...
|
||||
</span>
|
@@ -1,4 +0,0 @@
|
||||
.match {
|
||||
color: black;
|
||||
background-color: rgb(255, 211, 66);
|
||||
}
|
@@ -1,25 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ResultHighlightComponent } from './result-highlight.component';
|
||||
|
||||
describe('ResultHighlightComponent', () => {
|
||||
let component: ResultHighlightComponent;
|
||||
let fixture: ComponentFixture<ResultHighlightComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ ResultHighlightComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ResultHighlightComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@@ -1,19 +0,0 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { SearchHitHighlight } from 'src/app/data/search-result';
|
||||
|
||||
@Component({
|
||||
selector: 'app-result-highlight',
|
||||
templateUrl: './result-highlight.component.html',
|
||||
styleUrls: ['./result-highlight.component.scss']
|
||||
})
|
||||
export class ResultHighlightComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
@Input()
|
||||
highlights: SearchHitHighlight[][]
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
@@ -1,26 +0,0 @@
|
||||
<app-page-header i18n-title title="Search results">
|
||||
</app-page-header>
|
||||
|
||||
<div *ngIf="errorMessage" class="alert alert-danger" i18n>Invalid search query: {{errorMessage}}</div>
|
||||
|
||||
<p *ngIf="more_like" i18n>Showing documents similar to <a routerLink="/documents/{{more_like}}">{{more_like_doc?.original_file_name}}</a></p>
|
||||
|
||||
<p *ngIf="query">
|
||||
<ng-container i18n>Search query: <i>{{query}}</i></ng-container>
|
||||
<ng-container *ngIf="correctedQuery">
|
||||
- <ng-container i18n>Did you mean "<a [routerLink]="" (click)="searchCorrectedQuery()">{{correctedQuery}}</a>"?</ng-container>
|
||||
</ng-container>
|
||||
</p>
|
||||
|
||||
<div *ngIf="!errorMessage" [class.result-content-searching]="searching" infiniteScroll (scrolled)="onScroll()">
|
||||
<p i18n>{resultCount, plural, =0 {No results} =1 {One result} other {{{resultCount}} results}}</p>
|
||||
<ng-container *ngFor="let result of results">
|
||||
<app-document-card-large *ngIf="result.document"
|
||||
[document]="result.document"
|
||||
[details]="result.highlights"
|
||||
[searchScore]="result.score / maxScore"
|
||||
[moreLikeThis]="true">
|
||||
</app-document-card-large>
|
||||
</ng-container>
|
||||
|
||||
</div>
|
@@ -1,15 +0,0 @@
|
||||
.result-content {
|
||||
color: darkgray;
|
||||
}
|
||||
|
||||
.doc-img {
|
||||
object-fit: cover;
|
||||
object-position: top;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
|
||||
}
|
||||
|
||||
.result-content-searching {
|
||||
opacity: 0.3;
|
||||
}
|
@@ -1,25 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SearchComponent } from './search.component';
|
||||
|
||||
describe('SearchComponent', () => {
|
||||
let component: SearchComponent;
|
||||
let fixture: ComponentFixture<SearchComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ SearchComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SearchComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@@ -1,95 +0,0 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { PaperlessDocument } from 'src/app/data/paperless-document';
|
||||
import { PaperlessDocumentType } from 'src/app/data/paperless-document-type';
|
||||
import { SearchHit } from 'src/app/data/search-result';
|
||||
import { DocumentService } from 'src/app/services/rest/document.service';
|
||||
import { SearchService } from 'src/app/services/rest/search.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-search',
|
||||
templateUrl: './search.component.html',
|
||||
styleUrls: ['./search.component.scss']
|
||||
})
|
||||
export class SearchComponent implements OnInit {
|
||||
|
||||
results: SearchHit[] = []
|
||||
|
||||
query: string = ""
|
||||
|
||||
more_like: number
|
||||
|
||||
more_like_doc: PaperlessDocument
|
||||
|
||||
searching = false
|
||||
|
||||
currentPage = 1
|
||||
|
||||
pageCount = 1
|
||||
|
||||
resultCount
|
||||
|
||||
correctedQuery: string = null
|
||||
|
||||
errorMessage: string
|
||||
|
||||
get maxScore() {
|
||||
return this.results?.length > 0 ? this.results[0].score : 100
|
||||
}
|
||||
|
||||
constructor(private searchService: SearchService, private route: ActivatedRoute, private router: Router, private documentService: DocumentService) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.route.queryParamMap.subscribe(paramMap => {
|
||||
window.scrollTo(0, 0)
|
||||
this.query = paramMap.get('query')
|
||||
this.more_like = paramMap.has('more_like') ? +paramMap.get('more_like') : null
|
||||
if (this.more_like) {
|
||||
this.documentService.get(this.more_like).subscribe(r => {
|
||||
this.more_like_doc = r
|
||||
})
|
||||
} else {
|
||||
this.more_like_doc = null
|
||||
}
|
||||
this.searching = true
|
||||
this.currentPage = 1
|
||||
this.loadPage()
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
searchCorrectedQuery() {
|
||||
this.router.navigate(["search"], {queryParams: {query: this.correctedQuery, more_like: this.more_like}})
|
||||
}
|
||||
|
||||
loadPage(append: boolean = false) {
|
||||
this.errorMessage = null
|
||||
this.correctedQuery = null
|
||||
|
||||
this.searchService.search(this.query, this.currentPage, this.more_like).subscribe(result => {
|
||||
if (append) {
|
||||
this.results.push(...result.results)
|
||||
} else {
|
||||
this.results = result.results
|
||||
}
|
||||
this.pageCount = result.page_count
|
||||
this.searching = false
|
||||
this.resultCount = result.count
|
||||
this.correctedQuery = result.corrected_query
|
||||
}, error => {
|
||||
this.searching = false
|
||||
this.resultCount = 1
|
||||
this.pageCount = 1
|
||||
this.results = []
|
||||
this.errorMessage = error.error
|
||||
})
|
||||
}
|
||||
|
||||
onScroll() {
|
||||
if (this.currentPage < this.pageCount) {
|
||||
this.currentPage += 1
|
||||
this.loadPage(true)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user