mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-08-14 00:26:21 +00:00
Enhancement: delete pages PDF action (#6772)
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<pngx-page-header [(title)]="title">
|
||||
@if (contentRenderType === ContentRenderType.PDF && !useNativePdfViewer) {
|
||||
@if (archiveContentRenderType === ContentRenderType.PDF && !useNativePdfViewer) {
|
||||
@if (previewNumPages) {
|
||||
<div class="input-group input-group-sm d-none d-md-flex">
|
||||
<div class="input-group-text" i18n>Page</div>
|
||||
@@ -53,13 +53,17 @@
|
||||
<i-bs width="1em" height="1em" name="diagram-3"></i-bs> <span i18n>More like this</span>
|
||||
</button>
|
||||
|
||||
<button ngbDropdownItem (click)="splitDocument()" [disabled]="contentRenderType !== ContentRenderType.PDF || previewNumPages === 1">
|
||||
<button ngbDropdownItem (click)="splitDocument()" [disabled]="archiveContentRenderType !== ContentRenderType.PDF || previewNumPages === 1">
|
||||
<i-bs width="1em" height="1em" name="scissors"></i-bs> <span i18n>Split</span>
|
||||
</button>
|
||||
|
||||
<button ngbDropdownItem (click)="rotateDocument()" [disabled]="!userIsOwner || metadata?.original_mime_type !== 'application/pdf'">
|
||||
<button ngbDropdownItem (click)="rotateDocument()" [disabled]="!userIsOwner || originalContentRenderType !== ContentRenderType.PDF">
|
||||
<i-bs name="arrow-clockwise"></i-bs> <ng-container i18n>Rotate</ng-container>
|
||||
</button>
|
||||
|
||||
<button ngbDropdownItem (click)="deletePages()" [disabled]="!userIsOwner || originalContentRenderType !== ContentRenderType.PDF || previewNumPages === 1">
|
||||
<i-bs name="file-earmark-minus"></i-bs> <ng-container i18n>Delete page(s)</ng-container>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -343,7 +347,7 @@
|
||||
</div>
|
||||
</div>
|
||||
} @else {
|
||||
@switch (contentRenderType) {
|
||||
@switch (archiveContentRenderType) {
|
||||
@case (ContentRenderType.PDF) {
|
||||
@if (!useNativePdfViewer) {
|
||||
<div class="preview-sticky pdf-viewer-container">
|
||||
|
@@ -81,6 +81,7 @@ 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'
|
||||
import { PdfViewerModule } from 'ng2-pdf-viewer'
|
||||
import { DeletePagesConfirmDialogComponent } from '../common/confirm-dialog/delete-pages-confirm-dialog/delete-pages-confirm-dialog.component'
|
||||
|
||||
const doc: Document = {
|
||||
id: 3,
|
||||
@@ -178,6 +179,7 @@ describe('DocumentDetailComponent', () => {
|
||||
CustomFieldsDropdownComponent,
|
||||
SplitConfirmDialogComponent,
|
||||
RotateConfirmDialogComponent,
|
||||
DeletePagesConfirmDialogComponent,
|
||||
],
|
||||
providers: [
|
||||
DocumentTitlePipe,
|
||||
@@ -1035,7 +1037,9 @@ describe('DocumentDetailComponent', () => {
|
||||
component.metadata = { has_archive_version: true }
|
||||
initNormally()
|
||||
fixture.detectChanges()
|
||||
expect(component.contentRenderType).toEqual(component.ContentRenderType.PDF)
|
||||
expect(component.archiveContentRenderType).toEqual(
|
||||
component.ContentRenderType.PDF
|
||||
)
|
||||
expect(
|
||||
fixture.debugElement.query(By.css('pdf-viewer-container'))
|
||||
).not.toBeUndefined()
|
||||
@@ -1045,7 +1049,7 @@ describe('DocumentDetailComponent', () => {
|
||||
original_mime_type: 'text/plain',
|
||||
}
|
||||
fixture.detectChanges()
|
||||
expect(component.contentRenderType).toEqual(
|
||||
expect(component.archiveContentRenderType).toEqual(
|
||||
component.ContentRenderType.Text
|
||||
)
|
||||
expect(
|
||||
@@ -1057,7 +1061,7 @@ describe('DocumentDetailComponent', () => {
|
||||
original_mime_type: 'image/jpg',
|
||||
}
|
||||
fixture.detectChanges()
|
||||
expect(component.contentRenderType).toEqual(
|
||||
expect(component.archiveContentRenderType).toEqual(
|
||||
component.ContentRenderType.Image
|
||||
)
|
||||
expect(
|
||||
@@ -1070,7 +1074,7 @@ describe('DocumentDetailComponent', () => {
|
||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
}
|
||||
fixture.detectChanges()
|
||||
expect(component.contentRenderType).toEqual(
|
||||
expect(component.archiveContentRenderType).toEqual(
|
||||
component.ContentRenderType.Other
|
||||
)
|
||||
expect(
|
||||
@@ -1130,6 +1134,31 @@ describe('DocumentDetailComponent', () => {
|
||||
req.flush(true)
|
||||
})
|
||||
|
||||
it('should support delete pages', () => {
|
||||
let modal: NgbModalRef
|
||||
modalService.activeInstances.subscribe((m) => (modal = m[0]))
|
||||
initNormally()
|
||||
component.deletePages()
|
||||
expect(modal).not.toBeUndefined()
|
||||
modal.componentInstance.documentID = doc.id
|
||||
modal.componentInstance.pages = [1, 2]
|
||||
modal.componentInstance.confirm()
|
||||
let req = httpTestingController.expectOne(
|
||||
`${environment.apiBaseUrl}documents/bulk_edit/`
|
||||
)
|
||||
expect(req.request.body).toEqual({
|
||||
documents: [doc.id],
|
||||
method: 'delete_pages',
|
||||
parameters: { pages: [1, 2] },
|
||||
})
|
||||
req.error(new ProgressEvent('failed'))
|
||||
modal.componentInstance.confirm()
|
||||
req = httpTestingController.expectOne(
|
||||
`${environment.apiBaseUrl}documents/bulk_edit/`
|
||||
)
|
||||
req.flush(true)
|
||||
})
|
||||
|
||||
it('should support keyboard shortcuts', () => {
|
||||
initNormally()
|
||||
|
||||
|
@@ -68,6 +68,7 @@ import { CustomFieldInstance } from 'src/app/data/custom-field-instance'
|
||||
import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service'
|
||||
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'
|
||||
import { DeletePagesConfirmDialogComponent } from '../common/confirm-dialog/delete-pages-confirm-dialog/delete-pages-confirm-dialog.component'
|
||||
import { HotKeyService } from 'src/app/services/hot-key.service'
|
||||
import { PDFDocumentProxy } from 'ng2-pdf-viewer'
|
||||
|
||||
@@ -216,19 +217,27 @@ export class DocumentDetailComponent
|
||||
return this.settings.get(SETTINGS_KEYS.USE_NATIVE_PDF_VIEWER)
|
||||
}
|
||||
|
||||
get contentRenderType(): ContentRenderType {
|
||||
if (!this.metadata) return ContentRenderType.Unknown
|
||||
const contentType = this.metadata?.has_archive_version
|
||||
? 'application/pdf'
|
||||
: this.metadata?.original_mime_type
|
||||
get archiveContentRenderType(): ContentRenderType {
|
||||
return this.getRenderType(
|
||||
this.metadata?.has_archive_version
|
||||
? 'application/pdf'
|
||||
: this.metadata?.original_mime_type
|
||||
)
|
||||
}
|
||||
|
||||
if (contentType === 'application/pdf') {
|
||||
get originalContentRenderType(): ContentRenderType {
|
||||
return this.getRenderType(this.metadata?.original_mime_type)
|
||||
}
|
||||
|
||||
private getRenderType(mimeType: string): ContentRenderType {
|
||||
if (!mimeType) return ContentRenderType.Unknown
|
||||
if (mimeType === 'application/pdf') {
|
||||
return ContentRenderType.PDF
|
||||
} else if (
|
||||
['text/plain', 'application/csv', 'text/csv'].includes(contentType)
|
||||
['text/plain', 'application/csv', 'text/csv'].includes(mimeType)
|
||||
) {
|
||||
return ContentRenderType.Text
|
||||
} else if (contentType?.indexOf('image/') === 0) {
|
||||
} else if (mimeType?.indexOf('image/') === 0) {
|
||||
return ContentRenderType.Image
|
||||
}
|
||||
return ContentRenderType.Other
|
||||
@@ -1138,7 +1147,6 @@ export class DocumentDetailComponent
|
||||
})
|
||||
modal.componentInstance.title = $localize`Rotate confirm`
|
||||
modal.componentInstance.messageBold = $localize`This operation will permanently rotate the original version of 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
|
||||
@@ -1173,4 +1181,41 @@ export class DocumentDetailComponent
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
deletePages() {
|
||||
let modal = this.modalService.open(DeletePagesConfirmDialogComponent, {
|
||||
backdrop: 'static',
|
||||
})
|
||||
modal.componentInstance.title = $localize`Delete pages confirm`
|
||||
modal.componentInstance.messageBold = $localize`This operation will permanently delete the selected pages from the original document.`
|
||||
modal.componentInstance.btnCaption = $localize`Proceed`
|
||||
modal.componentInstance.documentID = this.document.id
|
||||
modal.componentInstance.confirmClicked
|
||||
.pipe(takeUntil(this.unsubscribeNotifier))
|
||||
.subscribe(() => {
|
||||
modal.componentInstance.buttonsEnabled = false
|
||||
this.documentsService
|
||||
.bulkEdit([this.document.id], 'delete_pages', {
|
||||
pages: modal.componentInstance.pages,
|
||||
})
|
||||
.pipe(first(), takeUntil(this.unsubscribeNotifier))
|
||||
.subscribe({
|
||||
next: () => {
|
||||
this.toastService.showInfo(
|
||||
$localize`Delete pages operation will begin in the background. Close and re-open or reload this document after the operation has completed to see the changes.`
|
||||
)
|
||||
modal.close()
|
||||
},
|
||||
error: (error) => {
|
||||
if (modal) {
|
||||
modal.componentInstance.buttonsEnabled = true
|
||||
}
|
||||
this.toastService.showError(
|
||||
$localize`Error executing delete pages operation`,
|
||||
error
|
||||
)
|
||||
},
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user