Basic frontend

This commit is contained in:
shamoon 2024-12-11 01:56:53 -08:00
parent a7a4ca86bd
commit 3dbc9d9fc1
3 changed files with 116 additions and 10 deletions

View File

@ -11,6 +11,7 @@ import { SavedView } from 'src/app/data/saved-view'
import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive' import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive'
import { PermissionsGuard } from 'src/app/guards/permissions.guard' import { PermissionsGuard } from 'src/app/guards/permissions.guard'
import { PermissionsService } from 'src/app/services/permissions.service' import { PermissionsService } from 'src/app/services/permissions.service'
import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service'
import { SavedViewService } from 'src/app/services/rest/saved-view.service' import { SavedViewService } from 'src/app/services/rest/saved-view.service'
import { ToastService } from 'src/app/services/toast.service' import { ToastService } from 'src/app/services/toast.service'
import { ConfirmButtonComponent } from '../../common/confirm-button/confirm-button.component' import { ConfirmButtonComponent } from '../../common/confirm-button/confirm-button.component'
@ -60,6 +61,17 @@ describe('SavedViewsComponent', () => {
currentUserCan: () => true, currentUserCan: () => true,
}, },
}, },
{
provide: CustomFieldsService,
useValue: {
listAll: () =>
of({
all: [],
count: 0,
results: [],
}),
},
},
PermissionsGuard, PermissionsGuard,
provideHttpClient(withInterceptorsFromDi()), provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(), provideHttpClientTesting(),

View File

@ -4,7 +4,8 @@ import {
provideHttpClientTesting, provideHttpClientTesting,
} from '@angular/common/http/testing' } from '@angular/common/http/testing'
import { TestBed } from '@angular/core/testing' import { TestBed } from '@angular/core/testing'
import { Subscription } from 'rxjs' import { of, Subscription } from 'rxjs'
import { CustomFieldDataType } from 'src/app/data/custom-field'
import { import {
DOCUMENT_SORT_FIELDS, DOCUMENT_SORT_FIELDS,
DOCUMENT_SORT_FIELDS_FULLTEXT, DOCUMENT_SORT_FIELDS_FULLTEXT,
@ -14,12 +15,15 @@ import { SETTINGS_KEYS } from 'src/app/data/ui-settings'
import { environment } from 'src/environments/environment' import { environment } from 'src/environments/environment'
import { PermissionsService } from '../permissions.service' import { PermissionsService } from '../permissions.service'
import { SettingsService } from '../settings.service' import { SettingsService } from '../settings.service'
import { CustomFieldsService } from './custom-fields.service'
import { DocumentService } from './document.service' import { DocumentService } from './document.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
let permissionsService: PermissionsService
let customFieldsService: CustomFieldsService
const endpoint = 'documents' const endpoint = 'documents'
const documents = [ const documents = [
@ -55,8 +59,29 @@ beforeEach(() => {
}) })
httpTestingController = TestBed.inject(HttpTestingController) httpTestingController = TestBed.inject(HttpTestingController)
service = TestBed.inject(DocumentService)
settingsService = TestBed.inject(SettingsService) settingsService = TestBed.inject(SettingsService)
customFieldsService = TestBed.inject(CustomFieldsService)
permissionsService = TestBed.inject(PermissionsService)
jest.spyOn(permissionsService, 'currentUserCan').mockReturnValue(true)
jest.spyOn(customFieldsService, 'listAll').mockReturnValue(
of({
all: [1, 2, 3],
count: 3,
results: [
{
id: 1,
name: 'Custom Field 1',
data_type: CustomFieldDataType.String,
},
{
id: 2,
name: 'Custom Field 2',
data_type: CustomFieldDataType.Integer,
},
],
})
)
service = TestBed.inject(DocumentService)
}) })
describe(`DocumentService`, () => { describe(`DocumentService`, () => {
@ -289,18 +314,25 @@ describe(`DocumentService`, () => {
it('should construct sort fields respecting permissions', () => { it('should construct sort fields respecting permissions', () => {
expect( expect(
service.sortFields.find((f) => f.field === 'correspondent__name') service.sortFields.find((f) => f.field === 'correspondent__name')
).toBeUndefined() ).not.toBeUndefined()
expect( expect(
service.sortFields.find((f) => f.field === 'document_type__name') service.sortFields.find((f) => f.field === 'document_type__name')
).toBeUndefined() ).not.toBeUndefined()
expect(
service.sortFields.find((f) => f.field === 'owner')
).not.toBeUndefined()
const permissionsService: PermissionsService = jest.spyOn(permissionsService, 'currentUserCan').mockReturnValue(false)
TestBed.inject(PermissionsService)
jest.spyOn(permissionsService, 'currentUserCan').mockReturnValue(true)
service['setupSortFields']() service['setupSortFields']()
expect(service.sortFields).toEqual(DOCUMENT_SORT_FIELDS) const fields = DOCUMENT_SORT_FIELDS.filter(
(f) =>
['correspondent__name', 'document_type__name', 'owner'].indexOf(
f.field
) === -1
)
expect(service.sortFields).toEqual(fields)
expect(service.sortFieldsFullText).toEqual([ expect(service.sortFieldsFullText).toEqual([
...DOCUMENT_SORT_FIELDS, ...fields,
...DOCUMENT_SORT_FIELDS_FULLTEXT, ...DOCUMENT_SORT_FIELDS_FULLTEXT,
]) ])
@ -311,6 +343,38 @@ it('should construct sort fields respecting permissions', () => {
).toBeUndefined() ).toBeUndefined()
}) })
it('should include custom fields in sort fields if user has permission', () => {
const permissionsService: PermissionsService =
TestBed.inject(PermissionsService)
jest.spyOn(permissionsService, 'currentUserCan').mockReturnValue(true)
service['customFields'] = [
{
id: 1,
name: 'Custom Field 1',
data_type: CustomFieldDataType.String,
},
{
id: 2,
name: 'Custom Field 2',
data_type: CustomFieldDataType.Integer,
},
]
service['setupSortFields']()
expect(service.sortFields).toEqual([
...DOCUMENT_SORT_FIELDS,
{
field: 'custom_field_1',
name: 'Custom Field 1',
},
{
field: 'custom_field_2',
name: 'Custom Field 2',
},
])
})
afterEach(() => { afterEach(() => {
subscription?.unsubscribe() subscription?.unsubscribe()
httpTestingController.verify() httpTestingController.verify()

View File

@ -3,6 +3,7 @@ import { Injectable } from '@angular/core'
import { Observable } from 'rxjs' import { Observable } from 'rxjs'
import { map, tap } from 'rxjs/operators' import { map, tap } from 'rxjs/operators'
import { AuditLogEntry } from 'src/app/data/auditlog-entry' import { AuditLogEntry } from 'src/app/data/auditlog-entry'
import { CustomField } from 'src/app/data/custom-field'
import { import {
DOCUMENT_SORT_FIELDS, DOCUMENT_SORT_FIELDS,
DOCUMENT_SORT_FIELDS_FULLTEXT, DOCUMENT_SORT_FIELDS_FULLTEXT,
@ -22,6 +23,7 @@ import {
import { SettingsService } from '../settings.service' import { SettingsService } from '../settings.service'
import { AbstractPaperlessService } from './abstract-paperless-service' import { AbstractPaperlessService } from './abstract-paperless-service'
import { CorrespondentService } from './correspondent.service' import { CorrespondentService } from './correspondent.service'
import { CustomFieldsService } from './custom-fields.service'
import { DocumentTypeService } from './document-type.service' import { DocumentTypeService } from './document-type.service'
import { StoragePathService } from './storage-path.service' import { StoragePathService } from './storage-path.service'
import { TagService } from './tag.service' import { TagService } from './tag.service'
@ -55,6 +57,8 @@ export class DocumentService extends AbstractPaperlessService<Document> {
return this._sortFieldsFullText return this._sortFieldsFullText
} }
private customFields: CustomField[] = []
constructor( constructor(
http: HttpClient, http: HttpClient,
private correspondentService: CorrespondentService, private correspondentService: CorrespondentService,
@ -62,14 +66,40 @@ export class DocumentService extends AbstractPaperlessService<Document> {
private tagService: TagService, private tagService: TagService,
private storagePathService: StoragePathService, private storagePathService: StoragePathService,
private permissionsService: PermissionsService, private permissionsService: PermissionsService,
private settingsService: SettingsService private settingsService: SettingsService,
private customFieldService: CustomFieldsService
) { ) {
super(http, 'documents') super(http, 'documents')
if (
this.permissionsService.currentUserCan(
PermissionAction.View,
PermissionType.CustomField
)
) {
this.customFieldService.listAll().subscribe((fields) => {
this.customFields = fields.results
this.setupSortFields()
})
}
this.setupSortFields() this.setupSortFields()
} }
private setupSortFields() { private setupSortFields() {
this._sortFields = [...DOCUMENT_SORT_FIELDS] this._sortFields = [...DOCUMENT_SORT_FIELDS]
if (
this.permissionsService.currentUserCan(
PermissionAction.View,
PermissionType.CustomField
)
) {
this.customFields.forEach((field) => {
this._sortFields.push({
field: `custom_field_${field.id}`,
name: field.name,
})
})
}
let excludes = [] let excludes = []
if ( if (
!this.permissionsService.currentUserCan( !this.permissionsService.currentUserCan(