mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-11-07 07:19:22 +00:00
Add to doc details
This commit is contained in:
3 files changed
+79
No files matched your search
@@ -49,6 +49,12 @@
|
||||
<pngx-bs-icon width="1em" height="1em" name="arrow-counterclockwise" class="me-2"></pngx-bs-icon><span i18n>Reprocess</span>
|
||||
</button>
|
||||
|
||||
@if (manualWorkflows().length > 0) {
|
||||
<button ngbDropdownItem (click)="runWorkflow()" [disabled]="!userCanEdit || !userIsOwner">
|
||||
<pngx-bs-icon width="1em" height="1em" name="play-circle" class="me-2"></pngx-bs-icon><span i18n>Run workflow</span>
|
||||
</button>
|
||||
}
|
||||
|
||||
<button ngbDropdownItem (click)="printDocument()" [hidden]="useNativePdfViewer || isMobile">
|
||||
<pngx-bs-icon width="1em" height="1em" name="printer" class="me-2"></pngx-bs-icon><span i18n>Print</span>
|
||||
</button>
|
||||
|
||||
@@ -1030,6 +1030,27 @@ describe('DocumentDetailComponent', () => {
|
||||
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))
|
||||
let openModal: NgbModalRef
|
||||
modalService.activeInstances.subscribe((modal) => (openModal = modal[0]))
|
||||
const toastSpy = jest.spyOn(toastService, 'showInfo')
|
||||
component.runWorkflow()
|
||||
const modalCloseSpy = jest.spyOn(openModal, 'close')
|
||||
openModal.componentInstance.workflowId = 5
|
||||
openModal.componentInstance.force = true
|
||||
openModal.componentInstance.confirmClicked.next()
|
||||
expect(bulkEditSpy).toHaveBeenCalledWith(
|
||||
{ documents: [doc.id] },
|
||||
'run_workflow',
|
||||
{ workflow: 5, filter_documents: false }
|
||||
)
|
||||
expect(toastSpy).toHaveBeenCalled()
|
||||
expect(modalCloseSpy).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should pass remote OCR choice when reprocessing', () => {
|
||||
initNormally()
|
||||
const reprocessSpy = jest.spyOn(documentService, 'reprocessDocuments')
|
||||
|
||||
@@ -68,6 +68,8 @@ import { StoragePath } from 'src/app/data/storage-path'
|
||||
import { Tag } from 'src/app/data/tag'
|
||||
import { SETTINGS_KEYS, SuggestionSource } from 'src/app/data/ui-settings'
|
||||
import { User } from 'src/app/data/user'
|
||||
import { Workflow } from 'src/app/data/workflow'
|
||||
import { WorkflowTriggerType } from 'src/app/data/workflow-trigger'
|
||||
import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive'
|
||||
import { CustomDatePipe } from 'src/app/pipes/custom-date.pipe'
|
||||
import { DocumentTitlePipe } from 'src/app/pipes/document-title.pipe'
|
||||
@@ -93,6 +95,7 @@ import { SavedViewService } from 'src/app/services/rest/saved-view.service'
|
||||
import { StoragePathService } from 'src/app/services/rest/storage-path.service'
|
||||
import { TagService } from 'src/app/services/rest/tag.service'
|
||||
import { UserService } from 'src/app/services/rest/user.service'
|
||||
import { WorkflowService } from 'src/app/services/rest/workflow.service'
|
||||
import { SettingsService } from 'src/app/services/settings.service'
|
||||
import { ToastService } from 'src/app/services/toast.service'
|
||||
import { TrashService } from 'src/app/services/trash.service'
|
||||
@@ -104,6 +107,7 @@ import { DocumentDetailFieldID } from '../admin/settings/settings.component'
|
||||
import { ConfirmDialogComponent } from '../common/confirm-dialog/confirm-dialog.component'
|
||||
import { PasswordRemovalConfirmDialogComponent } from '../common/confirm-dialog/password-removal-confirm-dialog/password-removal-confirm-dialog.component'
|
||||
import { ReprocessConfirmDialogComponent } from '../common/confirm-dialog/reprocess-confirm-dialog/reprocess-confirm-dialog.component'
|
||||
import { RunWorkflowConfirmDialogComponent } from '../common/confirm-dialog/run-workflow-confirm-dialog/run-workflow-confirm-dialog.component'
|
||||
import { CustomFieldsDropdownComponent } from '../common/custom-fields-dropdown/custom-fields-dropdown.component'
|
||||
import { CorrespondentEditDialogComponent } from '../common/edit-dialog/correspondent-edit-dialog/correspondent-edit-dialog.component'
|
||||
import { DocumentTypeEditDialogComponent } from '../common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component'
|
||||
@@ -233,6 +237,7 @@ export class DocumentDetailComponent
|
||||
private componentRouterService = inject(ComponentRouterService)
|
||||
private deviceDetectorService = inject(DeviceDetectorService)
|
||||
private savedViewService = inject(SavedViewService)
|
||||
private readonly workflowService = inject(WorkflowService)
|
||||
private readonly websocketStatusService = inject(WebsocketStatusService)
|
||||
private readonly useNativePdfViewerSetting = this.settings.getSignal<boolean>(
|
||||
SETTINGS_KEYS.USE_NATIVE_PDF_VIEWER
|
||||
@@ -295,6 +300,7 @@ export class DocumentDetailComponent
|
||||
readonly correspondents = signal<Correspondent[]>(undefined)
|
||||
readonly documentTypes = signal<DocumentType[]>(undefined)
|
||||
readonly storagePaths = signal<StoragePath[]>(undefined)
|
||||
readonly manualWorkflows = signal<Workflow[]>([])
|
||||
|
||||
documentForm: FormGroup = new FormGroup({
|
||||
title: new FormControl(''),
|
||||
@@ -836,6 +842,19 @@ export class DocumentDetailComponent
|
||||
.pipe(first(), takeUntil(this.unsubscribeNotifier))
|
||||
.subscribe((result) => this.users.set(result.results))
|
||||
}
|
||||
if (
|
||||
this.permissionsService.currentUserCan(
|
||||
PermissionAction.View,
|
||||
PermissionType.Workflow
|
||||
)
|
||||
) {
|
||||
this.workflowService
|
||||
.list(1, 100000, null, null, {
|
||||
trigger_type: WorkflowTriggerType.Manual,
|
||||
})
|
||||
.pipe(first(), takeUntil(this.unsubscribeNotifier))
|
||||
.subscribe((result) => this.manualWorkflows.set(result.results))
|
||||
}
|
||||
|
||||
this.getCustomFields()
|
||||
|
||||
@@ -1559,6 +1578,39 @@ export class DocumentDetailComponent
|
||||
})
|
||||
}
|
||||
|
||||
runWorkflow() {
|
||||
const modal = this.modalService.open(RunWorkflowConfirmDialogComponent, {
|
||||
backdrop: 'static',
|
||||
})
|
||||
modal.componentInstance.title = $localize`Run workflow`
|
||||
modal.componentInstance.message = $localize`Run a workflow on "${this.document().title}".`
|
||||
modal.componentInstance.btnCaption = $localize`Run`
|
||||
modal.componentInstance.workflows = this.manualWorkflows()
|
||||
modal.componentInstance.confirmClicked.subscribe(() => {
|
||||
modal.componentInstance.buttonsEnabled.set(false)
|
||||
this.documentsService
|
||||
.bulkEdit({ documents: [this.document().id] }, 'run_workflow', {
|
||||
workflow: modal.componentInstance.workflowId,
|
||||
filter_documents: !modal.componentInstance.force,
|
||||
})
|
||||
.subscribe({
|
||||
next: () => {
|
||||
this.toastService.showInfo(
|
||||
$localize`Workflow will run on "${this.document().title}" in the background.`
|
||||
)
|
||||
modal.close()
|
||||
},
|
||||
error: (error) => {
|
||||
modal.componentInstance.buttonsEnabled.set(true)
|
||||
this.toastService.showError(
|
||||
$localize`Error executing operation`,
|
||||
error
|
||||
)
|
||||
},
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
private getSelectedNonLatestVersionId(): number | null {
|
||||
const versions = this.document()?.versions ?? []
|
||||
if (!versions.length || !this.selectedVersionId()) {
|
||||
|
||||
Reference in new issue
Block a user