diff --git a/src-ui/messages.xlf b/src-ui/messages.xlf index 68fe2703a..037ef0b17 100644 --- a/src-ui/messages.xlf +++ b/src-ui/messages.xlf @@ -1889,6 +1889,14 @@ 23 + + Search score + + src/app/services/rest/document.service.ts + 28 + + Score is a value returned by the full text search engine and specifies how well a result matches the given query + Create new item diff --git a/src-ui/src/app/components/document-list/document-list.component.ts b/src-ui/src/app/components/document-list/document-list.component.ts index 13a827e97..79adb99d0 100644 --- a/src-ui/src/app/components/document-list/document-list.component.ts +++ b/src-ui/src/app/components/document-list/document-list.component.ts @@ -2,14 +2,14 @@ import { Component, OnDestroy, OnInit, QueryList, ViewChild, ViewChildren } from import { ActivatedRoute, Router } from '@angular/router'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { Subscription } from 'rxjs'; -import { FilterRule } from 'src/app/data/filter-rule'; +import { FilterRule, isFullTextFilterRule } from 'src/app/data/filter-rule'; import { FILTER_FULLTEXT_MORELIKE } from 'src/app/data/filter-rule-type'; import { PaperlessDocument } from 'src/app/data/paperless-document'; import { PaperlessSavedView } from 'src/app/data/paperless-saved-view'; import { SortableDirective, SortEvent } from 'src/app/directives/sortable.directive'; import { ConsumerStatusService } from 'src/app/services/consumer-status.service'; import { DocumentListViewService } from 'src/app/services/document-list-view.service'; -import { DOCUMENT_SORT_FIELDS } from 'src/app/services/rest/document.service'; +import { DOCUMENT_SORT_FIELDS, DOCUMENT_SORT_FIELDS_FULLTEXT } from 'src/app/services/rest/document.service'; import { SavedViewService } from 'src/app/services/rest/saved-view.service'; import { ToastService } from 'src/app/services/toast.service'; import { FilterEditorComponent } from './filter-editor/filter-editor.component'; @@ -52,7 +52,7 @@ export class DocumentListComponent implements OnInit, OnDestroy { } getSortFields() { - return DOCUMENT_SORT_FIELDS + return isFullTextFilterRule(this.list.filterRules) ? DOCUMENT_SORT_FIELDS_FULLTEXT : DOCUMENT_SORT_FIELDS } onSort(event: SortEvent) { diff --git a/src-ui/src/app/data/filter-rule.ts b/src-ui/src/app/data/filter-rule.ts index 82d8498f3..5a0ed7368 100644 --- a/src-ui/src/app/data/filter-rule.ts +++ b/src-ui/src/app/data/filter-rule.ts @@ -1,3 +1,5 @@ +import { FILTER_FULLTEXT_MORELIKE, FILTER_FULLTEXT_QUERY } from "./filter-rule-type" + export function cloneFilterRules(filterRules: FilterRule[]): FilterRule[] { if (filterRules) { let newRules: FilterRule[] = [] @@ -10,6 +12,10 @@ export function cloneFilterRules(filterRules: FilterRule[]): FilterRule[] { } } +export function isFullTextFilterRule(filterRules: FilterRule[]): boolean { + return filterRules.find(r => r.rule_type == FILTER_FULLTEXT_QUERY || r.rule_type == FILTER_FULLTEXT_MORELIKE) != null +} + export interface FilterRule { rule_type: number value: string diff --git a/src-ui/src/app/services/document-list-view.service.ts b/src-ui/src/app/services/document-list-view.service.ts index aa82190d7..4e1a8aad4 100644 --- a/src-ui/src/app/services/document-list-view.service.ts +++ b/src-ui/src/app/services/document-list-view.service.ts @@ -1,28 +1,53 @@ import { Injectable } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { Observable } from 'rxjs'; -import { cloneFilterRules, FilterRule } from '../data/filter-rule'; -import { FILTER_FULLTEXT_MORELIKE, FILTER_FULLTEXT_QUERY } from '../data/filter-rule-type'; +import { cloneFilterRules, FilterRule, isFullTextFilterRule } from '../data/filter-rule'; import { PaperlessDocument } from '../data/paperless-document'; import { PaperlessSavedView } from '../data/paperless-saved-view'; import { DOCUMENT_LIST_SERVICE } from '../data/storage-keys'; import { DocumentService } from './rest/document.service'; import { SettingsService, SETTINGS_KEYS } from './settings.service'; +/** + * Captures the current state of the list view. + */ interface ListViewState { + /** + * Title of the document list view. Either "Documents" (localized) or the name of a saved view. + */ title?: string + /** + * Current paginated list of documents displayed. + */ documents?: PaperlessDocument[] currentPage: number + + /** + * Total amount of documents with the current filter rules. Used to calculate the number of pages. + */ collectionSize: number + /** + * Currently selected sort field. + */ sortField: string + + /** + * True if the list is sorted in reverse. + */ sortReverse: boolean + /** + * Filter rules for the current list view. + */ filterRules: FilterRule[] + /** + * Contains the IDs of all selected documents. + */ selected?: Set } @@ -134,10 +159,10 @@ export class DocumentListViewService { } set filterRules(filterRules: FilterRule[]) { - this.activeListViewState.filterRules = filterRules - if (filterRules.find(r => (r.rule_type == FILTER_FULLTEXT_QUERY || r.rule_type == FILTER_FULLTEXT_MORELIKE))) { - this.activeListViewState.currentPage = 1 + if (!isFullTextFilterRule(filterRules) && this.activeListViewState.sortField == "score") { + this.activeListViewState.sortField = "created" } + this.activeListViewState.filterRules = filterRules this.reload() this.reduceSelectionToFilter() this.saveDocumentListView() @@ -213,6 +238,10 @@ export class DocumentListViewService { this._activeSavedViewId = null this.activeListViewState.filterRules = filterRules this.activeListViewState.currentPage = 1 + if (isFullTextFilterRule(filterRules)) { + this.activeListViewState.sortField = "score" + this.activeListViewState.sortReverse = false + } this.reduceSelectionToFilter() this.saveDocumentListView() if (this.router.url == "/documents") { diff --git a/src-ui/src/app/services/rest/document.service.ts b/src-ui/src/app/services/rest/document.service.ts index 712b0492f..c6bc61dc8 100644 --- a/src-ui/src/app/services/rest/document.service.ts +++ b/src-ui/src/app/services/rest/document.service.ts @@ -23,6 +23,11 @@ export const DOCUMENT_SORT_FIELDS = [ { field: 'modified', name: $localize`Modified` } ] +export const DOCUMENT_SORT_FIELDS_FULLTEXT = [ + ...DOCUMENT_SORT_FIELDS, + { field: 'score', name: $localize`:Score is a value returned by the full text search engine and specifies how well a result matches the given query:Search score` } +] + export interface SelectionDataItem { id: number document_count: number