mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-07-28 18:24:38 -05:00
Merge remote-tracking branch 'upstream/dev' into feature/popover-previews
This commit is contained in:
@@ -47,6 +47,7 @@ import { SavedViewWidgetComponent } from './components/dashboard/widgets/saved-v
|
||||
import { StatisticsWidgetComponent } from './components/dashboard/widgets/statistics-widget/statistics-widget.component';
|
||||
import { UploadFileWidgetComponent } from './components/dashboard/widgets/upload-file-widget/upload-file-widget.component';
|
||||
import { WidgetFrameComponent } from './components/dashboard/widgets/widget-frame/widget-frame.component';
|
||||
import { PdfViewerModule } from 'ng2-pdf-viewer';
|
||||
import { WelcomeWidgetComponent } from './components/dashboard/widgets/welcome-widget/welcome-widget.component';
|
||||
import { YesNoPipe } from './pipes/yes-no.pipe';
|
||||
import { FileSizePipe } from './pipes/file-size.pipe';
|
||||
@@ -143,6 +144,7 @@ registerLocaleData(localeRo)
|
||||
ReactiveFormsModule,
|
||||
NgxFileDropModule,
|
||||
InfiniteScrollModule,
|
||||
PdfViewerModule,
|
||||
NgSelectModule,
|
||||
ColorSliderModule
|
||||
],
|
||||
|
@@ -99,7 +99,7 @@
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item w-100" *ngIf="openDocuments.length > 1">
|
||||
<li class="nav-item w-100" *ngIf="openDocuments.length >= 1">
|
||||
<a class="nav-link text-truncate" [routerLink]="" (click)="closeAll()">
|
||||
<svg class="sidebaricon" fill="currentColor">
|
||||
<use xlink:href="assets/bootstrap-icons.svg#x"/>
|
||||
|
@@ -1,4 +1,14 @@
|
||||
<app-page-header [(title)]="title">
|
||||
<div class="input-group input-group-sm mr-5 d-none d-md-flex" *ngIf="getContentType() == 'application/pdf' && !useNativePdfViewer">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text" i18n>Page</div>
|
||||
</div>
|
||||
<input class="form-control flex-grow-0 w-auto" type="number" min="1" [max]="previewNumPages" [(ngModel)]="previewCurrentPage" />
|
||||
<div class="input-group-append">
|
||||
<div class="input-group-text" i18n>of {{previewNumPages}}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="button" class="btn btn-sm btn-outline-danger mr-2 ml-auto" (click)="delete()">
|
||||
<svg class="buttonicon" fill="currentColor">
|
||||
<use xlink:href="assets/bootstrap-icons.svg#trash" />
|
||||
@@ -125,7 +135,12 @@
|
||||
|
||||
<div class="col-md-6 col-xl-8 mb-3">
|
||||
<ng-container *ngIf="getContentType() == 'application/pdf'">
|
||||
<object [data]="previewUrl | safe" class="preview-sticky" width="100%"></object>
|
||||
<div class="preview-sticky pdf-viewer-container" *ngIf="!useNativePdfViewer ; else nativePdfViewer">
|
||||
<pdf-viewer [src]="previewUrl" [original-size]="false" [show-borders]="true" [show-all]="true" [(page)]="previewCurrentPage" [render-text-mode]="2" (after-load-complete)="pdfPreviewLoaded($event)"></pdf-viewer>
|
||||
</div>
|
||||
<ng-template #nativePdfViewer>
|
||||
<object [data]="previewUrl | safe" type="application/pdf" class="preview-sticky" width="100%"></object>
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="getContentType() == 'text/plain'">
|
||||
<object [data]="previewUrl | safe" type="text/plain" class="preview-sticky" width="100%"></object>
|
||||
|
@@ -15,6 +15,7 @@ import { DocumentService } from 'src/app/services/rest/document.service';
|
||||
import { ConfirmDialogComponent } from '../common/confirm-dialog/confirm-dialog.component';
|
||||
import { CorrespondentEditDialogComponent } from '../manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component';
|
||||
import { DocumentTypeEditDialogComponent } from '../manage/document-type-list/document-type-edit-dialog/document-type-edit-dialog.component';
|
||||
import { PDFDocumentProxy } from 'ng2-pdf-viewer';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
import { TextComponent } from '../common/input/text/text.component';
|
||||
import { SettingsService, SETTINGS_KEYS } from 'src/app/services/settings.service';
|
||||
@@ -60,6 +61,9 @@ export class DocumentDetailComponent implements OnInit {
|
||||
tags: new FormControl([])
|
||||
})
|
||||
|
||||
previewCurrentPage: number = 1
|
||||
previewNumPages: number = 1
|
||||
|
||||
constructor(
|
||||
private documentsService: DocumentService,
|
||||
private route: ActivatedRoute,
|
||||
@@ -73,6 +77,10 @@ export class DocumentDetailComponent implements OnInit {
|
||||
private toastService: ToastService,
|
||||
private settings: SettingsService) { }
|
||||
|
||||
get useNativePdfViewer(): boolean {
|
||||
return this.settings.get(SETTINGS_KEYS.USE_NATIVE_PDF_VIEWER)
|
||||
}
|
||||
|
||||
getContentType() {
|
||||
return this.metadata?.has_archive_version ? 'application/pdf' : this.metadata?.original_mime_type
|
||||
}
|
||||
@@ -218,4 +226,8 @@ export class DocumentDetailComponent implements OnInit {
|
||||
return this.documentListViewService.hasNext(this.documentId)
|
||||
}
|
||||
|
||||
pdfPreviewLoaded(pdf: PDFDocumentProxy) {
|
||||
this.previewNumPages = pdf.numPages
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
<div class="card mb-3 shadow-sm" [class.card-selected]="selected" [class.document-card]="selectable" [class.popover-hidden]="popoverHidden" (mouseleave)="mouseLeaveCard()">
|
||||
<div class="card mb-3 shadow-sm" [class.card-selected]="selected" [class.document-card]="selectable">
|
||||
<div class="row no-gutters">
|
||||
<div class="col-md-2 d-none d-lg-block doc-img-background rounded-left" [class.doc-img-background-selected]="selected" (click)="this.toggleSelected.emit($event)">
|
||||
<img [src]="getThumbUrl()" class="card-img doc-img border-right rounded-left" [class.inverted]="getIsThumbInverted()">
|
||||
@@ -43,9 +43,7 @@
|
||||
<path fill-rule="evenodd" d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5L13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175l-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z"/>
|
||||
</svg> <span class="d-block d-md-inline" i18n>Edit</span>
|
||||
</a>
|
||||
<a class="btn btn-sm btn-outline-secondary" [href]="previewUrl" title="Click to view in browser" i18n-title
|
||||
[ngbPopover]="previewContent" [popoverTitle]="document.title | documentTitle"
|
||||
autoClose="true" popoverClass="shadow" (mouseenter)="mouseEnterPreview()" (mouseleave)="mouseLeavePreview()" #popover="ngbPopover">
|
||||
<a class="btn btn-sm btn-outline-secondary" [href]="getPreviewUrl()">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-eye" viewBox="0 0 16 16">
|
||||
<path d="M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8zM1.173 8a13.133 13.133 0 0 1 1.66-2.043C4.12 4.668 5.88 3.5 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.133 13.133 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755C11.879 11.332 10.119 12.5 8 12.5c-2.12 0-3.879-1.168-5.168-2.457A13.134 13.134 0 0 1 1.172 8z"/>
|
||||
<path d="M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM4.5 8a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0z"/>
|
||||
@@ -60,6 +58,7 @@
|
||||
<path fill-rule="evenodd" d="M7.646 11.854a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V1.5a.5.5 0 0 0-1 0v8.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3z"/>
|
||||
</svg> <span class="d-block d-md-inline" i18n>Download</span>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
<div *ngIf="searchScore" class="d-flex align-items-center ml-md-auto mt-2 mt-md-0">
|
||||
|
@@ -1,14 +1,13 @@
|
||||
import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { DomSanitizer } from '@angular/platform-browser';
|
||||
import { PaperlessDocument } from 'src/app/data/paperless-document';
|
||||
import { DocumentService } from 'src/app/services/rest/document.service';
|
||||
import { SettingsService, SETTINGS_KEYS } from 'src/app/services/settings.service';
|
||||
import { NgbPopover } from '@ng-bootstrap/ng-bootstrap';
|
||||
|
||||
@Component({
|
||||
selector: 'app-document-card-large',
|
||||
templateUrl: './document-card-large.component.html',
|
||||
styleUrls: ['./document-card-large.component.scss', '../popover-preview/popover-preview.scss']
|
||||
styleUrls: ['./document-card-large.component.scss']
|
||||
})
|
||||
export class DocumentCardLargeComponent implements OnInit {
|
||||
|
||||
@@ -85,7 +84,7 @@ export class DocumentCardLargeComponent implements OnInit {
|
||||
return this.documentService.getDownloadUrl(this.document.id)
|
||||
}
|
||||
|
||||
get previewUrl() {
|
||||
getPreviewUrl() {
|
||||
return this.documentService.getPreviewUrl(this.document.id)
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { PaperlessDocument } from 'src/app/data/paperless-document';
|
||||
import { PaperlessDocumentMetadata } from 'src/app/data/paperless-document-metadata';
|
||||
import { DocumentService } from 'src/app/services/rest/document.service';
|
||||
import { SettingsService, SETTINGS_KEYS } from 'src/app/services/settings.service';
|
||||
import { NgbPopover } from '@ng-bootstrap/ng-bootstrap';
|
||||
@@ -36,7 +37,12 @@ export class DocumentCardSmallComponent implements OnInit {
|
||||
mouseOnPreview = false
|
||||
popoverHidden = true
|
||||
|
||||
metadata: PaperlessDocumentMetadata
|
||||
|
||||
ngOnInit(): void {
|
||||
this.documentService.getMetadata(this.document?.id).subscribe(result => {
|
||||
this.metadata = result
|
||||
})
|
||||
}
|
||||
|
||||
getIsThumbInverted() {
|
||||
|
@@ -170,5 +170,5 @@
|
||||
</table>
|
||||
|
||||
<div class="m-n2 row row-cols-paperless-cards" *ngIf="displayMode == 'smallCards'">
|
||||
<app-document-card-small [selected]="list.isSelected(d)" (toggleSelected)="toggleSelected(d, $event)" [document]="d" *ngFor="let d of list.documents; trackBy: trackByDocumentId" (clickTag)="clickTag($event)" (clickCorrespondent)="clickCorrespondent($event)"></app-document-card-small>
|
||||
<app-document-card-small [selected]="list.isSelected(d)" (toggleSelected)="toggleSelected(d, $event)" [document]="d" *ngFor="let d of list.documents; trackBy: trackByDocumentId" (clickTag)="clickTag($event)" (clickCorrespondent)="clickCorrespondent($event)"></app-document-card-small>
|
||||
</div>
|
||||
|
@@ -1,22 +0,0 @@
|
||||
::ng-deep .popover {
|
||||
max-width: 40rem;
|
||||
|
||||
.preview {
|
||||
min-width: 30rem;
|
||||
min-height: 18rem;
|
||||
max-height: 35rem;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.spinner-border {
|
||||
position: absolute;
|
||||
top: 4rem;
|
||||
left: calc(50% - 0.5rem);
|
||||
z-index: 0;
|
||||
}
|
||||
}
|
||||
|
||||
::ng-deep .popover-hidden .popover {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
@@ -78,6 +78,17 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row form-group">
|
||||
<div class="col-md-3 col-form-label">
|
||||
<span i18n>Document editor</span>
|
||||
</div>
|
||||
<div class="col">
|
||||
|
||||
<app-input-check i18n-title title="Use PDF viewer provided by the browser" i18n-hint hint="This is usually faster for displaying large PDF documents, but it might not work on some browsers." formControlName="useNativePdfViewer"></app-input-check>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row form-group">
|
||||
<div class="col-md-3 col-form-label">
|
||||
<span i18n>Dark mode</span>
|
||||
@@ -100,11 +111,11 @@
|
||||
|
||||
</ng-template>
|
||||
</li>
|
||||
|
||||
|
||||
<li [ngbNavItem]="2">
|
||||
<a ngbNavLink i18n>Notifications</a>
|
||||
<ng-template ngbNavContent>
|
||||
|
||||
|
||||
<h4 i18n>Document processing</h4>
|
||||
|
||||
<div class="form-row form-group">
|
||||
|
@@ -22,6 +22,7 @@ export class SettingsComponent implements OnInit {
|
||||
'darkModeUseSystem': new FormControl(this.settings.get(SETTINGS_KEYS.DARK_MODE_USE_SYSTEM)),
|
||||
'darkModeEnabled': new FormControl(this.settings.get(SETTINGS_KEYS.DARK_MODE_ENABLED)),
|
||||
'darkModeInvertThumbs': new FormControl(this.settings.get(SETTINGS_KEYS.DARK_MODE_THUMB_INVERTED)),
|
||||
'useNativePdfViewer': new FormControl(this.settings.get(SETTINGS_KEYS.USE_NATIVE_PDF_VIEWER)),
|
||||
'savedViews': this.savedViewGroup,
|
||||
'displayLanguage': new FormControl(this.settings.getLanguage()),
|
||||
'dateLocale': new FormControl(this.settings.get(SETTINGS_KEYS.DATE_LOCALE)),
|
||||
@@ -75,6 +76,7 @@ export class SettingsComponent implements OnInit {
|
||||
this.settings.set(SETTINGS_KEYS.DARK_MODE_USE_SYSTEM, this.settingsForm.value.darkModeUseSystem)
|
||||
this.settings.set(SETTINGS_KEYS.DARK_MODE_ENABLED, (this.settingsForm.value.darkModeEnabled == true).toString())
|
||||
this.settings.set(SETTINGS_KEYS.DARK_MODE_THUMB_INVERTED, (this.settingsForm.value.darkModeInvertThumbs == true).toString())
|
||||
this.settings.set(SETTINGS_KEYS.USE_NATIVE_PDF_VIEWER, this.settingsForm.value.useNativePdfViewer)
|
||||
this.settings.set(SETTINGS_KEYS.DATE_LOCALE, this.settingsForm.value.dateLocale)
|
||||
this.settings.set(SETTINGS_KEYS.DATE_FORMAT, this.settingsForm.value.dateFormat)
|
||||
this.settings.set(SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_NEW_DOCUMENT, this.settingsForm.value.notificationsConsumerNewDocument)
|
||||
|
@@ -27,6 +27,7 @@ export const SETTINGS_KEYS = {
|
||||
DARK_MODE_USE_SYSTEM: 'general-settings:dark-mode:use-system',
|
||||
DARK_MODE_ENABLED: 'general-settings:dark-mode:enabled',
|
||||
DARK_MODE_THUMB_INVERTED: 'general-settings:dark-mode:thumb-inverted',
|
||||
USE_NATIVE_PDF_VIEWER: 'general-settings:document-details:native-pdf-viewer',
|
||||
DATE_LOCALE: 'general-settings:date-display:date-locale',
|
||||
DATE_FORMAT: 'general-settings:date-display:date-format',
|
||||
NOTIFICATIONS_CONSUMER_NEW_DOCUMENT: 'general-settings:notifications:consumer-new-documents',
|
||||
@@ -42,6 +43,7 @@ const SETTINGS: PaperlessSettings[] = [
|
||||
{key: SETTINGS_KEYS.DARK_MODE_USE_SYSTEM, type: "boolean", default: true},
|
||||
{key: SETTINGS_KEYS.DARK_MODE_ENABLED, type: "boolean", default: false},
|
||||
{key: SETTINGS_KEYS.DARK_MODE_THUMB_INVERTED, type: "boolean", default: true},
|
||||
{key: SETTINGS_KEYS.USE_NATIVE_PDF_VIEWER, type: "boolean", default: false},
|
||||
{key: SETTINGS_KEYS.DATE_LOCALE, type: "string", default: ""},
|
||||
{key: SETTINGS_KEYS.DATE_FORMAT, type: "string", default: "mediumDate"},
|
||||
{key: SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_NEW_DOCUMENT, type: "boolean", default: true},
|
||||
|
2282
src-ui/src/locale/messages.cs_CZ.xlf
Normal file
2282
src-ui/src/locale/messages.cs_CZ.xlf
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
2282
src-ui/src/locale/messages.es_ES.xlf
Normal file
2282
src-ui/src/locale/messages.es_ES.xlf
Normal file
File diff suppressed because it is too large
Load Diff
2282
src-ui/src/locale/messages.fr_FR.xlf
Normal file
2282
src-ui/src/locale/messages.fr_FR.xlf
Normal file
File diff suppressed because it is too large
Load Diff
2282
src-ui/src/locale/messages.hu_HU.xlf
Normal file
2282
src-ui/src/locale/messages.hu_HU.xlf
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
2282
src-ui/src/locale/messages.la_LA.xlf
Normal file
2282
src-ui/src/locale/messages.la_LA.xlf
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
2282
src-ui/src/locale/messages.pt_PT.xlf
Normal file
2282
src-ui/src/locale/messages.pt_PT.xlf
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
2282
src-ui/src/locale/messages.ru_RU.xlf
Normal file
2282
src-ui/src/locale/messages.ru_RU.xlf
Normal file
File diff suppressed because it is too large
Load Diff
2282
src-ui/src/locale/messages.th_TH.xlf
Normal file
2282
src-ui/src/locale/messages.th_TH.xlf
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
2282
src-ui/src/locale/messages.zh_CN.xlf
Normal file
2282
src-ui/src/locale/messages.zh_CN.xlf
Normal file
File diff suppressed because it is too large
Load Diff
@@ -392,7 +392,7 @@ $border-color-dark-mode: #47494f;
|
||||
border-color: $border-color-dark-mode;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$placements: 'top', 'right', 'bottom', 'left';
|
||||
|
||||
@each $placement in $placements {
|
||||
|
Reference in New Issue
Block a user