diff --git a/src-ui/messages.xlf b/src-ui/messages.xlf index 6270f5373..5f12c504c 100644 --- a/src-ui/messages.xlf +++ b/src-ui/messages.xlf @@ -149,8 +149,8 @@ <context context-type="linenumber">161</context> </context-group> </trans-unit> - <trans-unit id="5277522254327902345" datatype="html"> - <source>Do you really want to delete document '<x id="PH" equiv-text="this.document.title"/>'?</source> + <trans-unit id="5382975254277698192" datatype="html"> + <source>Do you really want to delete document "<x id="PH" equiv-text="this.document.title"/>"?</source> <context-group purpose="location"> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="linenumber">162</context> @@ -373,11 +373,11 @@ <context context-type="linenumber">1</context> </context-group> </trans-unit> - <trans-unit id="2133075428913430816" datatype="html"> - <source>Do you really want to delete the tag <x id="PH" equiv-text="object.name"/>?</source> + <trans-unit id="93754014749412887" datatype="html"> + <source>Do you really want to delete the tag "<x id="PH" equiv-text="object.name"/>"?</source> <context-group purpose="location"> <context context-type="sourcefile">src/app/components/manage/tag-list/tag-list.component.ts</context> - <context context-type="linenumber">30</context> + <context context-type="linenumber">31</context> </context-group> </trans-unit> <trans-unit id="70a67e04629f6d412db0a12d51820b480788d795" datatype="html"> @@ -436,8 +436,8 @@ <context context-type="linenumber">37</context> </context-group> </trans-unit> - <trans-unit id="3954409824493602446" datatype="html"> - <source>Do you really want to delete the document type <x id="PH" equiv-text="object.name"/>?</source> + <trans-unit id="4990731724078522539" datatype="html"> + <source>Do you really want to delete the document type "<x id="PH" equiv-text="object.name"/>"?</source> <context-group purpose="location"> <context context-type="sourcefile">src/app/components/manage/document-type-list/document-type-list.component.ts</context> <context context-type="linenumber">26</context> @@ -576,8 +576,8 @@ <context context-type="linenumber">7</context> </context-group> </trans-unit> - <trans-unit id="2337099367951805921" datatype="html"> - <source>Do you really want to delete the correspondent <x id="PH" equiv-text="object.name"/>?</source> + <trans-unit id="7427874343955308724" datatype="html"> + <source>Do you really want to delete the correspondent "<x id="PH" equiv-text="object.name"/>"?</source> <context-group purpose="location"> <context context-type="sourcefile">src/app/components/manage/correspondent-list/correspondent-list.component.ts</context> <context context-type="linenumber">26</context> @@ -878,11 +878,32 @@ <context context-type="linenumber">4</context> </context-group> </trans-unit> + <trans-unit id="02d184c288f567825a1fcbf83bcd3099a10853d5" datatype="html"> + <source>Filter tags</source> + <context-group purpose="location"> + <context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.html</context> + <context context-type="linenumber">12</context> + </context-group> + </trans-unit> + <trans-unit id="4b089ca12c472cf0b46167bb5afe4b527b301bbc" datatype="html"> + <source>Filter correspondents</source> + <context-group purpose="location"> + <context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.html</context> + <context context-type="linenumber">19</context> + </context-group> + </trans-unit> + <trans-unit id="0ad509732aaf702b7ea8c771c7809fa84bc85908" datatype="html"> + <source>Filter document types</source> + <context-group purpose="location"> + <context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.html</context> + <context context-type="linenumber">25</context> + </context-group> + </trans-unit> <trans-unit id="2f33515a935c36763660e8420940b8a7e11fb1f4" datatype="html"> <source>Clear all filters</source> <context-group purpose="location"> <context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.html</context> - <context context-type="linenumber">23</context> + <context context-type="linenumber">47</context> </context-group> </trans-unit> <trans-unit id="7593728289020204896" datatype="html"> @@ -891,6 +912,7 @@ <context context-type="sourcefile">src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts</context> <context context-type="linenumber">145</context> </context-group> + <note priority="1" from="description">Filter drop down element to filter for documents with no correspondent/type/tag assigned</note> </trans-unit> <trans-unit id="c2d0ac9f528bbd5f53fd34269fde8b59e029621b" datatype="html"> <source>Apply</source> @@ -990,12 +1012,20 @@ <context context-type="linenumber">40</context> </context-group> </trans-unit> - <trans-unit id="5033601776243148314" datatype="html"> - <source><x id="PH" equiv-text="items[0].name"/> and <x id="PH_1" equiv-text="items[1].name"/></source> + <trans-unit id="8639884465898458690" datatype="html"> + <source>"<x id="PH" equiv-text="items[0].name"/>" and "<x id="PH_1" equiv-text="items[1].name"/>"</source> <context-group purpose="location"> <context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context> <context context-type="linenumber">103</context> </context-group> + <note priority="1" from="description">This is for messages like 'modify "tag1" and "tag2"'</note> + </trans-unit> + <trans-unit id="7894972847287473517" datatype="html"> + <source>"<x id="PH" equiv-text="i.name"/>"</source> + <context-group purpose="location"> + <context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context> + <context context-type="linenumber">105</context> + </context-group> </trans-unit> <trans-unit id="760986369763309193" datatype="html"> <source>, </source> @@ -1003,6 +1033,15 @@ <context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context> <context context-type="linenumber">105</context> </context-group> + <note priority="1" from="description">this is used to separate enumerations and should probably be a comma and a whitespace in most languages</note> + </trans-unit> + <trans-unit id="1822679894391095557" datatype="html"> + <source><x id="PH" equiv-text="list"/> and "<x id="PH_1" equiv-text="items[items.length - 1].name"/>"</source> + <context-group purpose="location"> + <context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context> + <context context-type="linenumber">106</context> + </context-group> + <note priority="1" from="description">this is for messages like 'modify "tag1", "tag2" and "tag3"'</note> </trans-unit> <trans-unit id="4137232459980262849" datatype="html"> <source>Confirm tags assignment</source> @@ -1011,36 +1050,36 @@ <context context-type="linenumber">115</context> </context-group> </trans-unit> - <trans-unit id="5778291417880283825" datatype="html"> - <source>This operation will add the tag <x id="PH" equiv-text="tag.name"/> to all <x id="PH_1" equiv-text="this.list.selected.size"/> selected document(s).</source> + <trans-unit id="6619516195038467207" datatype="html"> + <source>This operation will add the tag "<x id="PH" equiv-text="tag.name"/>" to <x id="PH_1" equiv-text="this.list.selected.size"/> selected document(s).</source> <context-group purpose="location"> <context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context> <context context-type="linenumber">118</context> </context-group> </trans-unit> - <trans-unit id="4791265247184178563" datatype="html"> - <source>This operation will add the tags <x id="PH" equiv-text="this._localizeList(changedTags.itemsToAdd)"/> to all <x id="PH_1" equiv-text="this.list.selected.size"/> selected document(s).</source> + <trans-unit id="1894412783609570695" datatype="html"> + <source>This operation will add the tags <x id="PH" equiv-text="this._localizeList(changedTags.itemsToAdd)"/> to <x id="PH_1" equiv-text="this.list.selected.size"/> selected document(s).</source> <context-group purpose="location"> <context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context> <context context-type="linenumber">120</context> </context-group> </trans-unit> - <trans-unit id="7202114001606049276" datatype="html"> - <source>This operation will remove the tag <x id="PH" equiv-text="tag.name"/> from all <x id="PH_1" equiv-text="this.list.selected.size"/> selected document(s).</source> + <trans-unit id="7181166515756808573" datatype="html"> + <source>This operation will remove the tag "<x id="PH" equiv-text="tag.name"/>" from <x id="PH_1" equiv-text="this.list.selected.size"/> selected document(s).</source> <context-group purpose="location"> <context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context> <context context-type="linenumber">123</context> </context-group> </trans-unit> - <trans-unit id="247266594076352528" datatype="html"> - <source>This operation will remove the tags <x id="PH" equiv-text="this._localizeList(changedTags.itemsToRemove)"/> from all <x id="PH_1" equiv-text="this.list.selected.size"/> selected document(s).</source> + <trans-unit id="3819792277998068944" datatype="html"> + <source>This operation will remove the tags <x id="PH" equiv-text="this._localizeList(changedTags.itemsToRemove)"/> from <x id="PH_1" equiv-text="this.list.selected.size"/> selected document(s).</source> <context-group purpose="location"> <context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context> <context context-type="linenumber">125</context> </context-group> </trans-unit> - <trans-unit id="4286636723521919383" datatype="html"> - <source>This operation will add the tags <x id="PH" equiv-text="this._localizeList(changedTags.itemsToAdd)"/> and remove the tags <x id="PH_1" equiv-text="this._localizeList(changedTags.itemsToRemove)"/> on all <x id="PH_2" equiv-text="this.list.selected.size"/> selected document(s).</source> + <trans-unit id="2739066218579571288" datatype="html"> + <source>This operation will add the tags <x id="PH" equiv-text="this._localizeList(changedTags.itemsToAdd)"/> and remove the tags <x id="PH_1" equiv-text="this._localizeList(changedTags.itemsToRemove)"/> on <x id="PH_2" equiv-text="this.list.selected.size"/> selected document(s).</source> <context-group purpose="location"> <context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context> <context context-type="linenumber">127</context> @@ -1053,15 +1092,15 @@ <context context-type="linenumber">157</context> </context-group> </trans-unit> - <trans-unit id="9000739289559833849" datatype="html"> - <source>This operation will assign the correspondent <x id="PH" equiv-text="correspondent.name"/> to all <x id="PH_1" equiv-text="this.list.selected.size"/> selected document(s).</source> + <trans-unit id="6900893559485781849" datatype="html"> + <source>This operation will assign the correspondent "<x id="PH" equiv-text="correspondent.name"/>" to <x id="PH_1" equiv-text="this.list.selected.size"/> selected document(s).</source> <context-group purpose="location"> <context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context> <context context-type="linenumber">159</context> </context-group> </trans-unit> - <trans-unit id="5197985579238314950" datatype="html"> - <source>This operation will remove the correspondent from all <x id="PH" equiv-text="this.list.selected.size"/> selected document(s).</source> + <trans-unit id="1257522660364398440" datatype="html"> + <source>This operation will remove the correspondent from <x id="PH" equiv-text="this.list.selected.size"/> selected document(s).</source> <context-group purpose="location"> <context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context> <context context-type="linenumber">161</context> @@ -1074,15 +1113,15 @@ <context context-type="linenumber">190</context> </context-group> </trans-unit> - <trans-unit id="471313288900612996" datatype="html"> - <source>This operation will assign the document type <x id="PH" equiv-text="documentType.name"/> to all <x id="PH_1" equiv-text="this.list.selected.size"/> selected document(s).</source> + <trans-unit id="332180123895325027" datatype="html"> + <source>This operation will assign the document type "<x id="PH" equiv-text="documentType.name"/>" to <x id="PH_1" equiv-text="this.list.selected.size"/> selected document(s).</source> <context-group purpose="location"> <context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context> <context context-type="linenumber">192</context> </context-group> </trans-unit> - <trans-unit id="6005206188202839923" datatype="html"> - <source>This operation will remove the document type from all <x id="PH" equiv-text="this.list.selected.size"/> selected document(s).</source> + <trans-unit id="2236642492594872779" datatype="html"> + <source>This operation will remove the document type from <x id="PH" equiv-text="this.list.selected.size"/> selected document(s).</source> <context-group purpose="location"> <context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context> <context context-type="linenumber">194</context> @@ -1095,8 +1134,8 @@ <context context-type="linenumber">219</context> </context-group> </trans-unit> - <trans-unit id="3928393581343272038" datatype="html"> - <source>This operation will permanently delete all <x id="PH" equiv-text="this.list.selected.size"/> selected document(s).</source> + <trans-unit id="4303174930844518780" datatype="html"> + <source>This operation will permanently delete <x id="PH" equiv-text="this.list.selected.size"/> selected document(s).</source> <context-group purpose="location"> <context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context> <context context-type="linenumber">220</context> @@ -1214,8 +1253,15 @@ <context context-type="linenumber">5</context> </context-group> </trans-unit> - <trans-unit id="1be5ea6494cb95abc74f42ee9cfddb7ba3a53709" datatype="html"> - <source>Uploading <x id="INTERPOLATION" equiv-text="{{uploadStatus.length}}"/> file(s)</source> + <trans-unit id="a7b50b2df68e875a918d1f4f98f358d756139c13" datatype="html"> + <source>{VAR_PLURAL, plural, =1 {file} =other {<x id="INTERPOLATION"/> files}}</source> + <context-group purpose="location"> + <context context-type="sourcefile">src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html</context> + <context context-type="linenumber">13</context> + </context-group> + </trans-unit> + <trans-unit id="ec37c68a90632530f5cc8b7e5245cab89ef8bf82" datatype="html"> + <source>Uploading <x id="ICU" equiv-text="{uploadStatus.length, plural, =1 {file} =other {{{uploadStatus.length}} files}}"/>...</source> <context-group purpose="location"> <context context-type="sourcefile">src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html</context> <context context-type="linenumber">13</context> @@ -1235,15 +1281,15 @@ <context context-type="linenumber">5</context> </context-group> </trans-unit> - <trans-unit id="73d73c4f994d21fcb441cf316884db54693be3fa" datatype="html"> - <source>You can start uploading documents by dropping them in the file upload box to the right or by dropping them in the configured consumption folder and they'll start showing up in the documents list. After you've added some metadata to your documents, use the filtering mechanisms of paperless to create custom views (such as 'Recently added', 'Tagged TODO') and have them displayed on the dashboard instead of this message.</source> + <trans-unit id="ea8d9a9486d5639d1c38c012900b8d34d5e4135d" datatype="html"> + <source>You can start uploading documents by dropping them in the file upload box to the right or by dropping them in the configured consumption folder and they'll start showing up in the documents list. After you've added some metadata to your documents, use the filtering mechanisms of paperless to create custom views (such as 'Recently added', 'Tagged TODO') and they will appear on the dashboard instead of this message.</source> <context-group purpose="location"> <context context-type="sourcefile">src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html</context> <context context-type="linenumber">6,7</context> </context-group> </trans-unit> - <trans-unit id="0b87e4267fd45103b1a9c474d243b3366dbf12ee" datatype="html"> - <source>Paperless offers some more features that try to make your life easier, such as:</source> + <trans-unit id="cf5f85690feaba6e29343f9881e57a6c0ea6e82b" datatype="html"> + <source>Paperless offers some more features that try to make your life easier:</source> <context-group purpose="location"> <context context-type="sourcefile">src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html</context> <context context-type="linenumber">8</context> diff --git a/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.html b/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.html index 7215faa79..015269c17 100644 --- a/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.html +++ b/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -16,7 +16,7 @@ <div class="list-group list-group-flush"> <div class="list-group-item"> <div class="input-group input-group-sm"> - <input class="form-control" type="text" [(ngModel)]="filterText" placeholder="Filter {{title}}" (keyup.enter)="listFilterEnter()" #listFilterTextInput> + <input class="form-control" type="text" [(ngModel)]="filterText" [placeholder]="filterPlaceholder" (keyup.enter)="listFilterEnter()" #listFilterTextInput> </div> </div> <div *ngIf="selectionModel.items" class="items"> diff --git a/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts b/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts index 915d10677..e1aa6a06a 100644 --- a/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts +++ b/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts @@ -142,7 +142,7 @@ export class FilterableDropdownComponent { if (items) { this._selectionModel.items = Array.from(items) this._selectionModel.items.unshift({ - name: $localize`Not assigned`, + name: $localize`:Filter drop down element to filter for documents with no correspondent/type/tag assigned:Not assigned`, id: null }) } @@ -186,6 +186,9 @@ export class FilterableDropdownComponent { @Input() title: string + @Input() + filterPlaceholder: string = "" + @Input() icon: string diff --git a/src-ui/src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html b/src-ui/src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html index 91fff4e83..38aff96ab 100644 --- a/src-ui/src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html +++ b/src-ui/src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html @@ -10,7 +10,7 @@ </ngx-file-drop> </form> <div *ngIf="uploadVisible" class="mt-3"> - <p i18n>Uploading {{uploadStatus.length}} file(s)</p> + <p i18n>Uploading {uploadStatus.length, plural, =1 {file} =other {{{uploadStatus.length}} files}}...</p> <ngb-progressbar [value]="loadedSum" [max]="totalSum" [striped]="true" [animated]="uploadStatus.length > 0"> </ngb-progressbar> </div> diff --git a/src-ui/src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html b/src-ui/src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html index 6c9c34d5b..6320189cc 100644 --- a/src-ui/src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html +++ b/src-ui/src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html @@ -4,8 +4,8 @@ <img src="assets/save-filter.png" class="float-right"> <p i18n>Paperless is running! :)</p> <p i18n>You can start uploading documents by dropping them in the file upload box to the right or by dropping them in the configured consumption folder and they'll start showing up in the documents list. - After you've added some metadata to your documents, use the filtering mechanisms of paperless to create custom views (such as 'Recently added', 'Tagged TODO') and have them displayed on the dashboard instead of this message.</p> - <p i18n>Paperless offers some more features that try to make your life easier, such as:</p> + After you've added some metadata to your documents, use the filtering mechanisms of paperless to create custom views (such as 'Recently added', 'Tagged TODO') and they will appear on the dashboard instead of this message.</p> + <p i18n>Paperless offers some more features that try to make your life easier:</p> <ul> <li i18n>Once you've got a couple documents in paperless and added metadata to them, paperless can assign that metadata to new documents automatically.</li> <li i18n>You can configure paperless to read your mails and add documents from attached files.</li> diff --git a/src-ui/src/app/components/document-detail/document-detail.component.ts b/src-ui/src/app/components/document-detail/document-detail.component.ts index 2efd32f27..053258f34 100644 --- a/src-ui/src/app/components/document-detail/document-detail.component.ts +++ b/src-ui/src/app/components/document-detail/document-detail.component.ts @@ -159,7 +159,7 @@ export class DocumentDetailComponent implements OnInit { delete() { let modal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'}) modal.componentInstance.title = $localize`Confirm delete` - modal.componentInstance.messageBold = $localize`Do you really want to delete document '${this.document.title}'?` + modal.componentInstance.messageBold = $localize`Do you really want to delete document "${this.document.title}"?` modal.componentInstance.message = $localize`The files for this document will be deleted permanently. This operation cannot be undone.` modal.componentInstance.btnClass = "btn-danger" modal.componentInstance.btnCaption = $localize`Delete document` diff --git a/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.html b/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.html index 62a2bb95d..b9912ec1d 100644 --- a/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.html +++ b/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -26,7 +26,8 @@ <div class="col-auto mb-2 mb-xl-0"> <div class="d-flex"> <label class="ml-auto mt-1 mb-0 mr-2" i18n>Edit:</label> - <app-filterable-dropdown class="mr-2 mr-md-3" title="Tags" icon="tag-fill" + <app-filterable-dropdown class="mr-2 mr-md-3" title="Tags" icon="tag-fill" i18n-title + filterPlaceholder="Filter tags" i18n-filterPlaceholder [items]="tags" [editing]="true" [multiple]="true" @@ -35,7 +36,8 @@ [(selectionModel)]="tagSelectionModel" (apply)="setTags($event)"> </app-filterable-dropdown> - <app-filterable-dropdown class="mr-2 mr-md-3" title="Correspondent" icon="person-fill" + <app-filterable-dropdown class="mr-2 mr-md-3" title="Correspondent" icon="person-fill" i18n-title + filterPlaceholder="Filter correspondents" i18n-filterPlaceholder [items]="correspondents" [editing]="true" [applyOnClose]="applyOnClose" @@ -43,7 +45,8 @@ [(selectionModel)]="correspondentSelectionModel" (apply)="setCorrespondents($event)"> </app-filterable-dropdown> - <app-filterable-dropdown class="mr-2 mr-md-3" title="Document Type" icon="file-earmark-fill" + <app-filterable-dropdown class="mr-2 mr-md-3" title="Document type" icon="file-earmark-fill" i18n-title + filterPlaceholder="Filter document types" i18n-filterPlaceholder [items]="documentTypes" [editing]="true" [applyOnClose]="applyOnClose" diff --git a/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.ts b/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.ts index 88efcee06..e69ab241b 100644 --- a/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.ts +++ b/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.ts @@ -100,10 +100,10 @@ export class BulkEditorComponent { } else if (items.length == 1) { return items[0].name } else if (items.length == 2) { - return $localize`${items[0].name} and ${items[1].name}` + return $localize`:This is for messages like 'modify "tag1" and "tag2"':"${items[0].name}" and "${items[1].name}"` } else { - let list = items.slice(0, items.length - 1).map(i => i.name).join($localize`, `) - return $localize`${list} and ${items[items.length - 1].name}` + let list = items.slice(0, items.length - 1).map(i => $localize`"${i.name}"`).join($localize`:this is used to separate enumerations and should probably be a comma and a whitespace in most languages:, `) + return $localize`:this is for messages like 'modify "tag1", "tag2" and "tag3"':${list} and "${items[items.length - 1].name}"` } } @@ -115,16 +115,16 @@ export class BulkEditorComponent { modal.componentInstance.title = $localize`Confirm tags assignment` if (changedTags.itemsToAdd.length == 1 && changedTags.itemsToRemove.length == 0) { let tag = changedTags.itemsToAdd[0] - modal.componentInstance.message = $localize`This operation will add the tag ${tag.name} to all ${this.list.selected.size} selected document(s).` + modal.componentInstance.message = $localize`This operation will add the tag "${tag.name}" to ${this.list.selected.size} selected document(s).` } else if (changedTags.itemsToAdd.length > 1 && changedTags.itemsToRemove.length == 0) { - modal.componentInstance.message = $localize`This operation will add the tags ${this._localizeList(changedTags.itemsToAdd)} to all ${this.list.selected.size} selected document(s).` + modal.componentInstance.message = $localize`This operation will add the tags ${this._localizeList(changedTags.itemsToAdd)} to ${this.list.selected.size} selected document(s).` } else if (changedTags.itemsToAdd.length == 0 && changedTags.itemsToRemove.length == 1) { let tag = changedTags.itemsToRemove[0] - modal.componentInstance.message = $localize`This operation will remove the tag ${tag.name} from all ${this.list.selected.size} selected document(s).` + modal.componentInstance.message = $localize`This operation will remove the tag "${tag.name}" from ${this.list.selected.size} selected document(s).` } else if (changedTags.itemsToAdd.length == 0 && changedTags.itemsToRemove.length > 1) { - modal.componentInstance.message = $localize`This operation will remove the tags ${this._localizeList(changedTags.itemsToRemove)} from all ${this.list.selected.size} selected document(s).` + modal.componentInstance.message = $localize`This operation will remove the tags ${this._localizeList(changedTags.itemsToRemove)} from ${this.list.selected.size} selected document(s).` } else { - modal.componentInstance.message = $localize`This operation will add the tags ${this._localizeList(changedTags.itemsToAdd)} and remove the tags ${this._localizeList(changedTags.itemsToRemove)} on all ${this.list.selected.size} selected document(s).` + modal.componentInstance.message = $localize`This operation will add the tags ${this._localizeList(changedTags.itemsToAdd)} and remove the tags ${this._localizeList(changedTags.itemsToRemove)} on ${this.list.selected.size} selected document(s).` } modal.componentInstance.btnClass = "btn-warning" @@ -156,9 +156,9 @@ export class BulkEditorComponent { let modal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'}) modal.componentInstance.title = $localize`Confirm correspondent assignment` if (correspondent) { - modal.componentInstance.message = $localize`This operation will assign the correspondent ${correspondent.name} to all ${this.list.selected.size} selected document(s).` + modal.componentInstance.message = $localize`This operation will assign the correspondent "${correspondent.name}" to ${this.list.selected.size} selected document(s).` } else { - modal.componentInstance.message = $localize`This operation will remove the correspondent from all ${this.list.selected.size} selected document(s).` + modal.componentInstance.message = $localize`This operation will remove the correspondent from ${this.list.selected.size} selected document(s).` } modal.componentInstance.btnClass = "btn-warning" modal.componentInstance.btnCaption = $localize`Confirm` @@ -189,9 +189,9 @@ export class BulkEditorComponent { let modal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'}) modal.componentInstance.title = $localize`Confirm document type assignment` if (documentType) { - modal.componentInstance.message = $localize`This operation will assign the document type ${documentType.name} to all ${this.list.selected.size} selected document(s).` + modal.componentInstance.message = $localize`This operation will assign the document type "${documentType.name}" to ${this.list.selected.size} selected document(s).` } else { - modal.componentInstance.message = $localize`This operation will remove the document type from all ${this.list.selected.size} selected document(s).` + modal.componentInstance.message = $localize`This operation will remove the document type from ${this.list.selected.size} selected document(s).` } modal.componentInstance.btnClass = "btn-warning" modal.componentInstance.btnCaption = $localize`Confirm` @@ -217,7 +217,7 @@ export class BulkEditorComponent { let modal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'}) modal.componentInstance.delayConfirm(5) modal.componentInstance.title = $localize`Delete confirm` - modal.componentInstance.messageBold = $localize`This operation will permanently delete all ${this.list.selected.size} selected document(s).` + modal.componentInstance.messageBold = $localize`This operation will permanently delete ${this.list.selected.size} selected document(s).` modal.componentInstance.message = $localize`This operation cannot be undone.` modal.componentInstance.btnClass = "btn-danger" modal.componentInstance.btnCaption = $localize`Delete document(s)` diff --git a/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.html b/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.html index f0c83ae73..efbf6ce7e 100644 --- a/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.html +++ b/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.html @@ -6,13 +6,37 @@ </div> </div> <div class="w-100 d-xl-none"></div> - <div class="col col-xl-auto mb-2 mb-xl-0"> - <div class="d-flex"> - <app-filterable-dropdown class="mr-2 mr-md-3" [items]="tags" [(selectionModel)]="tagSelectionModel" (selectionModelChange)="updateRules()" [multiple]="true" [allowSelectNone]="true" title="Tags" icon="tag-fill" i18n-title></app-filterable-dropdown> - <app-filterable-dropdown class="mr-2 mr-md-3" [items]="correspondents" [(selectionModel)]="correspondentSelectionModel" (selectionModelChange)="updateRules()" [allowSelectNone]="true" title="Correspondents" icon="person-fill" i18n-title></app-filterable-dropdown> - <app-filterable-dropdown class="mr-2 mr-md-3" [items]="documentTypes" [(selectionModel)]="documentTypeSelectionModel" (selectionModelChange)="updateRules()" [allowSelectNone]="true" title="Document types" icon="file-earmark-fill" i18n-title></app-filterable-dropdown> - <app-date-dropdown class="mr-2 mr-md-3" [(dateBefore)]="dateCreatedBefore" [(dateAfter)]="dateCreatedAfter" title="Created" (datesSet)="updateRules()" i18n-title></app-date-dropdown> - <app-date-dropdown [(dateBefore)]="dateAddedBefore" [(dateAfter)]="dateAddedAfter" title="Added" (datesSet)="updateRules()" i18n-title></app-date-dropdown> + <div class="col col-xl-auto mb-2 mb-xl-0"> + <div class="d-flex"> + <app-filterable-dropdown class="mr-2 mr-md-3" title="Tags" icon="tag-fill" i18n-title + filterPlaceholder="Filter tags" i18n-filterPlaceholder + [items]="tags" + [(selectionModel)]="tagSelectionModel" + (selectionModelChange)="updateRules()" + [multiple]="true" + [allowSelectNone]="true"></app-filterable-dropdown> + <app-filterable-dropdown class="mr-2 mr-md-3" title="Correspondent" icon="person-fill" i18n-title + filterPlaceholder="Filter correspondents" i18n-filterPlaceholder + [items]="correspondents" + [(selectionModel)]="correspondentSelectionModel" + (selectionModelChange)="updateRules()" + [allowSelectNone]="true"></app-filterable-dropdown> + <app-filterable-dropdown class="mr-2 mr-md-3" title="Document type" icon="file-earmark-fill" i18n-title + filterPlaceholder="Filter document types" i18n-filterPlaceholder + [items]="documentTypes" + [(selectionModel)]="documentTypeSelectionModel" + (selectionModelChange)="updateRules()" + [allowSelectNone]="true"></app-filterable-dropdown> + <app-date-dropdown class="mr-2 mr-md-3" + title="Created" i18n-title + (datesSet)="updateRules()" + [(dateBefore)]="dateCreatedBefore" + [(dateAfter)]="dateCreatedAfter"></app-date-dropdown> + <app-date-dropdown + [(dateBefore)]="dateAddedBefore" + [(dateAfter)]="dateAddedAfter" + title="Added" i18n-title + (datesSet)="updateRules()"></app-date-dropdown> </div> </div> <div class="w-100 d-xl-none"></div> diff --git a/src-ui/src/app/components/manage/correspondent-list/correspondent-list.component.ts b/src-ui/src/app/components/manage/correspondent-list/correspondent-list.component.ts index bc3bf7b02..d3b71b4ab 100644 --- a/src-ui/src/app/components/manage/correspondent-list/correspondent-list.component.ts +++ b/src-ui/src/app/components/manage/correspondent-list/correspondent-list.component.ts @@ -23,7 +23,7 @@ export class CorrespondentListComponent extends GenericListComponent<PaperlessCo } getDeleteMessage(object: PaperlessCorrespondent) { - return $localize`Do you really want to delete the correspondent ${object.name}?` + return $localize`Do you really want to delete the correspondent "${object.name}"?` } filterDocuments(object: PaperlessCorrespondent) { diff --git a/src-ui/src/app/components/manage/document-type-list/document-type-list.component.ts b/src-ui/src/app/components/manage/document-type-list/document-type-list.component.ts index b376b2576..66469619c 100644 --- a/src-ui/src/app/components/manage/document-type-list/document-type-list.component.ts +++ b/src-ui/src/app/components/manage/document-type-list/document-type-list.component.ts @@ -23,7 +23,7 @@ export class DocumentTypeListComponent extends GenericListComponent<PaperlessDoc } getDeleteMessage(object: PaperlessDocumentType) { - return $localize`Do you really want to delete the document type ${object.name}?` + return $localize`Do you really want to delete the document type "${object.name}"?` } diff --git a/src-ui/src/app/components/manage/tag-list/tag-list.component.ts b/src-ui/src/app/components/manage/tag-list/tag-list.component.ts index e43410f41..3d1ccd778 100644 --- a/src-ui/src/app/components/manage/tag-list/tag-list.component.ts +++ b/src-ui/src/app/components/manage/tag-list/tag-list.component.ts @@ -27,7 +27,8 @@ export class TagListComponent extends GenericListComponent<PaperlessTag> { } getDeleteMessage(object: PaperlessTag) { - return $localize`Do you really want to delete the tag ${object.name}?` + + return $localize`Do you really want to delete the tag "${object.name}"?` } filterDocuments(object: PaperlessTag) { diff --git a/src-ui/src/app/services/open-documents.service.ts b/src-ui/src/app/services/open-documents.service.ts index c91031f83..9e5746c10 100644 --- a/src-ui/src/app/services/open-documents.service.ts +++ b/src-ui/src/app/services/open-documents.service.ts @@ -28,6 +28,9 @@ export class OpenDocumentsService { if (index > -1) { this.documentService.get(id).subscribe(doc => { this.openDocuments[index] = doc + }, error => { + this.openDocuments.splice(index, 1) + this.save() }) } } diff --git a/src/documents/management/commands/document_thumbnails.py b/src/documents/management/commands/document_thumbnails.py new file mode 100644 index 000000000..01df14624 --- /dev/null +++ b/src/documents/management/commands/document_thumbnails.py @@ -0,0 +1,68 @@ +import logging +import multiprocessing +import shutil + +import tqdm +from django import db +from django.core.management.base import BaseCommand + +from documents.models import Document +from ...mixins import Renderable +from ...parsers import get_parser_class_for_mime_type + + +def _process_document(doc_in): + document = Document.objects.get(id=doc_in) + parser = get_parser_class_for_mime_type(document.mime_type)( + logging_group=None) + try: + thumb = parser.get_optimised_thumbnail( + document.source_path, document.mime_type) + + shutil.move(thumb, document.thumbnail_path) + finally: + parser.cleanup() + + +class Command(Renderable, BaseCommand): + + help = """ + This will regenerate the thumbnails for all documents. + """.replace(" ", "") + + def __init__(self, *args, **kwargs): + self.verbosity = 0 + BaseCommand.__init__(self, *args, **kwargs) + + def add_arguments(self, parser): + parser.add_argument( + "-d", "--document", + default=None, + type=int, + required=False, + help="Specify the ID of a document, and this command will only " + "run on this specific document." + ) + + def handle(self, *args, **options): + + self.verbosity = options["verbosity"] + + logging.getLogger().handlers[0].level = logging.ERROR + + if options['document']: + documents = Document.objects.filter(pk=options['document']) + else: + documents = Document.objects.all() + + ids = [doc.id for doc in documents] + + # Note to future self: this prevents django from reusing database + # conncetions between processes, which is bad and does not work + # with postgres. + db.connections.close_all() + + with multiprocessing.Pool() as pool: + list(tqdm.tqdm( + pool.imap_unordered(_process_document, ids), total=len(ids) + )) diff --git a/src/documents/parsers.py b/src/documents/parsers.py index cbbb912de..725e605a2 100644 --- a/src/documents/parsers.py +++ b/src/documents/parsers.py @@ -117,6 +117,7 @@ def run_convert(input_file, trim=False, type=None, depth=None, + auto_orient=False, extra=None, logging_group=None): @@ -134,6 +135,7 @@ def run_convert(input_file, args += ['-trim'] if trim else [] args += ['-type', str(type)] if type else [] args += ['-depth', str(depth)] if depth else [] + args += ['-auto-orient'] if auto_orient else [] args += [input_file, output_file] logger.debug("Execute: " + " ".join(args), extra={'group': logging_group}) diff --git a/src/documents/signals/handlers.py b/src/documents/signals/handlers.py index 586897585..f2743c212 100755 --- a/src/documents/signals/handlers.py +++ b/src/documents/signals/handlers.py @@ -276,13 +276,6 @@ def update_filename_and_move_files(sender, instance, **kwargs): Document.objects.filter(pk=instance.pk).update( filename=new_filename) - logging.getLogger(__name__).debug( - f"Moved file {old_source_path} to {new_source_path}.") - - if instance.archive_checksum: - logging.getLogger(__name__).debug( - f"Moved file {old_archive_path} to {new_archive_path}.") - except OSError as e: instance.filename = old_filename # this happens when we can't move a file. If that's the case for diff --git a/src/documents/tasks.py b/src/documents/tasks.py index f9937c177..ba7010ea9 100644 --- a/src/documents/tasks.py +++ b/src/documents/tasks.py @@ -94,7 +94,10 @@ def bulk_update_documents(document_ids): documents = Document.objects.filter(id__in=document_ids) ix = index.open_index() + + for doc in documents: + post_save.send(Document, instance=doc, created=False) + with AsyncWriter(ix) as writer: for doc in documents: index.update_document(writer, doc) - post_save.send(Document, instance=doc, created=False) diff --git a/src/paperless_tesseract/parsers.py b/src/paperless_tesseract/parsers.py index 80e200f27..4da5af2c0 100644 --- a/src/paperless_tesseract/parsers.py +++ b/src/paperless_tesseract/parsers.py @@ -60,6 +60,7 @@ class RasterisedDocumentParser(DocumentParser): alpha="remove", strip=True, trim=False, + auto_orient=True, input_file="{}[0]".format(document_path), output_file=out_path, logging_group=self.logging_group) @@ -84,6 +85,7 @@ class RasterisedDocumentParser(DocumentParser): alpha="remove", strip=True, trim=False, + auto_orient=True, input_file=gs_out_path, output_file=out_path, logging_group=self.logging_group)