Fix: render images not converted to pdf, refactor doc detail rendering (#5475)

This commit is contained in:
shamoon 2024-01-20 08:26:24 -08:00 committed by GitHub
parent 5781a0d51f
commit 5842944d1e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 116 additions and 47 deletions

View File

@ -1,5 +1,5 @@
<pngx-page-header [(title)]="title">
@if (getContentType() === 'application/pdf' && !useNativePdfViewer) {
@if (contentRenderType === ContentRenderType.PDF && !useNativePdfViewer) {
<div class="input-group input-group-sm me-2 d-none d-md-flex">
<div class="input-group-text" i18n>Page</div>
<input class="form-control flex-grow-0 w-auto" type="number" min="1" [max]="previewNumPages" [(ngModel)]="previewCurrentPage" />
@ -106,7 +106,7 @@
@for (fieldInstance of document?.custom_fields; track fieldInstance; let i = $index) {
<div [formGroup]="customFieldFormFields.controls[i]">
@switch (getCustomFieldFromInstance(fieldInstance)?.data_type) {
@case (PaperlessCustomFieldDataType.String) {
@case (CustomFieldDataType.String) {
<pngx-input-text formControlName="value"
[title]="getCustomFieldFromInstance(fieldInstance)?.name"
[removable]="userIsOwner"
@ -114,7 +114,7 @@
[horizontal]="true"
[error]="getCustomFieldError(i)"></pngx-input-text>
}
@case (PaperlessCustomFieldDataType.Date) {
@case (CustomFieldDataType.Date) {
<pngx-input-date formControlName="value"
[title]="getCustomFieldFromInstance(fieldInstance)?.name"
[removable]="userIsOwner"
@ -122,7 +122,7 @@
[horizontal]="true"
[error]="getCustomFieldError(i)"></pngx-input-date>
}
@case (PaperlessCustomFieldDataType.Integer) {
@case (CustomFieldDataType.Integer) {
<pngx-input-number formControlName="value"
[title]="getCustomFieldFromInstance(fieldInstance)?.name"
[removable]="userIsOwner"
@ -131,7 +131,7 @@
[showAdd]="false"
[error]="getCustomFieldError(i)"></pngx-input-number>
}
@case (PaperlessCustomFieldDataType.Float) {
@case (CustomFieldDataType.Float) {
<pngx-input-number formControlName="value"
[title]="getCustomFieldFromInstance(fieldInstance)?.name"
[removable]="userIsOwner"
@ -141,7 +141,7 @@
[step]=".1"
[error]="getCustomFieldError(i)"></pngx-input-number>
}
@case (PaperlessCustomFieldDataType.Monetary) {
@case (CustomFieldDataType.Monetary) {
<pngx-input-number formControlName="value"
[title]="getCustomFieldFromInstance(fieldInstance)?.name"
[removable]="userIsOwner"
@ -151,14 +151,14 @@
[step]=".01"
[error]="getCustomFieldError(i)"></pngx-input-number>
}
@case (PaperlessCustomFieldDataType.Boolean) {
@case (CustomFieldDataType.Boolean) {
<pngx-input-check formControlName="value"
[title]="getCustomFieldFromInstance(fieldInstance)?.name"
[removable]="userIsOwner"
(removed)="removeField(fieldInstance)"
[horizontal]="true"></pngx-input-check>
}
@case (PaperlessCustomFieldDataType.Url) {
@case (CustomFieldDataType.Url) {
<pngx-input-url formControlName="value"
[title]="getCustomFieldFromInstance(fieldInstance)?.name"
[removable]="userIsOwner"
@ -166,7 +166,7 @@
[horizontal]="true"
[error]="getCustomFieldError(i)"></pngx-input-url>
}
@case (PaperlessCustomFieldDataType.DocumentLink) {
@case (CustomFieldDataType.DocumentLink) {
<pngx-input-document-link formControlName="value"
[title]="getCustomFieldFromInstance(fieldInstance)?.name"
[parentDocumentID]="documentId"
@ -260,7 +260,9 @@
<a ngbNavLink i18n>Preview</a>
@if (!pdfPreview.offsetParent) {
<ng-template ngbNavContent>
<ng-container *ngTemplateOutlet="previewContent"></ng-container>
<div class="position-relative">
<ng-container *ngTemplateOutlet="previewContent"></ng-container>
</div>
</ng-template>
}
</li>
@ -295,16 +297,6 @@
<div class="col-md-6 col-xl-8 mb-3 d-none d-md-block position-relative" #pdfPreview>
<ng-container *ngTemplateOutlet="previewContent"></ng-container>
@if (renderAsPlainText) {
<div [innerText]="previewText" class="preview-sticky bg-light p-3 overflow-auto" width="100%"></div>
}
@if (requiresPassword) {
<div class="password-prompt">
<form>
<input autocomplete="" class="form-control" i18n-placeholder placeholder="Enter Password" type="password" (keyup)="onPasswordKeyUp($event)" />
</form>
</div>
}
</div>
</div>
@ -333,29 +325,39 @@
</div>
</div>
}
@if (getContentType() === 'application/pdf') {
@if (!useNativePdfViewer ) {
<div class="preview-sticky pdf-viewer-container">
<pngx-pdf-viewer
[src]="{ url: previewUrl, password: password }"
[original-size]="false"
[show-borders]="true"
[show-all]="true"
[(page)]="previewCurrentPage"
[zoom-scale]="previewZoomScale"
[zoom]="previewZoomSetting"
(error)="onError($event)"
(after-load-complete)="pdfPreviewLoaded($event)">
</pngx-pdf-viewer>
@switch (contentRenderType) {
@case (ContentRenderType.PDF) {
@if (!useNativePdfViewer) {
<div class="preview-sticky pdf-viewer-container">
<pngx-pdf-viewer
[src]="{ url: previewUrl, password: password }"
[original-size]="false"
[show-borders]="true"
[show-all]="true"
[(page)]="previewCurrentPage"
[zoom-scale]="previewZoomScale"
[zoom]="previewZoomSetting"
(error)="onError($event)"
(after-load-complete)="pdfPreviewLoaded($event)">
</pngx-pdf-viewer>
</div>
} @else {
<object [data]="previewUrl | safeUrl" class="preview-sticky" width="100%"></object>
}
}
@case (ContentRenderType.Text) {
<div class="preview-sticky bg-light p-3 overflow-auto" width="100%">{{previewText}}</div>
}
@case (ContentRenderType.Image) {
<div class="preview-sticky">
<img [src]="previewUrl | safeUrl" width="100%" height="100%" alt="{{title}}" />
</div>
} @else {
}
@case (ContentRenderType.Other) {
<object [data]="previewUrl | safeUrl" class="preview-sticky" width="100%"></object>
}
}
@if (renderAsPlainText) {
<div [innerText]="previewText" class="preview-sticky bg-light p-3 overflow-auto" width="100%"></div>
}
@if (showPasswordField) {
@if (requiresPassword) {
<div class="password-prompt">
<form>
<input autocomplete="" autofocus="true" class="form-control" i18n-placeholder placeholder="Enter Password" type="password" (keyup)="onPasswordKeyUp($event)" />

View File

@ -58,3 +58,9 @@ textarea.rtl {
border-top-right-radius: var(--bs-border-radius-sm);
border-bottom-right-radius: var(--bs-border-radius-sm);
}
.preview-sticky img {
width: 100%;
height: 100%;
object-fit: contain;
}

View File

@ -996,6 +996,53 @@ describe('DocumentDetailComponent', () => {
expect(closeSpy).toHaveBeenCalled()
})
it('should change preview element by render type', () => {
component.metadata = { has_archive_version: true }
initNormally()
fixture.detectChanges()
expect(component.contentRenderType).toEqual(component.ContentRenderType.PDF)
expect(
fixture.debugElement.query(By.css('pdf-viewer-container'))
).not.toBeUndefined()
component.metadata = {
has_archive_version: false,
original_mime_type: 'text/plain',
}
fixture.detectChanges()
expect(component.contentRenderType).toEqual(
component.ContentRenderType.Text
)
expect(
fixture.debugElement.query(By.css('div.preview-sticky'))
).not.toBeUndefined()
component.metadata = {
has_archive_version: false,
original_mime_type: 'image/jpg',
}
fixture.detectChanges()
expect(component.contentRenderType).toEqual(
component.ContentRenderType.Image
)
expect(
fixture.debugElement.query(By.css('.preview-sticky img'))
).not.toBeUndefined()
component.metadata = {
has_archive_version: false,
original_mime_type:
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
}
fixture.detectChanges()
expect(component.contentRenderType).toEqual(
component.ContentRenderType.Other
)
expect(
fixture.debugElement.query(By.css('object.preview-sticky'))
).not.toBeUndefined()
})
function initNormally() {
jest
.spyOn(activatedRoute, 'paramMap', 'get')

View File

@ -77,6 +77,13 @@ enum DocumentDetailNavIDs {
Permissions = 6,
}
enum ContentRenderType {
PDF = 'pdf',
Image = 'image',
Text = 'text',
Other = 'other',
}
enum ZoomSetting {
PageFit = 'page-fit',
PageWidth = 'page-width',
@ -154,7 +161,9 @@ export class DocumentDetailComponent
ogDate: Date
customFields: CustomField[]
public readonly PaperlessCustomFieldDataType = CustomFieldDataType
public readonly CustomFieldDataType = CustomFieldDataType
public readonly ContentRenderType = ContentRenderType
@ViewChild('nav') nav: NgbNav
@ViewChild('pdfPreview') set pdfPreview(element) {
@ -201,16 +210,21 @@ export class DocumentDetailComponent
return this.settings.get(SETTINGS_KEYS.USE_NATIVE_PDF_VIEWER)
}
getContentType() {
return this.metadata?.has_archive_version
get contentRenderType(): ContentRenderType {
const contentType = this.metadata?.has_archive_version
? 'application/pdf'
: this.metadata?.original_mime_type
}
get renderAsPlainText(): boolean {
return ['text/plain', 'application/csv', 'text/csv'].includes(
this.getContentType()
)
if (contentType === 'application/pdf') {
return ContentRenderType.PDF
} else if (
['text/plain', 'application/csv', 'text/csv'].includes(contentType)
) {
return ContentRenderType.Text
} else if (contentType?.indexOf('image/') === 0) {
return ContentRenderType.Image
}
return ContentRenderType.Other
}
get isRTL() {