diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bd6080d35..a8fb1f8e9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -24,3 +24,7 @@ feature-X branches is for experimental stuff that will eventually be merged into I'm trying to get most of paperless tested, so please do the same for your code! I know its a hassle, but it makes sure that your code works now and will allow us to detect regressions easily. To test your code, execute `pytest` in the src/ directory. Executing that in the project root is no good. This also generates a html coverage report, which you can use to see if you missed anything important during testing. + +## More info: + +... is available in the documentation. https://paperless-ng.readthedocs.io/en/latest/extending.html diff --git a/README.md b/README.md index e754669a8..41f85af19 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ Here's what you get: # Features * Performs OCR on your documents, adds selectable text to image only documents and adds tags, correspondents and document types to your documents. +* Paperless stores your documents plain on disk. Filenames and folders are managed by paperless and can be configured freely. * Single page application front end. Should be pretty snappy. Will be mobile friendly in the future. * Includes a dashboard that shows basic statistics and has document upload. * Filtering by tags, correspondents, types, and more. diff --git a/docs/faq.rst b/docs/faq.rst index 6eac18617..d9efddd0f 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -78,6 +78,12 @@ that automatically, I'm all ears. For now, you have to grab the latest release archive from the project page and build the image yourself. The release comes with the front end already compiled, so you don't have to do this on the Pi. +**Q:** *How do I run this on unRaid?* + +**A:** Head over to ``_, +`Uli Fahrer `_ created a container template for that. +I don't exactly know how to use that though, since I don't use unRaid. + **Q:** *How do I run this on my toaster?* **A:** I honestly don't know! As for all other devices that might be able diff --git a/src-ui/package-lock.json b/src-ui/package-lock.json index b6b66e1c6..5eca0b3c0 100644 --- a/src-ui/package-lock.json +++ b/src-ui/package-lock.json @@ -2215,6 +2215,11 @@ "integrity": "sha512-UV1/ZJMC+HcP902wWdpC43cAcGu0IQk/I5bXjP2aSuCjsk3cE74mDvFrLKga7oDC170ugOAYBwfT4DSQW3akDA==", "dev": true }, + "@types/pdfjs-dist": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@types/pdfjs-dist/-/pdfjs-dist-2.1.7.tgz", + "integrity": "sha512-nQIwcPUhkAIyn7x9NS0lR/qxYfd5unRtfGkMjvpgF4Sh28IXftRymaNmFKTTdejDNY25NDGSIyjwj/BRwAPexg==" + }, "@types/q": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", @@ -3023,6 +3028,16 @@ "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", "dev": true }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, "blob": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", @@ -5508,6 +5523,13 @@ "schema-utils": "^2.6.5" } }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -8208,6 +8230,13 @@ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "dev": true }, + "nan": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", + "dev": true, + "optional": true + }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -8260,6 +8289,23 @@ "moment": "2.18.1" } }, + "ng2-pdf-viewer": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/ng2-pdf-viewer/-/ng2-pdf-viewer-6.3.2.tgz", + "integrity": "sha512-H2tBhDd+Lq6CUzK2g54HsCcZDR2wTn1sDjYqKY3yF0Ydasl2R5ppCKynZBU/zge4EKvmHglJI120FbQMpJKDYQ==", + "requires": { + "@types/pdfjs-dist": "^2.1.4", + "pdfjs-dist": "^2.4.456", + "tslib": "^1.10.0" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, "ngx-cookie-service": { "version": "10.1.1", "resolved": "https://registry.npmjs.org/ngx-cookie-service/-/ngx-cookie-service-10.1.1.tgz", @@ -9270,6 +9316,11 @@ "sha.js": "^2.4.8" } }, + "pdfjs-dist": { + "version": "2.5.207", + "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-2.5.207.tgz", + "integrity": "sha512-xGDUhnCYPfHy+unMXCLCJtlpZaaZ17Ew3WIL0tnSgKFUZXHAPD49GO9xScyszSsQMoutNDgRb+rfBXIaX/lJbw==" + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -13228,7 +13279,11 @@ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", "dev": true, - "optional": true + "optional": true, + "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + } }, "glob-parent": { "version": "3.1.0", @@ -13832,7 +13887,11 @@ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", "dev": true, - "optional": true + "optional": true, + "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + } }, "glob-parent": { "version": "3.1.0", diff --git a/src-ui/package.json b/src-ui/package.json index af3334db9..6293f2672 100644 --- a/src-ui/package.json +++ b/src-ui/package.json @@ -23,6 +23,7 @@ "@ng-bootstrap/ng-bootstrap": "^8.0.0", "bootstrap": "^4.5.0", "ng-bootstrap": "^1.6.3", + "ng2-pdf-viewer": "^6.3.2", "ngx-cookie-service": "^10.1.1", "ngx-file-drop": "^10.0.0", "ngx-infinite-scroll": "^9.1.0", diff --git a/src-ui/src/app/app.module.ts b/src-ui/src/app/app.module.ts index 675c882a7..f935b7701 100644 --- a/src-ui/src/app/app.module.ts +++ b/src-ui/src/app/app.module.ts @@ -14,10 +14,9 @@ import { LogsComponent } from './components/manage/logs/logs.component'; import { SettingsComponent } from './components/manage/settings/settings.component'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { DatePipe } from '@angular/common'; -import { SafePipe } from './pipes/safe.pipe'; import { NotFoundComponent } from './components/not-found/not-found.component'; import { CorrespondentListComponent } from './components/manage/correspondent-list/correspondent-list.component'; -import { DeleteDialogComponent } from './components/common/delete-dialog/delete-dialog.component'; +import { ConfirmDialogComponent } from './components/common/confirm-dialog/confirm-dialog.component'; import { CorrespondentEditDialogComponent } from './components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component'; import { TagEditDialogComponent } from './components/manage/tag-list/tag-edit-dialog/tag-edit-dialog.component'; import { DocumentTypeEditDialogComponent } from './components/manage/document-type-list/document-type-edit-dialog/document-type-edit-dialog.component'; @@ -28,6 +27,9 @@ import { PageHeaderComponent } from './components/common/page-header/page-header import { AppFrameComponent } from './components/app-frame/app-frame.component'; import { ToastsComponent } from './components/common/toasts/toasts.component'; import { FilterEditorComponent } from './components/filter-editor/filter-editor.component'; +import { FilterDropdownComponent } from './components/filter-editor/filter-dropdown/filter-dropdown.component'; +import { FilterDropdownButtonComponent } from './components/filter-editor/filter-dropdown/filter-dropdown-button/filter-dropdown-button.component'; +import { FilterDropdownDateComponent } from './components/filter-editor/filter-dropdown-date/filter-dropdown-date.component'; import { DocumentCardLargeComponent } from './components/document-list/document-card-large/document-card-large.component'; import { DocumentCardSmallComponent } from './components/document-list/document-card-small/document-card-small.component'; import { NgxFileDropModule } from 'ngx-file-drop'; @@ -45,10 +47,13 @@ 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'; +import { FilterPipe } from './pipes/filter.pipe'; import { DocumentTitlePipe } from './pipes/document-title.pipe'; +import { MetadataCollapseComponent } from './components/document-detail/metadata-collapse/metadata-collapse.component'; @NgModule({ declarations: [ @@ -61,10 +66,9 @@ import { DocumentTitlePipe } from './pipes/document-title.pipe'; DocumentTypeListComponent, LogsComponent, SettingsComponent, - SafePipe, NotFoundComponent, CorrespondentEditDialogComponent, - DeleteDialogComponent, + ConfirmDialogComponent, TagEditDialogComponent, DocumentTypeEditDialogComponent, TagComponent, @@ -74,6 +78,9 @@ import { DocumentTitlePipe } from './pipes/document-title.pipe'; AppFrameComponent, ToastsComponent, FilterEditorComponent, + FilterDropdownComponent, + FilterDropdownButtonComponent, + FilterDropdownDateComponent, DocumentCardLargeComponent, DocumentCardSmallComponent, TextComponent, @@ -90,7 +97,9 @@ import { DocumentTitlePipe } from './pipes/document-title.pipe'; WelcomeWidgetComponent, YesNoPipe, FileSizePipe, - DocumentTitlePipe + FilterPipe, + DocumentTitlePipe, + MetadataCollapseComponent ], imports: [ BrowserModule, @@ -100,7 +109,8 @@ import { DocumentTitlePipe } from './pipes/document-title.pipe'; FormsModule, ReactiveFormsModule, NgxFileDropModule, - InfiniteScrollModule + InfiniteScrollModule, + PdfViewerModule ], providers: [ DatePipe, @@ -108,7 +118,8 @@ import { DocumentTitlePipe } from './pipes/document-title.pipe'; provide: HTTP_INTERCEPTORS, useClass: CsrfInterceptor, multi: true - } + }, + FilterPipe ], bootstrap: [AppComponent] }) diff --git a/src-ui/src/app/components/app-frame/app-frame.component.html b/src-ui/src/app/components/app-frame/app-frame.component.html index 3f326afdd..1cedeefde 100644 --- a/src-ui/src/app/components/app-frame/app-frame.component.html +++ b/src-ui/src/app/components/app-frame/app-frame.component.html @@ -132,7 +132,7 @@