mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-05-01 11:19:32 -05:00
Feature: improve history display of object names etc (#7102)
This commit is contained in:
parent
d92659a63d
commit
2b024dc72e
@ -48,7 +48,7 @@
|
|||||||
@if (change.key === 'content') {
|
@if (change.key === 'content') {
|
||||||
<code class="text-primary">{{ change.value[1]?.substring(0,100) }}...</code>
|
<code class="text-primary">{{ change.value[1]?.substring(0,100) }}...</code>
|
||||||
} @else {
|
} @else {
|
||||||
<code class="text-primary">{{ change.value[1] }}</code>
|
<code class="text-primary">{{ getPrettyName(change.key, change.value[1]) | async }}</code>
|
||||||
}
|
}
|
||||||
</li>
|
</li>
|
||||||
}
|
}
|
||||||
|
@ -9,11 +9,20 @@ import { CustomDatePipe } from 'src/app/pipes/custom-date.pipe'
|
|||||||
import { DatePipe } from '@angular/common'
|
import { DatePipe } from '@angular/common'
|
||||||
import { NgbCollapseModule, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbCollapseModule, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
|
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
|
||||||
|
import { CorrespondentService } from 'src/app/services/rest/correspondent.service'
|
||||||
|
import { DocumentTypeService } from 'src/app/services/rest/document-type.service'
|
||||||
|
import { StoragePathService } from 'src/app/services/rest/storage-path.service'
|
||||||
|
import { UserService } from 'src/app/services/rest/user.service'
|
||||||
|
import { DataType } from 'src/app/data/datatype'
|
||||||
|
|
||||||
describe('DocumentHistoryComponent', () => {
|
describe('DocumentHistoryComponent', () => {
|
||||||
let component: DocumentHistoryComponent
|
let component: DocumentHistoryComponent
|
||||||
let fixture: ComponentFixture<DocumentHistoryComponent>
|
let fixture: ComponentFixture<DocumentHistoryComponent>
|
||||||
let documentService: DocumentService
|
let documentService: DocumentService
|
||||||
|
let correspondentService: CorrespondentService
|
||||||
|
let documentTypeService: DocumentTypeService
|
||||||
|
let storagePathService: StoragePathService
|
||||||
|
let userService: UserService
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
@ -29,6 +38,10 @@ describe('DocumentHistoryComponent', () => {
|
|||||||
|
|
||||||
fixture = TestBed.createComponent(DocumentHistoryComponent)
|
fixture = TestBed.createComponent(DocumentHistoryComponent)
|
||||||
documentService = TestBed.inject(DocumentService)
|
documentService = TestBed.inject(DocumentService)
|
||||||
|
correspondentService = TestBed.inject(CorrespondentService)
|
||||||
|
documentTypeService = TestBed.inject(DocumentTypeService)
|
||||||
|
storagePathService = TestBed.inject(StoragePathService)
|
||||||
|
userService = TestBed.inject(UserService)
|
||||||
component = fixture.componentInstance
|
component = fixture.componentInstance
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -55,4 +68,91 @@ describe('DocumentHistoryComponent', () => {
|
|||||||
fixture.detectChanges()
|
fixture.detectChanges()
|
||||||
expect(getHistorySpy).toHaveBeenCalledWith(1)
|
expect(getHistorySpy).toHaveBeenCalledWith(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('getPrettyName should return the correspondent name', () => {
|
||||||
|
const correspondentId = '1'
|
||||||
|
const correspondentName = 'John Doe'
|
||||||
|
const getCachedSpy = jest
|
||||||
|
.spyOn(correspondentService, 'getCached')
|
||||||
|
.mockReturnValue(of({ name: correspondentName }))
|
||||||
|
component
|
||||||
|
.getPrettyName(DataType.Correspondent, correspondentId)
|
||||||
|
.subscribe((result) => {
|
||||||
|
expect(result).toBe(correspondentName)
|
||||||
|
})
|
||||||
|
expect(getCachedSpy).toHaveBeenCalledWith(parseInt(correspondentId))
|
||||||
|
// no correspondent found
|
||||||
|
getCachedSpy.mockReturnValue(of(null))
|
||||||
|
component
|
||||||
|
.getPrettyName(DataType.Correspondent, correspondentId)
|
||||||
|
.subscribe((result) => {
|
||||||
|
expect(result).toBe(correspondentId)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('getPrettyName should return the document type name', () => {
|
||||||
|
const documentTypeId = '1'
|
||||||
|
const documentTypeName = 'Invoice'
|
||||||
|
const getCachedSpy = jest
|
||||||
|
.spyOn(documentTypeService, 'getCached')
|
||||||
|
.mockReturnValue(of({ name: documentTypeName }))
|
||||||
|
component
|
||||||
|
.getPrettyName(DataType.DocumentType, documentTypeId)
|
||||||
|
.subscribe((result) => {
|
||||||
|
expect(result).toBe(documentTypeName)
|
||||||
|
})
|
||||||
|
expect(getCachedSpy).toHaveBeenCalledWith(parseInt(documentTypeId))
|
||||||
|
// no document type found
|
||||||
|
getCachedSpy.mockReturnValue(of(null))
|
||||||
|
component
|
||||||
|
.getPrettyName(DataType.DocumentType, documentTypeId)
|
||||||
|
.subscribe((result) => {
|
||||||
|
expect(result).toBe(documentTypeId)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('getPrettyName should return the storage path path', () => {
|
||||||
|
const storagePathId = '1'
|
||||||
|
const storagePath = '/path/to/storage'
|
||||||
|
const getCachedSpy = jest
|
||||||
|
.spyOn(storagePathService, 'getCached')
|
||||||
|
.mockReturnValue(of({ path: storagePath }))
|
||||||
|
component
|
||||||
|
.getPrettyName(DataType.StoragePath, storagePathId)
|
||||||
|
.subscribe((result) => {
|
||||||
|
expect(result).toBe(storagePath)
|
||||||
|
})
|
||||||
|
expect(getCachedSpy).toHaveBeenCalledWith(parseInt(storagePathId))
|
||||||
|
// no storage path found
|
||||||
|
getCachedSpy.mockReturnValue(of(null))
|
||||||
|
component
|
||||||
|
.getPrettyName(DataType.StoragePath, storagePathId)
|
||||||
|
.subscribe((result) => {
|
||||||
|
expect(result).toBe(storagePathId)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('getPrettyName should return the owner username', () => {
|
||||||
|
const ownerId = '1'
|
||||||
|
const ownerUsername = 'user1'
|
||||||
|
const getCachedSpy = jest
|
||||||
|
.spyOn(userService, 'getCached')
|
||||||
|
.mockReturnValue(of({ username: ownerUsername }))
|
||||||
|
component.getPrettyName('owner', ownerId).subscribe((result) => {
|
||||||
|
expect(result).toBe(ownerUsername)
|
||||||
|
})
|
||||||
|
expect(getCachedSpy).toHaveBeenCalledWith(parseInt(ownerId))
|
||||||
|
// no user found
|
||||||
|
getCachedSpy.mockReturnValue(of(null))
|
||||||
|
component.getPrettyName('owner', ownerId).subscribe((result) => {
|
||||||
|
expect(result).toBe(ownerId)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('getPrettyName should return the value as is for other types', () => {
|
||||||
|
const id = '123'
|
||||||
|
component.getPrettyName('other', id).subscribe((result) => {
|
||||||
|
expect(result).toBe(id)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
import { Component, Input, OnInit } from '@angular/core'
|
import { Component, Input, OnInit } from '@angular/core'
|
||||||
|
import { Observable, first, map, of } from 'rxjs'
|
||||||
import { AuditLogAction, AuditLogEntry } from 'src/app/data/auditlog-entry'
|
import { AuditLogAction, AuditLogEntry } from 'src/app/data/auditlog-entry'
|
||||||
|
import { DataType } from 'src/app/data/datatype'
|
||||||
|
import { CorrespondentService } from 'src/app/services/rest/correspondent.service'
|
||||||
|
import { DocumentTypeService } from 'src/app/services/rest/document-type.service'
|
||||||
import { DocumentService } from 'src/app/services/rest/document.service'
|
import { DocumentService } from 'src/app/services/rest/document.service'
|
||||||
|
import { StoragePathService } from 'src/app/services/rest/storage-path.service'
|
||||||
|
import { UserService } from 'src/app/services/rest/user.service'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'pngx-document-history',
|
selector: 'pngx-document-history',
|
||||||
@ -20,7 +26,13 @@ export class DocumentHistoryComponent implements OnInit {
|
|||||||
public loading: boolean = true
|
public loading: boolean = true
|
||||||
public entries: AuditLogEntry[] = []
|
public entries: AuditLogEntry[] = []
|
||||||
|
|
||||||
constructor(private documentService: DocumentService) {}
|
constructor(
|
||||||
|
private documentService: DocumentService,
|
||||||
|
private correspondentService: CorrespondentService,
|
||||||
|
private storagePathService: StoragePathService,
|
||||||
|
private documentTypeService: DocumentTypeService,
|
||||||
|
private userService: UserService
|
||||||
|
) {}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
if (this._documentId) {
|
if (this._documentId) {
|
||||||
@ -33,4 +45,31 @@ export class DocumentHistoryComponent implements OnInit {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getPrettyName(type: DataType | string, id: string): Observable<string> {
|
||||||
|
switch (type) {
|
||||||
|
case DataType.Correspondent:
|
||||||
|
return this.correspondentService.getCached(parseInt(id, 10)).pipe(
|
||||||
|
first(),
|
||||||
|
map((correspondent) => correspondent?.name ?? id)
|
||||||
|
)
|
||||||
|
case DataType.DocumentType:
|
||||||
|
return this.documentTypeService.getCached(parseInt(id, 10)).pipe(
|
||||||
|
first(),
|
||||||
|
map((documentType) => documentType?.name ?? id)
|
||||||
|
)
|
||||||
|
case DataType.StoragePath:
|
||||||
|
return this.storagePathService.getCached(parseInt(id, 10)).pipe(
|
||||||
|
first(),
|
||||||
|
map((storagePath) => storagePath?.path ?? id)
|
||||||
|
)
|
||||||
|
case 'owner':
|
||||||
|
return this.userService.getCached(parseInt(id, 10)).pipe(
|
||||||
|
first(),
|
||||||
|
map((user) => user?.username ?? id)
|
||||||
|
)
|
||||||
|
default:
|
||||||
|
return of(id)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user