Hide sort fields if insufficient permissions

This commit is contained in:
shamoon 2024-04-19 09:53:25 -07:00
parent 89acce9507
commit 6f546b9cba
7 changed files with 252 additions and 351 deletions

File diff suppressed because it is too large Load Diff

View File

@ -53,11 +53,7 @@ import {
DisplayMode, DisplayMode,
Document, Document,
} from 'src/app/data/document' } from 'src/app/data/document'
import { import { DocumentService } from 'src/app/services/rest/document.service'
DOCUMENT_SORT_FIELDS,
DOCUMENT_SORT_FIELDS_FULLTEXT,
DocumentService,
} from 'src/app/services/rest/document.service'
import { ConfirmDialogComponent } from '../common/confirm-dialog/confirm-dialog.component' import { ConfirmDialogComponent } from '../common/confirm-dialog/confirm-dialog.component'
import { SafeHtmlPipe } from 'src/app/pipes/safehtml.pipe' import { SafeHtmlPipe } from 'src/app/pipes/safehtml.pipe'
import { SaveViewConfigDialogComponent } from './save-view-config-dialog/save-view-config-dialog.component' import { SaveViewConfigDialogComponent } from './save-view-config-dialog/save-view-config-dialog.component'
@ -193,7 +189,7 @@ describe('DocumentListComponent', () => {
}, },
] ]
fixture.detectChanges() fixture.detectChanges()
expect(component.getSortFields()).toEqual(DOCUMENT_SORT_FIELDS) expect(component.getSortFields()).toEqual(documentListService.sortFields)
documentListService.filterRules = [ documentListService.filterRules = [
{ {
@ -202,7 +198,9 @@ describe('DocumentListComponent', () => {
}, },
] ]
fixture.detectChanges() fixture.detectChanges()
expect(component.getSortFields()).toEqual(DOCUMENT_SORT_FIELDS_FULLTEXT) expect(component.getSortFields()).toEqual(
documentListService.sortFieldsFullText
)
}) })
it('should determine if filtered, support reset', () => { it('should determine if filtered, support reset', () => {

View File

@ -25,10 +25,6 @@ import {
import { ConsumerStatusService } from 'src/app/services/consumer-status.service' import { ConsumerStatusService } from 'src/app/services/consumer-status.service'
import { DocumentListViewService } from 'src/app/services/document-list-view.service' import { DocumentListViewService } from 'src/app/services/document-list-view.service'
import { OpenDocumentsService } from 'src/app/services/open-documents.service' import { OpenDocumentsService } from 'src/app/services/open-documents.service'
import {
DOCUMENT_SORT_FIELDS,
DOCUMENT_SORT_FIELDS_FULLTEXT,
} from 'src/app/services/rest/document.service'
import { PermissionsService } from 'src/app/services/permissions.service' import { PermissionsService } from 'src/app/services/permissions.service'
import { SavedViewService } from 'src/app/services/rest/saved-view.service' import { SavedViewService } from 'src/app/services/rest/saved-view.service'
import { SettingsService } from 'src/app/services/settings.service' import { SettingsService } from 'src/app/services/settings.service'
@ -131,8 +127,8 @@ export class DocumentListComponent
getSortFields() { getSortFields() {
return isFullTextFilterRule(this.list.filterRules) return isFullTextFilterRule(this.list.filterRules)
? DOCUMENT_SORT_FIELDS_FULLTEXT ? this.list.sortFieldsFullText
: DOCUMENT_SORT_FIELDS : this.list.sortFields
} }
set listSortReverse(reverse: boolean) { set listSortReverse(reverse: boolean) {

View File

@ -84,6 +84,25 @@ export const DEFAULT_DASHBOARD_DISPLAY_FIELDS = [
DisplayField.CORRESPONDENT, DisplayField.CORRESPONDENT,
] ]
export const DOCUMENT_SORT_FIELDS = [
{ field: 'archive_serial_number', name: $localize`ASN` },
{ field: 'correspondent__name', name: $localize`Correspondent` },
{ field: 'title', name: $localize`Title` },
{ field: 'document_type__name', name: $localize`Document type` },
{ field: 'created', name: $localize`Created` },
{ field: 'added', name: $localize`Added` },
{ field: 'modified', name: $localize`Modified` },
{ field: 'num_notes', name: $localize`Notes` },
{ field: 'owner', name: $localize`Owner` },
]
export const DOCUMENT_SORT_FIELDS_FULLTEXT = [
{
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 SearchHit { export interface SearchHit {
score?: number score?: number
rank?: number rank?: number

View File

@ -17,11 +17,7 @@ import { SavedView } from '../data/saved-view'
import { SETTINGS_KEYS } from '../data/ui-settings' import { SETTINGS_KEYS } from '../data/ui-settings'
import { DOCUMENT_LIST_SERVICE } from '../data/storage-keys' import { DOCUMENT_LIST_SERVICE } from '../data/storage-keys'
import { paramsFromViewState, paramsToViewState } from '../utils/query-params' import { paramsFromViewState, paramsToViewState } from '../utils/query-params'
import { import { DocumentService, SelectionData } from './rest/document.service'
DocumentService,
DOCUMENT_SORT_FIELDS,
SelectionData,
} from './rest/document.service'
import { SettingsService } from './settings.service' import { SettingsService } from './settings.service'
/** /**
@ -302,9 +298,8 @@ export class DocumentListViewService {
errorMessage = Object.keys(error.error) errorMessage = Object.keys(error.error)
.map((fieldName) => { .map((fieldName) => {
const fieldError: Array<string> = error.error[fieldName] const fieldError: Array<string> = error.error[fieldName]
return `${DOCUMENT_SORT_FIELDS.find( return `${this.sortFields.find((f) => f.field == fieldName)
(f) => f.field == fieldName ?.name}: ${fieldError[0]}`
)?.name}: ${fieldError[0]}`
}) })
.join(', ') .join(', ')
} else { } else {
@ -333,6 +328,14 @@ export class DocumentListViewService {
return this.activeListViewState.filterRules return this.activeListViewState.filterRules
} }
get sortFields(): any[] {
return this.documentService.sortFields
}
get sortFieldsFullText(): any[] {
return this.documentService.sortFieldsFullText
}
set sortField(field: string) { set sortField(field: string) {
this.activeListViewState.sortField = field this.activeListViewState.sortField = field
this.reload() this.reload()

View File

@ -9,11 +9,17 @@ import { DocumentService } from './document.service'
import { FILTER_TITLE } from 'src/app/data/filter-rule-type' import { FILTER_TITLE } from 'src/app/data/filter-rule-type'
import { SettingsService } from '../settings.service' import { SettingsService } from '../settings.service'
import { SETTINGS_KEYS } from 'src/app/data/ui-settings' import { SETTINGS_KEYS } from 'src/app/data/ui-settings'
import {
DOCUMENT_SORT_FIELDS,
DOCUMENT_SORT_FIELDS_FULLTEXT,
} from 'src/app/data/document'
import { PermissionsService } from '../permissions.service'
let httpTestingController: HttpTestingController let httpTestingController: HttpTestingController
let service: DocumentService let service: DocumentService
let subscription: Subscription let subscription: Subscription
let settingsService: SettingsService let settingsService: SettingsService
const endpoint = 'documents' const endpoint = 'documents'
const documents = [ const documents = [
{ {
@ -275,6 +281,25 @@ describe(`DocumentService`, () => {
}) })
}) })
it('should construct sort fields respecting permissions', () => {
expect(
service.sortFields.find((f) => f.field === 'correspondent__name')
).toBeUndefined()
expect(
service.sortFields.find((f) => f.field === 'document_type__name')
).toBeUndefined()
const permissionsService: PermissionsService =
TestBed.inject(PermissionsService)
jest.spyOn(permissionsService, 'currentUserCan').mockReturnValue(true)
service['setupSortFields']()
expect(service.sortFields).toEqual(DOCUMENT_SORT_FIELDS)
expect(service.sortFieldsFullText).toEqual([
...DOCUMENT_SORT_FIELDS,
...DOCUMENT_SORT_FIELDS_FULLTEXT,
])
})
afterEach(() => { afterEach(() => {
subscription?.unsubscribe() subscription?.unsubscribe()
httpTestingController.verify() httpTestingController.verify()

View File

@ -1,5 +1,9 @@
import { Injectable } from '@angular/core' import { Injectable } from '@angular/core'
import { Document } from 'src/app/data/document' import {
DOCUMENT_SORT_FIELDS,
DOCUMENT_SORT_FIELDS_FULLTEXT,
Document,
} from 'src/app/data/document'
import { DocumentMetadata } from 'src/app/data/document-metadata' import { DocumentMetadata } from 'src/app/data/document-metadata'
import { AbstractPaperlessService } from './abstract-paperless-service' import { AbstractPaperlessService } from './abstract-paperless-service'
import { HttpClient } from '@angular/common/http' import { HttpClient } from '@angular/common/http'
@ -22,26 +26,6 @@ import { SettingsService } from '../settings.service'
import { SETTINGS_KEYS } from 'src/app/data/ui-settings' import { SETTINGS_KEYS } from 'src/app/data/ui-settings'
import { AuditLogEntry } from 'src/app/data/auditlog-entry' import { AuditLogEntry } from 'src/app/data/auditlog-entry'
export const DOCUMENT_SORT_FIELDS = [
{ field: 'archive_serial_number', name: $localize`ASN` },
{ field: 'correspondent__name', name: $localize`Correspondent` },
{ field: 'title', name: $localize`Title` },
{ field: 'document_type__name', name: $localize`Document type` },
{ field: 'created', name: $localize`Created` },
{ field: 'added', name: $localize`Added` },
{ field: 'modified', name: $localize`Modified` },
{ field: 'num_notes', name: $localize`Notes` },
{ field: 'owner', name: $localize`Owner` },
]
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 { export interface SelectionDataItem {
id: number id: number
document_count: number document_count: number
@ -60,6 +44,16 @@ export interface SelectionData {
export class DocumentService extends AbstractPaperlessService<Document> { export class DocumentService extends AbstractPaperlessService<Document> {
private _searchQuery: string private _searchQuery: string
private _sortFields
get sortFields() {
return this._sortFields
}
private _sortFieldsFullText
get sortFieldsFullText() {
return this._sortFieldsFullText
}
constructor( constructor(
http: HttpClient, http: HttpClient,
private correspondentService: CorrespondentService, private correspondentService: CorrespondentService,
@ -70,6 +64,35 @@ export class DocumentService extends AbstractPaperlessService<Document> {
private settingsService: SettingsService private settingsService: SettingsService
) { ) {
super(http, 'documents') super(http, 'documents')
this.setupSortFields()
}
private setupSortFields() {
this._sortFields = [...DOCUMENT_SORT_FIELDS]
if (
!this.permissionsService.currentUserCan(
PermissionAction.View,
PermissionType.Correspondent
)
) {
this._sortFields = this._sortFields.filter(
(field) => field.field !== 'correspondent__name'
)
}
if (
!this.permissionsService.currentUserCan(
PermissionAction.View,
PermissionType.DocumentType
)
) {
this._sortFields = this._sortFields.filter(
(field) => field.field !== 'document_type__name'
)
}
this._sortFieldsFullText = [
...this._sortFields,
...DOCUMENT_SORT_FIELDS_FULLTEXT,
]
} }
addObservablesToDocument(doc: Document) { addObservablesToDocument(doc: Document) {