Move doc detail actions over

This commit is contained in:
shamoon committed 2026-11-14 00:13:29 -08:00
1 parent c7fcdbed61
commit dc292d7ede
4 files changed
+71 -38

No files matched your search

@@ -1013,30 +1013,39 @@ describe('DocumentDetailComponent', () => {
])
})
it('should support reprocess, confirm and close modal after started', () => {
it('should queue reprocess, show the task link and close the modal', () => {
initNormally()
const reprocessSpy = jest.spyOn(documentService, 'reprocessDocuments')
reprocessSpy.mockReturnValue(of(true))
reprocessSpy.mockReturnValue(of({ result: 'OK', task_id: 'reprocess-1' }))
let openModal: NgbModalRef
modalService.activeInstances.subscribe((modal) => (openModal = modal[0]))
const modalSpy = jest.spyOn(modalService, 'open')
const toastSpy = jest.spyOn(toastService, 'showInfo')
const toastSpy = jest.spyOn(toastService, 'show')
component.reprocess()
const modalCloseSpy = jest.spyOn(openModal, 'close')
openModal.componentInstance.confirmClicked.next()
expect(reprocessSpy).toHaveBeenCalledWith({ documents: [doc.id] }, false)
expect(modalSpy).toHaveBeenCalled()
expect(toastSpy).toHaveBeenCalled()
expect(toastSpy).toHaveBeenCalledWith(
expect.objectContaining({
content: 'Document reprocessing queued.',
actionName: 'View task',
})
)
toastSpy.mock.calls.at(-1)[0].action()
expect(router.navigate).toHaveBeenCalledWith(['/tasks'], {
queryParams: { task_id: 'reprocess-1' },
})
expect(modalCloseSpy).toHaveBeenCalled()
})
it('should run a workflow on the document, confirm and close modal', () => {
initNormally()
const bulkEditSpy = jest.spyOn(documentService, 'bulkEdit')
bulkEditSpy.mockReturnValue(of(true))
bulkEditSpy.mockReturnValue(of({ result: 'OK', task_id: 'workflow-1' }))
let openModal: NgbModalRef
modalService.activeInstances.subscribe((modal) => (openModal = modal[0]))
const toastSpy = jest.spyOn(toastService, 'showInfo')
const toastSpy = jest.spyOn(toastService, 'show')
component.runWorkflow()
expect(openModal.componentInstance.singleDocument).toBe(true)
expect(openModal.componentInstance.force).toBe(true)
@@ -1048,14 +1057,16 @@ describe('DocumentDetailComponent', () => {
'run_workflow',
{ workflow: 5, filter_documents: false }
)
expect(toastSpy).toHaveBeenCalled()
expect(toastSpy).toHaveBeenCalledWith(
expect.objectContaining({ content: 'Workflow queued.' })
)
expect(modalCloseSpy).toHaveBeenCalled()
})
it('should apply workflow filters when the single-document checkbox is cleared', () => {
initNormally()
const bulkEditSpy = jest.spyOn(documentService, 'bulkEdit')
bulkEditSpy.mockReturnValue(of(true))
bulkEditSpy.mockReturnValue(of({ result: 'OK', task_id: 'workflow-2' }))
let openModal: NgbModalRef
modalService.activeInstances.subscribe((modal) => (openModal = modal[0]))
component.runWorkflow()
@@ -1072,7 +1083,7 @@ describe('DocumentDetailComponent', () => {
it('should pass remote OCR choice when reprocessing', () => {
initNormally()
const reprocessSpy = jest.spyOn(documentService, 'reprocessDocuments')
reprocessSpy.mockReturnValue(of(true))
reprocessSpy.mockReturnValue(of({ result: 'OK', task_id: 'reprocess-2' }))
let openModal: NgbModalRef
modalService.activeInstances.subscribe((modal) => (openModal = modal[0]))
component.reprocess()
@@ -2005,6 +2016,7 @@ describe('DocumentDetailComponent', () => {
modalService.activeInstances.subscribe((m) => (modal = m[0]))
const closeSpy = jest.spyOn(openDocumentsService, 'closeDocument')
const errorSpy = jest.spyOn(toastService, 'showError')
const queuedToastSpy = jest.spyOn(toastService, 'show')
initNormally()
component.selectedVersionId.set(10)
component.editPdf()
@@ -2023,6 +2035,7 @@ describe('DocumentDetailComponent', () => {
update_document: false,
include_metadata: true,
source_mode: 'explicit_selection',
from_webui: true,
})
req.error(new ErrorEvent('failed'))
expect(errorSpy).toHaveBeenCalled()
@@ -2035,13 +2048,18 @@ describe('DocumentDetailComponent', () => {
req = httpTestingController.expectOne(
`${environment.apiBaseUrl}documents/edit_pdf/`
)
req.flush(true)
expect(closeSpy).toHaveBeenCalled()
req.flush({ result: 'OK', task_id: 'edit-pdf-1' })
expect(closeSpy).not.toHaveBeenCalled()
expect(queuedToastSpy).toHaveBeenCalledWith(
expect.objectContaining({ content: 'PDF edit queued.' })
)
})
it('should support removing password protection from pdfs', () => {
let modal: NgbModalRef
modalService.activeInstances.subscribe((m) => (modal = m[0]))
const closeSpy = jest.spyOn(openDocumentsService, 'closeDocument')
const queuedToastSpy = jest.spyOn(toastService, 'show')
initNormally()
component.selectedVersionId.set(10)
component.password = 'secret'
@@ -2062,8 +2080,13 @@ describe('DocumentDetailComponent', () => {
include_metadata: false,
delete_original: true,
source_mode: 'explicit_selection',
from_webui: true,
})
req.flush(true)
req.flush({ result: 'OK', task_id: 'remove-password-1' })
expect(closeSpy).not.toHaveBeenCalled()
expect(queuedToastSpy).toHaveBeenCalledWith(
expect.objectContaining({ content: 'Password removal queued.' })
)
})
it('should require the current password before removing it', () => {
@@ -2115,9 +2138,9 @@ describe('DocumentDetailComponent', () => {
const req = httpTestingController.expectOne(
`${environment.apiBaseUrl}documents/remove_password/`
)
req.flush(true)
req.flush({ result: 'OK', task_id: 'remove-password-2' })
expect(refreshSpy).toHaveBeenCalledWith(doc.id)
expect(refreshSpy).not.toHaveBeenCalled()
})
it('should support keyboard shortcuts', () => {
@@ -1558,9 +1558,10 @@ export class DocumentDetailComponent
modal.componentInstance.remoteOcr
)
.subscribe({
next: () => {
this.toastService.showInfo(
$localize`Reprocess operation for "${this.document().title}" will begin in the background.`
next: ({ task_id }) => {
this.notifyTaskQueued(
task_id,
$localize`Document reprocessing queued.`
)
if (modal) {
modal.close()
@@ -1597,10 +1598,8 @@ export class DocumentDetailComponent
filter_documents: !modal.componentInstance.force,
})
.subscribe({
next: () => {
this.toastService.showInfo(
$localize`Workflow will run on "${this.document().title}" in the background.`
)
next: ({ task_id }) => {
this.notifyTaskQueued(task_id, $localize`Workflow queued.`)
modal.close()
},
error: (error) => {
@@ -1614,6 +1613,26 @@ export class DocumentDetailComponent
})
}
private notifyTaskQueued(taskId: string, content: string) {
const canViewTasks = this.permissionsService.currentUserCan(
PermissionAction.View,
PermissionType.PaperlessTask
)
this.toastService.show({
content,
delay: 5000,
...(canViewTasks
? {
actionName: $localize`View task`,
action: () =>
this.router.navigate(['/tasks'], {
queryParams: { task_id: taskId },
}),
}
: {}),
})
}
private getSelectedNonLatestVersionId(): number | null {
const versions = this.document()?.versions ?? []
if (!versions.length || !this.selectedVersionId()) {
@@ -1989,14 +2008,9 @@ export class DocumentDetailComponent
})
.pipe(first(), takeUntil(this.unsubscribeNotifier))
.subscribe({
next: () => {
this.toastService.showInfo(
$localize`PDF edit operation for "${this.document().title}" will begin in the background.`
)
next: ({ task_id }) => {
this.notifyTaskQueued(task_id, $localize`PDF edit queued.`)
modal.close()
if (modal.componentInstance.deleteOriginal) {
this.openDocumentService.closeDocument(this.document())
}
},
error: (error) => {
if (modal) {
@@ -2046,17 +2060,13 @@ export class DocumentDetailComponent
})
.pipe(first(), takeUntil(this.unsubscribeNotifier))
.subscribe({
next: () => {
this.toastService.showInfo(
$localize`Password removal operation for "${this.document().title}" will begin in the background.`
next: ({ task_id }) => {
this.notifyTaskQueued(
task_id,
$localize`Password removal queued.`
)
this.networkActive.set(false)
modal.close()
if (!dialog.updateDocument && dialog.deleteOriginal) {
this.openDocumentService.closeDocument(this.document())
} else if (dialog.updateDocument) {
this.openDocumentService.refreshDocument(this.documentId())
}
},
error: (error) => {
dialog.buttonsEnabled.set(true)
@@ -418,7 +418,7 @@ describe('DocumentVersionDropdownComponent', () => {
expect(modal.close).toHaveBeenCalled()
expect(toastService.show).toHaveBeenCalledWith(
expect.objectContaining({
content: 'Bulk operation queued.',
content: 'Existing document queued to be added as a version.',
actionName: 'View task',
})
)
@@ -327,7 +327,7 @@ export class DocumentVersionDropdownComponent
PermissionType.PaperlessTask
)
this.toastService.show({
content: $localize`Bulk operation queued.`,
content: $localize`Existing document queued to be added as a version.`,
delay: 5000,
...(canViewTasks
? {