From c2cec70c9ae0a18bae4b9e4f1d60c857f78ce33f Mon Sep 17 00:00:00 2001
From: shamoon <4887959+shamoon@users.noreply.github.com>
Date: Mon, 4 Mar 2024 23:04:23 -0800
Subject: [PATCH] Allow rotate from doc details page
---
docs/usage.md | 8 +++-
.../rotate-confirm-dialog.component.html | 12 +++---
.../rotate-confirm-dialog.component.ts | 1 +
.../document-detail.component.html | 4 ++
.../document-detail.component.spec.ts | 29 +++++++++++++
.../document-detail.component.ts | 43 +++++++++++++++++++
.../bulk-editor/bulk-editor.component.html | 2 +-
7 files changed, 91 insertions(+), 8 deletions(-)
diff --git a/docs/usage.md b/docs/usage.md
index 156096106..e5ef3b2c0 100644
--- a/docs/usage.md
+++ b/docs/usage.md
@@ -461,8 +461,12 @@ Paperless-ngx added the ability to create shareable links to files in version 2.
Paperless-ngx supports 3 basic editing operations for PDFs (these operations cannot be performed on non-PDF files):
- Merging documents: available when selecting multiple documents for 'bulk editing'
-- Rotating documents: available when selecting multiple documents for 'bulk editing'. Note that rotation alters the source file.
-- Splitting documents: available from an individual documents details page
+- Rotating documents: available when selecting multiple documents for 'bulk editing' and from an individual document's details page.
+- Splitting documents: available from an individual document's details page
+
+!!! important
+
+ Note that rotation alters the Paperless-ngx original file.
## Best practices {#basic-searching}
diff --git a/src-ui/src/app/components/common/confirm-dialog/rotate-confirm-dialog/rotate-confirm-dialog.component.html b/src-ui/src/app/components/common/confirm-dialog/rotate-confirm-dialog/rotate-confirm-dialog.component.html
index 7c61aa14a..8a6eacef4 100644
--- a/src-ui/src/app/components/common/confirm-dialog/rotate-confirm-dialog/rotate-confirm-dialog.component.html
+++ b/src-ui/src/app/components/common/confirm-dialog/rotate-confirm-dialog/rotate-confirm-dialog.component.html
@@ -5,17 +5,17 @@
-
+
-
+
@if (documentID) {
![]()
}
-
-
Note that only PDFs will be rotated.
+ @if (showPDFNote) {
+
Note that only PDFs will be rotated.
+ }
diff --git a/src-ui/src/app/components/document-detail/document-detail.component.spec.ts b/src-ui/src/app/components/document-detail/document-detail.component.spec.ts
index 7663657c0..b26ad9024 100644
--- a/src-ui/src/app/components/document-detail/document-detail.component.spec.ts
+++ b/src-ui/src/app/components/document-detail/document-detail.component.spec.ts
@@ -75,6 +75,8 @@ import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service
import { PdfViewerComponent } from '../common/pdf-viewer/pdf-viewer.component'
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
import { environment } from 'src/environments/environment'
+import { RotateConfirmDialogComponent } from '../common/confirm-dialog/rotate-confirm-dialog/rotate-confirm-dialog.component'
+import { SplitConfirmDialogComponent } from '../common/confirm-dialog/split-confirm-dialog/split-confirm-dialog.component'
const doc: Document = {
id: 3,
@@ -171,6 +173,8 @@ describe('DocumentDetailComponent', () => {
ShareLinksDropdownComponent,
CustomFieldsDropdownComponent,
PdfViewerComponent,
+ SplitConfirmDialogComponent,
+ RotateConfirmDialogComponent,
],
providers: [
DocumentTitlePipe,
@@ -1097,6 +1101,31 @@ describe('DocumentDetailComponent', () => {
req.flush(true)
})
+ it('should support rotate', () => {
+ let modal: NgbModalRef
+ modalService.activeInstances.subscribe((m) => (modal = m[0]))
+ initNormally()
+ component.rotateDocument()
+ expect(modal).not.toBeUndefined()
+ modal.componentInstance.documentID = doc.id
+ modal.componentInstance.rotate()
+ modal.componentInstance.confirm()
+ let req = httpTestingController.expectOne(
+ `${environment.apiBaseUrl}documents/bulk_edit/`
+ )
+ expect(req.request.body).toEqual({
+ documents: [doc.id],
+ method: 'rotate',
+ parameters: { degrees: 90 },
+ })
+ req.error(new ProgressEvent('failed'))
+ modal.componentInstance.confirm()
+ req = httpTestingController.expectOne(
+ `${environment.apiBaseUrl}documents/bulk_edit/`
+ )
+ req.flush(true)
+ })
+
function initNormally() {
jest
.spyOn(activatedRoute, 'paramMap', 'get')
diff --git a/src-ui/src/app/components/document-detail/document-detail.component.ts b/src-ui/src/app/components/document-detail/document-detail.component.ts
index 0c61044aa..5c5efdc9f 100644
--- a/src-ui/src/app/components/document-detail/document-detail.component.ts
+++ b/src-ui/src/app/components/document-detail/document-detail.component.ts
@@ -68,6 +68,7 @@ import { CustomFieldInstance } from 'src/app/data/custom-field-instance'
import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service'
import { PDFDocumentProxy } from '../common/pdf-viewer/typings'
import { SplitConfirmDialogComponent } from '../common/confirm-dialog/split-confirm-dialog/split-confirm-dialog.component'
+import { RotateConfirmDialogComponent } from '../common/confirm-dialog/rotate-confirm-dialog/rotate-confirm-dialog.component'
enum DocumentDetailNavIDs {
Details = 1,
@@ -1078,4 +1079,46 @@ export class DocumentDetailComponent
})
})
}
+
+ rotateDocument() {
+ let modal = this.modalService.open(RotateConfirmDialogComponent, {
+ backdrop: 'static',
+ })
+ modal.componentInstance.title = $localize`Rotate confirm`
+ modal.componentInstance.messageBold = $localize`This operation will permanently rotate the current document.`
+ modal.componentInstance.message = $localize`This will alter the original copy.`
+ modal.componentInstance.btnCaption = $localize`Proceed`
+ modal.componentInstance.documentID = this.document.id
+ modal.componentInstance.showPDFNote = false
+ modal.componentInstance.confirmClicked
+ .pipe(takeUntil(this.unsubscribeNotifier))
+ .subscribe(() => {
+ modal.componentInstance.buttonsEnabled = false
+ this.documentsService
+ .bulkEdit([this.document.id], 'rotate', {
+ degrees: modal.componentInstance.degrees,
+ })
+ .pipe(first(), takeUntil(this.unsubscribeNotifier))
+ .subscribe({
+ next: () => {
+ this.toastService.show({
+ content: $localize`Rotation will begin in the background. Close and re-open the document after the operation has completed to see the changes.`,
+ delay: 8000,
+ action: this.close.bind(this),
+ actionName: $localize`Close`,
+ })
+ modal.close()
+ },
+ error: (error) => {
+ if (modal) {
+ modal.componentInstance.buttonsEnabled = true
+ }
+ this.toastService.showError(
+ $localize`Error executing rotate operation`,
+ error
+ )
+ },
+ })
+ })
+ }
}
diff --git a/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.html b/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.html
index dd3fec5a4..865502569 100644
--- a/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.html
+++ b/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.html
@@ -91,7 +91,7 @@
-