diff --git a/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts b/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts index f5b6ba89c..4b963c45a 100644 --- a/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts +++ b/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts @@ -20,9 +20,9 @@ import { Subject, filter, takeUntil } from 'rxjs' import { NEGATIVE_NULL_FILTER_VALUE } from 'src/app/data/filter-rule-type' import { MatchingModel } from 'src/app/data/matching-model' import { ObjectWithPermissions } from 'src/app/data/object-with-permissions' +import { SelectionDataItem } from 'src/app/data/results' import { FilterPipe } from 'src/app/pipes/filter.pipe' import { HotKeyService } from 'src/app/services/hot-key.service' -import { SelectionDataItem } from 'src/app/services/rest/document.service' import { pngxPopperOptions } from 'src/app/utils/popper-options' import { LoadingComponentWithPermissions } from '../../loading-component/loading.component' import { ClearableBadgeComponent } from '../clearable-badge/clearable-badge.component' diff --git a/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.ts b/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.ts index c23cd6c5f..b97cc76c4 100644 --- a/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.ts +++ b/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.ts @@ -16,6 +16,7 @@ import { first, map, Observable, Subject, switchMap, takeUntil } from 'rxjs' import { ConfirmDialogComponent } from 'src/app/components/common/confirm-dialog/confirm-dialog.component' import { CustomField } from 'src/app/data/custom-field' import { MatchingModel } from 'src/app/data/matching-model' +import { SelectionDataItem } from 'src/app/data/results' import { SETTINGS_KEYS } from 'src/app/data/ui-settings' import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive' import { DocumentListViewService } from 'src/app/services/document-list-view.service' @@ -32,7 +33,6 @@ import { DocumentBulkEditMethod, DocumentService, MergeDocumentsRequest, - SelectionDataItem, } from 'src/app/services/rest/document.service' import { SavedViewService } from 'src/app/services/rest/saved-view.service' import { ShareLinkBundleService } from 'src/app/services/rest/share-link-bundle.service' diff --git a/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.ts b/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.ts index b717c13fc..f7b50181b 100644 --- a/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.ts +++ b/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.ts @@ -76,6 +76,7 @@ import { FILTER_TITLE_CONTENT, NEGATIVE_NULL_FILTER_VALUE, } from 'src/app/data/filter-rule-type' +import { SelectionData, SelectionDataItem } from 'src/app/data/results' import { PermissionAction, PermissionType, @@ -84,11 +85,7 @@ import { import { CorrespondentService } from 'src/app/services/rest/correspondent.service' import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service' import { DocumentTypeService } from 'src/app/services/rest/document-type.service' -import { - DocumentService, - SelectionData, - SelectionDataItem, -} from 'src/app/services/rest/document.service' +import { DocumentService } from 'src/app/services/rest/document.service' import { SearchService } from 'src/app/services/rest/search.service' import { StoragePathService } from 'src/app/services/rest/storage-path.service' import { TagService } from 'src/app/services/rest/tag.service' diff --git a/src-ui/src/app/data/results.ts b/src-ui/src/app/data/results.ts index d29a55567..f985ed975 100644 --- a/src-ui/src/app/data/results.ts +++ b/src-ui/src/app/data/results.ts @@ -1,3 +1,5 @@ +import { Document } from './document' + export interface Results { count: number @@ -5,3 +7,20 @@ export interface Results { all: number[] } + +export interface SelectionDataItem { + id: number + document_count: number +} + +export interface SelectionData { + selected_storage_paths: SelectionDataItem[] + selected_correspondents: SelectionDataItem[] + selected_tags: SelectionDataItem[] + selected_document_types: SelectionDataItem[] + selected_custom_fields: SelectionDataItem[] +} + +export interface DocumentResults extends Results { + selection_data?: SelectionData +} diff --git a/src-ui/src/app/services/document-list-view.service.spec.ts b/src-ui/src/app/services/document-list-view.service.spec.ts index 6258c42b2..de574d6d3 100644 --- a/src-ui/src/app/services/document-list-view.service.spec.ts +++ b/src-ui/src/app/services/document-list-view.service.spec.ts @@ -126,13 +126,10 @@ describe('DocumentListViewService', () => { expect(documentListViewService.currentPage).toEqual(1) documentListViewService.reload() const req = httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true` + `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true&include_selection_data=true` ) expect(req.request.method).toEqual('GET') req.flush(full_results) - httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/selection_data/` - ) expect(req.request.method).toEqual('GET') expect(documentListViewService.isReloading).toBeFalsy() expect(documentListViewService.activeSavedViewId).toBeNull() @@ -144,12 +141,12 @@ describe('DocumentListViewService', () => { it('should handle error on page request out of range', () => { documentListViewService.currentPage = 50 let req = httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/?page=50&page_size=50&ordering=-created&truncate_content=true` + `${environment.apiBaseUrl}documents/?page=50&page_size=50&ordering=-created&truncate_content=true&include_selection_data=true` ) expect(req.request.method).toEqual('GET') req.flush([], { status: 404, statusText: 'Unexpected error' }) req = httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true` + `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true&include_selection_data=true` ) expect(req.request.method).toEqual('GET') expect(documentListViewService.currentPage).toEqual(1) @@ -166,7 +163,7 @@ describe('DocumentListViewService', () => { ] documentListViewService.setFilterRules(filterRulesAny) let req = httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true&tags__id__in=${tags__id__in}` + `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true&include_selection_data=true&tags__id__in=${tags__id__in}` ) expect(req.request.method).toEqual('GET') req.flush( @@ -174,13 +171,13 @@ describe('DocumentListViewService', () => { { status: 404, statusText: 'Unexpected error' } ) req = httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true` + `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true&include_selection_data=true` ) expect(req.request.method).toEqual('GET') // reset the list documentListViewService.setFilterRules([]) req = httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true` + `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true&include_selection_data=true` ) }) @@ -188,7 +185,7 @@ describe('DocumentListViewService', () => { documentListViewService.currentPage = 1 documentListViewService.sortField = 'custom_field_999' let req = httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-custom_field_999&truncate_content=true` + `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-custom_field_999&truncate_content=true&include_selection_data=true` ) expect(req.request.method).toEqual('GET') req.flush( @@ -197,7 +194,7 @@ describe('DocumentListViewService', () => { ) // resets itself req = httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true` + `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true&include_selection_data=true` ) }) @@ -212,7 +209,7 @@ describe('DocumentListViewService', () => { ] documentListViewService.setFilterRules(filterRulesAny) let req = httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true&tags__id__in=${tags__id__in}` + `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true&include_selection_data=true&tags__id__in=${tags__id__in}` ) expect(req.request.method).toEqual('GET') req.flush('Generic error', { status: 404, statusText: 'Unexpected error' }) @@ -220,7 +217,7 @@ describe('DocumentListViewService', () => { // reset the list documentListViewService.setFilterRules([]) req = httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true` + `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true&include_selection_data=true` ) }) @@ -229,7 +226,7 @@ describe('DocumentListViewService', () => { expect(documentListViewService.sortReverse).toBeTruthy() documentListViewService.setSort('added', false) let req = httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=added&truncate_content=true` + `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=added&truncate_content=true&include_selection_data=true` ) expect(req.request.method).toEqual('GET') expect(documentListViewService.sortField).toEqual('added') @@ -237,12 +234,12 @@ describe('DocumentListViewService', () => { documentListViewService.sortField = 'created' req = httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=created&truncate_content=true` + `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=created&truncate_content=true&include_selection_data=true` ) expect(documentListViewService.sortField).toEqual('created') documentListViewService.sortReverse = true req = httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true` + `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true&include_selection_data=true` ) expect(req.request.method).toEqual('GET') expect(documentListViewService.sortReverse).toBeTruthy() @@ -262,7 +259,7 @@ describe('DocumentListViewService', () => { const req = httpTestingController.expectOne( `${environment.apiBaseUrl}documents/?page=${page}&page_size=${ documentListViewService.pageSize - }&ordering=${reverse ? '-' : ''}${sort}&truncate_content=true` + }&ordering=${reverse ? '-' : ''}${sort}&truncate_content=true&include_selection_data=true` ) expect(req.request.method).toEqual('GET') expect(documentListViewService.currentPage).toEqual(page) @@ -279,7 +276,7 @@ describe('DocumentListViewService', () => { } documentListViewService.loadFromQueryParams(convertToParamMap(params)) let req = httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/?page=${documentListViewService.currentPage}&page_size=${documentListViewService.pageSize}&ordering=-added&truncate_content=true&tags__id__all=${tags__id__all}` + `${environment.apiBaseUrl}documents/?page=${documentListViewService.currentPage}&page_size=${documentListViewService.pageSize}&ordering=-added&truncate_content=true&include_selection_data=true&tags__id__all=${tags__id__all}` ) expect(req.request.method).toEqual('GET') expect(documentListViewService.filterRules).toEqual([ @@ -289,15 +286,12 @@ describe('DocumentListViewService', () => { }, ]) req.flush(full_results) - httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/selection_data/` - ) }) it('should use filter rules to update query params', () => { documentListViewService.setFilterRules(filterRules) const req = httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/?page=${documentListViewService.currentPage}&page_size=${documentListViewService.pageSize}&ordering=-created&truncate_content=true&tags__id__all=${tags__id__all}` + `${environment.apiBaseUrl}documents/?page=${documentListViewService.currentPage}&page_size=${documentListViewService.pageSize}&ordering=-created&truncate_content=true&include_selection_data=true&tags__id__all=${tags__id__all}` ) expect(req.request.method).toEqual('GET') }) @@ -306,34 +300,26 @@ describe('DocumentListViewService', () => { documentListViewService.currentPage = 2 let req = httpTestingController.expectOne((request) => request.urlWithParams.startsWith( - `${environment.apiBaseUrl}documents/?page=2&page_size=50&ordering=-created&truncate_content=true` + `${environment.apiBaseUrl}documents/?page=2&page_size=50&ordering=-created&truncate_content=true&include_selection_data=true` ) ) expect(req.request.method).toEqual('GET') req.flush(full_results) - req = httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/selection_data/` - ) - req.flush([]) documentListViewService.setFilterRules(filterRules, true) const filteredReqs = httpTestingController.match( - `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true&tags__id__all=${tags__id__all}` + `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true&include_selection_data=true&tags__id__all=${tags__id__all}` ) expect(filteredReqs).toHaveLength(1) filteredReqs[0].flush(full_results) - req = httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/selection_data/` - ) - req.flush([]) expect(documentListViewService.currentPage).toEqual(1) }) it('should support quick filter', () => { documentListViewService.quickFilter(filterRules) const req = httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/?page=${documentListViewService.currentPage}&page_size=${documentListViewService.pageSize}&ordering=-created&truncate_content=true&tags__id__all=${tags__id__all}` + `${environment.apiBaseUrl}documents/?page=${documentListViewService.currentPage}&page_size=${documentListViewService.pageSize}&ordering=-created&truncate_content=true&include_selection_data=true&tags__id__all=${tags__id__all}` ) expect(req.request.method).toEqual('GET') }) @@ -356,21 +342,21 @@ describe('DocumentListViewService', () => { convertToParamMap(params) ) let req = httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/?page=${page}&page_size=${documentListViewService.pageSize}&ordering=-added&truncate_content=true&tags__id__all=${tags__id__all}` + `${environment.apiBaseUrl}documents/?page=${page}&page_size=${documentListViewService.pageSize}&ordering=-added&truncate_content=true&include_selection_data=true&tags__id__all=${tags__id__all}` ) expect(req.request.method).toEqual('GET') // reset the list documentListViewService.currentPage = 1 req = httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-added&truncate_content=true&tags__id__all=9` + `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-added&truncate_content=true&include_selection_data=true&tags__id__all=9` ) documentListViewService.setFilterRules([]) req = httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-added&truncate_content=true` + `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-added&truncate_content=true&include_selection_data=true` ) documentListViewService.sortField = 'created' req = httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true` + `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true&include_selection_data=true` ) documentListViewService.activateSavedView(null) }) @@ -378,21 +364,18 @@ describe('DocumentListViewService', () => { it('should support navigating next / previous', () => { documentListViewService.setFilterRules([]) let req = httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true` + `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true&include_selection_data=true` ) expect(documentListViewService.currentPage).toEqual(1) documentListViewService.pageSize = 3 req = httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/?page=1&page_size=3&ordering=-created&truncate_content=true` + `${environment.apiBaseUrl}documents/?page=1&page_size=3&ordering=-created&truncate_content=true&include_selection_data=true` ) expect(req.request.method).toEqual('GET') req.flush({ count: 3, results: documents.slice(0, 3), }) - httpTestingController - .expectOne(`${environment.apiBaseUrl}documents/selection_data/`) - .flush([]) expect(documentListViewService.hasNext(documents[0].id)).toBeTruthy() expect(documentListViewService.hasPrevious(documents[0].id)).toBeFalsy() documentListViewService.getNext(documents[0].id).subscribe((docId) => { @@ -439,7 +422,7 @@ describe('DocumentListViewService', () => { expect(documentListViewService.currentPage).toEqual(1) documentListViewService.pageSize = 3 httpTestingController.match( - `${environment.apiBaseUrl}documents/?page=1&page_size=3&ordering=-created&truncate_content=true` + `${environment.apiBaseUrl}documents/?page=1&page_size=3&ordering=-created&truncate_content=true&include_selection_data=true` ) jest .spyOn(documentListViewService, 'getLastPage') @@ -454,7 +437,7 @@ describe('DocumentListViewService', () => { expect(reloadSpy).toHaveBeenCalled() expect(documentListViewService.currentPage).toEqual(2) const reqs = httpTestingController.match( - `${environment.apiBaseUrl}documents/?page=2&page_size=3&ordering=-created&truncate_content=true` + `${environment.apiBaseUrl}documents/?page=2&page_size=3&ordering=-created&truncate_content=true&include_selection_data=true` ) expect(reqs.length).toBeGreaterThan(0) }) @@ -489,11 +472,11 @@ describe('DocumentListViewService', () => { .mockReturnValue(documents) documentListViewService.currentPage = 2 httpTestingController.match( - `${environment.apiBaseUrl}documents/?page=2&page_size=50&ordering=-created&truncate_content=true` + `${environment.apiBaseUrl}documents/?page=2&page_size=50&ordering=-created&truncate_content=true&include_selection_data=true` ) documentListViewService.pageSize = 3 httpTestingController.match( - `${environment.apiBaseUrl}documents/?page=2&page_size=3&ordering=-created&truncate_content=true` + `${environment.apiBaseUrl}documents/?page=2&page_size=3&ordering=-created&truncate_content=true&include_selection_data=true` ) const reloadSpy = jest.spyOn(documentListViewService, 'reload') documentListViewService.getPrevious(1).subscribe({ @@ -503,7 +486,7 @@ describe('DocumentListViewService', () => { expect(reloadSpy).toHaveBeenCalled() expect(documentListViewService.currentPage).toEqual(1) const reqs = httpTestingController.match( - `${environment.apiBaseUrl}documents/?page=1&page_size=3&ordering=-created&truncate_content=true` + `${environment.apiBaseUrl}documents/?page=1&page_size=3&ordering=-created&truncate_content=true&include_selection_data=true` ) expect(reqs.length).toBeGreaterThan(0) }) @@ -516,13 +499,10 @@ describe('DocumentListViewService', () => { it('should support select a document', () => { documentListViewService.reload() const req = httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true` + `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true&include_selection_data=true` ) expect(req.request.method).toEqual('GET') req.flush(full_results) - httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/selection_data/` - ) documentListViewService.toggleSelected(documents[0]) expect(documentListViewService.isSelected(documents[0])).toBeTruthy() documentListViewService.toggleSelected(documents[0]) @@ -544,16 +524,13 @@ describe('DocumentListViewService', () => { it('should support select page', () => { documentListViewService.pageSize = 3 const req = httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/?page=1&page_size=3&ordering=-created&truncate_content=true` + `${environment.apiBaseUrl}documents/?page=1&page_size=3&ordering=-created&truncate_content=true&include_selection_data=true` ) expect(req.request.method).toEqual('GET') req.flush({ count: 3, results: documents.slice(0, 3), }) - httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/selection_data/` - ) documentListViewService.selectPage() expect(documentListViewService.selected.size).toEqual(3) expect(documentListViewService.isSelected(documents[5])).toBeFalsy() @@ -562,13 +539,10 @@ describe('DocumentListViewService', () => { it('should support select range', () => { documentListViewService.reload() const req = httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true` + `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true&include_selection_data=true` ) expect(req.request.method).toEqual('GET') req.flush(full_results) - httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/selection_data/` - ) documentListViewService.toggleSelected(documents[0]) expect(documentListViewService.isSelected(documents[0])).toBeTruthy() documentListViewService.selectRangeTo(documents[2]) @@ -588,7 +562,7 @@ describe('DocumentListViewService', () => { documentListViewService.setFilterRules(filterRules) httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true&tags__id__all=9` + `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true&include_selection_data=true&tags__id__all=9` ) const reqs = httpTestingController.match( `${environment.apiBaseUrl}documents/?page=1&page_size=100000&fields=id&tags__id__all=9` @@ -604,7 +578,7 @@ describe('DocumentListViewService', () => { const cancelSpy = jest.spyOn(documentListViewService, 'cancelPending') documentListViewService.reload() httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true&tags__id__all=9` + `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true&include_selection_data=true&tags__id__all=9` ) expect(cancelSpy).toHaveBeenCalled() }) @@ -623,7 +597,7 @@ describe('DocumentListViewService', () => { documentListViewService.setFilterRules([]) expect(documentListViewService.sortField).toEqual('created') httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true` + `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true&include_selection_data=true` ) }) @@ -650,11 +624,11 @@ describe('DocumentListViewService', () => { expect(localStorageSpy).toHaveBeenCalled() // reload triggered httpTestingController.match( - `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true` + `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true&include_selection_data=true` ) documentListViewService.displayFields = null httpTestingController.match( - `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true` + `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true&include_selection_data=true` ) expect(documentListViewService.displayFields).toEqual( DEFAULT_DISPLAY_FIELDS.filter((f) => f.id !== DisplayField.ADDED).map( @@ -694,7 +668,7 @@ describe('DocumentListViewService', () => { it('should generate quick filter URL preserving default state', () => { documentListViewService.reload() httpTestingController.expectOne( - `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true` + `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true&include_selection_data=true` ) const urlTree = documentListViewService.getQuickFilterUrl(filterRules) expect(urlTree).toBeDefined() 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 6989db8ed..9413d3562 100644 --- a/src-ui/src/app/services/document-list-view.service.ts +++ b/src-ui/src/app/services/document-list-view.service.ts @@ -1,6 +1,6 @@ import { Injectable, inject } from '@angular/core' import { ParamMap, Router, UrlTree } from '@angular/router' -import { Observable, Subject, first, takeUntil } from 'rxjs' +import { Observable, Subject, takeUntil } from 'rxjs' import { DEFAULT_DISPLAY_FIELDS, DisplayField, @@ -8,6 +8,7 @@ import { Document, } from '../data/document' import { FilterRule } from '../data/filter-rule' +import { DocumentResults, SelectionData } from '../data/results' import { SavedView } from '../data/saved-view' import { DOCUMENT_LIST_SERVICE } from '../data/storage-keys' import { SETTINGS_KEYS } from '../data/ui-settings' @@ -17,7 +18,7 @@ import { isFullTextFilterRule, } from '../utils/filter-rules' import { paramsFromViewState, paramsToViewState } from '../utils/query-params' -import { DocumentService, SelectionData } from './rest/document.service' +import { DocumentService } from './rest/document.service' import { SettingsService } from './settings.service' const LIST_DEFAULT_DISPLAY_FIELDS: DisplayField[] = DEFAULT_DISPLAY_FIELDS.map( @@ -260,27 +261,17 @@ export class DocumentListViewService { activeListViewState.sortField, activeListViewState.sortReverse, activeListViewState.filterRules, - { truncate_content: true } + { truncate_content: true, include_selection_data: true } ) .pipe(takeUntil(this.unsubscribeNotifier)) .subscribe({ next: (result) => { + const resultWithSelectionData = result as DocumentResults this.initialized = true this.isReloading = false activeListViewState.collectionSize = result.count activeListViewState.documents = result.results - - this.documentService - .getSelectionData(result.all) - .pipe(first()) - .subscribe({ - next: (selectionData) => { - this.selectionData = selectionData - }, - error: () => { - this.selectionData = null - }, - }) + this.selectionData = resultWithSelectionData.selection_data ?? null if (updateQueryParams && !this._activeSavedViewId) { let base = ['/documents'] diff --git a/src-ui/src/app/services/rest/document.service.ts b/src-ui/src/app/services/rest/document.service.ts index 971396bac..203b35341 100644 --- a/src-ui/src/app/services/rest/document.service.ts +++ b/src-ui/src/app/services/rest/document.service.ts @@ -12,7 +12,7 @@ import { import { DocumentMetadata } from 'src/app/data/document-metadata' import { DocumentSuggestions } from 'src/app/data/document-suggestions' import { FilterRule } from 'src/app/data/filter-rule' -import { Results } from 'src/app/data/results' +import { Results, SelectionData } from 'src/app/data/results' import { SETTINGS_KEYS } from 'src/app/data/ui-settings' import { queryParamsFromFilterRules } from '../../utils/query-params' import { @@ -24,19 +24,6 @@ import { SettingsService } from '../settings.service' import { AbstractPaperlessService } from './abstract-paperless-service' import { CustomFieldsService } from './custom-fields.service' -export interface SelectionDataItem { - id: number - document_count: number -} - -export interface SelectionData { - selected_storage_paths: SelectionDataItem[] - selected_correspondents: SelectionDataItem[] - selected_tags: SelectionDataItem[] - selected_document_types: SelectionDataItem[] - selected_custom_fields: SelectionDataItem[] -} - export enum BulkEditSourceMode { LATEST_VERSION = 'latest_version', EXPLICIT_SELECTION = 'explicit_selection', diff --git a/src/documents/views.py b/src/documents/views.py index d3a856a8e..d401e80d7 100644 --- a/src/documents/views.py +++ b/src/documents/views.py @@ -2698,6 +2698,7 @@ class PostDocumentView(GenericAPIView): @extend_schema_view( post=extend_schema( + deprecated=True, description="Get selection data for the selected documents", responses={ (200, "application/json"): inline_serializer( @@ -2753,6 +2754,7 @@ class PostDocumentView(GenericAPIView): }, ), ) +# TODO: remove class SelectionDataView(GenericAPIView): permission_classes = (IsAuthenticated,) serializer_class = DocumentListSerializer