diff --git a/docs/advanced_usage.rst b/docs/advanced_usage.rst index 48a86384c..8f6b91b4c 100644 --- a/docs/advanced_usage.rst +++ b/docs/advanced_usage.rst @@ -5,85 +5,6 @@ Advanced topics Paperless offers a couple features that automate certain tasks and make your life easier. -Guesswork -######### - - -Any document you put into the consumption directory will be consumed, but if -you name the file right, it'll automatically set some values in the database -for you. This is is the logic the consumer follows: - -1. Try to find the correspondent, title, and tags in the file name following - the pattern: ``Date - Correspondent - Title - tag,tag,tag.pdf``. Note that - the format of the date is **rigidly defined** as ``YYYYMMDDHHMMSSZ`` or - ``YYYYMMDDZ``. The ``Z`` refers "Zulu time" AKA "UTC". - The tags are optional, so the format ``Date - Correspondent - Title.pdf`` - works as well. -2. If that doesn't work, we skip the date and try this pattern: - ``Correspondent - Title - tag,tag,tag.pdf``. -3. If that doesn't work, we try to find the correspondent and title in the file - name following the pattern: ``Correspondent - Title.pdf``. -4. If that doesn't work, just assume that the name of the file is the title. - -So given the above, the following examples would work as you'd expect: - -* ``20150314000700Z - Some Company Name - Invoice 2016-01-01 - money,invoices.pdf`` -* ``20150314Z - Some Company Name - Invoice 2016-01-01 - money,invoices.pdf`` -* ``Some Company Name - Invoice 2016-01-01 - money,invoices.pdf`` -* ``Another Company - Letter of Reference.jpg`` -* ``Dad's Recipe for Pancakes.png`` - -These however wouldn't work: - -* ``2015-03-14 00:07:00 UTC - Some Company Name, Invoice 2016-01-01, money, invoices.pdf`` -* ``2015-03-14 - Some Company Name, Invoice 2016-01-01, money, invoices.pdf`` -* ``Some Company Name, Invoice 2016-01-01, money, invoices.pdf`` -* ``Another Company- Letter of Reference.jpg`` - -Do I have to be so strict about naming? -======================================= - -Rather than using the strict document naming rules, one can also set the option -``PAPERLESS_FILENAME_DATE_ORDER`` in ``paperless.conf`` to any date order -that is accepted by dateparser_. Doing so will cause ``paperless`` to default -to any date format that is found in the title, instead of a date pulled from -the document's text, without requiring the strict formatting of the document -filename as described above. - -.. _dateparser: https://github.com/scrapinghub/dateparser/blob/v0.7.0/docs/usage.rst#settings - -.. _advanced-transforming_filenames: - -Transforming filenames for parsing -================================== - -Some devices can't produce filenames that can be parsed by the default -parser. By configuring the option ``PAPERLESS_FILENAME_PARSE_TRANSFORMS`` in -``paperless.conf`` one can add transformations that are applied to the filename -before it's parsed. - -The option contains a list of dictionaries of regular expressions (key: -``pattern``) and replacements (key: ``repl``) in JSON format, which are -applied in order by passing them to ``re.subn``. Transformation stops -after the first match, so at most one transformation is applied. The general -syntax is - -.. code:: python - - [{"pattern":"pattern1", "repl":"repl1"}, {"pattern":"pattern2", "repl":"repl2"}, ..., {"pattern":"patternN", "repl":"replN"}] - -The example below is for a Brother ADS-2400N, a scanner that allows -different names to different hardware buttons (useful for handling -multiple entities in one instance), but insists on adding ``_`` -to the filename. - -.. code:: python - - # Brother profile configuration, support "Name_Date_Count" (the default - # setting) and "Name_Count" (use "Name" as tag and "Count" as title). - PAPERLESS_FILENAME_PARSE_TRANSFORMS=[{"pattern":"^([a-z]+)_(\\d{8})_(\\d{6})_([0-9]+)\\.", "repl":"\\2\\3Z - \\4 - \\1."}, {"pattern":"^([a-z]+)_([0-9]+)\\.", "repl":" - \\2 - \\1."}] - - .. _advanced-matching: Matching tags, correspondents and document types diff --git a/docs/api.rst b/docs/api.rst index d352758fa..cff72a970 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -221,21 +221,16 @@ Each fragment contains a list of strings, and some of them are marked as a highl [ [ - {"text": "This is a sample text with a "}, - {"text": "highlighted", "term": 0}, - {"text": " word."} + {"text": "This is a sample text with a ", "highlight": false}, + {"text": "highlighted", "highlight": true}, + {"text": " word.", "highlight": false} ], [ - {"text": "Another", "term": 1}, - {"text": " fragment with a highlight."} + {"text": "Another", "highlight": true}, + {"text": " fragment with a highlight.", "highlight": false} ] ] - - -When ``term`` is present within a string, the word within ``text`` should be highlighted. -The term index groups multiple matches together and words with the same index -should get identical highlighting. A client may use this example to produce the following output: ... This is a sample text with a **highlighted** word. ... **Another** fragment with a highlight. ... diff --git a/docs/configuration.rst b/docs/configuration.rst index d3f47215b..efc1a9db1 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -400,11 +400,6 @@ PAPERLESS_FILENAME_DATE_ORDER= Defaults to none, which disables this feature. -PAPERLESS_FILENAME_PARSE_TRANSFORMS - Transforms filenames before they are processed by paperless. See - :ref:`advanced-transforming_filenames` for details. - - Defaults to none, which disables this feature. Binaries ######## diff --git a/src-ui/package-lock.json b/src-ui/package-lock.json index 5eca0b3c0..10215a32d 100644 --- a/src-ui/package-lock.json +++ b/src-ui/package-lock.json @@ -2056,6 +2056,14 @@ "tslib": "^2.0.0" } }, + "@ng-select/ng-select": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/@ng-select/ng-select/-/ng-select-5.0.9.tgz", + "integrity": "sha512-YZeSAiS8/Nx/eHZJPmOOYL8YmcvSq+dr1P8WIrsKmRA7mueorBpPc5xlUj+nLQbpLtsiQvdWDQspf/ykOvD/lA==", + "requires": { + "tslib": "^2.0.0" + } + }, "@ngtools/webpack": { "version": "10.2.0", "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-10.2.0.tgz", diff --git a/src-ui/package.json b/src-ui/package.json index 6293f2672..14d828483 100644 --- a/src-ui/package.json +++ b/src-ui/package.json @@ -21,6 +21,7 @@ "@angular/platform-browser-dynamic": "~10.1.5", "@angular/router": "~10.1.5", "@ng-bootstrap/ng-bootstrap": "^8.0.0", + "@ng-select/ng-select": "^5.0.9", "bootstrap": "^4.5.0", "ng-bootstrap": "^1.6.3", "ng2-pdf-viewer": "^6.3.2", diff --git a/src-ui/src/app/app.module.ts b/src-ui/src/app/app.module.ts index 095de0f7c..37b3a027d 100644 --- a/src-ui/src/app/app.module.ts +++ b/src-ui/src/app/app.module.ts @@ -54,6 +54,7 @@ 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'; +import { NgSelectModule } from '@ng-select/ng-select'; import { SelectDialogComponent } from './components/common/select-dialog/select-dialog.component'; @NgModule({ @@ -112,7 +113,8 @@ import { SelectDialogComponent } from './components/common/select-dialog/select- ReactiveFormsModule, NgxFileDropModule, InfiniteScrollModule, - PdfViewerModule + PdfViewerModule, + NgSelectModule ], providers: [ DatePipe, diff --git a/src-ui/src/app/components/common/input/select/select.component.html b/src-ui/src/app/components/common/input/select/select.component.html index 717aa7964..d33dae425 100644 --- a/src-ui/src/app/components/common/input/select/select.component.html +++ b/src-ui/src/app/components/common/input/select/select.component.html @@ -1,11 +1,15 @@ -
+
- + + {{i.name}} + +
{{hint}} -
\ No newline at end of file +
diff --git a/src-ui/src/app/components/common/input/select/select.component.scss b/src-ui/src/app/components/common/input/select/select.component.scss index e69de29bb..8faec3bc0 100644 --- a/src-ui/src/app/components/common/input/select/select.component.scss +++ b/src-ui/src/app/components/common/input/select/select.component.scss @@ -0,0 +1 @@ +// styles for ng-select child are in styles.scss diff --git a/src-ui/src/app/components/common/input/tags/tags.component.html b/src-ui/src/app/components/common/input/tags/tags.component.html index 8029dd860..8a5dbc4f2 100644 --- a/src-ui/src/app/components/common/input/tags/tags.component.html +++ b/src-ui/src/app/components/common/input/tags/tags.component.html @@ -1,30 +1,41 @@ -
- +
+ -
-
- -
+
+ -
- -
- -
-
+ + + + + + + + + +
+
+ + + +
+ +
+
+
-
-
{{hint}} -
\ No newline at end of file +
diff --git a/src-ui/src/app/components/common/input/tags/tags.component.scss b/src-ui/src/app/components/common/input/tags/tags.component.scss index f2635b7f2..2eaaa4f6d 100644 --- a/src-ui/src/app/components/common/input/tags/tags.component.scss +++ b/src-ui/src/app/components/common/input/tags/tags.component.scss @@ -1,10 +1,12 @@ -.tags-form-control { - height: auto; +.selected-icon { + min-width: 1em; + min-height: 1em; } +.tag-wrap { + font-size: 1rem; +} -.scrollable-menu { - height: auto; - max-height: 300px; - overflow-x: hidden; -} \ No newline at end of file +.tag-wrap-delete { + cursor: pointer; +} diff --git a/src-ui/src/app/components/common/input/tags/tags.component.ts b/src-ui/src/app/components/common/input/tags/tags.component.ts index cca99cc55..5501ac5a6 100644 --- a/src-ui/src/app/components/common/input/tags/tags.component.ts +++ b/src-ui/src/app/components/common/input/tags/tags.component.ts @@ -21,7 +21,7 @@ export class TagsComponent implements OnInit, ControlValueAccessor { onChange = (newValue: number[]) => {}; - + onTouched = () => {}; writeValue(newValue: number[]): void { @@ -66,29 +66,28 @@ export class TagsComponent implements OnInit, ControlValueAccessor { removeTag(id) { let index = this.displayValue.indexOf(id) if (index > -1) { - this.displayValue.splice(index, 1) + let oldValue = this.displayValue + oldValue.splice(index, 1) + this.displayValue = [...oldValue] this.onChange(this.displayValue) } } - addTag(id) { - let index = this.displayValue.indexOf(id) - if (index == -1) { - this.displayValue.push(id) - this.onChange(this.displayValue) - } - } - - createTag() { var modal = this.modalService.open(TagEditDialogComponent, {backdrop: 'static'}) modal.componentInstance.dialogMode = 'create' modal.componentInstance.success.subscribe(newTag => { this.tagService.listAll().subscribe(tags => { this.tags = tags.results - this.addTag(newTag.id) + this.displayValue = [...this.displayValue, newTag.id] + this.onChange(this.displayValue) }) }) } + ngSelectChange() { + this.value = this.displayValue + this.onChange(this.displayValue) + } + } diff --git a/src-ui/src/app/components/dashboard/dashboard.component.html b/src-ui/src/app/components/dashboard/dashboard.component.html index 627e7ff22..541255a68 100644 --- a/src-ui/src/app/components/dashboard/dashboard.component.html +++ b/src-ui/src/app/components/dashboard/dashboard.component.html @@ -1,4 +1,4 @@ - + diff --git a/src-ui/src/app/components/dashboard/dashboard.component.ts b/src-ui/src/app/components/dashboard/dashboard.component.ts index a14ec5e90..db9b5d425 100644 --- a/src-ui/src/app/components/dashboard/dashboard.component.ts +++ b/src-ui/src/app/components/dashboard/dashboard.component.ts @@ -1,4 +1,5 @@ import { Component, OnInit } from '@angular/core'; +import { Meta } from '@angular/platform-browser'; import { PaperlessSavedView } from 'src/app/data/paperless-saved-view'; import { SavedViewService } from 'src/app/services/rest/saved-view.service'; @@ -11,8 +12,29 @@ import { SavedViewService } from 'src/app/services/rest/saved-view.service'; export class DashboardComponent implements OnInit { constructor( - private savedViewService: SavedViewService) { } + private savedViewService: SavedViewService, + private meta: Meta + ) { } + get displayName() { + let tagFullName = this.meta.getTag('name=full_name') + let tagUsername = this.meta.getTag('name=username') + if (tagFullName && tagFullName.content) { + return tagFullName.content + } else if (tagUsername && tagUsername.content) { + return tagUsername.content + } else { + return null + } + } + + get subtitle() { + if (this.displayName) { + return `Hello ${this.displayName}, welcome to Paperless-ng!` + } else { + return `Welcome to Paperless-ng!` + } + } savedViews: PaperlessSavedView[] = [] diff --git a/src-ui/src/app/components/document-detail/document-detail.component.html b/src-ui/src/app/components/document-detail/document-detail.component.html index f4a64c2cc..228264378 100644 --- a/src-ui/src/app/components/document-detail/document-detail.component.html +++ b/src-ui/src/app/components/document-detail/document-detail.component.html @@ -1,4 +1,14 @@ +
+
+
Page
+
+ +
+
of {{previewNumPages}}
+
+
+
+