Compare commits

..

8 Commits

Author SHA1 Message Date
shamoon
ec12e71487 Basic option selection 2024-11-08 20:36:58 -08:00
shamoon
62b470f691 Retry action, basic frontend, cleanup handler 2024-11-07 18:47:48 -08:00
shamoon
a2e4977201 Fix for ci 2024-11-07 13:29:15 -08:00
shamoon
0fcd69b739 Move it out of consumer 2024-11-07 13:19:06 -08:00
shamoon
af1c64e969 Try this 2024-11-07 12:28:20 -08:00
shamoon
85c661dff2 Update consumer.py 2024-11-07 10:44:58 -08:00
shamoon
3a7eee2c2e Fix tests 2024-11-07 10:32:15 -08:00
shamoon
bc4d3925cc Messing around 2024-10-30 01:04:14 -07:00
54 changed files with 3874 additions and 1855 deletions

View File

@@ -98,7 +98,7 @@ body:
label: Browser label: Browser
description: Which browser you are using, if relevant. description: Which browser you are using, if relevant.
placeholder: e.g. Chrome, Safari placeholder: e.g. Chrome, Safari
- type: textarea - type: input
id: config-changes id: config-changes
attributes: attributes:
label: Configuration changes label: Configuration changes

View File

@@ -1,52 +1,5 @@
# Changelog # Changelog
## paperless-ngx 2.13.3
### Bug Fixes
- Fix: fix auto-clean PDFs, create parent dir for storing unmodified original [@shamoon](https://github.com/shamoon) ([#8157](https://github.com/paperless-ngx/paperless-ngx/pull/8157))
- Fix: correctly handle exists, false in custom field query filter @yichi-yang ([#8158](https://github.com/paperless-ngx/paperless-ngx/pull/8158))
- Fix: dont use filters for inverted thumbnails in Safari [@shamoon](https://github.com/shamoon) ([#8121](https://github.com/paperless-ngx/paperless-ngx/pull/8121))
- Fix: use static object for activedisplayfields to prevent changes [@shamoon](https://github.com/shamoon) ([#8120](https://github.com/paperless-ngx/paperless-ngx/pull/8120))
- Fix: dont invert pdf colors in FF [@shamoon](https://github.com/shamoon) ([#8110](https://github.com/paperless-ngx/paperless-ngx/pull/8110))
- Fix: make mail account password and refresh token text fields [@shamoon](https://github.com/shamoon) ([#8107](https://github.com/paperless-ngx/paperless-ngx/pull/8107))
### Dependencies
<details>
<summary>8 changes</summary>
- Chore(deps-dev): Bump the frontend-eslint-dependencies group in /src-ui with 4 updates [@dependabot](https://github.com/dependabot) ([#8145](https://github.com/paperless-ngx/paperless-ngx/pull/8145))
- Chore(deps-dev): Bump @types/node from 22.7.4 to 22.8.6 in /src-ui [@dependabot](https://github.com/dependabot) ([#8148](https://github.com/paperless-ngx/paperless-ngx/pull/8148))
- Chore(deps-dev): Bump @playwright/test from 1.47.2 to 1.48.2 in /src-ui [@dependabot](https://github.com/dependabot) ([#8147](https://github.com/paperless-ngx/paperless-ngx/pull/8147))
- Chore(deps): Bump uuid from 10.0.0 to 11.0.2 in /src-ui [@dependabot](https://github.com/dependabot) ([#8146](https://github.com/paperless-ngx/paperless-ngx/pull/8146))
- Chore(deps): Bump tslib from 2.7.0 to 2.8.1 in /src-ui [@dependabot](https://github.com/dependabot) ([#8149](https://github.com/paperless-ngx/paperless-ngx/pull/8149))
- Chore(deps-dev): Bump @codecov/webpack-plugin from 1.2.0 to 1.2.1 in /src-ui [@dependabot](https://github.com/dependabot) ([#8150](https://github.com/paperless-ngx/paperless-ngx/pull/8150))
- Chore(deps-dev): Bump @types/jest from 29.5.13 to 29.5.14 in /src-ui in the frontend-jest-dependencies group [@dependabot](https://github.com/dependabot) ([#8144](https://github.com/paperless-ngx/paperless-ngx/pull/8144))
- Chore(deps): Bump the frontend-angular-dependencies group in /src-ui with 21 updates [@dependabot](https://github.com/dependabot) ([#8143](https://github.com/paperless-ngx/paperless-ngx/pull/8143))
</details>
### All App Changes
<details>
<summary>14 changes</summary>
- Fix: fix auto-clean PDFs, create parent dir for storing unmodified original [@shamoon](https://github.com/shamoon) ([#8157](https://github.com/paperless-ngx/paperless-ngx/pull/8157))
- Fix: correctly handle exists, false in custom field query filter @yichi-yang ([#8158](https://github.com/paperless-ngx/paperless-ngx/pull/8158))
- Chore(deps-dev): Bump the frontend-eslint-dependencies group in /src-ui with 4 updates [@dependabot](https://github.com/dependabot) ([#8145](https://github.com/paperless-ngx/paperless-ngx/pull/8145))
- Chore(deps-dev): Bump @types/node from 22.7.4 to 22.8.6 in /src-ui [@dependabot](https://github.com/dependabot) ([#8148](https://github.com/paperless-ngx/paperless-ngx/pull/8148))
- Chore(deps-dev): Bump @playwright/test from 1.47.2 to 1.48.2 in /src-ui [@dependabot](https://github.com/dependabot) ([#8147](https://github.com/paperless-ngx/paperless-ngx/pull/8147))
- Chore(deps): Bump uuid from 10.0.0 to 11.0.2 in /src-ui [@dependabot](https://github.com/dependabot) ([#8146](https://github.com/paperless-ngx/paperless-ngx/pull/8146))
- Chore(deps): Bump tslib from 2.7.0 to 2.8.1 in /src-ui [@dependabot](https://github.com/dependabot) ([#8149](https://github.com/paperless-ngx/paperless-ngx/pull/8149))
- Chore(deps-dev): Bump @codecov/webpack-plugin from 1.2.0 to 1.2.1 in /src-ui [@dependabot](https://github.com/dependabot) ([#8150](https://github.com/paperless-ngx/paperless-ngx/pull/8150))
- Chore(deps-dev): Bump @types/jest from 29.5.13 to 29.5.14 in /src-ui in the frontend-jest-dependencies group [@dependabot](https://github.com/dependabot) ([#8144](https://github.com/paperless-ngx/paperless-ngx/pull/8144))
- Chore(deps): Bump the frontend-angular-dependencies group in /src-ui with 21 updates [@dependabot](https://github.com/dependabot) ([#8143](https://github.com/paperless-ngx/paperless-ngx/pull/8143))
- Fix: dont use filters for inverted thumbnails in Safari [@shamoon](https://github.com/shamoon) ([#8121](https://github.com/paperless-ngx/paperless-ngx/pull/8121))
- Fix: use static object for activedisplayfields to prevent changes [@shamoon](https://github.com/shamoon) ([#8120](https://github.com/paperless-ngx/paperless-ngx/pull/8120))
- Fix: dont invert pdf colors in FF [@shamoon](https://github.com/shamoon) ([#8110](https://github.com/paperless-ngx/paperless-ngx/pull/8110))
- Fix: make mail account password and refresh token text fields [@shamoon](https://github.com/shamoon) ([#8107](https://github.com/paperless-ngx/paperless-ngx/pull/8107))
</details>
## paperless-ngx 2.13.2 ## paperless-ngx 2.13.2
### Bug Fixes ### Bug Fixes
@@ -105,120 +58,6 @@
- Fix: oauth settings without base url [@shamoon](https://github.com/shamoon) ([#8020](https://github.com/paperless-ngx/paperless-ngx/pull/8020)) - Fix: oauth settings without base url [@shamoon](https://github.com/shamoon) ([#8020](https://github.com/paperless-ngx/paperless-ngx/pull/8020))
</details> </details>
## paperless-ngx 2.13.0
### Notable Changes
- Feature: OAuth2 Gmail and Outlook email support [@shamoon](https://github.com/shamoon) ([#7866](https://github.com/paperless-ngx/paperless-ngx/pull/7866))
- Feature: Enhanced templating for filename format [@stumpylog](https://github.com/stumpylog) ([#7836](https://github.com/paperless-ngx/paperless-ngx/pull/7836))
- Feature: custom fields queries [@shamoon](https://github.com/shamoon) ([#7761](https://github.com/paperless-ngx/paperless-ngx/pull/7761))
- Chore: Drop Python 3.9 support [@stumpylog](https://github.com/stumpylog) ([#7774](https://github.com/paperless-ngx/paperless-ngx/pull/7774))
### Features
- Enhancement: QoL, auto-focus default select field in custom field dropdown [@shamoon](https://github.com/shamoon) ([#7961](https://github.com/paperless-ngx/paperless-ngx/pull/7961))
- Change: open not edit [@shamoon](https://github.com/shamoon) ([#7942](https://github.com/paperless-ngx/paperless-ngx/pull/7942))
- Enhancement: support retain barcode split pages [@shamoon](https://github.com/shamoon) ([#7912](https://github.com/paperless-ngx/paperless-ngx/pull/7912))
- Enhancement: don't wait for doc API to load preview [@shamoon](https://github.com/shamoon) ([#7894](https://github.com/paperless-ngx/paperless-ngx/pull/7894))
- Feature: OAuth2 Gmail and Outlook email support [@shamoon](https://github.com/shamoon) ([#7866](https://github.com/paperless-ngx/paperless-ngx/pull/7866))
- Enhancement: live preview of storage path [@shamoon](https://github.com/shamoon) ([#7870](https://github.com/paperless-ngx/paperless-ngx/pull/7870))
- Enhancement: management list button improvements [@shamoon](https://github.com/shamoon) ([#7848](https://github.com/paperless-ngx/paperless-ngx/pull/7848))
- Enhancement: check for mail destination directory, log post-consume errors [@mrichtarsky](https://github.com/mrichtarsky) ([#7808](https://github.com/paperless-ngx/paperless-ngx/pull/7808))
- Enhancement: workflow overview toggle enable button [@shamoon](https://github.com/shamoon) ([#7818](https://github.com/paperless-ngx/paperless-ngx/pull/7818))
- Enhancement: disable-able mail rules, add toggle to overview [@shamoon](https://github.com/shamoon) ([#7810](https://github.com/paperless-ngx/paperless-ngx/pull/7810))
- Feature: auto-clean some invalid pdfs [@shamoon](https://github.com/shamoon) ([#7651](https://github.com/paperless-ngx/paperless-ngx/pull/7651))
- Feature: page count [@s0llvan](https://github.com/s0llvan) ([#7750](https://github.com/paperless-ngx/paperless-ngx/pull/7750))
- Enhancement: use apt only when needed docker-entrypoint.sh [@gawa971](https://github.com/gawa971) ([#7756](https://github.com/paperless-ngx/paperless-ngx/pull/7756))
- Enhancement: set Django SESSION_EXPIRE_AT_BROWSER_CLOSE from PAPERLESS_ACCOUNT_SESSION_REMEMBER [@shamoon](https://github.com/shamoon) ([#7748](https://github.com/paperless-ngx/paperless-ngx/pull/7748))
- Enhancement: allow setting session cookie age [@shamoon](https://github.com/shamoon) ([#7743](https://github.com/paperless-ngx/paperless-ngx/pull/7743))
- Feature: copy workflows and mail rules, improve layout [@shamoon](https://github.com/shamoon) ([#7727](https://github.com/paperless-ngx/paperless-ngx/pull/7727))
### Bug Fixes
- Fix: remove space before my profile button in dropdown [@tooomm](https://github.com/tooomm) ([#7963](https://github.com/paperless-ngx/paperless-ngx/pull/7963))
- Fix: v2.13.0 RC1 - Handling of Nones when using custom fields in filepath templating [@stumpylog](https://github.com/stumpylog) ([#7933](https://github.com/paperless-ngx/paperless-ngx/pull/7933))
- Fix: v2.13.0 RC1 - trigger move and rename after CustomFieldInstance saved [@shamoon](https://github.com/shamoon) ([#7927](https://github.com/paperless-ngx/paperless-ngx/pull/7927))
- Fix: v2.13.0 RC1 - increase field max lengths to accommodate larger tokens [@shamoon](https://github.com/shamoon) ([#7916](https://github.com/paperless-ngx/paperless-ngx/pull/7916))
- Fix: preserve text linebreaks in doc edit [@shamoon](https://github.com/shamoon) ([#7908](https://github.com/paperless-ngx/paperless-ngx/pull/7908))
- Fix: only show colon on cards if correspondent and title shown [@shamoon](https://github.com/shamoon) ([#7893](https://github.com/paperless-ngx/paperless-ngx/pull/7893))
- Fix: Allow ASN values of 0 from barcodes [@stumpylog](https://github.com/stumpylog) ([#7878](https://github.com/paperless-ngx/paperless-ngx/pull/7878))
- Fix: fix auto-dismiss completed tasks on open document [@shamoon](https://github.com/shamoon) ([#7869](https://github.com/paperless-ngx/paperless-ngx/pull/7869))
- Fix: trigger change warning for saved views with default fields if changed [@shamoon](https://github.com/shamoon) ([#7865](https://github.com/paperless-ngx/paperless-ngx/pull/7865))
- Fix: hidden canvas element causes scroll bug [@shamoon](https://github.com/shamoon) ([#7770](https://github.com/paperless-ngx/paperless-ngx/pull/7770))
- Fix: handle overflowing dropdowns on mobile [@shamoon](https://github.com/shamoon) ([#7758](https://github.com/paperless-ngx/paperless-ngx/pull/7758))
- Fix: chrome scrolling in >= 129 [@shamoon](https://github.com/shamoon) ([#7738](https://github.com/paperless-ngx/paperless-ngx/pull/7738))
### Maintenance
- Enhancement: use apt only when needed docker-entrypoint.sh [@gawa971](https://github.com/gawa971) ([#7756](https://github.com/paperless-ngx/paperless-ngx/pull/7756))
### Dependencies
<details>
<summary>10 changes</summary>
- Chore(deps-dev): Bump @codecov/webpack-plugin from 1.0.1 to 1.2.0 in /src-ui [@dependabot](https://github.com/dependabot) ([#7830](https://github.com/paperless-ngx/paperless-ngx/pull/7830))
- Chore(deps-dev): Bump @types/node from 22.5.2 to 22.7.4 in /src-ui [@dependabot](https://github.com/dependabot) ([#7829](https://github.com/paperless-ngx/paperless-ngx/pull/7829))
- Chore(deps-dev): Bump the frontend-eslint-dependencies group in /src-ui with 4 updates [@dependabot](https://github.com/dependabot) ([#7827](https://github.com/paperless-ngx/paperless-ngx/pull/7827))
- Chore(deps-dev): Bump the frontend-jest-dependencies group in /src-ui with 2 updates [@dependabot](https://github.com/dependabot) ([#7826](https://github.com/paperless-ngx/paperless-ngx/pull/7826))
- Chore(deps-dev): Bump @playwright/test from 1.46.1 to 1.47.2 in /src-ui [@dependabot](https://github.com/dependabot) ([#7828](https://github.com/paperless-ngx/paperless-ngx/pull/7828))
- Chore(deps): Bump the frontend-angular-dependencies group in /src-ui with 21 updates [@dependabot](https://github.com/dependabot) ([#7825](https://github.com/paperless-ngx/paperless-ngx/pull/7825))
- Chore: Upgrades OCRMyPDF to v16 [@stumpylog](https://github.com/stumpylog) ([#7815](https://github.com/paperless-ngx/paperless-ngx/pull/7815))
- Chore: Upgrades the Docker image to use Python 3.12 [@stumpylog](https://github.com/stumpylog) ([#7796](https://github.com/paperless-ngx/paperless-ngx/pull/7796))
- Chore: Upgrade Django to 5.1 [@stumpylog](https://github.com/stumpylog) ([#7795](https://github.com/paperless-ngx/paperless-ngx/pull/7795))
- Chore(deps-dev): Bump the development group with 2 updates [@dependabot](https://github.com/dependabot) ([#7723](https://github.com/paperless-ngx/paperless-ngx/pull/7723))
</details>
### All App Changes
<details>
<summary>43 changes</summary>
- Change: Use a TextField for the storage path field [@stumpylog](https://github.com/stumpylog) ([#7967](https://github.com/paperless-ngx/paperless-ngx/pull/7967))
- Fix: remove space before my profile button in dropdown [@tooomm](https://github.com/tooomm) ([#7963](https://github.com/paperless-ngx/paperless-ngx/pull/7963))
- Enhancement: QoL, auto-focus default select field in custom field dropdown [@shamoon](https://github.com/shamoon) ([#7961](https://github.com/paperless-ngx/paperless-ngx/pull/7961))
- Change: open not edit [@shamoon](https://github.com/shamoon) ([#7942](https://github.com/paperless-ngx/paperless-ngx/pull/7942))
- Fix: v2.13.0 RC1 - Handling of Nones when using custom fields in filepath templating [@stumpylog](https://github.com/stumpylog) ([#7933](https://github.com/paperless-ngx/paperless-ngx/pull/7933))
- Fix: v2.13.0 RC1 - trigger move and rename after CustomFieldInstance saved [@shamoon](https://github.com/shamoon) ([#7927](https://github.com/paperless-ngx/paperless-ngx/pull/7927))
- Fix: v2.13.0 RC1 - increase field max lengths to accommodate larger tokens [@shamoon](https://github.com/shamoon) ([#7916](https://github.com/paperless-ngx/paperless-ngx/pull/7916))
- Enhancement: support retain barcode split pages [@shamoon](https://github.com/shamoon) ([#7912](https://github.com/paperless-ngx/paperless-ngx/pull/7912))
- Fix: preserve text linebreaks in doc edit [@shamoon](https://github.com/shamoon) ([#7908](https://github.com/paperless-ngx/paperless-ngx/pull/7908))
- Enhancement: don't wait for doc API to load preview [@shamoon](https://github.com/shamoon) ([#7894](https://github.com/paperless-ngx/paperless-ngx/pull/7894))
- Fix: only show colon on cards if correspondent and title shown [@shamoon](https://github.com/shamoon) ([#7893](https://github.com/paperless-ngx/paperless-ngx/pull/7893))
- Feature: OAuth2 Gmail and Outlook email support [@shamoon](https://github.com/shamoon) ([#7866](https://github.com/paperless-ngx/paperless-ngx/pull/7866))
- Chore: Consolidate workflow logic [@shamoon](https://github.com/shamoon) ([#7880](https://github.com/paperless-ngx/paperless-ngx/pull/7880))
- Enhancement: live preview of storage path [@shamoon](https://github.com/shamoon) ([#7870](https://github.com/paperless-ngx/paperless-ngx/pull/7870))
- Fix: Allow ASN values of 0 from barcodes [@stumpylog](https://github.com/stumpylog) ([#7878](https://github.com/paperless-ngx/paperless-ngx/pull/7878))
- Fix: fix auto-dismiss completed tasks on open document [@shamoon](https://github.com/shamoon) ([#7869](https://github.com/paperless-ngx/paperless-ngx/pull/7869))
- Fix: trigger change warning for saved views with default fields if changed [@shamoon](https://github.com/shamoon) ([#7865](https://github.com/paperless-ngx/paperless-ngx/pull/7865))
- Feature: Enhanced templating for filename format [@stumpylog](https://github.com/stumpylog) ([#7836](https://github.com/paperless-ngx/paperless-ngx/pull/7836))
- Enhancement: management list button improvements [@shamoon](https://github.com/shamoon) ([#7848](https://github.com/paperless-ngx/paperless-ngx/pull/7848))
- Enhancement: check for mail destination directory, log post-consume errors [@mrichtarsky](https://github.com/mrichtarsky) ([#7808](https://github.com/paperless-ngx/paperless-ngx/pull/7808))
- Feature: custom fields queries [@shamoon](https://github.com/shamoon) ([#7761](https://github.com/paperless-ngx/paperless-ngx/pull/7761))
- Chore(deps-dev): Bump @codecov/webpack-plugin from 1.0.1 to 1.2.0 in /src-ui [@dependabot](https://github.com/dependabot) ([#7830](https://github.com/paperless-ngx/paperless-ngx/pull/7830))
- Chore(deps-dev): Bump @types/node from 22.5.2 to 22.7.4 in /src-ui [@dependabot](https://github.com/dependabot) ([#7829](https://github.com/paperless-ngx/paperless-ngx/pull/7829))
- Chore(deps-dev): Bump the frontend-eslint-dependencies group in /src-ui with 4 updates [@dependabot](https://github.com/dependabot) ([#7827](https://github.com/paperless-ngx/paperless-ngx/pull/7827))
- Chore(deps-dev): Bump the frontend-jest-dependencies group in /src-ui with 2 updates [@dependabot](https://github.com/dependabot) ([#7826](https://github.com/paperless-ngx/paperless-ngx/pull/7826))
- Chore(deps-dev): Bump @playwright/test from 1.46.1 to 1.47.2 in /src-ui [@dependabot](https://github.com/dependabot) ([#7828](https://github.com/paperless-ngx/paperless-ngx/pull/7828))
- Chore(deps): Bump the frontend-angular-dependencies group in /src-ui with 21 updates [@dependabot](https://github.com/dependabot) ([#7825](https://github.com/paperless-ngx/paperless-ngx/pull/7825))
- Chore: Upgrades OCRMyPDF to v16 [@stumpylog](https://github.com/stumpylog) ([#7815](https://github.com/paperless-ngx/paperless-ngx/pull/7815))
- Enhancement: workflow overview toggle enable button [@shamoon](https://github.com/shamoon) ([#7818](https://github.com/paperless-ngx/paperless-ngx/pull/7818))
- Enhancement: disable-able mail rules, add toggle to overview [@shamoon](https://github.com/shamoon) ([#7810](https://github.com/paperless-ngx/paperless-ngx/pull/7810))
- Chore: Upgrades the Docker image to use Python 3.12 [@stumpylog](https://github.com/stumpylog) ([#7796](https://github.com/paperless-ngx/paperless-ngx/pull/7796))
- Chore: Upgrade Django to 5.1 [@stumpylog](https://github.com/stumpylog) ([#7795](https://github.com/paperless-ngx/paperless-ngx/pull/7795))
- Chore: Drop Python 3.9 support [@stumpylog](https://github.com/stumpylog) ([#7774](https://github.com/paperless-ngx/paperless-ngx/pull/7774))
- Feature: auto-clean some invalid pdfs [@shamoon](https://github.com/shamoon) ([#7651](https://github.com/paperless-ngx/paperless-ngx/pull/7651))
- Feature: page count [@s0llvan](https://github.com/s0llvan) ([#7750](https://github.com/paperless-ngx/paperless-ngx/pull/7750))
- Fix: hidden canvas element causes scroll bug [@shamoon](https://github.com/shamoon) ([#7770](https://github.com/paperless-ngx/paperless-ngx/pull/7770))
- Enhancement: compactify dates dropdown [@shamoon](https://github.com/shamoon) ([#7759](https://github.com/paperless-ngx/paperless-ngx/pull/7759))
- Fix: handle overflowing dropdowns on mobile [@shamoon](https://github.com/shamoon) ([#7758](https://github.com/paperless-ngx/paperless-ngx/pull/7758))
- Enhancement: set Django SESSION_EXPIRE_AT_BROWSER_CLOSE from PAPERLESS_ACCOUNT_SESSION_REMEMBER [@shamoon](https://github.com/shamoon) ([#7748](https://github.com/paperless-ngx/paperless-ngx/pull/7748))
- Enhancement: allow setting session cookie age [@shamoon](https://github.com/shamoon) ([#7743](https://github.com/paperless-ngx/paperless-ngx/pull/7743))
- Fix: chrome scrolling in >= 129 [@shamoon](https://github.com/shamoon) ([#7738](https://github.com/paperless-ngx/paperless-ngx/pull/7738))
- Feature: copy workflows and mail rules, improve layout [@shamoon](https://github.com/shamoon) ([#7727](https://github.com/paperless-ngx/paperless-ngx/pull/7727))
- Chore(deps-dev): Bump the development group with 2 updates [@dependabot](https://github.com/dependabot) ([#7723](https://github.com/paperless-ngx/paperless-ngx/pull/7723))
</details>
## paperless-ngx 2.12.1 ## paperless-ngx 2.12.1
### Bug Fixes ### Bug Fixes

View File

@@ -18,6 +18,7 @@
# Paths and folders # Paths and folders
#PAPERLESS_CONSUMPTION_DIR=../consume #PAPERLESS_CONSUMPTION_DIR=../consume
#PAPERLESS_CONSUMPTION_FAILED_DIR=../consume/failed
#PAPERLESS_DATA_DIR=../data #PAPERLESS_DATA_DIR=../data
#PAPERLESS_EMPTY_TRASH_DIR= #PAPERLESS_EMPTY_TRASH_DIR=
#PAPERLESS_MEDIA_ROOT=../media #PAPERLESS_MEDIA_ROOT=../media

View File

@@ -1994,120 +1994,141 @@
<context context-type="linenumber">72</context> <context context-type="linenumber">72</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="7934833136974560675" datatype="html">
<source>Retry</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">86</context>
</context-group>
</trans-unit>
<trans-unit id="1536087519743707362" datatype="html"> <trans-unit id="1536087519743707362" datatype="html">
<source>Dismiss</source> <source>Dismiss</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">85</context> <context context-type="linenumber">90</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">68</context> <context context-type="linenumber">71</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="2134950584701094962" datatype="html"> <trans-unit id="2134950584701094962" datatype="html">
<source>Open Document</source> <source>Open Document</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">90</context> <context context-type="linenumber">95</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="428536141871853903" datatype="html"> <trans-unit id="428536141871853903" datatype="html">
<source>{VAR_PLURAL, plural, =1 {One <x id="INTERPOLATION"/> task} other {<x id="INTERPOLATION_1"/> total <x id="INTERPOLATION"/> tasks}}</source> <source>{VAR_PLURAL, plural, =1 {One <x id="INTERPOLATION"/> task} other {<x id="INTERPOLATION_1"/> total <x id="INTERPOLATION"/> tasks}}</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">109</context> <context context-type="linenumber">114</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1943508481059904274" datatype="html"> <trans-unit id="1943508481059904274" datatype="html">
<source> (<x id="INTERPOLATION" equiv-text="{{selectedTasks.size}}"/> selected)</source> <source> (<x id="INTERPOLATION" equiv-text="{{selectedTasks.size}}"/> selected)</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">111</context> <context context-type="linenumber">116</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="5639839509673911668" datatype="html"> <trans-unit id="5639839509673911668" datatype="html">
<source>Failed<x id="START_BLOCK_IF" equiv-text="@if (tasksService.failedFileTasks.length &gt; 0) {"/><x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;badge bg-danger ms-2&quot;&gt;"/><x id="INTERPOLATION" equiv-text="{{tasksService.failedFileTasks.length}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/><x id="CLOSE_BLOCK_IF" equiv-text="}"/></source> <source>Failed<x id="START_BLOCK_IF" equiv-text="@if (tasksService.failedFileTasks.length &gt; 0) {"/><x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;badge bg-danger ms-2&quot;&gt;"/><x id="INTERPOLATION" equiv-text="{{tasksService.failedFileTasks.length}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/><x id="CLOSE_BLOCK_IF" equiv-text="}"/></source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">123,125</context> <context context-type="linenumber">128,130</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="8210778930307085868" datatype="html"> <trans-unit id="8210778930307085868" datatype="html">
<source>Complete<x id="START_BLOCK_IF" equiv-text="@if (tasksService.completedFileTasks.length &gt; 0) {"/><x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;badge bg-secondary ms-2&quot;&gt;"/><x id="INTERPOLATION" equiv-text="{{tasksService.completedFileTasks.length}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/><x id="CLOSE_BLOCK_IF" equiv-text="}"/></source> <source>Complete<x id="START_BLOCK_IF" equiv-text="@if (tasksService.completedFileTasks.length &gt; 0) {"/><x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;badge bg-secondary ms-2&quot;&gt;"/><x id="INTERPOLATION" equiv-text="{{tasksService.completedFileTasks.length}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/><x id="CLOSE_BLOCK_IF" equiv-text="}"/></source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">131,133</context> <context context-type="linenumber">136,138</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="3522801015717851360" datatype="html"> <trans-unit id="3522801015717851360" datatype="html">
<source>Started<x id="START_BLOCK_IF" equiv-text="@if (tasksService.startedFileTasks.length &gt; 0) {"/><x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;badge bg-secondary ms-2&quot;&gt;"/><x id="INTERPOLATION" equiv-text="{{tasksService.startedFileTasks.length}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/><x id="CLOSE_BLOCK_IF" equiv-text="}"/></source> <source>Started<x id="START_BLOCK_IF" equiv-text="@if (tasksService.startedFileTasks.length &gt; 0) {"/><x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;badge bg-secondary ms-2&quot;&gt;"/><x id="INTERPOLATION" equiv-text="{{tasksService.startedFileTasks.length}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/><x id="CLOSE_BLOCK_IF" equiv-text="}"/></source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">139,141</context> <context context-type="linenumber">144,146</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="2341807459308874922" datatype="html"> <trans-unit id="2341807459308874922" datatype="html">
<source>Queued<x id="START_BLOCK_IF" equiv-text="@if (tasksService.queuedFileTasks.length &gt; 0) {"/><x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;badge bg-secondary ms-2&quot;&gt;"/><x id="INTERPOLATION" equiv-text="{{tasksService.queuedFileTasks.length}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/><x id="CLOSE_BLOCK_IF" equiv-text="}"/></source> <source>Queued<x id="START_BLOCK_IF" equiv-text="@if (tasksService.queuedFileTasks.length &gt; 0) {"/><x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;badge bg-secondary ms-2&quot;&gt;"/><x id="INTERPOLATION" equiv-text="{{tasksService.queuedFileTasks.length}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/><x id="CLOSE_BLOCK_IF" equiv-text="}"/></source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">147,149</context> <context context-type="linenumber">152,154</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="5404910960991552159" datatype="html"> <trans-unit id="5404910960991552159" datatype="html">
<source>Dismiss selected</source> <source>Dismiss selected</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">31</context> <context context-type="linenumber">33</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="8829078752502782653" datatype="html"> <trans-unit id="8829078752502782653" datatype="html">
<source>Dismiss all</source> <source>Dismiss all</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">32</context> <context context-type="linenumber">34</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1323591410517879795" datatype="html"> <trans-unit id="1323591410517879795" datatype="html">
<source>Confirm Dismiss All</source> <source>Confirm Dismiss All</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">65</context> <context context-type="linenumber">68</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="4157200209636243740" datatype="html"> <trans-unit id="4157200209636243740" datatype="html">
<source>Dismiss all <x id="PH" equiv-text="tasks.size"/> tasks?</source> <source>Dismiss all <x id="PH" equiv-text="tasks.size"/> tasks?</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">66</context> <context context-type="linenumber">69</context>
</context-group>
</trans-unit>
<trans-unit id="7611027432301841688" datatype="html">
<source>Retrying task...</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">92</context>
</context-group>
</trans-unit>
<trans-unit id="5445438607105804721" datatype="html">
<source>Failed to retry task</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">95</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="9011556615675272238" datatype="html"> <trans-unit id="9011556615675272238" datatype="html">
<source>queued</source> <source>queued</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">135</context> <context context-type="linenumber">149</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="6415892379431855826" datatype="html"> <trans-unit id="6415892379431855826" datatype="html">
<source>started</source> <source>started</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">137</context> <context context-type="linenumber">151</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="7510279840486540181" datatype="html"> <trans-unit id="7510279840486540181" datatype="html">
<source>completed</source> <source>completed</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">139</context> <context context-type="linenumber">153</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="4083337005045748464" datatype="html"> <trans-unit id="4083337005045748464" datatype="html">
<source>failed</source> <source>failed</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">141</context> <context context-type="linenumber">155</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="3418677553313974490" datatype="html"> <trans-unit id="3418677553313974490" datatype="html">

4079
src-ui/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -11,54 +11,54 @@
}, },
"private": true, "private": true,
"dependencies": { "dependencies": {
"@angular/cdk": "^18.2.11", "@angular/cdk": "^18.2.6",
"@angular/common": "~18.2.10", "@angular/common": "~18.2.6",
"@angular/compiler": "~18.2.10", "@angular/compiler": "~18.2.6",
"@angular/core": "~18.2.10", "@angular/core": "~18.2.6",
"@angular/forms": "~18.2.10", "@angular/forms": "~18.2.6",
"@angular/localize": "~18.2.10", "@angular/localize": "~18.2.6",
"@angular/platform-browser": "~18.2.10", "@angular/platform-browser": "~18.2.6",
"@angular/platform-browser-dynamic": "~18.2.10", "@angular/platform-browser-dynamic": "~18.2.6",
"@angular/router": "~18.2.10", "@angular/router": "~18.2.6",
"@ng-bootstrap/ng-bootstrap": "^17.0.1", "@ng-bootstrap/ng-bootstrap": "^17.0.1",
"@ng-select/ng-select": "^13.9.1", "@ng-select/ng-select": "^13.9.0",
"@ngneat/dirty-check-forms": "^3.0.3", "@ngneat/dirty-check-forms": "^3.0.3",
"@popperjs/core": "^2.11.8", "@popperjs/core": "^2.11.8",
"bootstrap": "^5.3.3", "bootstrap": "^5.3.3",
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"mime-names": "^1.0.0", "mime-names": "^1.0.0",
"ng2-pdf-viewer": "^10.3.4", "ng2-pdf-viewer": "^10.3.1",
"ngx-bootstrap-icons": "^1.9.3", "ngx-bootstrap-icons": "^1.9.3",
"ngx-color": "^9.0.0", "ngx-color": "^9.0.0",
"ngx-cookie-service": "^18.0.0", "ngx-cookie-service": "^18.0.0",
"ngx-file-drop": "^16.0.0", "ngx-file-drop": "^16.0.0",
"ngx-ui-tour-ng-bootstrap": "^15.0.0", "ngx-ui-tour-ng-bootstrap": "^15.0.0",
"rxjs": "^7.8.1", "rxjs": "^7.8.1",
"tslib": "^2.8.1", "tslib": "^2.7.0",
"uuid": "^11.0.2", "uuid": "^10.0.0",
"zone.js": "^0.14.8" "zone.js": "^0.14.8"
}, },
"devDependencies": { "devDependencies": {
"@angular-builders/custom-webpack": "^18.0.0", "@angular-builders/custom-webpack": "^18.0.0",
"@angular-builders/jest": "^18.0.0", "@angular-builders/jest": "^18.0.0",
"@angular-devkit/build-angular": "^18.2.2", "@angular-devkit/build-angular": "^18.2.2",
"@angular-devkit/core": "^18.2.11", "@angular-devkit/core": "^18.2.6",
"@angular-devkit/schematics": "^18.2.11", "@angular-devkit/schematics": "^18.2.6",
"@angular-eslint/builder": "18.4.0", "@angular-eslint/builder": "18.3.1",
"@angular-eslint/eslint-plugin": "18.4.0", "@angular-eslint/eslint-plugin": "18.3.1",
"@angular-eslint/eslint-plugin-template": "18.4.0", "@angular-eslint/eslint-plugin-template": "18.3.1",
"@angular-eslint/schematics": "18.4.0", "@angular-eslint/schematics": "18.3.1",
"@angular-eslint/template-parser": "18.4.0", "@angular-eslint/template-parser": "18.3.1",
"@angular/cli": "~18.2.11", "@angular/cli": "~18.2.6",
"@angular/compiler-cli": "~18.2.2", "@angular/compiler-cli": "~18.2.2",
"@codecov/webpack-plugin": "^1.2.1", "@codecov/webpack-plugin": "^1.2.0",
"@playwright/test": "^1.48.2", "@playwright/test": "^1.47.2",
"@types/jest": "^29.5.14", "@types/jest": "^29.5.13",
"@types/node": "^22.8.6", "@types/node": "^22.7.4",
"@typescript-eslint/eslint-plugin": "^8.12.2", "@typescript-eslint/eslint-plugin": "^8.8.0",
"@typescript-eslint/parser": "^8.12.2", "@typescript-eslint/parser": "^8.8.0",
"@typescript-eslint/utils": "^8.0.0", "@typescript-eslint/utils": "^8.0.0",
"eslint": "^9.14.0", "eslint": "^9.11.1",
"jest": "29.7.0", "jest": "29.7.0",
"jest-environment-jsdom": "^29.7.0", "jest-environment-jsdom": "^29.7.0",
"jest-preset-angular": "^14.2.4", "jest-preset-angular": "^14.2.4",

View File

@@ -81,6 +81,9 @@
</td> </td>
<td scope="row"> <td scope="row">
<div class="btn-group" role="group"> <div class="btn-group" role="group">
@if (task.status === PaperlessTaskStatus.Failed) {
<ng-container *ngTemplateOutlet="retryDropdown; context: { task: task }"></ng-container>
}
<button class="btn btn-sm btn-outline-secondary" (click)="dismissTask(task); $event.stopPropagation();" *pngxIfPermissions="{ action: PermissionAction.Change, type: PermissionType.PaperlessTask }"> <button class="btn btn-sm btn-outline-secondary" (click)="dismissTask(task); $event.stopPropagation();" *pngxIfPermissions="{ action: PermissionAction.Change, type: PermissionType.PaperlessTask }">
<i-bs name="check"></i-bs>&nbsp;<ng-container i18n>Dismiss</ng-container> <i-bs name="check"></i-bs>&nbsp;<ng-container i18n>Dismiss</ng-container>
</button> </button>
@@ -153,3 +156,25 @@
</li> </li>
</ul> </ul>
<div [ngbNavOutlet]="nav"></div> <div [ngbNavOutlet]="nav"></div>
<ng-template #retryDropdown let-task="task">
<div ngbDropdown>
<button class="btn btn-sm btn-outline-primary" (click)="$event.stopImmediatePropagation()" ngbDropdownToggle>
<i-bs name="arrow-repeat"></i-bs>&nbsp;<ng-container i18n>Retry</ng-container>
</button>
<div ngbDropdownMenu class="shadow retry-dropdown">
<div class="p-2">
<ul class="list-group list-group-flush">
<li class="list-group-item small" i18n>
<pngx-input-check [(ngModel)]="retryClean" i18n-title title="Attempt to clean pdf"></pngx-input-check>
</li>
</ul>
<div class="d-flex justify-content-end">
<button class="btn btn-sm btn-outline-primary" (click)="retryTask(task); $event.stopPropagation();">
<ng-container i18n>Proceed</ng-container>
</button>
</div>
</div>
</div>
</div>
</ng-template>

View File

@@ -26,3 +26,7 @@ pre {
max-width: 150px; max-width: 150px;
} }
} }
.retry-dropdown {
width: 300px;
}

View File

@@ -31,6 +31,9 @@ import { PermissionsGuard } from 'src/app/guards/permissions.guard'
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons' import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
import { FormsModule } from '@angular/forms' import { FormsModule } from '@angular/forms'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http' import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
import { ToastService } from 'src/app/services/toast.service'
import { of, throwError } from 'rxjs'
import { CheckComponent } from '../../common/input/check/check.component'
const tasks: PaperlessTask[] = [ const tasks: PaperlessTask[] = [
{ {
@@ -115,6 +118,7 @@ describe('TasksComponent', () => {
let modalService: NgbModal let modalService: NgbModal
let router: Router let router: Router
let httpTestingController: HttpTestingController let httpTestingController: HttpTestingController
let toastService: ToastService
let reloadSpy let reloadSpy
beforeEach(async () => { beforeEach(async () => {
@@ -125,6 +129,7 @@ describe('TasksComponent', () => {
IfPermissionsDirective, IfPermissionsDirective,
CustomDatePipe, CustomDatePipe,
ConfirmDialogComponent, ConfirmDialogComponent,
CheckComponent,
], ],
imports: [ imports: [
NgbModule, NgbModule,
@@ -152,6 +157,7 @@ describe('TasksComponent', () => {
httpTestingController = TestBed.inject(HttpTestingController) httpTestingController = TestBed.inject(HttpTestingController)
modalService = TestBed.inject(NgbModal) modalService = TestBed.inject(NgbModal)
router = TestBed.inject(Router) router = TestBed.inject(Router)
toastService = TestBed.inject(ToastService)
fixture = TestBed.createComponent(TasksComponent) fixture = TestBed.createComponent(TasksComponent)
component = fixture.componentInstance component = fixture.componentInstance
jest.useFakeTimers() jest.useFakeTimers()
@@ -173,8 +179,10 @@ describe('TasksComponent', () => {
`Failed${currentTasksLength}` `Failed${currentTasksLength}`
) )
expect( expect(
fixture.debugElement.queryAll(By.css('table input[type="checkbox"]')) fixture.debugElement.queryAll(
).toHaveLength(currentTasksLength + 1) By.css('table td > .form-check input[type="checkbox"]')
)
).toHaveLength(currentTasksLength)
currentTasksLength = tasks.filter( currentTasksLength = tasks.filter(
(t) => t.status === PaperlessTaskStatus.Complete (t) => t.status === PaperlessTaskStatus.Complete
@@ -289,4 +297,20 @@ describe('TasksComponent', () => {
jest.advanceTimersByTime(6000) jest.advanceTimersByTime(6000)
expect(reloadSpy).toHaveBeenCalledTimes(2) expect(reloadSpy).toHaveBeenCalledTimes(2)
}) })
it('should retry a task, show toast on error or success', () => {
const retrySpy = jest.spyOn(tasksService, 'retryTask')
const toastInfoSpy = jest.spyOn(toastService, 'showInfo')
const toastErrorSpy = jest.spyOn(toastService, 'showError')
retrySpy.mockReturnValueOnce(of({ task_id: '123' }))
component.retryTask(tasks[0])
expect(retrySpy).toHaveBeenCalledWith(tasks[0], false)
expect(toastInfoSpy).toHaveBeenCalledWith('Retrying task...')
retrySpy.mockReturnValueOnce(throwError(() => new Error('test')))
component.retryTask(tasks[0])
expect(toastErrorSpy).toHaveBeenCalledWith(
'Failed to retry task',
new Error('test')
)
})
}) })

View File

@@ -2,10 +2,11 @@ import { Component, OnInit, OnDestroy } from '@angular/core'
import { Router } from '@angular/router' import { Router } from '@angular/router'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { first } from 'rxjs' import { first } from 'rxjs'
import { PaperlessTask } from 'src/app/data/paperless-task' import { PaperlessTask, PaperlessTaskStatus } from 'src/app/data/paperless-task'
import { TasksService } from 'src/app/services/tasks.service' import { TasksService } from 'src/app/services/tasks.service'
import { ConfirmDialogComponent } from '../../common/confirm-dialog/confirm-dialog.component' import { ConfirmDialogComponent } from '../../common/confirm-dialog/confirm-dialog.component'
import { ComponentWithPermissions } from '../../with-permissions/with-permissions.component' import { ComponentWithPermissions } from '../../with-permissions/with-permissions.component'
import { ToastService } from 'src/app/services/toast.service'
@Component({ @Component({
selector: 'pngx-tasks', selector: 'pngx-tasks',
@@ -16,6 +17,7 @@ export class TasksComponent
extends ComponentWithPermissions extends ComponentWithPermissions
implements OnInit, OnDestroy implements OnInit, OnDestroy
{ {
public PaperlessTaskStatus = PaperlessTaskStatus
public activeTab: string public activeTab: string
public selectedTasks: Set<number> = new Set() public selectedTasks: Set<number> = new Set()
public togggleAll: boolean = false public togggleAll: boolean = false
@@ -26,6 +28,8 @@ export class TasksComponent
public autoRefreshInterval: any public autoRefreshInterval: any
public retryClean: boolean = false
get dismissButtonText(): string { get dismissButtonText(): string {
return this.selectedTasks.size > 0 return this.selectedTasks.size > 0
? $localize`Dismiss selected` ? $localize`Dismiss selected`
@@ -35,6 +39,7 @@ export class TasksComponent
constructor( constructor(
public tasksService: TasksService, public tasksService: TasksService,
private modalService: NgbModal, private modalService: NgbModal,
private toastService: ToastService,
private readonly router: Router private readonly router: Router
) { ) {
super() super()
@@ -83,6 +88,17 @@ export class TasksComponent
this.router.navigate(['documents', task.related_document]) this.router.navigate(['documents', task.related_document])
} }
retryTask(task: PaperlessTask) {
this.tasksService.retryTask(task, this.retryClean).subscribe({
next: () => {
this.toastService.showInfo($localize`Retrying task...`)
},
error: (e) => {
this.toastService.showError($localize`Failed to retry task`, e)
},
})
}
expandTask(task: PaperlessTask) { expandTask(task: PaperlessTask) {
this.expandedTask = this.expandedTask == task.id ? undefined : task.id this.expandedTask = this.expandedTask == task.id ? undefined : task.id
} }

View File

@@ -38,7 +38,7 @@
@for (item of selectionModel.itemsSorted | filter: filterText:'name'; track item; let i = $index) { @for (item of selectionModel.itemsSorted | filter: filterText:'name'; track item; let i = $index) {
@if (allowSelectNone || item.id) { @if (allowSelectNone || item.id) {
<pngx-toggleable-dropdown-button <pngx-toggleable-dropdown-button
[item]="item" [hideCount]="hideCount(item)" [state]="selectionModel.get(item.id)" [count]="getUpdatedDocumentCount(item.id)" (toggled)="selectionModel.toggle(item.id)" (exclude)="excludeClicked(item.id)" (click)="setButtonItemIndex(i - 1)" [disabled]="disabled"> [item]="item" [hideCount]="hideCount(item)" [state]="selectionModel.get(item.id)" [count]="getUpdatedDocumentCount(item.id)" (toggle)="selectionModel.toggle(item.id)" (exclude)="excludeClicked(item.id)" (click)="setButtonItemIndex(i - 1)" [disabled]="disabled">
</pngx-toggleable-dropdown-button> </pngx-toggleable-dropdown-button>
} }
} }

View File

@@ -58,7 +58,7 @@ describe('ToggleableDropdownButtonComponent', () => {
let toggleResult let toggleResult
component.state = ToggleableItemState.Selected component.state = ToggleableItemState.Selected
component.exclude.subscribe(() => (excludeResult = true)) component.exclude.subscribe(() => (excludeResult = true))
component.toggled.subscribe(() => (toggleResult = true)) component.toggle.subscribe(() => (toggleResult = true))
const button = fixture.nativeElement.querySelector('button') const button = fixture.nativeElement.querySelector('button')
button.dispatchEvent(new MouseEvent('click')) button.dispatchEvent(new MouseEvent('click'))
expect(excludeResult).toBeTruthy() expect(excludeResult).toBeTruthy()
@@ -70,7 +70,7 @@ describe('ToggleableDropdownButtonComponent', () => {
let toggleResult let toggleResult
component.state = ToggleableItemState.Excluded component.state = ToggleableItemState.Excluded
component.exclude.subscribe(() => (excludeResult = true)) component.exclude.subscribe(() => (excludeResult = true))
component.toggled.subscribe(() => (toggleResult = true)) component.toggle.subscribe(() => (toggleResult = true))
const button = fixture.nativeElement.querySelector('button') const button = fixture.nativeElement.querySelector('button')
button.dispatchEvent(new MouseEvent('click')) button.dispatchEvent(new MouseEvent('click'))
expect(excludeResult).toBeFalsy() expect(excludeResult).toBeFalsy()

View File

@@ -30,7 +30,7 @@ export class ToggleableDropdownButtonComponent {
hideCount: boolean = false hideCount: boolean = false
@Output() @Output()
toggled = new EventEmitter() toggle = new EventEmitter()
@Output() @Output()
exclude = new EventEmitter() exclude = new EventEmitter()
@@ -43,7 +43,7 @@ export class ToggleableDropdownButtonComponent {
if (this.state == ToggleableItemState.Selected) { if (this.state == ToggleableItemState.Selected) {
this.exclude.emit() this.exclude.emit()
} else { } else {
this.toggled.emit() this.toggle.emit()
} }
} }

View File

@@ -5,7 +5,7 @@
</div> </div>
} @else { } @else {
@if (renderAsObject) { @if (renderAsObject) {
<object [data]="previewURL | safeUrl" width="100%" class="bg-light" [class.p-2]="!isPdf" [class.pdf]="isPdf"></object> <object [data]="previewURL | safeUrl" width="100%" class="bg-light" [class.p-2]="!isPdf"></object>
} @else { } @else {
@if (requiresPassword) { @if (requiresPassword) {
<div class="w-100 h-100 position-relative"> <div class="w-100 h-100 position-relative">

View File

@@ -17,7 +17,7 @@
background-color: #e7e7e7; background-color: #e7e7e7;
} }
object:not(.pdf) { object {
mix-blend-mode: difference; mix-blend-mode: difference;
&.p-2 { &.p-2 {
padding: 0 !important; padding: 0 !important;

View File

@@ -1,6 +1,6 @@
<div class="card mb-3 shadow-sm bg-light" [class.card-selected]="selected" [class.document-card]="selectable" [class.popover-hidden]="popoverHidden" (mouseleave)="mouseLeaveCard()"> <div class="card mb-3 shadow-sm bg-light" [class.card-selected]="selected" [class.document-card]="selectable" [class.popover-hidden]="popoverHidden" (mouseleave)="mouseLeaveCard()">
<div class="row g-0"> <div class="row g-0">
<div class="col-md-2 doc-img-container rounded-start" (click)="this.toggleSelected.emit($event)" (dblclick)="dblClickDocument.emit()"> <div class="col-md-2 doc-img-background rounded-start" [class.doc-img-background-selected]="selected" (click)="this.toggleSelected.emit($event)" (dblclick)="dblClickDocument.emit()">
<img [src]="getThumbUrl()" class="card-img doc-img border-end rounded-start" [class.inverted]="getIsThumbInverted()"> <img [src]="getThumbUrl()" class="card-img doc-img border-end rounded-start" [class.inverted]="getIsThumbInverted()">
<div class="border-end border-bottom bg-light document-card-check"> <div class="border-end border-bottom bg-light document-card-check">

View File

@@ -2,7 +2,7 @@
overflow-wrap: anywhere; overflow-wrap: anywhere;
} }
.doc-img-container { .doc-img-background {
position: relative; position: relative;
} }
@@ -11,6 +11,7 @@
object-position: top left; object-position: top left;
height: 100%; height: 100%;
position: absolute; position: absolute;
mix-blend-mode: multiply;
} }
.card-title { .card-title {
@@ -48,6 +49,18 @@
display: block; display: block;
} }
.card-selected {
border-color: var(--bs-primary);
.document-card-check {
display: block;
}
}
.doc-img-background-selected {
background-color: var(--pngx-primary-faded);
}
.card-info { .card-info {
line-height: 1; line-height: 1;

View File

@@ -1,7 +1,7 @@
<div class="col p-2 h-100"> <div class="col p-2 h-100">
<div class="card h-100 shadow-sm document-card" [class.card-selected]="selected" [class.popover-hidden]="popoverHidden" (mouseleave)="mouseLeaveCard()"> <div class="card h-100 shadow-sm document-card" [class.card-selected]="selected" [class.popover-hidden]="popoverHidden" (mouseleave)="mouseLeaveCard()">
<div class="border-bottom doc-img-container" (click)="this.toggleSelected.emit($event)" (dblclick)="dblClickDocument.emit(this)"> <div class="border-bottom doc-img-container" [class.doc-img-background-selected]="selected" (click)="this.toggleSelected.emit($event)" (dblclick)="dblClickDocument.emit(this)">
<img class="card-img doc-img" [class.inverted]="getIsThumbInverted()" [src]="getThumbUrl()"> <img class="card-img doc-img rounded-top" [class.inverted]="getIsThumbInverted()" [src]="getThumbUrl()">
<div class="border-end border-bottom bg-light py-1 px-2 document-card-check"> <div class="border-end border-bottom bg-light py-1 px-2 document-card-check">
<div class="form-check"> <div class="form-check">

View File

@@ -6,6 +6,7 @@
object-fit: cover; object-fit: cover;
object-position: top left; object-position: top left;
height: 180px; height: 180px;
mix-blend-mode: multiply;
} }
.document-card-check { .document-card-check {
@@ -39,6 +40,18 @@
top: 142px; top: 142px;
} }
.card-selected {
border-color:var(--bs-primary);
.document-card-check {
display: block;
}
}
.doc-img-background-selected {
background-color: var(--pngx-primary-faded);
}
.card-info { .card-info {
line-height: 1; line-height: 1;

View File

@@ -1204,7 +1204,7 @@ describe('FilterEditorComponent', () => {
const tagButton = tagsFilterableDropdown.queryAll( const tagButton = tagsFilterableDropdown.queryAll(
By.directive(ToggleableDropdownButtonComponent) By.directive(ToggleableDropdownButtonComponent)
)[0] )[0]
tagButton.triggerEventHandler('toggled') tagButton.triggerEventHandler('toggle')
fixture.detectChanges() fixture.detectChanges()
expect(component.filterRules).toEqual([ expect(component.filterRules).toEqual([
{ {
@@ -1222,8 +1222,8 @@ describe('FilterEditorComponent', () => {
const tagButtons = tagsFilterableDropdown.queryAll( const tagButtons = tagsFilterableDropdown.queryAll(
By.directive(ToggleableDropdownButtonComponent) By.directive(ToggleableDropdownButtonComponent)
) )
tagButtons[1].triggerEventHandler('toggled') tagButtons[1].triggerEventHandler('toggle')
tagButtons[2].triggerEventHandler('toggled') tagButtons[2].triggerEventHandler('toggle')
fixture.detectChanges() fixture.detectChanges()
expect(component.filterRules).toEqual([ expect(component.filterRules).toEqual([
{ {
@@ -1273,8 +1273,8 @@ describe('FilterEditorComponent', () => {
const correspondentButtons = correspondentsFilterableDropdown.queryAll( const correspondentButtons = correspondentsFilterableDropdown.queryAll(
By.directive(ToggleableDropdownButtonComponent) By.directive(ToggleableDropdownButtonComponent)
) )
correspondentButtons[1].triggerEventHandler('toggled') correspondentButtons[1].triggerEventHandler('toggle')
correspondentButtons[2].triggerEventHandler('toggled') correspondentButtons[2].triggerEventHandler('toggle')
fixture.detectChanges() fixture.detectChanges()
expect(component.filterRules).toEqual([ expect(component.filterRules).toEqual([
{ {
@@ -1312,7 +1312,7 @@ describe('FilterEditorComponent', () => {
const notAssignedButton = correspondentsFilterableDropdown.queryAll( const notAssignedButton = correspondentsFilterableDropdown.queryAll(
By.directive(ToggleableDropdownButtonComponent) By.directive(ToggleableDropdownButtonComponent)
)[0] )[0]
notAssignedButton.triggerEventHandler('toggled') notAssignedButton.triggerEventHandler('toggle')
fixture.detectChanges() fixture.detectChanges()
expect(component.filterRules).toEqual([ expect(component.filterRules).toEqual([
{ {
@@ -1330,8 +1330,8 @@ describe('FilterEditorComponent', () => {
const documentTypeButtons = documentTypesFilterableDropdown.queryAll( const documentTypeButtons = documentTypesFilterableDropdown.queryAll(
By.directive(ToggleableDropdownButtonComponent) By.directive(ToggleableDropdownButtonComponent)
) )
documentTypeButtons[1].triggerEventHandler('toggled') documentTypeButtons[1].triggerEventHandler('toggle')
documentTypeButtons[2].triggerEventHandler('toggled') documentTypeButtons[2].triggerEventHandler('toggle')
fixture.detectChanges() fixture.detectChanges()
expect(component.filterRules).toEqual([ expect(component.filterRules).toEqual([
{ {
@@ -1369,7 +1369,7 @@ describe('FilterEditorComponent', () => {
const notAssignedButton = docTypesFilterableDropdown.queryAll( const notAssignedButton = docTypesFilterableDropdown.queryAll(
By.directive(ToggleableDropdownButtonComponent) By.directive(ToggleableDropdownButtonComponent)
)[0] )[0]
notAssignedButton.triggerEventHandler('toggled') notAssignedButton.triggerEventHandler('toggle')
fixture.detectChanges() fixture.detectChanges()
expect(component.filterRules).toEqual([ expect(component.filterRules).toEqual([
{ {
@@ -1387,8 +1387,8 @@ describe('FilterEditorComponent', () => {
const storagePathButtons = storagePathFilterableDropdown.queryAll( const storagePathButtons = storagePathFilterableDropdown.queryAll(
By.directive(ToggleableDropdownButtonComponent) By.directive(ToggleableDropdownButtonComponent)
) )
storagePathButtons[1].triggerEventHandler('toggled') storagePathButtons[1].triggerEventHandler('toggle')
storagePathButtons[2].triggerEventHandler('toggled') storagePathButtons[2].triggerEventHandler('toggle')
fixture.detectChanges() fixture.detectChanges()
expect(component.filterRules).toEqual([ expect(component.filterRules).toEqual([
{ {
@@ -1426,7 +1426,7 @@ describe('FilterEditorComponent', () => {
const notAssignedButton = storagePathsFilterableDropdown.queryAll( const notAssignedButton = storagePathsFilterableDropdown.queryAll(
By.directive(ToggleableDropdownButtonComponent) By.directive(ToggleableDropdownButtonComponent)
)[0] )[0]
notAssignedButton.triggerEventHandler('toggled') notAssignedButton.triggerEventHandler('toggle')
fixture.detectChanges() fixture.detectChanges()
expect(component.filterRules).toEqual([ expect(component.filterRules).toEqual([
{ {

View File

@@ -599,17 +599,14 @@ describe('DocumentListViewService', () => {
it('should not filter out custom fields if settings not initialized', () => { it('should not filter out custom fields if settings not initialized', () => {
const customFields = ['custom_field_1', 'custom_field_2'] const customFields = ['custom_field_1', 'custom_field_2']
documentListViewService.displayFields = customFields as any documentListViewService.displayFields = customFields as any
settingsService.displayFieldsInitialized = false
expect(documentListViewService.displayFields).toEqual(customFields) expect(documentListViewService.displayFields).toEqual(customFields)
jest.spyOn(settingsService, 'allDisplayFields', 'get').mockReturnValue([ jest.spyOn(settingsService, 'allDisplayFields', 'get').mockReturnValue([
{ id: DisplayField.ADDED, name: 'Added' }, { id: DisplayField.ADDED, name: 'Added' },
{ id: DisplayField.TITLE, name: 'Title' }, { id: DisplayField.TITLE, name: 'Title' },
{ id: 'custom_field_1', name: 'Custom Field 1' }, { id: 'custom_field_1', name: 'Custom Field 1' },
] as any) ] as any)
settingsService.displayFieldsInit.emit(true) settingsService.displayFieldsInitialized = true
expect(documentListViewService.displayFields).toEqual(['custom_field_1'])
// will now filter on set
documentListViewService.displayFields = customFields as any
expect(documentListViewService.displayFields).toEqual(['custom_field_1']) expect(documentListViewService.displayFields).toEqual(['custom_field_1'])
}) })
}) })

View File

@@ -20,10 +20,6 @@ import { paramsFromViewState, paramsToViewState } from '../utils/query-params'
import { DocumentService, SelectionData } from './rest/document.service' import { DocumentService, SelectionData } from './rest/document.service'
import { SettingsService } from './settings.service' import { SettingsService } from './settings.service'
const LIST_DEFAULT_DISPLAY_FIELDS: DisplayField[] = DEFAULT_DISPLAY_FIELDS.map(
(f) => f.id
).filter((f) => f !== DisplayField.ADDED)
/** /**
* Captures the current state of the list view. * Captures the current state of the list view.
*/ */
@@ -106,8 +102,6 @@ export class DocumentListViewService {
private _activeSavedViewId: number = null private _activeSavedViewId: number = null
private displayFieldsInitialized: boolean = false
get activeSavedViewId() { get activeSavedViewId() {
return this._activeSavedViewId return this._activeSavedViewId
} }
@@ -140,19 +134,6 @@ export class DocumentListViewService {
localStorage.removeItem(DOCUMENT_LIST_SERVICE.CURRENT_VIEW_CONFIG) localStorage.removeItem(DOCUMENT_LIST_SERVICE.CURRENT_VIEW_CONFIG)
} }
} }
this.settings.displayFieldsInit.subscribe(() => {
this.displayFieldsInitialized = true
if (this.activeListViewState.displayFields) {
this.activeListViewState.displayFields =
this.activeListViewState.displayFields.filter(
(field) =>
this.settings.allDisplayFields.find((f) => f.id === field) !==
undefined
)
this.saveDocumentListView()
}
})
} }
private defaultListViewState(): ListViewState { private defaultListViewState(): ListViewState {
@@ -434,17 +415,23 @@ export class DocumentListViewService {
} }
get displayFields(): DisplayField[] { get displayFields(): DisplayField[] {
return this.activeListViewState.displayFields ?? LIST_DEFAULT_DISPLAY_FIELDS let fields =
this.activeListViewState.displayFields ??
DEFAULT_DISPLAY_FIELDS.map((f) => f.id)
if (!this.activeListViewState.displayFields) {
fields = fields.filter((f) => f !== DisplayField.ADDED)
} }
return this.settings.displayFieldsInitialized
set displayFields(fields: DisplayField[]) { ? fields.filter(
this.activeListViewState.displayFields = this.displayFieldsInitialized
? fields?.filter(
(field) => (field) =>
this.settings.allDisplayFields.find((f) => f.id === field) !== this.settings.allDisplayFields.find((f) => f.id === field) !==
undefined undefined
) )
: fields : fields
}
set displayFields(fields: DisplayField[]) {
this.activeListViewState.displayFields = fields
this.saveDocumentListView() this.saveDocumentListView()
} }

View File

@@ -274,7 +274,7 @@ export class SettingsService {
public get allDisplayFields(): Array<{ id: DisplayField; name: string }> { public get allDisplayFields(): Array<{ id: DisplayField; name: string }> {
return this._allDisplayFields return this._allDisplayFields
} }
public displayFieldsInit: EventEmitter<boolean> = new EventEmitter() public displayFieldsInitialized: boolean = false
constructor( constructor(
rendererFactory: RendererFactory2, rendererFactory: RendererFactory2,
@@ -382,10 +382,10 @@ export class SettingsService {
} }
}) })
) )
this.displayFieldsInit.emit(true) this.displayFieldsInitialized = true
}) })
} else { } else {
this.displayFieldsInit.emit(true) this.displayFieldsInitialized = true
} }
} }

View File

@@ -118,4 +118,29 @@ describe('TasksService', () => {
expect(tasksService.queuedFileTasks).toHaveLength(1) expect(tasksService.queuedFileTasks).toHaveLength(1)
expect(tasksService.startedFileTasks).toHaveLength(1) expect(tasksService.startedFileTasks).toHaveLength(1)
}) })
it('should call retry task api endpoint', () => {
const task = {
id: 1,
type: PaperlessTaskType.File,
status: PaperlessTaskStatus.Failed,
acknowledged: false,
task_id: '1234',
task_file_name: 'file1.pdf',
date_created: new Date(),
}
tasksService.retryTask(task, true).subscribe()
const reloadSpy = jest.spyOn(tasksService, 'reload')
const req = httpTestingController.expectOne(
`${environment.apiBaseUrl}tasks/${task.id}/retry/`
)
expect(req.request.method).toEqual('POST')
expect(req.request.body).toEqual({
clean: true,
})
req.flush({ task_id: 12345 })
expect(reloadSpy).toHaveBeenCalled()
httpTestingController.expectOne(`${environment.apiBaseUrl}tasks/`).flush([])
})
}) })

View File

@@ -1,7 +1,7 @@
import { HttpClient } from '@angular/common/http' import { HttpClient } from '@angular/common/http'
import { Injectable } from '@angular/core' import { Injectable } from '@angular/core'
import { Subject } from 'rxjs' import { Observable, Subject } from 'rxjs'
import { first, takeUntil } from 'rxjs/operators' import { first, takeUntil, tap } from 'rxjs/operators'
import { import {
PaperlessTask, PaperlessTask,
PaperlessTaskStatus, PaperlessTaskStatus,
@@ -73,6 +73,20 @@ export class TasksService {
}) })
} }
public retryTask(task: PaperlessTask, clean: boolean): Observable<any> {
return this.http
.post(`${this.baseUrl}tasks/${task.id}/retry/`, {
clean,
})
.pipe(
takeUntil(this.unsubscribeNotifer),
first(),
tap(() => {
this.reload()
})
)
}
public cancelPending(): void { public cancelPending(): void {
this.unsubscribeNotifer.next(true) this.unsubscribeNotifer.next(true)
} }

View File

@@ -5,7 +5,7 @@ export const environment = {
apiBaseUrl: document.baseURI + 'api/', apiBaseUrl: document.baseURI + 'api/',
apiVersion: '5', apiVersion: '5',
appTitle: 'Paperless-ngx', appTitle: 'Paperless-ngx',
version: '2.13.4', version: '2.13.2',
webSocketHost: window.location.host, webSocketHost: window.location.host,
webSocketProtocol: window.location.protocol == 'https:' ? 'wss:' : 'ws:', webSocketProtocol: window.location.protocol == 'https:' ? 'wss:' : 'ws:',
webSocketBaseUrl: base_url.pathname + 'ws/', webSocketBaseUrl: base_url.pathname + 'ws/',

View File

@@ -3605,7 +3605,7 @@
</context-group> </context-group>
<target state="final">Fehler beim Speichern des Feldes.</target> <target state="final">Fehler beim Speichern des Feldes.</target>
</trans-unit> </trans-unit>
<trans-unit id="4465085913683915434" datatype="html" approved="yes"> <trans-unit id="4465085913683915434" datatype="html">
<source>True</source> <source>True</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context>
@@ -3619,9 +3619,9 @@
<context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context>
<context context-type="linenumber">79</context> <context context-type="linenumber">79</context>
</context-group> </context-group>
<target state="final">Wahr</target> <target state="translated">Wahr</target>
</trans-unit> </trans-unit>
<trans-unit id="3800326155195149498" datatype="html" approved="yes"> <trans-unit id="3800326155195149498" datatype="html">
<source>False</source> <source>False</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context>
@@ -3635,15 +3635,15 @@
<context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context>
<context context-type="linenumber">80</context> <context context-type="linenumber">80</context>
</context-group> </context-group>
<target state="final">Falsch</target> <target state="translated">Falsch</target>
</trans-unit> </trans-unit>
<trans-unit id="7551700625201096185" datatype="html" approved="yes"> <trans-unit id="7551700625201096185" datatype="html">
<source>Search docs...</source> <source>Search docs...</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context>
<context context-type="linenumber">96</context> <context context-type="linenumber">96</context>
</context-group> </context-group>
<target state="final">Suche Dokumente...</target> <target state="translated">Suche Dokumente...</target>
</trans-unit> </trans-unit>
<trans-unit id="3184700926171002527" datatype="html" approved="yes"> <trans-unit id="3184700926171002527" datatype="html" approved="yes">
<source>Any</source> <source>Any</source>
@@ -3685,29 +3685,29 @@
</context-group> </context-group>
<target state="final">Alle</target> <target state="final">Alle</target>
</trans-unit> </trans-unit>
<trans-unit id="1496549861742963591" datatype="html" approved="yes"> <trans-unit id="1496549861742963591" datatype="html">
<source>Not</source> <source>Not</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context>
<context context-type="linenumber">131</context> <context context-type="linenumber">131</context>
</context-group> </context-group>
<target state="final">Nicht</target> <target state="translated">Nicht</target>
</trans-unit> </trans-unit>
<trans-unit id="6548676277933116532" datatype="html" approved="yes"> <trans-unit id="6548676277933116532" datatype="html">
<source>Add query</source> <source>Add query</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context>
<context context-type="linenumber">150</context> <context context-type="linenumber">150</context>
</context-group> </context-group>
<target state="final">Abfrage hinzufügen</target> <target state="translated">Abfrage hinzufügen</target>
</trans-unit> </trans-unit>
<trans-unit id="5599577087865387184" datatype="html" approved="yes"> <trans-unit id="5599577087865387184" datatype="html">
<source>Add expression</source> <source>Add expression</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context>
<context context-type="linenumber">153</context> <context context-type="linenumber">153</context>
</context-group> </context-group>
<target state="final">Ausdruck hinzufügen</target> <target state="translated">Ausdruck hinzufügen</target>
</trans-unit> </trans-unit>
<trans-unit id="6052766076365105714" datatype="html" approved="yes"> <trans-unit id="6052766076365105714" datatype="html" approved="yes">
<source>now</source> <source>now</source>
@@ -4513,13 +4513,13 @@
</context-group> </context-group>
<target state="final">Pfad</target> <target state="final">Pfad</target>
</trans-unit> </trans-unit>
<trans-unit id="2816147949408898105" datatype="html" approved="yes"> <trans-unit id="2816147949408898105" datatype="html">
<source>See &lt;a target=&apos;_blank&apos; href=&apos;https://docs.paperless-ngx.com/advanced_usage/#file-name-handling&apos;&gt;the documentation&lt;/a&gt;.</source> <source>See &lt;a target=&apos;_blank&apos; href=&apos;https://docs.paperless-ngx.com/advanced_usage/#file-name-handling&apos;&gt;the documentation&lt;/a&gt;.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html</context>
<context context-type="linenumber">13</context> <context context-type="linenumber">13</context>
</context-group> </context-group>
<target state="final">Siehe &lt;a target='_blank' href='https://docs.paperless-ngx.com/advanced_usage/#file-name-handling'&gt;Dokumentation&lt;/a&gt;.</target> <target state="translated">Siehe &lt;a target='_blank' href='https://docs.paperless-ngx.com/advanced_usage/#file-name-handling'&gt;Dokumentation&lt;/a&gt;.</target>
</trans-unit> </trans-unit>
<trans-unit id="1295614462098694869" datatype="html" approved="yes"> <trans-unit id="1295614462098694869" datatype="html" approved="yes">
<source>Preview</source> <source>Preview</source>
@@ -4533,29 +4533,29 @@
</context-group> </context-group>
<target state="final">Vorschau</target> <target state="final">Vorschau</target>
</trans-unit> </trans-unit>
<trans-unit id="8057014866157903311" datatype="html" approved="yes"> <trans-unit id="8057014866157903311" datatype="html">
<source>Path test failed</source> <source>Path test failed</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html</context>
<context context-type="linenumber">30</context> <context context-type="linenumber">30</context>
</context-group> </context-group>
<target state="final">Pfadüberprüfung fehlgeschlagen</target> <target state="translated">Pfadüberprüfung fehlgeschlagen</target>
</trans-unit> </trans-unit>
<trans-unit id="9116034231465034307" datatype="html" approved="yes"> <trans-unit id="9116034231465034307" datatype="html">
<source>No document selected</source> <source>No document selected</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html</context>
<context context-type="linenumber">32</context> <context context-type="linenumber">32</context>
</context-group> </context-group>
<target state="final">Kein Dokument ausgewählt</target> <target state="translated">Kein Dokument ausgewählt</target>
</trans-unit> </trans-unit>
<trans-unit id="2083498114116917092" datatype="html" approved="yes"> <trans-unit id="2083498114116917092" datatype="html">
<source>Search for a document</source> <source>Search for a document</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html</context>
<context context-type="linenumber">38</context> <context context-type="linenumber">38</context>
</context-group> </context-group>
<target state="final">Ein Dokument suchen</target> <target state="translated">Ein Dokument suchen</target>
</trans-unit> </trans-unit>
<trans-unit id="6423278459497515329" datatype="html" approved="yes"> <trans-unit id="6423278459497515329" datatype="html" approved="yes">
<source>No documents found</source> <source>No documents found</source>
@@ -5342,21 +5342,21 @@
</context-group> </context-group>
<target state="final">Link öffnen</target> <target state="final">Link öffnen</target>
</trans-unit> </trans-unit>
<trans-unit id="6595008830732269870" datatype="html" approved="yes"> <trans-unit id="6595008830732269870" datatype="html">
<source>Not found</source> <source>Not found</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/input/document-link/document-link.component.html</context> <context context-type="sourcefile">src/app/components/common/input/document-link/document-link.component.html</context>
<context context-type="linenumber">50</context> <context context-type="linenumber">50</context>
</context-group> </context-group>
<target state="final">Nicht gefunden</target> <target state="needs-translation">Not found</target>
</trans-unit> </trans-unit>
<trans-unit id="5676637575587497817" datatype="html" approved="yes"> <trans-unit id="5676637575587497817" datatype="html">
<source>Search for documents</source> <source>Search for documents</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/input/document-link/document-link.component.ts</context> <context context-type="sourcefile">src/app/components/common/input/document-link/document-link.component.ts</context>
<context context-type="linenumber">53</context> <context context-type="linenumber">53</context>
</context-group> </context-group>
<target state="final">Nach Dokumenten suchen</target> <target state="translated">Nach Dokumenten suchen</target>
</trans-unit> </trans-unit>
<trans-unit id="8627133593113147800" datatype="html" approved="yes"> <trans-unit id="8627133593113147800" datatype="html" approved="yes">
<source>Selected items</source> <source>Selected items</source>
@@ -8100,13 +8100,13 @@
</context-group> </context-group>
<target state="final">Ohne Tag</target> <target state="final">Ohne Tag</target>
</trans-unit> </trans-unit>
<trans-unit id="8644099678903817943" datatype="html" approved="yes"> <trans-unit id="8644099678903817943" datatype="html">
<source>Custom fields query</source> <source>Custom fields query</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context> <context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
<context context-type="linenumber">238</context> <context context-type="linenumber">238</context>
</context-group> </context-group>
<target state="final">Benutzerdefinierte Feldabfrage</target> <target state="translated">Benutzerdefinierte Feldabfrage</target>
</trans-unit> </trans-unit>
<trans-unit id="6523384805359286307" datatype="html" approved="yes"> <trans-unit id="6523384805359286307" datatype="html" approved="yes">
<source>Title: <x id="PH" equiv-text="rule.value"/></source> <source>Title: <x id="PH" equiv-text="rule.value"/></source>
@@ -8296,7 +8296,7 @@
</context-group> </context-group>
<target state="final">Datentyp</target> <target state="final">Datentyp</target>
</trans-unit> </trans-unit>
<trans-unit id="6209318295562170730" datatype="html" approved="yes"> <trans-unit id="6209318295562170730" datatype="html">
<source>Filter Documents (<x id="INTERPOLATION" equiv-text="{{ field.document_count }}"/>)</source> <source>Filter Documents (<x id="INTERPOLATION" equiv-text="{{ field.document_count }}"/>)</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/custom-fields/custom-fields.component.html</context> <context context-type="sourcefile">src/app/components/manage/custom-fields/custom-fields.component.html</context>
@@ -8318,7 +8318,7 @@
<context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.html</context> <context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.html</context>
<context context-type="linenumber">85</context> <context context-type="linenumber">85</context>
</context-group> </context-group>
<target state="final">Dokumente filtern (<x id="INTERPOLATION" equiv-text="{{ field.document_count }}"/>)</target> <target state="translated">Dokumente filtern (<x id="INTERPOLATION" equiv-text="{{ field.document_count }}"/>)</target>
</trans-unit> </trans-unit>
<trans-unit id="651372623796033489" datatype="html" approved="yes"> <trans-unit id="651372623796033489" datatype="html" approved="yes">
<source>No fields defined.</source> <source>No fields defined.</source>
@@ -8408,21 +8408,21 @@
</context-group> </context-group>
<target state="final">Konto hinzufügen</target> <target state="final">Konto hinzufügen</target>
</trans-unit> </trans-unit>
<trans-unit id="5088684330574277786" datatype="html" approved="yes"> <trans-unit id="5088684330574277786" datatype="html">
<source>Connect Gmail Account</source> <source>Connect Gmail Account</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.html</context> <context context-type="sourcefile">src/app/components/manage/mail/mail.component.html</context>
<context context-type="linenumber">18</context> <context context-type="linenumber">18</context>
</context-group> </context-group>
<target state="final">Gmail-Konto verbinden</target> <target state="translated">Gmail-Konto verbinden</target>
</trans-unit> </trans-unit>
<trans-unit id="6630732552154686829" datatype="html" approved="yes"> <trans-unit id="6630732552154686829" datatype="html">
<source>Connect Outlook Account</source> <source>Connect Outlook Account</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.html</context> <context context-type="sourcefile">src/app/components/manage/mail/mail.component.html</context>
<context context-type="linenumber">23</context> <context context-type="linenumber">23</context>
</context-group> </context-group>
<target state="final">Outlook-Konto verbinden</target> <target state="translated">Outlook-Konto verbinden</target>
</trans-unit> </trans-unit>
<trans-unit id="2188854519574316630" datatype="html" approved="yes"> <trans-unit id="2188854519574316630" datatype="html" approved="yes">
<source>Server</source> <source>Server</source>
@@ -8500,21 +8500,21 @@
</context-group> </context-group>
<target state="final">Fehler beim Abrufen der E-Mail-Regeln</target> <target state="final">Fehler beim Abrufen der E-Mail-Regeln</target>
</trans-unit> </trans-unit>
<trans-unit id="763945516325093575" datatype="html" approved="yes"> <trans-unit id="763945516325093575" datatype="html">
<source>OAuth2 authentication success</source> <source>OAuth2 authentication success</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.ts</context> <context context-type="sourcefile">src/app/components/manage/mail/mail.component.ts</context>
<context context-type="linenumber">101</context> <context context-type="linenumber">101</context>
</context-group> </context-group>
<target state="final">OAuth2-Authentifizierung erfolgreich</target> <target state="translated">OAuth2-Authentifizierung erfolgreich</target>
</trans-unit> </trans-unit>
<trans-unit id="9022978370268070156" datatype="html" approved="yes"> <trans-unit id="9022978370268070156" datatype="html">
<source>OAuth2 authentication failed, see logs for details</source> <source>OAuth2 authentication failed, see logs for details</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.ts</context> <context context-type="sourcefile">src/app/components/manage/mail/mail.component.ts</context>
<context context-type="linenumber">112</context> <context context-type="linenumber">112</context>
</context-group> </context-group>
<target state="final">OAuth2-Authentifizierung fehlgeschlagen, siehe Protokolle für Details</target> <target state="translated">OAuth2-Authentifizierung fehlgeschlagen, siehe Protokolle für Details</target>
</trans-unit> </trans-unit>
<trans-unit id="6327501535846658797" datatype="html" approved="yes"> <trans-unit id="6327501535846658797" datatype="html" approved="yes">
<source>Saved account &quot;<x id="PH" equiv-text="newMailAccount.name"/>&quot;.</source> <source>Saved account &quot;<x id="PH" equiv-text="newMailAccount.name"/>&quot;.</source>
@@ -9000,93 +9000,93 @@
</context-group> </context-group>
<target state="final">Zur Startseite</target> <target state="final">Zur Startseite</target>
</trans-unit> </trans-unit>
<trans-unit id="7088714514100361567" datatype="html" approved="yes"> <trans-unit id="7088714514100361567" datatype="html">
<source>Equal to</source> <source>Equal to</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/data/custom-field-query.ts</context> <context context-type="sourcefile">src/app/data/custom-field-query.ts</context>
<context context-type="linenumber">24</context> <context context-type="linenumber">24</context>
</context-group> </context-group>
<target state="final">Ist gleich</target> <target state="translated">Ist gleich</target>
</trans-unit> </trans-unit>
<trans-unit id="2841739558138901231" datatype="html" approved="yes"> <trans-unit id="2841739558138901231" datatype="html">
<source>In</source> <source>In</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/data/custom-field-query.ts</context> <context context-type="sourcefile">src/app/data/custom-field-query.ts</context>
<context context-type="linenumber">25</context> <context context-type="linenumber">25</context>
</context-group> </context-group>
<target state="final">In</target> <target state="translated">In</target>
</trans-unit> </trans-unit>
<trans-unit id="6504828068656625171" datatype="html" approved="yes"> <trans-unit id="6504828068656625171" datatype="html">
<source>Is null</source> <source>Is null</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/data/custom-field-query.ts</context> <context context-type="sourcefile">src/app/data/custom-field-query.ts</context>
<context context-type="linenumber">26</context> <context context-type="linenumber">26</context>
</context-group> </context-group>
<target state="final">Ist null</target> <target state="translated">Ist null</target>
</trans-unit> </trans-unit>
<trans-unit id="4112599358351148632" datatype="html" approved="yes"> <trans-unit id="4112599358351148632" datatype="html">
<source>Exists</source> <source>Exists</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/data/custom-field-query.ts</context> <context context-type="sourcefile">src/app/data/custom-field-query.ts</context>
<context context-type="linenumber">27</context> <context context-type="linenumber">27</context>
</context-group> </context-group>
<target state="final">Existiert</target> <target state="translated">Existiert</target>
</trans-unit> </trans-unit>
<trans-unit id="6238291467288576076" datatype="html" approved="yes"> <trans-unit id="6238291467288576076" datatype="html">
<source>Contains</source> <source>Contains</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/data/custom-field-query.ts</context> <context context-type="sourcefile">src/app/data/custom-field-query.ts</context>
<context context-type="linenumber">28</context> <context context-type="linenumber">28</context>
</context-group> </context-group>
<target state="final">Enthält</target> <target state="translated">Enthält</target>
</trans-unit> </trans-unit>
<trans-unit id="870133374397538941" datatype="html" approved="yes"> <trans-unit id="870133374397538941" datatype="html">
<source>Contains (case-insensitive)</source> <source>Contains (case-insensitive)</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/data/custom-field-query.ts</context> <context context-type="sourcefile">src/app/data/custom-field-query.ts</context>
<context context-type="linenumber">29</context> <context context-type="linenumber">29</context>
</context-group> </context-group>
<target state="final">Enthält (beachte Groß- und Kleinschreibung)</target> <target state="translated">Enthält (beachte Groß- und Kleinschreibung)</target>
</trans-unit> </trans-unit>
<trans-unit id="7732309408488818531" datatype="html" approved="yes"> <trans-unit id="7732309408488818531" datatype="html">
<source>Greater than</source> <source>Greater than</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/data/custom-field-query.ts</context> <context context-type="sourcefile">src/app/data/custom-field-query.ts</context>
<context context-type="linenumber">30</context> <context context-type="linenumber">30</context>
</context-group> </context-group>
<target state="final">Größer als</target> <target state="translated">Größer als</target>
</trans-unit> </trans-unit>
<trans-unit id="9087788064443057357" datatype="html" approved="yes"> <trans-unit id="9087788064443057357" datatype="html">
<source>Greater than or equal to</source> <source>Greater than or equal to</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/data/custom-field-query.ts</context> <context context-type="sourcefile">src/app/data/custom-field-query.ts</context>
<context context-type="linenumber">31</context> <context context-type="linenumber">31</context>
</context-group> </context-group>
<target state="final">Größer oder gleich</target> <target state="translated">Größer oder gleich</target>
</trans-unit> </trans-unit>
<trans-unit id="5995604223909447366" datatype="html" approved="yes"> <trans-unit id="5995604223909447366" datatype="html">
<source>Less than</source> <source>Less than</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/data/custom-field-query.ts</context> <context context-type="sourcefile">src/app/data/custom-field-query.ts</context>
<context context-type="linenumber">32</context> <context context-type="linenumber">32</context>
</context-group> </context-group>
<target state="final">Kleiner als</target> <target state="translated">Kleiner als</target>
</trans-unit> </trans-unit>
<trans-unit id="6989379963430864867" datatype="html" approved="yes"> <trans-unit id="6989379963430864867" datatype="html">
<source>Less than or equal to</source> <source>Less than or equal to</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/data/custom-field-query.ts</context> <context context-type="sourcefile">src/app/data/custom-field-query.ts</context>
<context context-type="linenumber">33</context> <context context-type="linenumber">33</context>
</context-group> </context-group>
<target state="final">Kleiner oder gleich</target> <target state="translated">Kleiner oder gleich</target>
</trans-unit> </trans-unit>
<trans-unit id="2348971518300945764" datatype="html" approved="yes"> <trans-unit id="2348971518300945764" datatype="html">
<source>Range</source> <source>Range</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/data/custom-field-query.ts</context> <context context-type="sourcefile">src/app/data/custom-field-query.ts</context>
<context context-type="linenumber">34</context> <context context-type="linenumber">34</context>
</context-group> </context-group>
<target state="final">Bereich</target> <target state="translated">Bereich</target>
</trans-unit> </trans-unit>
<trans-unit id="969459137986754249" datatype="html" approved="yes"> <trans-unit id="969459137986754249" datatype="html" approved="yes">
<source>Boolean</source> <source>Boolean</source>

View File

@@ -1743,7 +1743,7 @@
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">385</context> <context context-type="linenumber">385</context>
</context-group> </context-group>
<target state="translated">Tabell</target> <target state="needs-translation">Table</target>
</trans-unit> </trans-unit>
<trans-unit id="4236040382842528005" datatype="html"> <trans-unit id="4236040382842528005" datatype="html">
<source>Small Cards</source> <source>Small Cards</source>
@@ -1771,7 +1771,7 @@
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context> <context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">17</context> <context context-type="linenumber">17</context>
</context-group> </context-group>
<target state="translated">Visa</target> <target state="needs-translation">Show</target>
</trans-unit> </trans-unit>
<trans-unit id="5607669932062416162" datatype="html"> <trans-unit id="5607669932062416162" datatype="html">
<source>Default</source> <source>Default</source>
@@ -2303,7 +2303,7 @@
<context context-type="sourcefile">src/app/components/app-frame/app-frame.component.html</context> <context context-type="sourcefile">src/app/components/app-frame/app-frame.component.html</context>
<context context-type="linenumber">223</context> <context context-type="linenumber">223</context>
</context-group> </context-group>
<target state="translated">Papperskorg</target> <target state="needs-translation">Trash</target>
</trans-unit> </trans-unit>
<trans-unit id="3818027200170621545" datatype="html"> <trans-unit id="3818027200170621545" datatype="html">
<source>Manage trashed documents that are pending deletion.</source> <source>Manage trashed documents that are pending deletion.</source>
@@ -3307,7 +3307,7 @@
<context context-type="sourcefile">src/app/components/app-frame/global-search/global-search.component.html</context> <context context-type="sourcefile">src/app/components/app-frame/global-search/global-search.component.html</context>
<context context-type="linenumber">131</context> <context context-type="linenumber">131</context>
</context-group> </context-group>
<target state="translated">Användare</target> <target state="needs-translation">Users</target>
</trans-unit> </trans-unit>
<trans-unit id="searchResults.groups" datatype="html"> <trans-unit id="searchResults.groups" datatype="html">
<source>Groups</source> <source>Groups</source>
@@ -3315,7 +3315,7 @@
<context context-type="sourcefile">src/app/components/app-frame/global-search/global-search.component.html</context> <context context-type="sourcefile">src/app/components/app-frame/global-search/global-search.component.html</context>
<context context-type="linenumber">138</context> <context context-type="linenumber">138</context>
</context-group> </context-group>
<target state="translated">Grupper</target> <target state="needs-translation">Groups</target>
</trans-unit> </trans-unit>
<trans-unit id="searchResults.customFields" datatype="html"> <trans-unit id="searchResults.customFields" datatype="html">
<source>Custom fields</source> <source>Custom fields</source>
@@ -3471,7 +3471,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
<context context-type="linenumber">7,8</context> <context context-type="linenumber">7,8</context>
</context-group> </context-group>
<target state="translated">av <x id="INTERPOLATION" equiv-text="{{totalPages}}"/></target> <target state="needs-translation">of <x id="INTERPOLATION" equiv-text="{{totalPages}}"/></target>
</trans-unit> </trans-unit>
<trans-unit id="6903610408081711391" datatype="html"> <trans-unit id="6903610408081711391" datatype="html">
<source>Pages to remove</source> <source>Pages to remove</source>
@@ -3487,7 +3487,7 @@
<context context-type="sourcefile">src/app/components/common/confirm-dialog/merge-confirm-dialog/merge-confirm-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/confirm-dialog/merge-confirm-dialog/merge-confirm-dialog.component.html</context>
<context context-type="linenumber">9</context> <context context-type="linenumber">9</context>
</context-group> </context-group>
<target state="translated">Dokument:</target> <target state="needs-translation">Documents:</target>
</trans-unit> </trans-unit>
<trans-unit id="7508164375697837821" datatype="html"> <trans-unit id="7508164375697837821" datatype="html">
<source>Use metadata from:</source> <source>Use metadata from:</source>
@@ -3579,7 +3579,7 @@
<context context-type="sourcefile">src/app/components/common/custom-fields-dropdown/custom-fields-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/custom-fields-dropdown/custom-fields-dropdown.component.html</context>
<context context-type="linenumber">21</context> <context context-type="linenumber">21</context>
</context-group> </context-group>
<target state="translated">Skapa nytt fält</target> <target state="needs-translation">Create new field</target>
</trans-unit> </trans-unit>
<trans-unit id="6973528734330066202" datatype="html"> <trans-unit id="6973528734330066202" datatype="html">
<source>Saved field &quot;<x id="PH" equiv-text="newField.name"/>&quot;.</source> <source>Saved field &quot;<x id="PH" equiv-text="newField.name"/>&quot;.</source>
@@ -3939,7 +3939,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.ts</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.ts</context>
<context context-type="linenumber">84</context> <context context-type="linenumber">84</context>
</context-group> </context-group>
<target state="translated">Redigera anpassat fält</target> <target state="needs-translation">Edit custom field</target>
</trans-unit> </trans-unit>
<trans-unit id="6672809941092516947" datatype="html" approved="yes"> <trans-unit id="6672809941092516947" datatype="html" approved="yes">
<source>Create new document type</source> <source>Create new document type</source>
@@ -5356,7 +5356,7 @@
<context context-type="sourcefile">src/app/components/common/input/document-link/document-link.component.ts</context> <context context-type="sourcefile">src/app/components/common/input/document-link/document-link.component.ts</context>
<context context-type="linenumber">53</context> <context context-type="linenumber">53</context>
</context-group> </context-group>
<target state="translated">Sök efter dokument</target> <target state="needs-translation">Search for documents</target>
</trans-unit> </trans-unit>
<trans-unit id="8627133593113147800" datatype="html"> <trans-unit id="8627133593113147800" datatype="html">
<source>Selected items</source> <source>Selected items</source>
@@ -5653,7 +5653,7 @@
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
<context context-type="linenumber">23</context> <context context-type="linenumber">23</context>
</context-group> </context-group>
<target state="translated">Bekräfta lösenord</target> <target state="needs-translation">Confirm Password</target>
</trans-unit> </trans-unit>
<trans-unit id="7554924397178347823" datatype="html"> <trans-unit id="7554924397178347823" datatype="html">
<source>API Auth Token</source> <source>API Auth Token</source>
@@ -5905,7 +5905,7 @@
<context context-type="sourcefile">src/app/components/common/share-links-dropdown/share-links-dropdown.component.ts</context> <context context-type="sourcefile">src/app/components/common/share-links-dropdown/share-links-dropdown.component.ts</context>
<context context-type="linenumber">94</context> <context context-type="linenumber">94</context>
</context-group> </context-group>
<target state="translated">1 dag</target> <target state="needs-translation">1 day</target>
</trans-unit> </trans-unit>
<trans-unit id="8542568275115626925" datatype="html"> <trans-unit id="8542568275115626925" datatype="html">
<source>7 days</source> <source>7 days</source>
@@ -5945,7 +5945,7 @@
<context context-type="sourcefile">src/app/components/common/share-links-dropdown/share-links-dropdown.component.ts</context> <context context-type="sourcefile">src/app/components/common/share-links-dropdown/share-links-dropdown.component.ts</context>
<context context-type="linenumber">94</context> <context context-type="linenumber">94</context>
</context-group> </context-group>
<target state="translated"><x id="PH" equiv-text="days"/> dagar</target> <target state="needs-translation"><x id="PH" equiv-text="days"/> days</target>
</trans-unit> </trans-unit>
<trans-unit id="2897042887615940599" datatype="html"> <trans-unit id="2897042887615940599" datatype="html">
<source>Error deleting link</source> <source>Error deleting link</source>
@@ -6025,7 +6025,7 @@
<context context-type="sourcefile">src/app/components/common/system-status-dialog/system-status-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/system-status-dialog/system-status-dialog.component.html</context>
<context context-type="linenumber">41</context> <context context-type="linenumber">41</context>
</context-group> </context-group>
<target state="translated">Databas</target> <target state="needs-translation">Database</target>
</trans-unit> </trans-unit>
<trans-unit id="5611592591303869712" datatype="html"> <trans-unit id="5611592591303869712" datatype="html">
<source>Status</source> <source>Status</source>
@@ -6045,7 +6045,7 @@
<context context-type="sourcefile">src/app/components/manage/workflows/workflows.component.html</context> <context context-type="sourcefile">src/app/components/manage/workflows/workflows.component.html</context>
<context context-type="linenumber">19</context> <context context-type="linenumber">19</context>
</context-group> </context-group>
<target state="translated">Status</target> <target state="needs-translation">Status</target>
</trans-unit> </trans-unit>
<trans-unit id="2256165083739630668" datatype="html"> <trans-unit id="2256165083739630668" datatype="html">
<source>Migration Status</source> <source>Migration Status</source>
@@ -6085,7 +6085,7 @@
<context context-type="sourcefile">src/app/components/common/system-status-dialog/system-status-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/system-status-dialog/system-status-dialog.component.html</context>
<context context-type="linenumber">83</context> <context context-type="linenumber">83</context>
</context-group> </context-group>
<target state="translated">Uppgifter</target> <target state="needs-translation">Tasks</target>
</trans-unit> </trans-unit>
<trans-unit id="6911698235105017958" datatype="html"> <trans-unit id="6911698235105017958" datatype="html">
<source>Redis Status</source> <source>Redis Status</source>
@@ -6157,7 +6157,7 @@
<context context-type="sourcefile">src/app/components/dashboard/dashboard.component.ts</context> <context context-type="sourcefile">src/app/components/dashboard/dashboard.component.ts</context>
<context context-type="linenumber">40</context> <context context-type="linenumber">40</context>
</context-group> </context-group>
<target state="translated">Välkommen till <x id="PH" equiv-text="environment.appTitle"/></target> <target state="needs-translation">Welcome to <x id="PH" equiv-text="environment.appTitle"/></target>
</trans-unit> </trans-unit>
<trans-unit id="1325877348738783391" datatype="html"> <trans-unit id="1325877348738783391" datatype="html">
<source>Dashboard updated</source> <source>Dashboard updated</source>
@@ -6892,7 +6892,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">502</context> <context context-type="linenumber">502</context>
</context-group> </context-group>
<target state="translated">Spara dokument</target> <target state="needs-translation">Save document</target>
</trans-unit> </trans-unit>
<trans-unit id="5758784066858623886" datatype="html"> <trans-unit id="5758784066858623886" datatype="html">
<source>Error retrieving metadata</source> <source>Error retrieving metadata</source>
@@ -9142,7 +9142,7 @@
<context context-type="sourcefile">src/app/data/custom-field.ts</context> <context context-type="sourcefile">src/app/data/custom-field.ts</context>
<context context-type="linenumber">42</context> <context context-type="linenumber">42</context>
</context-group> </context-group>
<target state="translated">URL</target> <target state="needs-translation">Url</target>
</trans-unit> </trans-unit>
<trans-unit id="3650316326183661476" datatype="html"> <trans-unit id="3650316326183661476" datatype="html">
<source>Document Link</source> <source>Document Link</source>
@@ -9295,7 +9295,7 @@
<context context-type="sourcefile">src/app/data/paperless-config.ts</context> <context context-type="sourcefile">src/app/data/paperless-config.ts</context>
<context context-type="linenumber">83</context> <context context-type="linenumber">83</context>
</context-group> </context-group>
<target state="translated">Språk</target> <target state="needs-translation">Language</target>
</trans-unit> </trans-unit>
<trans-unit id="1713271461473302108" datatype="html"> <trans-unit id="1713271461473302108" datatype="html">
<source>Mode</source> <source>Mode</source>
@@ -9487,7 +9487,7 @@
<context context-type="sourcefile">src/app/pipes/custom-date.pipe.ts</context> <context context-type="sourcefile">src/app/pipes/custom-date.pipe.ts</context>
<context context-type="linenumber">14</context> <context context-type="linenumber">14</context>
</context-group> </context-group>
<target state="translated">%s år sedan</target> <target state="needs-translation">%s year ago</target>
</trans-unit> </trans-unit>
<trans-unit id="3393387677918927062" datatype="html"> <trans-unit id="3393387677918927062" datatype="html">
<source>%s years ago</source> <source>%s years ago</source>
@@ -9495,7 +9495,7 @@
<context context-type="sourcefile">src/app/pipes/custom-date.pipe.ts</context> <context context-type="sourcefile">src/app/pipes/custom-date.pipe.ts</context>
<context context-type="linenumber">15</context> <context context-type="linenumber">15</context>
</context-group> </context-group>
<target state="translated">%s år sedan</target> <target state="needs-translation">%s years ago</target>
</trans-unit> </trans-unit>
<trans-unit id="3053246523831285824" datatype="html"> <trans-unit id="3053246523831285824" datatype="html">
<source>%s month ago</source> <source>%s month ago</source>
@@ -9503,7 +9503,7 @@
<context context-type="sourcefile">src/app/pipes/custom-date.pipe.ts</context> <context context-type="sourcefile">src/app/pipes/custom-date.pipe.ts</context>
<context context-type="linenumber">19</context> <context context-type="linenumber">19</context>
</context-group> </context-group>
<target state="translated">%s månad sedan</target> <target state="needs-translation">%s month ago</target>
</trans-unit> </trans-unit>
<trans-unit id="1158628882375251480" datatype="html"> <trans-unit id="1158628882375251480" datatype="html">
<source>%s months ago</source> <source>%s months ago</source>
@@ -9511,7 +9511,7 @@
<context context-type="sourcefile">src/app/pipes/custom-date.pipe.ts</context> <context context-type="sourcefile">src/app/pipes/custom-date.pipe.ts</context>
<context context-type="linenumber">20</context> <context context-type="linenumber">20</context>
</context-group> </context-group>
<target state="translated">%s månader sedan</target> <target state="needs-translation">%s months ago</target>
</trans-unit> </trans-unit>
<trans-unit id="7039133412826927309" datatype="html"> <trans-unit id="7039133412826927309" datatype="html">
<source>%s week ago</source> <source>%s week ago</source>
@@ -9519,7 +9519,7 @@
<context context-type="sourcefile">src/app/pipes/custom-date.pipe.ts</context> <context context-type="sourcefile">src/app/pipes/custom-date.pipe.ts</context>
<context context-type="linenumber">24</context> <context context-type="linenumber">24</context>
</context-group> </context-group>
<target state="translated">%s vecka sedan</target> <target state="needs-translation">%s week ago</target>
</trans-unit> </trans-unit>
<trans-unit id="2896962543647781653" datatype="html"> <trans-unit id="2896962543647781653" datatype="html">
<source>%s weeks ago</source> <source>%s weeks ago</source>
@@ -9527,7 +9527,7 @@
<context context-type="sourcefile">src/app/pipes/custom-date.pipe.ts</context> <context context-type="sourcefile">src/app/pipes/custom-date.pipe.ts</context>
<context context-type="linenumber">25</context> <context context-type="linenumber">25</context>
</context-group> </context-group>
<target state="translated">%s veckor sedan</target> <target state="needs-translation">%s weeks ago</target>
</trans-unit> </trans-unit>
<trans-unit id="91416192007234700" datatype="html"> <trans-unit id="91416192007234700" datatype="html">
<source>%s day ago</source> <source>%s day ago</source>
@@ -9535,7 +9535,7 @@
<context context-type="sourcefile">src/app/pipes/custom-date.pipe.ts</context> <context context-type="sourcefile">src/app/pipes/custom-date.pipe.ts</context>
<context context-type="linenumber">29</context> <context context-type="linenumber">29</context>
</context-group> </context-group>
<target state="translated">%s dag sedan</target> <target state="needs-translation">%s day ago</target>
</trans-unit> </trans-unit>
<trans-unit id="5601594741748068208" datatype="html"> <trans-unit id="5601594741748068208" datatype="html">
<source>%s days ago</source> <source>%s days ago</source>
@@ -9543,7 +9543,7 @@
<context context-type="sourcefile">src/app/pipes/custom-date.pipe.ts</context> <context context-type="sourcefile">src/app/pipes/custom-date.pipe.ts</context>
<context context-type="linenumber">30</context> <context context-type="linenumber">30</context>
</context-group> </context-group>
<target state="translated">%s dagar sedan</target> <target state="needs-translation">%s days ago</target>
</trans-unit> </trans-unit>
<trans-unit id="8387405724402999437" datatype="html"> <trans-unit id="8387405724402999437" datatype="html">
<source>%s hour ago</source> <source>%s hour ago</source>
@@ -9551,7 +9551,7 @@
<context context-type="sourcefile">src/app/pipes/custom-date.pipe.ts</context> <context context-type="sourcefile">src/app/pipes/custom-date.pipe.ts</context>
<context context-type="linenumber">34</context> <context context-type="linenumber">34</context>
</context-group> </context-group>
<target state="translated">%s timme sedan</target> <target state="needs-translation">%s hour ago</target>
</trans-unit> </trans-unit>
<trans-unit id="2008395012733474465" datatype="html"> <trans-unit id="2008395012733474465" datatype="html">
<source>%s hours ago</source> <source>%s hours ago</source>
@@ -9559,7 +9559,7 @@
<context context-type="sourcefile">src/app/pipes/custom-date.pipe.ts</context> <context context-type="sourcefile">src/app/pipes/custom-date.pipe.ts</context>
<context context-type="linenumber">35</context> <context context-type="linenumber">35</context>
</context-group> </context-group>
<target state="translated">%s timmar sedan</target> <target state="needs-translation">%s hours ago</target>
</trans-unit> </trans-unit>
<trans-unit id="5782387980670840884" datatype="html"> <trans-unit id="5782387980670840884" datatype="html">
<source>%s minute ago</source> <source>%s minute ago</source>
@@ -9567,7 +9567,7 @@
<context context-type="sourcefile">src/app/pipes/custom-date.pipe.ts</context> <context context-type="sourcefile">src/app/pipes/custom-date.pipe.ts</context>
<context context-type="linenumber">39</context> <context context-type="linenumber">39</context>
</context-group> </context-group>
<target state="translated">%s minut sedan</target> <target state="needs-translation">%s minute ago</target>
</trans-unit> </trans-unit>
<trans-unit id="7573942914011074807" datatype="html"> <trans-unit id="7573942914011074807" datatype="html">
<source>%s minutes ago</source> <source>%s minutes ago</source>
@@ -9575,7 +9575,7 @@
<context context-type="sourcefile">src/app/pipes/custom-date.pipe.ts</context> <context context-type="sourcefile">src/app/pipes/custom-date.pipe.ts</context>
<context context-type="linenumber">40</context> <context context-type="linenumber">40</context>
</context-group> </context-group>
<target state="translated">%s minuter sedan</target> <target state="needs-translation">%s minutes ago</target>
</trans-unit> </trans-unit>
<trans-unit id="4272436583644511364" datatype="html"> <trans-unit id="4272436583644511364" datatype="html">
<source>Just now</source> <source>Just now</source>
@@ -9583,7 +9583,7 @@
<context context-type="sourcefile">src/app/pipes/custom-date.pipe.ts</context> <context context-type="sourcefile">src/app/pipes/custom-date.pipe.ts</context>
<context context-type="linenumber">72</context> <context context-type="linenumber">72</context>
</context-group> </context-group>
<target state="translated">Just nu</target> <target state="needs-translation">Just now</target>
</trans-unit> </trans-unit>
<trans-unit id="7536524521722799066" datatype="html" approved="yes"> <trans-unit id="7536524521722799066" datatype="html" approved="yes">
<source>(no title)</source> <source>(no title)</source>
@@ -9923,7 +9923,7 @@
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">166</context> <context context-type="linenumber">166</context>
</context-group> </context-group>
<target state="translated">Norska</target> <target state="needs-translation">Norwegian</target>
</trans-unit> </trans-unit>
<trans-unit id="792060551707690640" datatype="html" approved="yes"> <trans-unit id="792060551707690640" datatype="html" approved="yes">
<source>Polish</source> <source>Polish</source>

View File

@@ -1743,7 +1743,7 @@
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">385</context> <context context-type="linenumber">385</context>
</context-group> </context-group>
<target state="translated">表格</target> <target state="needs-translation">Table</target>
</trans-unit> </trans-unit>
<trans-unit id="4236040382842528005" datatype="html"> <trans-unit id="4236040382842528005" datatype="html">
<source>Small Cards</source> <source>Small Cards</source>
@@ -2371,7 +2371,7 @@
<context context-type="sourcefile">src/app/components/admin/trash/trash.component.html</context> <context context-type="sourcefile">src/app/components/admin/trash/trash.component.html</context>
<context context-type="linenumber">89</context> <context context-type="linenumber">89</context>
</context-group> </context-group>
<target state="translated">{VAR_PLURAL, plural, =1 {垃圾桶中有一份文件} other {垃圾桶中共有 <x id="INTERPOLATION"/> 份文件}}</target> <target state="needs-translation">{VAR_PLURAL, plural, =1 {One document in trash} other {<x id="INTERPOLATION"/> total documents in trash}}</target>
</trans-unit> </trans-unit>
<trans-unit id="9021887951960049161" datatype="html"> <trans-unit id="9021887951960049161" datatype="html">
<source>Confirm delete</source> <source>Confirm delete</source>
@@ -3619,7 +3619,7 @@
<context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context>
<context context-type="linenumber">79</context> <context context-type="linenumber">79</context>
</context-group> </context-group>
<target state="translated">真</target> <target state="needs-translation">True</target>
</trans-unit> </trans-unit>
<trans-unit id="3800326155195149498" datatype="html"> <trans-unit id="3800326155195149498" datatype="html">
<source>False</source> <source>False</source>
@@ -3635,7 +3635,7 @@
<context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context>
<context context-type="linenumber">80</context> <context context-type="linenumber">80</context>
</context-group> </context-group>
<target state="translated">假</target> <target state="needs-translation">False</target>
</trans-unit> </trans-unit>
<trans-unit id="7551700625201096185" datatype="html"> <trans-unit id="7551700625201096185" datatype="html">
<source>Search docs...</source> <source>Search docs...</source>
@@ -3643,7 +3643,7 @@
<context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context>
<context context-type="linenumber">96</context> <context context-type="linenumber">96</context>
</context-group> </context-group>
<target state="translated">搜索文档...</target> <target state="needs-translation">Search docs...</target>
</trans-unit> </trans-unit>
<trans-unit id="3184700926171002527" datatype="html"> <trans-unit id="3184700926171002527" datatype="html">
<source>Any</source> <source>Any</source>
@@ -3691,7 +3691,7 @@
<context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context>
<context context-type="linenumber">131</context> <context context-type="linenumber">131</context>
</context-group> </context-group>
<target state="translated">否</target> <target state="needs-translation">Not</target>
</trans-unit> </trans-unit>
<trans-unit id="6548676277933116532" datatype="html"> <trans-unit id="6548676277933116532" datatype="html">
<source>Add query</source> <source>Add query</source>
@@ -3699,7 +3699,7 @@
<context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context>
<context context-type="linenumber">150</context> <context context-type="linenumber">150</context>
</context-group> </context-group>
<target state="translated">添加查询</target> <target state="needs-translation">Add query</target>
</trans-unit> </trans-unit>
<trans-unit id="5599577087865387184" datatype="html"> <trans-unit id="5599577087865387184" datatype="html">
<source>Add expression</source> <source>Add expression</source>
@@ -3707,7 +3707,7 @@
<context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context>
<context context-type="linenumber">153</context> <context context-type="linenumber">153</context>
</context-group> </context-group>
<target state="translated">添加表达式</target> <target state="needs-translation">Add expression</target>
</trans-unit> </trans-unit>
<trans-unit id="6052766076365105714" datatype="html"> <trans-unit id="6052766076365105714" datatype="html">
<source>now</source> <source>now</source>
@@ -4135,7 +4135,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html</context>
<context context-type="linenumber">19</context> <context context-type="linenumber">19</context>
</context-group> </context-group>
<target state="translated">顺序</target> <target state="needs-translation">Order</target>
</trans-unit> </trans-unit>
<trans-unit id="4816216590591222133" datatype="html"> <trans-unit id="4816216590591222133" datatype="html">
<source>Enabled</source> <source>Enabled</source>
@@ -4519,7 +4519,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html</context>
<context context-type="linenumber">13</context> <context context-type="linenumber">13</context>
</context-group> </context-group>
<target state="translated">请参阅 &lt;a target='_blank' href='https://docs.paperless-ngx.com/advanced_usage/#file-name-handling'&gt;文档&lt;/a&gt;</target> <target state="needs-translation">See &lt;a target='_blank' href='https://docs.paperless-ngx.com/advanced_usage/#file-name-handling'&gt;the documentation&lt;/a&gt;.</target>
</trans-unit> </trans-unit>
<trans-unit id="1295614462098694869" datatype="html"> <trans-unit id="1295614462098694869" datatype="html">
<source>Preview</source> <source>Preview</source>
@@ -4539,7 +4539,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html</context>
<context context-type="linenumber">30</context> <context context-type="linenumber">30</context>
</context-group> </context-group>
<target state="translated">路径测试失败</target> <target state="needs-translation">Path test failed</target>
</trans-unit> </trans-unit>
<trans-unit id="9116034231465034307" datatype="html"> <trans-unit id="9116034231465034307" datatype="html">
<source>No document selected</source> <source>No document selected</source>
@@ -4547,7 +4547,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html</context>
<context context-type="linenumber">32</context> <context context-type="linenumber">32</context>
</context-group> </context-group>
<target state="translated">没有选择文档</target> <target state="needs-translation">No document selected</target>
</trans-unit> </trans-unit>
<trans-unit id="2083498114116917092" datatype="html"> <trans-unit id="2083498114116917092" datatype="html">
<source>Search for a document</source> <source>Search for a document</source>
@@ -4555,7 +4555,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html</context>
<context context-type="linenumber">38</context> <context context-type="linenumber">38</context>
</context-group> </context-group>
<target state="translated">搜索文档</target> <target state="needs-translation">Search for a document</target>
</trans-unit> </trans-unit>
<trans-unit id="6423278459497515329" datatype="html"> <trans-unit id="6423278459497515329" datatype="html">
<source>No documents found</source> <source>No documents found</source>
@@ -4759,7 +4759,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">33</context> <context context-type="linenumber">33</context>
</context-group> </context-group>
<target state="translated">添加触发器</target> <target state="needs-translation">Add Trigger</target>
</trans-unit> </trans-unit>
<trans-unit id="6882912390704300247" datatype="html"> <trans-unit id="6882912390704300247" datatype="html">
<source>Apply Actions:</source> <source>Apply Actions:</source>
@@ -4767,7 +4767,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">73</context> <context context-type="linenumber">73</context>
</context-group> </context-group>
<target state="translated">应用操作:</target> <target state="needs-translation">Apply Actions:</target>
</trans-unit> </trans-unit>
<trans-unit id="51883444329775670" datatype="html"> <trans-unit id="51883444329775670" datatype="html">
<source>Add Action</source> <source>Add Action</source>
@@ -4775,7 +4775,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">75</context> <context context-type="linenumber">75</context>
</context-group> </context-group>
<target state="translated">添加动作</target> <target state="needs-translation">Add Action</target>
</trans-unit> </trans-unit>
<trans-unit id="3288318211116868972" datatype="html"> <trans-unit id="3288318211116868972" datatype="html">
<source>Trigger type</source> <source>Trigger type</source>
@@ -4783,7 +4783,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">121</context> <context context-type="linenumber">121</context>
</context-group> </context-group>
<target state="translated">触发类型</target> <target state="needs-translation">Trigger type</target>
</trans-unit> </trans-unit>
<trans-unit id="8727727835543352574" datatype="html"> <trans-unit id="8727727835543352574" datatype="html">
<source>Trigger for documents that match <x id="START_EMPHASISED_TEXT" ctype="x-em" equiv-text="&lt;em&gt;"/>all<x id="CLOSE_EMPHASISED_TEXT" ctype="x-em" equiv-text="&lt;/em&gt;"/> filters specified below.</source> <source>Trigger for documents that match <x id="START_EMPHASISED_TEXT" ctype="x-em" equiv-text="&lt;em&gt;"/>all<x id="CLOSE_EMPHASISED_TEXT" ctype="x-em" equiv-text="&lt;/em&gt;"/> filters specified below.</source>
@@ -4791,7 +4791,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">122</context> <context context-type="linenumber">122</context>
</context-group> </context-group>
<target state="translated">触发匹配下面指定的 <x id="START_EMPHASISED_TEXT" ctype="x-em" equiv-text="&lt;em&gt;"/>所有<x id="CLOSE_EMPHASISED_TEXT" ctype="x-em" equiv-text="&lt;/em&gt;"/> 过滤器的文档。</target> <target state="needs-translation">Trigger for documents that match <x id="START_EMPHASISED_TEXT" ctype="x-em" equiv-text="&lt;em&gt;"/>all<x id="CLOSE_EMPHASISED_TEXT" ctype="x-em" equiv-text="&lt;/em&gt;"/> filters specified below.</target>
</trans-unit> </trans-unit>
<trans-unit id="7467799586957602479" datatype="html"> <trans-unit id="7467799586957602479" datatype="html">
<source>Filter filename</source> <source>Filter filename</source>
@@ -4831,7 +4831,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">128</context> <context context-type="linenumber">128</context>
</context-group> </context-group>
<target state="translated">应用于匹配此路径的文档。允许指定为*的通配符。不区分大小写。&lt;/a&gt;</target> <target state="needs-translation">Apply to documents that match this path. Wildcards specified as * are allowed. Case-normalized.&lt;/a&gt;</target>
</trans-unit> </trans-unit>
<trans-unit id="7468453896129193641" datatype="html"> <trans-unit id="7468453896129193641" datatype="html">
<source>Filter mail rule</source> <source>Filter mail rule</source>
@@ -4847,7 +4847,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">129</context> <context context-type="linenumber">129</context>
</context-group> </context-group>
<target state="translated">应用于通过此邮件规则消费的文档。</target> <target state="needs-translation">Apply to documents consumed via this mail rule.</target>
</trans-unit> </trans-unit>
<trans-unit id="6840369584127435743" datatype="html"> <trans-unit id="6840369584127435743" datatype="html">
<source>Content matching algorithm</source> <source>Content matching algorithm</source>
@@ -4855,7 +4855,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">132</context> <context context-type="linenumber">132</context>
</context-group> </context-group>
<target state="translated">内容匹配算法</target> <target state="needs-translation">Content matching algorithm</target>
</trans-unit> </trans-unit>
<trans-unit id="510635115034690805" datatype="html"> <trans-unit id="510635115034690805" datatype="html">
<source>Content matching pattern</source> <source>Content matching pattern</source>
@@ -4863,7 +4863,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">134</context> <context context-type="linenumber">134</context>
</context-group> </context-group>
<target state="translated">内容匹配模式</target> <target state="needs-translation">Content matching pattern</target>
</trans-unit> </trans-unit>
<trans-unit id="3484236514968690689" datatype="html"> <trans-unit id="3484236514968690689" datatype="html">
<source>Has any of tags</source> <source>Has any of tags</source>
@@ -4871,7 +4871,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">143</context> <context context-type="linenumber">143</context>
</context-group> </context-group>
<target state="translated">有任何标签</target> <target state="needs-translation">Has any of tags</target>
</trans-unit> </trans-unit>
<trans-unit id="5281365940563983618" datatype="html"> <trans-unit id="5281365940563983618" datatype="html">
<source>Has correspondent</source> <source>Has correspondent</source>
@@ -4879,7 +4879,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">144</context> <context context-type="linenumber">144</context>
</context-group> </context-group>
<target state="translated">已有联系人</target> <target state="needs-translation">Has correspondent</target>
</trans-unit> </trans-unit>
<trans-unit id="4806713133917046341" datatype="html"> <trans-unit id="4806713133917046341" datatype="html">
<source>Has document type</source> <source>Has document type</source>
@@ -4887,7 +4887,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">145</context> <context context-type="linenumber">145</context>
</context-group> </context-group>
<target state="translated">有文档类型</target> <target state="needs-translation">Has document type</target>
</trans-unit> </trans-unit>
<trans-unit id="6417103744331194518" datatype="html"> <trans-unit id="6417103744331194518" datatype="html">
<source>Action type</source> <source>Action type</source>
@@ -4895,7 +4895,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">155</context> <context context-type="linenumber">155</context>
</context-group> </context-group>
<target state="translated">操作类型</target> <target state="needs-translation">Action type</target>
</trans-unit> </trans-unit>
<trans-unit id="6019822389883736115" datatype="html"> <trans-unit id="6019822389883736115" datatype="html">
<source>Assign title</source> <source>Assign title</source>
@@ -4911,7 +4911,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">160</context> <context context-type="linenumber">160</context>
</context-group> </context-group>
<target state="translated">可以包含一些占位符,请参阅 &lt;a target='_blank' href='https://docs.paperless-ngx.com/usage/#workflows'&gt;文档&lt;/a&gt;</target> <target state="needs-translation">Can include some placeholders, see &lt;a target='_blank' href='https://docs.paperless-ngx.com/usage/#workflows'&gt;documentation&lt;/a&gt;.</target>
</trans-unit> </trans-unit>
<trans-unit id="6528897010417701530" datatype="html"> <trans-unit id="6528897010417701530" datatype="html">
<source>Assign tags</source> <source>Assign tags</source>
@@ -4967,7 +4967,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">216</context> <context context-type="linenumber">216</context>
</context-group> </context-group>
<target state="translated">移除标签</target> <target state="needs-translation">Remove tags</target>
</trans-unit> </trans-unit>
<trans-unit id="7890599006071681081" datatype="html"> <trans-unit id="7890599006071681081" datatype="html">
<source>Remove all</source> <source>Remove all</source>
@@ -4999,7 +4999,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">254</context> <context context-type="linenumber">254</context>
</context-group> </context-group>
<target state="translated">移除全部</target> <target state="needs-translation">Remove all</target>
</trans-unit> </trans-unit>
<trans-unit id="8636414563726517994" datatype="html"> <trans-unit id="8636414563726517994" datatype="html">
<source>Remove correspondents</source> <source>Remove correspondents</source>
@@ -5007,7 +5007,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">222</context> <context context-type="linenumber">222</context>
</context-group> </context-group>
<target state="translated">移除所有通讯员</target> <target state="needs-translation">Remove correspondents</target>
</trans-unit> </trans-unit>
<trans-unit id="5305293055593064952" datatype="html"> <trans-unit id="5305293055593064952" datatype="html">
<source>Remove document types</source> <source>Remove document types</source>
@@ -5015,7 +5015,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">228</context> <context context-type="linenumber">228</context>
</context-group> </context-group>
<target state="translated">移除所有文档类型</target> <target state="needs-translation">Remove document types</target>
</trans-unit> </trans-unit>
<trans-unit id="2400388879708187" datatype="html"> <trans-unit id="2400388879708187" datatype="html">
<source>Remove storage paths</source> <source>Remove storage paths</source>

View File

@@ -8,7 +8,7 @@
<context context-type="sourcefile">node_modules/src/ngb-config.ts</context> <context context-type="sourcefile">node_modules/src/ngb-config.ts</context>
<context context-type="linenumber">13</context> <context context-type="linenumber">13</context>
</context-group> </context-group>
<target state="translated">關閉</target> <target state="needs-translation">Close</target>
</trans-unit> </trans-unit>
<trans-unit id="ngb.timepicker.HH" datatype="html"> <trans-unit id="ngb.timepicker.HH" datatype="html">
<source>HH</source> <source>HH</source>
@@ -16,7 +16,7 @@
<context context-type="sourcefile">node_modules/src/ngb-config.ts</context> <context context-type="sourcefile">node_modules/src/ngb-config.ts</context>
<context context-type="linenumber">13</context> <context context-type="linenumber">13</context>
</context-group> </context-group>
<target state="translated">HH</target> <target state="needs-translation">HH</target>
</trans-unit> </trans-unit>
<trans-unit id="ngb.toast.close-aria" datatype="html"> <trans-unit id="ngb.toast.close-aria" datatype="html">
<source>Close</source> <source>Close</source>
@@ -24,7 +24,7 @@
<context context-type="sourcefile">node_modules/src/ngb-config.ts</context> <context context-type="sourcefile">node_modules/src/ngb-config.ts</context>
<context context-type="linenumber">13</context> <context context-type="linenumber">13</context>
</context-group> </context-group>
<target state="translated">關閉</target> <target state="needs-translation">Close</target>
</trans-unit> </trans-unit>
<trans-unit id="ngb.datepicker.select-month" datatype="html"> <trans-unit id="ngb.datepicker.select-month" datatype="html">
<source>Select month</source> <source>Select month</source>
@@ -36,7 +36,7 @@
<context context-type="sourcefile">node_modules/src/ngb-config.ts</context> <context context-type="sourcefile">node_modules/src/ngb-config.ts</context>
<context context-type="linenumber">13</context> <context context-type="linenumber">13</context>
</context-group> </context-group>
<target state="translated">選取月份</target> <target state="needs-translation">Select month</target>
</trans-unit> </trans-unit>
<trans-unit id="ngb.pagination.first" datatype="html"> <trans-unit id="ngb.pagination.first" datatype="html">
<source>««</source> <source>««</source>
@@ -56,7 +56,7 @@
<context context-type="sourcefile">node_modules/src/ngb-config.ts</context> <context context-type="sourcefile">node_modules/src/ngb-config.ts</context>
<context context-type="linenumber">13</context> <context context-type="linenumber">13</context>
</context-group> </context-group>
<target state="translated">上個月</target> <target state="needs-translation">Previous month</target>
</trans-unit> </trans-unit>
<trans-unit id="ngb.progressbar.value" datatype="html"> <trans-unit id="ngb.progressbar.value" datatype="html">
<source> <source>
@@ -82,7 +82,7 @@
<context context-type="sourcefile">node_modules/src/ngb-config.ts</context> <context context-type="sourcefile">node_modules/src/ngb-config.ts</context>
<context context-type="linenumber">13</context> <context context-type="linenumber">13</context>
</context-group> </context-group>
<target state="translated">小時</target> <target state="needs-translation">Hours</target>
</trans-unit> </trans-unit>
<trans-unit id="ngb.pagination.previous" datatype="html"> <trans-unit id="ngb.pagination.previous" datatype="html">
<source>«</source> <source>«</source>
@@ -98,7 +98,7 @@
<context context-type="sourcefile">node_modules/src/ngb-config.ts</context> <context context-type="sourcefile">node_modules/src/ngb-config.ts</context>
<context context-type="linenumber">13</context> <context context-type="linenumber">13</context>
</context-group> </context-group>
<target state="translated">上一個</target> <target state="needs-translation">Previous</target>
</trans-unit> </trans-unit>
<trans-unit id="ngb.timepicker.MM" datatype="html"> <trans-unit id="ngb.timepicker.MM" datatype="html">
<source>MM</source> <source>MM</source>
@@ -106,7 +106,7 @@
<context context-type="sourcefile">node_modules/src/ngb-config.ts</context> <context context-type="sourcefile">node_modules/src/ngb-config.ts</context>
<context context-type="linenumber">13</context> <context context-type="linenumber">13</context>
</context-group> </context-group>
<target state="translated">MM</target> <target state="needs-translation">MM</target>
</trans-unit> </trans-unit>
<trans-unit id="ngb.pagination.next" datatype="html"> <trans-unit id="ngb.pagination.next" datatype="html">
<source>»</source> <source>»</source>
@@ -126,7 +126,7 @@
<context context-type="sourcefile">node_modules/src/ngb-config.ts</context> <context context-type="sourcefile">node_modules/src/ngb-config.ts</context>
<context context-type="linenumber">13</context> <context context-type="linenumber">13</context>
</context-group> </context-group>
<target state="translated">選擇年份</target> <target state="needs-translation">Select year</target>
</trans-unit> </trans-unit>
<trans-unit id="ngb.datepicker.next-month" datatype="html"> <trans-unit id="ngb.datepicker.next-month" datatype="html">
<source>Next month</source> <source>Next month</source>
@@ -138,7 +138,7 @@
<context context-type="sourcefile">node_modules/src/ngb-config.ts</context> <context context-type="sourcefile">node_modules/src/ngb-config.ts</context>
<context context-type="linenumber">13</context> <context context-type="linenumber">13</context>
</context-group> </context-group>
<target state="translated">下一個月</target> <target state="needs-translation">Next month</target>
</trans-unit> </trans-unit>
<trans-unit id="ngb.carousel.next" datatype="html"> <trans-unit id="ngb.carousel.next" datatype="html">
<source>Next</source> <source>Next</source>
@@ -146,7 +146,7 @@
<context context-type="sourcefile">node_modules/src/ngb-config.ts</context> <context context-type="sourcefile">node_modules/src/ngb-config.ts</context>
<context context-type="linenumber">13</context> <context context-type="linenumber">13</context>
</context-group> </context-group>
<target state="translated">下一個</target> <target state="needs-translation">Next</target>
</trans-unit> </trans-unit>
<trans-unit id="ngb.timepicker.minutes" datatype="html"> <trans-unit id="ngb.timepicker.minutes" datatype="html">
<source>Minutes</source> <source>Minutes</source>
@@ -154,7 +154,7 @@
<context context-type="sourcefile">node_modules/src/ngb-config.ts</context> <context context-type="sourcefile">node_modules/src/ngb-config.ts</context>
<context context-type="linenumber">13</context> <context context-type="linenumber">13</context>
</context-group> </context-group>
<target state="translated">分鐘</target> <target state="needs-translation">Minutes</target>
</trans-unit> </trans-unit>
<trans-unit id="ngb.pagination.last" datatype="html"> <trans-unit id="ngb.pagination.last" datatype="html">
<source>»»</source> <source>»»</source>
@@ -170,7 +170,7 @@
<context context-type="sourcefile">node_modules/src/ngb-config.ts</context> <context context-type="sourcefile">node_modules/src/ngb-config.ts</context>
<context context-type="linenumber">13</context> <context context-type="linenumber">13</context>
</context-group> </context-group>
<target state="translated">第一頁</target> <target state="needs-translation">First</target>
</trans-unit> </trans-unit>
<trans-unit id="ngb.timepicker.increment-hours" datatype="html"> <trans-unit id="ngb.timepicker.increment-hours" datatype="html">
<source>Increment hours</source> <source>Increment hours</source>
@@ -186,7 +186,7 @@
<context context-type="sourcefile">node_modules/src/ngb-config.ts</context> <context context-type="sourcefile">node_modules/src/ngb-config.ts</context>
<context context-type="linenumber">13</context> <context context-type="linenumber">13</context>
</context-group> </context-group>
<target state="translated">上一頁</target> <target state="needs-translation">Previous</target>
</trans-unit> </trans-unit>
<trans-unit id="ngb.timepicker.decrement-hours" datatype="html"> <trans-unit id="ngb.timepicker.decrement-hours" datatype="html">
<source>Decrement hours</source> <source>Decrement hours</source>
@@ -202,7 +202,7 @@
<context context-type="sourcefile">node_modules/src/ngb-config.ts</context> <context context-type="sourcefile">node_modules/src/ngb-config.ts</context>
<context context-type="linenumber">13</context> <context context-type="linenumber">13</context>
</context-group> </context-group>
<target state="translated">下一頁</target> <target state="needs-translation">Next</target>
</trans-unit> </trans-unit>
<trans-unit id="ngb.timepicker.increment-minutes" datatype="html"> <trans-unit id="ngb.timepicker.increment-minutes" datatype="html">
<source>Increment minutes</source> <source>Increment minutes</source>
@@ -218,7 +218,7 @@
<context context-type="sourcefile">node_modules/src/ngb-config.ts</context> <context context-type="sourcefile">node_modules/src/ngb-config.ts</context>
<context context-type="linenumber">13</context> <context context-type="linenumber">13</context>
</context-group> </context-group>
<target state="translated">最後一頁</target> <target state="needs-translation">Last</target>
</trans-unit> </trans-unit>
<trans-unit id="ngb.timepicker.decrement-minutes" datatype="html"> <trans-unit id="ngb.timepicker.decrement-minutes" datatype="html">
<source>Decrement minutes</source> <source>Decrement minutes</source>

View File

@@ -490,23 +490,9 @@ ul.pagination {
.doc-img-container { .doc-img-container {
border: none !important; border: none !important;
border-top-left-radius: .25rem;
border-top-right-radius: .25rem;
overflow: hidden; overflow: hidden;
.doc-img {
overflow: visible;
}
}
.card-selected {
border-color:var(--bs-primary);
.document-card-check {
display: block;
}
.doc-img-container {
background-color: var(--pngx-primary-faded);
}
} }
table.table { table.table {
@@ -719,8 +705,6 @@ i-bs svg {
vertical-align: text-bottom; vertical-align: text-bottom;
} }
.document-card { .document-card .card-footer i-bs svg {
.card-footer i-bs svg {
vertical-align: middle; vertical-align: middle;
} }
}

View File

@@ -183,7 +183,7 @@ $form-check-radio-checked-bg-image-dark: url("data:image/svg+xml,<svg xmlns='htt
} }
.doc-img { .doc-img {
mix-blend-mode: normal; mix-blend-mode: normal !important;
border-radius: 0; border-radius: 0;
border-color: var(--bs-border-color); border-color: var(--bs-border-color);
filter: invert(10%); filter: invert(10%);
@@ -201,24 +201,6 @@ $form-check-radio-checked-bg-image-dark: url("data:image/svg+xml,<svg xmlns='htt
mix-blend-mode: luminosity; mix-blend-mode: luminosity;
} }
@supports (hanging-punctuation: first) and (font: -apple-system-body) and (-webkit-appearance: none) {
// Safari does not like the filters on the image, see https://github.com/paperless-ngx/paperless-ngx/pull/8121
.doc-img-container {
background-color: #ffffff;
}
.doc-img {
filter: none !important;
box-shadow: inset 0px 0px 0px 10px rgba(0,0,0,1);
}
.doc-img.inverted {
filter: none !important;
mix-blend-mode: difference;
opacity: 0.95;
}
}
.paperless-input-select .ng-select .ng-dropdown-panel .ng-dropdown-panel-items .ng-option:not(.ng-option-selected):hover, .paperless-input-select .ng-select .ng-dropdown-panel .ng-dropdown-panel-items .ng-option:not(.ng-option-selected):hover,
.paperless-input-select .ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-marked { .paperless-input-select .ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-marked {
background-color: var(--bs-light) !important; background-color: var(--bs-light) !important;

View File

@@ -148,6 +148,17 @@ class ConsumerPlugin(
): ):
self._send_progress(100, 100, ProgressStatusOptions.FAILED, message) self._send_progress(100, 100, ProgressStatusOptions.FAILED, message)
self.log.error(log_message or message, exc_info=exc_info) self.log.error(log_message or message, exc_info=exc_info)
# Move the file to the failed directory
if (
self.input_doc.original_file.exists()
and not Path(
settings.CONSUMPTION_FAILED_DIR / self.input_doc.original_file.name,
).exists()
):
copy_file_with_basic_stats(
self.input_doc.original_file,
settings.CONSUMPTION_FAILED_DIR / self.input_doc.original_file.name,
)
raise ConsumerError(f"{self.filename}: {log_message or message}") from exception raise ConsumerError(f"{self.filename}: {log_message or message}") from exception
def pre_check_file_exists(self): def pre_check_file_exists(self):
@@ -411,7 +422,6 @@ class ConsumerPlugin(
self.unmodified_original = ( self.unmodified_original = (
Path(tempdir.name) / Path("uo") / Path(self.filename) Path(tempdir.name) / Path("uo") / Path(self.filename)
) )
self.unmodified_original.parent.mkdir(exist_ok=True)
copy_file_with_basic_stats( copy_file_with_basic_stats(
self.input_doc.original_file, self.input_doc.original_file,
self.unmodified_original, self.unmodified_original,

View File

@@ -424,28 +424,20 @@ class CustomFieldQueryParser:
value_field_name = "value_monetary_amount" value_field_name = "value_monetary_amount"
has_field = Q(custom_fields__field=custom_field) has_field = Q(custom_fields__field=custom_field)
# We need to use an annotation here because different atoms
# might be referring to different instances of custom fields.
annotation_name = f"_custom_field_filter_{len(self._annotations)}"
# Our special exists operator. # Our special exists operator.
if op == "exists": if op == "exists":
annotation = Count("custom_fields", filter=has_field) field_filter = has_field if value else ~has_field
# A Document should have > 0 match if it has this field, or 0 if doesn't.
query_op = "gt" if value else "exact"
query = Q(**{f"{annotation_name}__{query_op}": 0})
else: else:
# Check if 1) custom field name matches, and 2) value satisfies condition
field_filter = has_field & Q( field_filter = has_field & Q(
**{f"custom_fields__{value_field_name}__{op}": value}, **{f"custom_fields__{value_field_name}__{op}": value},
) )
# Annotate how many matching custom fields each document has
annotation = Count("custom_fields", filter=field_filter)
# Filter document by count
query = Q(**{f"{annotation_name}__gt": 0})
self._annotations[annotation_name] = annotation # We need to use an annotation here because different atoms
return query # might be referring to different instances of custom fields.
annotation_name = f"_custom_field_filter_{len(self._annotations)}"
self._annotations[annotation_name] = Count("custom_fields", filter=field_filter)
return Q(**{f"{annotation_name}__gt": 0})
@handle_validation_prefix @handle_validation_prefix
def _get_custom_field(self, id_or_name): def _get_custom_field(self, id_or_name):

View File

@@ -679,24 +679,28 @@ class PaperlessTask(models.Model):
verbose_name=_("Task State"), verbose_name=_("Task State"),
help_text=_("Current state of the task being run"), help_text=_("Current state of the task being run"),
) )
date_created = models.DateTimeField( date_created = models.DateTimeField(
null=True, null=True,
default=timezone.now, default=timezone.now,
verbose_name=_("Created DateTime"), verbose_name=_("Created DateTime"),
help_text=_("Datetime field when the task result was created in UTC"), help_text=_("Datetime field when the task result was created in UTC"),
) )
date_started = models.DateTimeField( date_started = models.DateTimeField(
null=True, null=True,
default=None, default=None,
verbose_name=_("Started DateTime"), verbose_name=_("Started DateTime"),
help_text=_("Datetime field when the task was started in UTC"), help_text=_("Datetime field when the task was started in UTC"),
) )
date_done = models.DateTimeField( date_done = models.DateTimeField(
null=True, null=True,
default=None, default=None,
verbose_name=_("Completed DateTime"), verbose_name=_("Completed DateTime"),
help_text=_("Datetime field when the task was completed in UTC"), help_text=_("Datetime field when the task was completed in UTC"),
) )
result = models.TextField( result = models.TextField(
null=True, null=True,
default=None, default=None,

View File

@@ -1585,6 +1585,14 @@ class TasksViewSerializer(serializers.ModelSerializer):
return result return result
class RetryTaskSerializer(serializers.Serializer):
clean = serializers.BooleanField(
default=False,
write_only=True,
required=False,
)
class AcknowledgeTasksViewSerializer(serializers.Serializer): class AcknowledgeTasksViewSerializer(serializers.Serializer):
tasks = serializers.ListField( tasks = serializers.ListField(
required=True, required=True,

View File

@@ -1,6 +1,7 @@
import logging import logging
import os import os
import shutil import shutil
from pathlib import Path
from celery import states from celery import states
from celery.signals import before_task_publish from celery.signals import before_task_publish
@@ -520,6 +521,19 @@ def update_filename_and_move_files(
) )
@receiver(models.signals.post_save, sender=PaperlessTask)
def cleanup_failed_documents(sender, instance: PaperlessTask, **kwargs):
if instance.status != states.FAILURE or not instance.acknowledged:
return
if instance.task_file_name:
try:
Path(settings.CONSUMPTION_FAILED_DIR / instance.task_file_name).unlink()
logger.debug(f"Cleaned up failed file {instance.task_file_name}")
except FileNotFoundError:
logger.warning(f"Failed to clean up failed file {instance.task_file_name}")
def set_log_entry(sender, document: Document, logging_group=None, **kwargs): def set_log_entry(sender, document: Document, logging_group=None, **kwargs):
ct = ContentType.objects.get(model="document") ct = ContentType.objects.get(model="document")
user = User.objects.get(username="consumer") user = User.objects.get(username="consumer")

View File

@@ -9,6 +9,7 @@ from tempfile import TemporaryDirectory
import tqdm import tqdm
from celery import Task from celery import Task
from celery import shared_task from celery import shared_task
from celery import states
from django.conf import settings from django.conf import settings
from django.db import models from django.db import models
from django.db import transaction from django.db import transaction
@@ -27,12 +28,14 @@ from documents.consumer import ConsumerPlugin
from documents.consumer import WorkflowTriggerPlugin from documents.consumer import WorkflowTriggerPlugin
from documents.data_models import ConsumableDocument from documents.data_models import ConsumableDocument
from documents.data_models import DocumentMetadataOverrides from documents.data_models import DocumentMetadataOverrides
from documents.data_models import DocumentSource
from documents.double_sided import CollatePlugin from documents.double_sided import CollatePlugin
from documents.file_handling import create_source_path_directory from documents.file_handling import create_source_path_directory
from documents.file_handling import generate_unique_filename from documents.file_handling import generate_unique_filename
from documents.models import Correspondent from documents.models import Correspondent
from documents.models import Document from documents.models import Document
from documents.models import DocumentType from documents.models import DocumentType
from documents.models import PaperlessTask
from documents.models import StoragePath from documents.models import StoragePath
from documents.models import Tag from documents.models import Tag
from documents.parsers import DocumentParser from documents.parsers import DocumentParser
@@ -44,6 +47,8 @@ from documents.plugins.helpers import ProgressStatusOptions
from documents.sanity_checker import SanityCheckFailedException from documents.sanity_checker import SanityCheckFailedException
from documents.signals import document_updated from documents.signals import document_updated
from documents.signals.handlers import cleanup_document_deletion from documents.signals.handlers import cleanup_document_deletion
from documents.utils import copy_file_with_basic_stats
from documents.utils import run_subprocess
if settings.AUDIT_LOG_ENABLED: if settings.AUDIT_LOG_ENABLED:
from auditlog.models import LogEntry from auditlog.models import LogEntry
@@ -169,6 +174,48 @@ def consume_file(
return msg return msg
@shared_task
def retry_failed_file(task_id: str, clean: bool = False, skip_ocr: bool = False):
task = PaperlessTask.objects.get(task_id=task_id, status=states.FAILURE)
if task:
failed_file = settings.CONSUMPTION_FAILED_DIR / task.task_file_name
if not failed_file.exists():
logger.error(f"File {failed_file} not found")
raise FileNotFoundError(f"File {failed_file} not found")
working_copy = settings.SCRATCH_DIR / failed_file.name
copy_file_with_basic_stats(failed_file, working_copy)
if clean:
try:
result = run_subprocess(
[
"qpdf",
"--replace-input",
"--warning-exit-0",
working_copy,
],
logger=logger,
)
if result.returncode != 0:
raise Exception(
f"qpdf failed with exit code {result.returncode}, error: {result.stderr}",
)
else:
logger.debug("PDF cleaned successfully")
except Exception as e:
logger.error(f"Error while cleaning PDF: {e}")
raise e
task = consume_file.delay(
ConsumableDocument(
source=DocumentSource.ConsumeFolder,
original_file=working_copy,
),
)
return task.id
@shared_task @shared_task
def sanity_check(): def sanity_check():
messages = sanity_checker.check_sanity() messages = sanity_checker.check_sanity()

Binary file not shown.

View File

@@ -289,12 +289,6 @@ class TestCustomFieldsSearch(DirectoriesMixin, APITestCase):
lambda document: "string_field" in document, lambda document: "string_field" in document,
) )
def test_exists_false(self):
self._assert_query_match_predicate(
["string_field", "exists", False],
lambda document: "string_field" not in document,
)
def test_select(self): def test_select(self):
# For select fields, you can either specify the index # For select fields, you can either specify the index
# or the name of the option. They function exactly the same. # or the name of the option. They function exactly the same.

View File

@@ -1,5 +1,8 @@
import os import os
import shutil
import uuid
from datetime import timedelta from datetime import timedelta
from pathlib import Path
from unittest import mock from unittest import mock
from django.conf import settings from django.conf import settings
@@ -7,15 +10,22 @@ from django.test import TestCase
from django.utils import timezone from django.utils import timezone
from documents import tasks from documents import tasks
from documents.data_models import ConsumableDocument
from documents.data_models import DocumentSource
from documents.models import Correspondent from documents.models import Correspondent
from documents.models import Document from documents.models import Document
from documents.models import DocumentType from documents.models import DocumentType
from documents.models import PaperlessTask
from documents.models import Tag from documents.models import Tag
from documents.sanity_checker import SanityCheckFailedException from documents.sanity_checker import SanityCheckFailedException
from documents.sanity_checker import SanityCheckMessages from documents.sanity_checker import SanityCheckMessages
from documents.signals.handlers import before_task_publish_handler
from documents.signals.handlers import task_failure_handler
from documents.tests.test_classifier import dummy_preprocess from documents.tests.test_classifier import dummy_preprocess
from documents.tests.utils import DirectoriesMixin from documents.tests.utils import DirectoriesMixin
from documents.tests.utils import DummyProgressManager
from documents.tests.utils import FileSystemAssertsMixin from documents.tests.utils import FileSystemAssertsMixin
from documents.tests.utils import SampleDirMixin
class TestIndexReindex(DirectoriesMixin, TestCase): class TestIndexReindex(DirectoriesMixin, TestCase):
@@ -184,3 +194,68 @@ class TestEmptyTrashTask(DirectoriesMixin, FileSystemAssertsMixin, TestCase):
tasks.empty_trash() tasks.empty_trash()
self.assertEqual(Document.global_objects.count(), 0) self.assertEqual(Document.global_objects.count(), 0)
class TestRetryConsumeTask(
DirectoriesMixin,
SampleDirMixin,
FileSystemAssertsMixin,
TestCase,
):
def do_failed_task(self, test_file: Path) -> PaperlessTask:
temp_copy = self.dirs.scratch_dir / test_file.name
shutil.copy(test_file, temp_copy)
headers = {
"id": str(uuid.uuid4()),
"task": "documents.tasks.consume_file",
}
body = (
# args
(
ConsumableDocument(
source=DocumentSource.ConsumeFolder,
original_file=str(temp_copy),
),
None,
),
# kwargs
{},
# celery stuff
{"callbacks": None, "errbacks": None, "chain": None, "chord": None},
)
before_task_publish_handler(headers=headers, body=body)
with mock.patch("documents.tasks.ProgressManager", DummyProgressManager):
with self.assertRaises(Exception):
tasks.consume_file(
ConsumableDocument(
source=DocumentSource.ConsumeFolder,
original_file=temp_copy,
),
)
task_failure_handler(
task_id=headers["id"],
exception="Example failure",
)
task = PaperlessTask.objects.first()
# Ensure the file is moved to the failed dir
self.assertIsFile(settings.CONSUMPTION_FAILED_DIR / task.task_file_name)
return task
@mock.patch("documents.tasks.consume_file.delay")
@mock.patch("documents.tasks.run_subprocess")
def test_retry_consume_clean(self, m_subprocess, m_consume_file):
task = self.do_failed_task(self.SAMPLE_DIR / "corrupted.pdf")
m_subprocess.return_value.returncode = 0
task_id = tasks.retry_failed_file(task_id=task.task_id, clean=True)
self.assertIsNotNone(task_id)
m_consume_file.assert_called_once()
def test_cleanup(self):
task = self.do_failed_task(self.SAMPLE_DIR / "corrupted.pdf")
task.acknowledged = True
task.save() # simulate the task being acknowledged
self.assertIsNotFile(settings.CONSUMPTION_FAILED_DIR / task.task_file_name)

View File

@@ -35,6 +35,7 @@ def setup_directories():
dirs.scratch_dir = Path(tempfile.mkdtemp()) dirs.scratch_dir = Path(tempfile.mkdtemp())
dirs.media_dir = Path(tempfile.mkdtemp()) dirs.media_dir = Path(tempfile.mkdtemp())
dirs.consumption_dir = Path(tempfile.mkdtemp()) dirs.consumption_dir = Path(tempfile.mkdtemp())
dirs.consumption_failed_dir = Path(tempfile.mkdtemp("failed"))
dirs.static_dir = Path(tempfile.mkdtemp()) dirs.static_dir = Path(tempfile.mkdtemp())
dirs.index_dir = dirs.data_dir / "index" dirs.index_dir = dirs.data_dir / "index"
dirs.originals_dir = dirs.media_dir / "documents" / "originals" dirs.originals_dir = dirs.media_dir / "documents" / "originals"
@@ -56,6 +57,7 @@ def setup_directories():
THUMBNAIL_DIR=dirs.thumbnail_dir, THUMBNAIL_DIR=dirs.thumbnail_dir,
ARCHIVE_DIR=dirs.archive_dir, ARCHIVE_DIR=dirs.archive_dir,
CONSUMPTION_DIR=dirs.consumption_dir, CONSUMPTION_DIR=dirs.consumption_dir,
CONSUMPTION_FAILED_DIR=dirs.consumption_failed_dir,
LOGGING_DIR=dirs.logging_dir, LOGGING_DIR=dirs.logging_dir,
INDEX_DIR=dirs.index_dir, INDEX_DIR=dirs.index_dir,
STATIC_ROOT=dirs.static_dir, STATIC_ROOT=dirs.static_dir,
@@ -72,6 +74,7 @@ def remove_dirs(dirs):
shutil.rmtree(dirs.data_dir, ignore_errors=True) shutil.rmtree(dirs.data_dir, ignore_errors=True)
shutil.rmtree(dirs.scratch_dir, ignore_errors=True) shutil.rmtree(dirs.scratch_dir, ignore_errors=True)
shutil.rmtree(dirs.consumption_dir, ignore_errors=True) shutil.rmtree(dirs.consumption_dir, ignore_errors=True)
shutil.rmtree(dirs.consumption_failed_dir, ignore_errors=True)
shutil.rmtree(dirs.static_dir, ignore_errors=True) shutil.rmtree(dirs.static_dir, ignore_errors=True)
dirs.settings_override.disable() dirs.settings_override.disable()

View File

@@ -136,6 +136,7 @@ from documents.serialisers import DocumentListSerializer
from documents.serialisers import DocumentSerializer from documents.serialisers import DocumentSerializer
from documents.serialisers import DocumentTypeSerializer from documents.serialisers import DocumentTypeSerializer
from documents.serialisers import PostDocumentSerializer from documents.serialisers import PostDocumentSerializer
from documents.serialisers import RetryTaskSerializer
from documents.serialisers import SavedViewSerializer from documents.serialisers import SavedViewSerializer
from documents.serialisers import SearchResultSerializer from documents.serialisers import SearchResultSerializer
from documents.serialisers import ShareLinkSerializer from documents.serialisers import ShareLinkSerializer
@@ -152,6 +153,7 @@ from documents.serialisers import WorkflowTriggerSerializer
from documents.signals import document_updated from documents.signals import document_updated
from documents.tasks import consume_file from documents.tasks import consume_file
from documents.tasks import empty_trash from documents.tasks import empty_trash
from documents.tasks import retry_failed_file
from documents.templating.filepath import validate_filepath_template_and_render from documents.templating.filepath import validate_filepath_template_and_render
from paperless import version from paperless import version
from paperless.celery import app as celery_app from paperless.celery import app as celery_app
@@ -1718,6 +1720,25 @@ class TasksViewSet(ReadOnlyModelViewSet):
queryset = PaperlessTask.objects.filter(task_id=task_id) queryset = PaperlessTask.objects.filter(task_id=task_id)
return queryset return queryset
@action(methods=["post"], detail=True)
def retry(self, request, pk=None):
task = self.get_object()
serializer = RetryTaskSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
clean = serializer.validated_data.get("clean")
try:
new_task_id = retry_failed_file(task.task_id, clean)
return Response({"task_id": new_task_id})
except FileNotFoundError:
return HttpResponseBadRequest("Original file not found")
except Exception as e:
logger.warning(f"An error occurred retrying task: {e!s}")
return HttpResponseBadRequest(
"Error retrying task, check logs for more detail.",
)
class AcknowledgeTasksView(GenericAPIView): class AcknowledgeTasksView(GenericAPIView):
permission_classes = (IsAuthenticated,) permission_classes = (IsAuthenticated,)

View File

@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: paperless-ngx\n" "Project-Id-Version: paperless-ngx\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-10-19 22:56-0700\n" "POT-Creation-Date: 2024-10-19 22:56-0700\n"
"PO-Revision-Date: 2024-11-02 00:29\n" "PO-Revision-Date: 2024-10-20 12:11\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: German\n" "Language-Team: German\n"
"Language: de_DE\n" "Language: de_DE\n"
@@ -47,7 +47,7 @@ msgstr "{name!r} ist kein gültiges benutzerdefiniertes Feld."
#: documents/filters.py:492 #: documents/filters.py:492
msgid "{data_type} does not support query expr {expr!r}." msgid "{data_type} does not support query expr {expr!r}."
msgstr "{data_type} unterstützt den Abfrageausdruck {expr!r} nicht." msgstr "{data_type} unterstützt Abfrage expr {expr!r} nicht."
#: documents/filters.py:600 #: documents/filters.py:600
msgid "Maximum nesting depth exceeded." msgid "Maximum nesting depth exceeded."
@@ -1547,11 +1547,11 @@ msgstr "IMAP"
#: paperless_mail/models.py:20 #: paperless_mail/models.py:20
msgid "Gmail OAuth" msgid "Gmail OAuth"
msgstr "Gmail-OAuth" msgstr "Gmail OAuth"
#: paperless_mail/models.py:21 #: paperless_mail/models.py:21
msgid "Outlook OAuth" msgid "Outlook OAuth"
msgstr "Outlook-OAuth" msgstr "Outlook OAuh"
#: paperless_mail/models.py:25 #: paperless_mail/models.py:25
msgid "IMAP server" msgid "IMAP server"
@@ -1599,7 +1599,7 @@ msgstr "Aktualisierungstoken"
#: paperless_mail/models.py:71 #: paperless_mail/models.py:71
msgid "The refresh token to use for token authentication e.g. with oauth2." msgid "The refresh token to use for token authentication e.g. with oauth2."
msgstr "Das Aktualisierungstoken, das für die Tokenauthentifizierung (z.B. mit OAuth2) verwendet werden soll." msgstr "Das Aktualisierungstoken für die Tokenauthentifizierung z.B. mit OAuth2."
#: paperless_mail/models.py:80 #: paperless_mail/models.py:80
msgid "The expiration date of the refresh token. " msgid "The expiration date of the refresh token. "

View File

@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: paperless-ngx\n" "Project-Id-Version: paperless-ngx\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-10-19 22:56-0700\n" "POT-Creation-Date: 2024-10-19 22:56-0700\n"
"PO-Revision-Date: 2024-11-03 04:57\n" "PO-Revision-Date: 2024-10-20 05:58\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: Spanish\n" "Language-Team: Spanish\n"
"Language: es_ES\n" "Language: es_ES\n"
@@ -23,35 +23,35 @@ msgstr "Documentos"
#: documents/filters.py:334 #: documents/filters.py:334
msgid "Value must be valid JSON." msgid "Value must be valid JSON."
msgstr "El valor debe ser JSON válido." msgstr ""
#: documents/filters.py:353 #: documents/filters.py:353
msgid "Invalid custom field query expression" msgid "Invalid custom field query expression"
msgstr "Expresión de consulta de campo personalizado no válida" msgstr ""
#: documents/filters.py:363 #: documents/filters.py:363
msgid "Invalid expression list. Must be nonempty." msgid "Invalid expression list. Must be nonempty."
msgstr "Lista de expresiones no válida. Debe ser no vacía." msgstr ""
#: documents/filters.py:384 #: documents/filters.py:384
msgid "Invalid logical operator {op!r}" msgid "Invalid logical operator {op!r}"
msgstr "Operador lógico inválido {op!r}" msgstr ""
#: documents/filters.py:398 #: documents/filters.py:398
msgid "Maximum number of query conditions exceeded." msgid "Maximum number of query conditions exceeded."
msgstr "Se ha superado el número máximo de condiciones de consulta." msgstr ""
#: documents/filters.py:455 #: documents/filters.py:455
msgid "{name!r} is not a valid custom field." msgid "{name!r} is not a valid custom field."
msgstr "{nombre!r} no es un campo personalizado válido." msgstr ""
#: documents/filters.py:492 #: documents/filters.py:492
msgid "{data_type} does not support query expr {expr!r}." msgid "{data_type} does not support query expr {expr!r}."
msgstr "{data_type} no admite la consulta expr {expr!r}." msgstr ""
#: documents/filters.py:600 #: documents/filters.py:600
msgid "Maximum nesting depth exceeded." msgid "Maximum nesting depth exceeded."
msgstr "Profundidad máxima de nidificación superada." msgstr ""
#: documents/models.py:41 documents/models.py:802 #: documents/models.py:41 documents/models.py:802
msgid "owner" msgid "owner"
@@ -192,11 +192,11 @@ msgstr "La cadena de verificación del documento archivado."
#: documents/models.py:211 #: documents/models.py:211
msgid "page count" msgid "page count"
msgstr "número de páginas" msgstr ""
#: documents/models.py:218 #: documents/models.py:218
msgid "The number of pages of the document." msgid "The number of pages of the document."
msgstr "El número de páginas del documento." msgstr ""
#: documents/models.py:222 documents/models.py:402 documents/models.py:722 #: documents/models.py:222 documents/models.py:402 documents/models.py:722
#: documents/models.py:760 documents/models.py:831 documents/models.py:889 #: documents/models.py:760 documents/models.py:831 documents/models.py:889
@@ -353,7 +353,7 @@ msgstr "ASN"
#: documents/models.py:431 #: documents/models.py:431
msgid "Pages" msgid "Pages"
msgstr "Páginas" msgstr ""
#: documents/models.py:437 #: documents/models.py:437
msgid "show on dashboard" msgid "show on dashboard"
@@ -561,7 +561,7 @@ msgstr "no tiene campo personalizado"
#: documents/models.py:525 #: documents/models.py:525
msgid "custom fields query" msgid "custom fields query"
msgstr "consulta de campos personalizados" msgstr ""
#: documents/models.py:535 #: documents/models.py:535
msgid "rule type" msgid "rule type"
@@ -1543,7 +1543,7 @@ msgstr "Usar STARTTLS"
#: paperless_mail/models.py:19 #: paperless_mail/models.py:19
msgid "IMAP" msgid "IMAP"
msgstr "IMAP" msgstr ""
#: paperless_mail/models.py:20 #: paperless_mail/models.py:20
msgid "Gmail OAuth" msgid "Gmail OAuth"

View File

@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: paperless-ngx\n" "Project-Id-Version: paperless-ngx\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-10-19 22:56-0700\n" "POT-Creation-Date: 2024-10-19 22:56-0700\n"
"PO-Revision-Date: 2024-11-03 00:33\n" "PO-Revision-Date: 2024-10-29 18:05\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: Italian\n" "Language-Team: Italian\n"
"Language: it_IT\n" "Language: it_IT\n"
@@ -23,11 +23,11 @@ msgstr "Documenti"
#: documents/filters.py:334 #: documents/filters.py:334
msgid "Value must be valid JSON." msgid "Value must be valid JSON."
msgstr "Il valore deve essere un JSON valido." msgstr ""
#: documents/filters.py:353 #: documents/filters.py:353
msgid "Invalid custom field query expression" msgid "Invalid custom field query expression"
msgstr "Espressione della query del campo personalizzato non valida" msgstr ""
#: documents/filters.py:363 #: documents/filters.py:363
msgid "Invalid expression list. Must be nonempty." msgid "Invalid expression list. Must be nonempty."
@@ -35,7 +35,7 @@ msgstr ""
#: documents/filters.py:384 #: documents/filters.py:384
msgid "Invalid logical operator {op!r}" msgid "Invalid logical operator {op!r}"
msgstr "Operatore logico non valido {op!r}" msgstr ""
#: documents/filters.py:398 #: documents/filters.py:398
msgid "Maximum number of query conditions exceeded." msgid "Maximum number of query conditions exceeded."
@@ -43,7 +43,7 @@ msgstr ""
#: documents/filters.py:455 #: documents/filters.py:455
msgid "{name!r} is not a valid custom field." msgid "{name!r} is not a valid custom field."
msgstr "{name!r} non è un campo personalizzato valido." msgstr ""
#: documents/filters.py:492 #: documents/filters.py:492
msgid "{data_type} does not support query expr {expr!r}." msgid "{data_type} does not support query expr {expr!r}."

View File

@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: paperless-ngx\n" "Project-Id-Version: paperless-ngx\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-10-19 22:56-0700\n" "POT-Creation-Date: 2024-10-19 22:56-0700\n"
"PO-Revision-Date: 2024-11-02 00:29\n" "PO-Revision-Date: 2024-10-25 12:12\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: Swedish\n" "Language-Team: Swedish\n"
"Language: sv_SE\n" "Language: sv_SE\n"
@@ -1015,7 +1015,7 @@ msgstr "Vänligen logga in."
#: documents/templates/account/login.html:12 #: documents/templates/account/login.html:12
#, python-format #, python-format
msgid "Don't have an account yet? <a href=\"%(signup_url)s\">Sign up</a>" msgid "Don't have an account yet? <a href=\"%(signup_url)s\">Sign up</a>"
msgstr "Har du inget konto än? <a href=\"%(signup_url)s\">Registrera dig</a>" msgstr ""
#: documents/templates/account/login.html:19 #: documents/templates/account/login.html:19
#: documents/templates/account/signup.html:15 #: documents/templates/account/signup.html:15
@@ -1117,7 +1117,7 @@ msgstr ""
#: documents/templates/account/signup.html:10 #: documents/templates/account/signup.html:10
#, python-format #, python-format
msgid "Already have an account? <a href=\"%(login_url)s\">Sign in</a>" msgid "Already have an account? <a href=\"%(login_url)s\">Sign in</a>"
msgstr "Har du redan ett konto? <a href=\"%(login_url)s\">Logga in</a>" msgstr ""
#: documents/templates/account/signup.html:16 #: documents/templates/account/signup.html:16
#: documents/templates/socialaccount/signup.html:14 #: documents/templates/socialaccount/signup.html:14
@@ -1131,7 +1131,7 @@ msgstr ""
#: documents/templates/account/signup.html:36 #: documents/templates/account/signup.html:36
#: documents/templates/socialaccount/signup.html:27 #: documents/templates/socialaccount/signup.html:27
msgid "Sign up" msgid "Sign up"
msgstr "Registrera dig" msgstr ""
#: documents/templates/index.html:61 #: documents/templates/index.html:61
msgid "Paperless-ngx is loading..." msgid "Paperless-ngx is loading..."
@@ -1170,7 +1170,7 @@ msgstr ""
#: documents/templates/socialaccount/login.html:13 #: documents/templates/socialaccount/login.html:13
msgid "Continue" msgid "Continue"
msgstr "Fortsätt" msgstr ""
#: documents/templates/socialaccount/signup.html:5 #: documents/templates/socialaccount/signup.html:5
msgid "Paperless-ngx social account sign up" msgid "Paperless-ngx social account sign up"
@@ -1366,7 +1366,7 @@ msgstr "Belarusiska"
#: paperless/settings.py:688 #: paperless/settings.py:688
msgid "Bulgarian" msgid "Bulgarian"
msgstr "Bulgariska" msgstr ""
#: paperless/settings.py:689 #: paperless/settings.py:689
msgid "Catalan" msgid "Catalan"
@@ -1386,7 +1386,7 @@ msgstr "Tyska"
#: paperless/settings.py:693 #: paperless/settings.py:693
msgid "Greek" msgid "Greek"
msgstr "Grekiska" msgstr ""
#: paperless/settings.py:694 #: paperless/settings.py:694
msgid "English (GB)" msgid "English (GB)"
@@ -1414,7 +1414,7 @@ msgstr "Italienska"
#: paperless/settings.py:700 #: paperless/settings.py:700
msgid "Japanese" msgid "Japanese"
msgstr "Japanska" msgstr ""
#: paperless/settings.py:701 #: paperless/settings.py:701
msgid "Korean" msgid "Korean"
@@ -1426,7 +1426,7 @@ msgstr "Luxemburgiska"
#: paperless/settings.py:703 #: paperless/settings.py:703
msgid "Norwegian" msgid "Norwegian"
msgstr "Norska" msgstr ""
#: paperless/settings.py:704 #: paperless/settings.py:704
msgid "Dutch" msgid "Dutch"
@@ -1542,7 +1542,7 @@ msgstr "Använd STARTTLS"
#: paperless_mail/models.py:19 #: paperless_mail/models.py:19
msgid "IMAP" msgid "IMAP"
msgstr "IMAP" msgstr ""
#: paperless_mail/models.py:20 #: paperless_mail/models.py:20
msgid "Gmail OAuth" msgid "Gmail OAuth"

View File

@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: paperless-ngx\n" "Project-Id-Version: paperless-ngx\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-10-19 22:56-0700\n" "POT-Creation-Date: 2024-10-19 22:56-0700\n"
"PO-Revision-Date: 2024-10-31 12:12\n" "PO-Revision-Date: 2024-10-20 05:58\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: Thai\n" "Language-Team: Thai\n"
"Language: th_TH\n" "Language: th_TH\n"
@@ -23,35 +23,35 @@ msgstr "เอกสาร"
#: documents/filters.py:334 #: documents/filters.py:334
msgid "Value must be valid JSON." msgid "Value must be valid JSON."
msgstr "ค่า ต้องอยู่ในรูปแบบ JSON ที่ถูกต้อง" msgstr ""
#: documents/filters.py:353 #: documents/filters.py:353
msgid "Invalid custom field query expression" msgid "Invalid custom field query expression"
msgstr "รูปแบบการค้นหาฟิลด์ที่กำหนดเองไม่ถูกต้อง" msgstr ""
#: documents/filters.py:363 #: documents/filters.py:363
msgid "Invalid expression list. Must be nonempty." msgid "Invalid expression list. Must be nonempty."
msgstr "รายการคำสั่งไม่ถูกต้อง ต้องไม่เว้นว่าง" msgstr ""
#: documents/filters.py:384 #: documents/filters.py:384
msgid "Invalid logical operator {op!r}" msgid "Invalid logical operator {op!r}"
msgstr "ตัวดำเนินการเชิงตรรกะ {op!r} ไม่ถูกต้อง" msgstr ""
#: documents/filters.py:398 #: documents/filters.py:398
msgid "Maximum number of query conditions exceeded." msgid "Maximum number of query conditions exceeded."
msgstr "จำนวนเงื่อนไขในการค้นหาเกินกำหนด" msgstr ""
#: documents/filters.py:455 #: documents/filters.py:455
msgid "{name!r} is not a valid custom field." msgid "{name!r} is not a valid custom field."
msgstr "{name!r} ไม่ใช่ฟิลด์ที่กำหนดเองที่ถูกต้อง" msgstr ""
#: documents/filters.py:492 #: documents/filters.py:492
msgid "{data_type} does not support query expr {expr!r}." msgid "{data_type} does not support query expr {expr!r}."
msgstr "{data_type} ไม่รองรับรูปแบบการค้นหา {expr!r}" msgstr ""
#: documents/filters.py:600 #: documents/filters.py:600
msgid "Maximum nesting depth exceeded." msgid "Maximum nesting depth exceeded."
msgstr "จำนวนการซ้อนเงื่อนไขสูงสุดเกินขีดจำกัด" msgstr ""
#: documents/models.py:41 documents/models.py:802 #: documents/models.py:41 documents/models.py:802
msgid "owner" msgid "owner"
@@ -192,11 +192,11 @@ msgstr "ค่า checksum ของเอกสารประเภทเก
#: documents/models.py:211 #: documents/models.py:211
msgid "page count" msgid "page count"
msgstr "จำนวนหน้า" msgstr ""
#: documents/models.py:218 #: documents/models.py:218
msgid "The number of pages of the document." msgid "The number of pages of the document."
msgstr "จำนวนหน้าทั้งหมดของเอกสาร" msgstr ""
#: documents/models.py:222 documents/models.py:402 documents/models.py:722 #: documents/models.py:222 documents/models.py:402 documents/models.py:722
#: documents/models.py:760 documents/models.py:831 documents/models.py:889 #: documents/models.py:760 documents/models.py:831 documents/models.py:889
@@ -301,11 +301,11 @@ msgstr "ตาราง"
#: documents/models.py:416 #: documents/models.py:416
msgid "Small Cards" msgid "Small Cards"
msgstr "การ์ดขนาดเล็ก" msgstr ""
#: documents/models.py:417 #: documents/models.py:417
msgid "Large Cards" msgid "Large Cards"
msgstr "การ์ดขนาดใหญ่" msgstr ""
#: documents/models.py:420 #: documents/models.py:420
msgid "Title" msgid "Title"
@@ -313,11 +313,11 @@ msgstr ""
#: documents/models.py:421 #: documents/models.py:421
msgid "Created" msgid "Created"
msgstr "วันที่สร้าง" msgstr ""
#: documents/models.py:422 #: documents/models.py:422
msgid "Added" msgid "Added"
msgstr "วันที่เพิ่ม" msgstr ""
#: documents/models.py:423 #: documents/models.py:423
msgid "Tags" msgid "Tags"
@@ -333,7 +333,7 @@ msgstr "ประเภทเอกสาร"
#: documents/models.py:426 #: documents/models.py:426
msgid "Storage Path" msgid "Storage Path"
msgstr "ตำแหน่งจัดเก็บ" msgstr ""
#: documents/models.py:427 #: documents/models.py:427
msgid "Note" msgid "Note"
@@ -345,7 +345,7 @@ msgstr "เจ้าของ"
#: documents/models.py:429 #: documents/models.py:429
msgid "Shared" msgid "Shared"
msgstr "แชร์แล้ว" msgstr ""
#: documents/models.py:430 #: documents/models.py:430
msgid "ASN" msgid "ASN"
@@ -353,7 +353,7 @@ msgstr ""
#: documents/models.py:431 #: documents/models.py:431
msgid "Pages" msgid "Pages"
msgstr "หน้า" msgstr ""
#: documents/models.py:437 #: documents/models.py:437
msgid "show on dashboard" msgid "show on dashboard"
@@ -373,15 +373,15 @@ msgstr "เรียงย้อนกลับ"
#: documents/models.py:452 #: documents/models.py:452
msgid "View page size" msgid "View page size"
msgstr "ขนาดการแสดงผลหน้า" msgstr ""
#: documents/models.py:460 #: documents/models.py:460
msgid "View display mode" msgid "View display mode"
msgstr "โหมดการแสดงผล" msgstr ""
#: documents/models.py:467 #: documents/models.py:467
msgid "Document display fields" msgid "Document display fields"
msgstr "ฟิลด์การแสดงผลของเอกสาร" msgstr ""
#: documents/models.py:474 documents/models.py:532 #: documents/models.py:474 documents/models.py:532
msgid "saved view" msgid "saved view"
@@ -537,31 +537,31 @@ msgstr "ไม่มีเจ้าของเป็น"
#: documents/models.py:519 #: documents/models.py:519
msgid "has custom field value" msgid "has custom field value"
msgstr "มีค่าฟิลด์ที่กำหนดเอง" msgstr ""
#: documents/models.py:520 #: documents/models.py:520
msgid "is shared by me" msgid "is shared by me"
msgstr "แชร์โดยฉัน" msgstr ""
#: documents/models.py:521 #: documents/models.py:521
msgid "has custom fields" msgid "has custom fields"
msgstr "มีฟิลด์ที่กำหนดเอง" msgstr ""
#: documents/models.py:522 #: documents/models.py:522
msgid "has custom field in" msgid "has custom field in"
msgstr "มีฟิลด์ที่กำหนดเองใน" msgstr ""
#: documents/models.py:523 #: documents/models.py:523
msgid "does not have custom field in" msgid "does not have custom field in"
msgstr "ไม่มีฟิลด์ที่กำหนดเอง" msgstr ""
#: documents/models.py:524 #: documents/models.py:524
msgid "does not have custom field" msgid "does not have custom field"
msgstr "ไม่มีฟิลด์ที่กำหนดเองใน" msgstr ""
#: documents/models.py:525 #: documents/models.py:525
msgid "custom fields query" msgid "custom fields query"
msgstr "การค้นหาฟิลด์ที่กำหนดเอง" msgstr ""
#: documents/models.py:535 #: documents/models.py:535
msgid "rule type" msgid "rule type"
@@ -717,11 +717,11 @@ msgstr "Float"
#: documents/models.py:826 #: documents/models.py:826
msgid "Monetary" msgid "Monetary"
msgstr "จำนวนเงิน" msgstr ""
#: documents/models.py:827 #: documents/models.py:827
msgid "Document Link" msgid "Document Link"
msgstr "ลิงก์ของเอกสาร" msgstr ""
#: documents/models.py:828 #: documents/models.py:828
msgid "Select" msgid "Select"
@@ -733,23 +733,23 @@ msgstr "ชนิดข้อมูล"
#: documents/models.py:847 #: documents/models.py:847
msgid "extra data" msgid "extra data"
msgstr "ข้อมูลเพิ่มเติม" msgstr ""
#: documents/models.py:851 #: documents/models.py:851
msgid "Extra data for the custom field, such as select options" msgid "Extra data for the custom field, such as select options"
msgstr "ข้อมูลเพิ่มเติมสำหรับฟิลด์ที่กำหนดเอง เช่น ตัวเลือก" msgstr ""
#: documents/models.py:857 #: documents/models.py:857
msgid "custom field" msgid "custom field"
msgstr "ฟิลด์ที่กำหนดเอง" msgstr ""
#: documents/models.py:858 #: documents/models.py:858
msgid "custom fields" msgid "custom fields"
msgstr "ฟิลด์ที่กำหนดเอง" msgstr ""
#: documents/models.py:955 #: documents/models.py:955
msgid "custom field instance" msgid "custom field instance"
msgstr "ชุดข้อมูลฟิลด์ที่กำหนดเอง" msgstr ""
#: documents/models.py:956 #: documents/models.py:956
msgid "custom field instances" msgid "custom field instances"
@@ -757,7 +757,7 @@ msgstr ""
#: documents/models.py:1017 #: documents/models.py:1017
msgid "Consumption Started" msgid "Consumption Started"
msgstr "เริ่มใช้งาน" msgstr ""
#: documents/models.py:1018 #: documents/models.py:1018
msgid "Document Added" msgid "Document Added"
@@ -769,7 +769,7 @@ msgstr "ปรับปรุงเอกสารแล้ว"
#: documents/models.py:1022 #: documents/models.py:1022
msgid "Consume Folder" msgid "Consume Folder"
msgstr "โฟลเดอร์ใช้งาน" msgstr ""
#: documents/models.py:1023 #: documents/models.py:1023
msgid "Api Upload" msgid "Api Upload"

View File

@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: paperless-ngx\n" "Project-Id-Version: paperless-ngx\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-10-19 22:56-0700\n" "POT-Creation-Date: 2024-10-19 22:56-0700\n"
"PO-Revision-Date: 2024-11-03 04:57\n" "PO-Revision-Date: 2024-10-29 12:12\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: Chinese Simplified\n" "Language-Team: Chinese Simplified\n"
"Language: zh_CN\n" "Language: zh_CN\n"
@@ -1603,7 +1603,7 @@ msgstr ""
#: paperless_mail/models.py:80 #: paperless_mail/models.py:80
msgid "The expiration date of the refresh token. " msgid "The expiration date of the refresh token. "
msgstr "刷新令牌的到期日期。 " msgstr ""
#: paperless_mail/models.py:90 #: paperless_mail/models.py:90
msgid "mail rule" msgid "mail rule"

File diff suppressed because it is too large Load Diff

View File

@@ -65,6 +65,10 @@ def paths_check(app_configs, **kwargs):
+ path_check("PAPERLESS_EMPTY_TRASH_DIR", settings.EMPTY_TRASH_DIR) + path_check("PAPERLESS_EMPTY_TRASH_DIR", settings.EMPTY_TRASH_DIR)
+ path_check("PAPERLESS_MEDIA_ROOT", settings.MEDIA_ROOT) + path_check("PAPERLESS_MEDIA_ROOT", settings.MEDIA_ROOT)
+ path_check("PAPERLESS_CONSUMPTION_DIR", settings.CONSUMPTION_DIR) + path_check("PAPERLESS_CONSUMPTION_DIR", settings.CONSUMPTION_DIR)
+ path_check(
"PAPERLESS_CONSUMPTION_FAILED_DIR",
settings.CONSUMPTION_FAILED_DIR,
)
) )

View File

@@ -281,6 +281,11 @@ CONSUMPTION_DIR = __get_path(
BASE_DIR.parent / "consume", BASE_DIR.parent / "consume",
) )
CONSUMPTION_FAILED_DIR = __get_path(
"PAPERLESS_CONSUMPTION_FAILED_DIR",
CONSUMPTION_DIR / "failed",
)
# This will be created if it doesn't exist # This will be created if it doesn't exist
SCRATCH_DIR = __get_path( SCRATCH_DIR = __get_path(
"PAPERLESS_SCRATCH_DIR", "PAPERLESS_SCRATCH_DIR",
@@ -890,6 +895,8 @@ CONSUMER_IGNORE_PATTERNS = list(
), ),
), ),
) )
if CONSUMPTION_DIR in CONSUMPTION_FAILED_DIR.parents:
CONSUMER_IGNORE_PATTERNS.append(CONSUMPTION_FAILED_DIR.name)
CONSUMER_SUBDIRS_AS_TAGS = __get_boolean("PAPERLESS_CONSUMER_SUBDIRS_AS_TAGS") CONSUMER_SUBDIRS_AS_TAGS = __get_boolean("PAPERLESS_CONSUMER_SUBDIRS_AS_TAGS")

View File

@@ -29,10 +29,11 @@ class TestChecks(DirectoriesMixin, TestCase):
MEDIA_ROOT="uuh", MEDIA_ROOT="uuh",
DATA_DIR="whatever", DATA_DIR="whatever",
CONSUMPTION_DIR="idontcare", CONSUMPTION_DIR="idontcare",
CONSUMPTION_FAILED_DIR="nope",
) )
def test_paths_check_dont_exist(self): def test_paths_check_dont_exist(self):
msgs = paths_check(None) msgs = paths_check(None)
self.assertEqual(len(msgs), 3, str(msgs)) self.assertEqual(len(msgs), 4, str(msgs))
for msg in msgs: for msg in msgs:
self.assertTrue(msg.msg.endswith("is set but doesn't exist.")) self.assertTrue(msg.msg.endswith("is set but doesn't exist."))
@@ -41,13 +42,15 @@ class TestChecks(DirectoriesMixin, TestCase):
os.chmod(self.dirs.data_dir, 0o000) os.chmod(self.dirs.data_dir, 0o000)
os.chmod(self.dirs.media_dir, 0o000) os.chmod(self.dirs.media_dir, 0o000)
os.chmod(self.dirs.consumption_dir, 0o000) os.chmod(self.dirs.consumption_dir, 0o000)
os.chmod(self.dirs.consumption_failed_dir, 0o000)
self.addCleanup(os.chmod, self.dirs.data_dir, 0o777) self.addCleanup(os.chmod, self.dirs.data_dir, 0o777)
self.addCleanup(os.chmod, self.dirs.media_dir, 0o777) self.addCleanup(os.chmod, self.dirs.media_dir, 0o777)
self.addCleanup(os.chmod, self.dirs.consumption_dir, 0o777) self.addCleanup(os.chmod, self.dirs.consumption_dir, 0o777)
self.addCleanup(os.chmod, self.dirs.consumption_failed_dir, 0o777)
msgs = paths_check(None) msgs = paths_check(None)
self.assertEqual(len(msgs), 3) self.assertEqual(len(msgs), 4)
for msg in msgs: for msg in msgs:
self.assertTrue(msg.msg.endswith("is not writeable")) self.assertTrue(msg.msg.endswith("is not writeable"))

View File

@@ -1,6 +1,6 @@
from typing import Final from typing import Final
__version__: Final[tuple[int, int, int]] = (2, 13, 4) __version__: Final[tuple[int, int, int]] = (2, 13, 2)
# Version string like X.Y.Z # Version string like X.Y.Z
__full_version_str__: Final[str] = ".".join(map(str, __version__)) __full_version_str__: Final[str] = ".".join(map(str, __version__))
# Version string like X.Y # Version string like X.Y