Merge remote-tracking branch 'origin/dev'

This commit is contained in:
Trenton Holmes 2023-05-03 06:53:33 -07:00
commit 7545e5312c
33 changed files with 689 additions and 474 deletions

6
Pipfile.lock generated
View File

@ -569,11 +569,11 @@
}, },
"filelock": { "filelock": {
"hashes": [ "hashes": [
"sha256:75997740323c5f12e18f10b494bc11c03e42843129f980f17c04352cc7b09d40", "sha256:ad98852315c2ab702aeb628412cbf7e95b7ce8c3bf9565670b4eaecf1db370a9",
"sha256:eb8f0f2d37ed68223ea63e3bddf2fac99667e4362c88b3f762e434d160190d18" "sha256:fc03ae43288c013d2ea83c8597001b1129db351aad9c57fe2409327916b8e718"
], ],
"index": "pypi", "index": "pypi",
"version": "==3.10.2" "version": "==3.12.0"
}, },
"flower": { "flower": {
"hashes": [ "hashes": [

View File

@ -15,6 +15,10 @@ do
env_name=${line%%=*} env_name=${line%%=*}
# Check if it starts with "PAPERLESS_" and ends in "_FILE" # Check if it starts with "PAPERLESS_" and ends in "_FILE"
if [[ ${env_name} == PAPERLESS_*_FILE ]]; then if [[ ${env_name} == PAPERLESS_*_FILE ]]; then
# This should have been named different..
if [[ ${env_name} == "PAPERLESS_OCR_SKIP_ARCHIVE_FILE" ]]; then
continue
fi
# Extract the value of the environment # Extract the value of the environment
env_value=${line#*=} env_value=${line#*=}

View File

@ -322,8 +322,7 @@ You can read more about this in [the Django project's documentation](https://doc
Can also be set using PAPERLESS_URL (see above). Can also be set using PAPERLESS_URL (see above).
If manually set, please remember to include "localhost". Otherwise "localhost" is always allowed for docker healthcheck
docker healthcheck will fail.
Defaults to "\*", which is all hosts. Defaults to "\*", which is all hosts.

378
src-ui/package-lock.json generated
View File

@ -8,14 +8,14 @@
"name": "paperless-ui", "name": "paperless-ui",
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"@angular/common": "~15.2.7", "@angular/common": "~15.2.8",
"@angular/compiler": "~15.2.7", "@angular/compiler": "~15.2.8",
"@angular/core": "~15.2.7", "@angular/core": "~15.2.8",
"@angular/forms": "~15.2.7", "@angular/forms": "~15.2.8",
"@angular/localize": "~15.2.7", "@angular/localize": "~15.2.8",
"@angular/platform-browser": "~15.2.7", "@angular/platform-browser": "~15.2.8",
"@angular/platform-browser-dynamic": "~15.2.7", "@angular/platform-browser-dynamic": "~15.2.8",
"@angular/router": "~15.2.7", "@angular/router": "~15.2.8",
"@ng-bootstrap/ng-bootstrap": "^14.1.0", "@ng-bootstrap/ng-bootstrap": "^14.1.0",
"@ng-select/ng-select": "^10.0.4", "@ng-select/ng-select": "^10.0.4",
"@ngneat/dirty-check-forms": "^3.0.3", "@ngneat/dirty-check-forms": "^3.0.3",
@ -28,7 +28,7 @@
"ngx-cookie-service": "^15.0.0", "ngx-cookie-service": "^15.0.0",
"ngx-file-drop": "^15.0.0", "ngx-file-drop": "^15.0.0",
"ngx-ui-tour-ng-bootstrap": "^12.6.0", "ngx-ui-tour-ng-bootstrap": "^12.6.0",
"rxjs": "^7.8.0", "rxjs": "^7.8.1",
"tslib": "^2.4.1", "tslib": "^2.4.1",
"uuid": "^9.0.0", "uuid": "^9.0.0",
"zone.js": "^0.13.0" "zone.js": "^0.13.0"
@ -41,14 +41,14 @@
"@angular-eslint/eslint-plugin-template": "15.2.1", "@angular-eslint/eslint-plugin-template": "15.2.1",
"@angular-eslint/schematics": "15.2.1", "@angular-eslint/schematics": "15.2.1",
"@angular-eslint/template-parser": "15.2.1", "@angular-eslint/template-parser": "15.2.1",
"@angular/cli": "~15.2.6", "@angular/cli": "~15.2.7",
"@angular/compiler-cli": "~15.2.7", "@angular/compiler-cli": "~15.2.8",
"@types/jest": "^29.5.0", "@types/jest": "^29.5.0",
"@types/node": "^18.15.11", "@types/node": "^18.16.3",
"@typescript-eslint/eslint-plugin": "^5.58.0", "@typescript-eslint/eslint-plugin": "^5.59.2",
"@typescript-eslint/parser": "^5.58.0", "@typescript-eslint/parser": "^5.59.2",
"concurrently": "^8.0.1", "concurrently": "^8.0.1",
"eslint": "^8.38.0", "eslint": "^8.39.0",
"jest": "28.1.3", "jest": "28.1.3",
"jest-environment-jsdom": "^29.5.0", "jest-environment-jsdom": "^29.5.0",
"jest-preset-angular": "^12.2.6", "jest-preset-angular": "^12.2.6",
@ -58,7 +58,7 @@
}, },
"optionalDependencies": { "optionalDependencies": {
"@cypress/schematic": "^2.1.1", "@cypress/schematic": "^2.1.1",
"cypress": "^12.9.0" "cypress": "^12.11.0"
} }
}, },
"node_modules/@ampproject/remapping": { "node_modules/@ampproject/remapping": {
@ -306,12 +306,12 @@
} }
}, },
"node_modules/@angular-devkit/architect": { "node_modules/@angular-devkit/architect": {
"version": "0.1502.6", "version": "0.1502.7",
"resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1502.6.tgz", "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1502.7.tgz",
"integrity": "sha512-n4oJ9vzFWwabf+AfgqqevVzdJhNKNCav7ytefjD/Y01vkNwlXqWnHcvyyHCLkVibJ6WR8J9lK4t77j/HFlDvWQ==", "integrity": "sha512-MzB6D/yUo6cBJfQ31zNDHJ3C3iKmBtxP3i9WIRnnkZwS1VUfO8OX3TZ6lycYbREF1oL/AQ/r9GK+KA5DNEBSAw==",
"devOptional": true, "devOptional": true,
"dependencies": { "dependencies": {
"@angular-devkit/core": "15.2.6", "@angular-devkit/core": "15.2.7",
"rxjs": "6.6.7" "rxjs": "6.6.7"
}, },
"engines": { "engines": {
@ -339,15 +339,15 @@
"devOptional": true "devOptional": true
}, },
"node_modules/@angular-devkit/build-angular": { "node_modules/@angular-devkit/build-angular": {
"version": "15.2.6", "version": "15.2.7",
"resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-15.2.6.tgz", "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-15.2.7.tgz",
"integrity": "sha512-OmMcdXXUrAdZNxwxDE8SUx1FMcq9FyMnrSv1PmP9sHPBoxAdBVc/qNdGA9V7C5yHvWHGgzsx7ZK5TDuvifzS5g==", "integrity": "sha512-zZ+tlt5aNGY9APUdjQHeVFJpVLeixlZRNHmfdXD+rN4WR2q9E0pTvLUThrkOmO8YrVyGbdvcw1O7XNdL+3b02w==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@ampproject/remapping": "2.2.0", "@ampproject/remapping": "2.2.0",
"@angular-devkit/architect": "0.1502.6", "@angular-devkit/architect": "0.1502.7",
"@angular-devkit/build-webpack": "0.1502.6", "@angular-devkit/build-webpack": "0.1502.7",
"@angular-devkit/core": "15.2.6", "@angular-devkit/core": "15.2.7",
"@babel/core": "7.20.12", "@babel/core": "7.20.12",
"@babel/generator": "7.20.14", "@babel/generator": "7.20.14",
"@babel/helper-annotate-as-pure": "7.18.6", "@babel/helper-annotate-as-pure": "7.18.6",
@ -359,7 +359,7 @@
"@babel/runtime": "7.20.13", "@babel/runtime": "7.20.13",
"@babel/template": "7.20.7", "@babel/template": "7.20.7",
"@discoveryjs/json-ext": "0.5.7", "@discoveryjs/json-ext": "0.5.7",
"@ngtools/webpack": "15.2.6", "@ngtools/webpack": "15.2.7",
"ansi-colors": "4.1.3", "ansi-colors": "4.1.3",
"autoprefixer": "10.4.13", "autoprefixer": "10.4.13",
"babel-loader": "9.1.2", "babel-loader": "9.1.2",
@ -479,12 +479,12 @@
"dev": true "dev": true
}, },
"node_modules/@angular-devkit/build-webpack": { "node_modules/@angular-devkit/build-webpack": {
"version": "0.1502.6", "version": "0.1502.7",
"resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1502.6.tgz", "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1502.7.tgz",
"integrity": "sha512-X7XQ11QDz2Bs5qpJ3a5glIytvI+S74ORQxdzvT6a6KB8ayW0SgZEhTwD+GF7pa5My8draIaXBGzzQR1qmpWK5Q==", "integrity": "sha512-sNE4t4shSwxagqm+jdojbkYfuo/CHNMi4faItDWTTsCOf9wQxCxV4Waxee4akAkv3K6fzrnZy3ad/oQQMUl0Iw==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@angular-devkit/architect": "0.1502.6", "@angular-devkit/architect": "0.1502.7",
"rxjs": "6.6.7" "rxjs": "6.6.7"
}, },
"engines": { "engines": {
@ -516,9 +516,9 @@
"dev": true "dev": true
}, },
"node_modules/@angular-devkit/core": { "node_modules/@angular-devkit/core": {
"version": "15.2.6", "version": "15.2.7",
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-15.2.6.tgz", "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-15.2.7.tgz",
"integrity": "sha512-YVTWZ+M+xNKdFX4EnY9QX49PZraawiaA0iTd2CUW8ZoTUvU7yOGMKZLSdz6aokTMRVfm0449wt6YL994ibOo1g==", "integrity": "sha512-k2MKUm4ygTD9+89neqMmBphDr0o8Tp9RtgfzbS8VHgGkGYlbu0KPsxHyHB3Mvzl1EkSz6EHyrU3t89m+Rcj1lw==",
"devOptional": true, "devOptional": true,
"dependencies": { "dependencies": {
"ajv": "8.12.0", "ajv": "8.12.0",
@ -560,12 +560,12 @@
"devOptional": true "devOptional": true
}, },
"node_modules/@angular-devkit/schematics": { "node_modules/@angular-devkit/schematics": {
"version": "15.2.6", "version": "15.2.7",
"resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-15.2.6.tgz", "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-15.2.7.tgz",
"integrity": "sha512-f7VgnAcok7AwR/DhX0ZWskB0rFBo/KsvtIUA2qZSrpKMf8eFiwu03dv/b2mI0vnf+1FBfIQzJvO0ww45zRp6dA==", "integrity": "sha512-umQ+SgEMjqPHimHOBVhDn5NNGVoMLKQkI2fwbENXV72BqQqdh1K3D4QSNlUXitTaH0NEZZaAawE1vZHzzeAoNA==",
"devOptional": true, "devOptional": true,
"dependencies": { "dependencies": {
"@angular-devkit/core": "15.2.6", "@angular-devkit/core": "15.2.7",
"jsonc-parser": "3.2.0", "jsonc-parser": "3.2.0",
"magic-string": "0.29.0", "magic-string": "0.29.0",
"ora": "5.4.1", "ora": "5.4.1",
@ -700,15 +700,15 @@
} }
}, },
"node_modules/@angular/cli": { "node_modules/@angular/cli": {
"version": "15.2.6", "version": "15.2.7",
"resolved": "https://registry.npmjs.org/@angular/cli/-/cli-15.2.6.tgz", "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-15.2.7.tgz",
"integrity": "sha512-wNkQ/qCVbd4pERaGVagKJPifEvjRNY5otwsd4iRVubY/XOcIHcYChUThZwgQdVfNAImfJPMZNrhbGxejuWLA9w==", "integrity": "sha512-gGUIjaVN//bO72zRK3GNcCRVeism56BCRfkXSywKedCWFK4IZsatIL1IXT6OiJC22NsUCMaAFPD0wygSUCZaig==",
"devOptional": true, "devOptional": true,
"dependencies": { "dependencies": {
"@angular-devkit/architect": "0.1502.6", "@angular-devkit/architect": "0.1502.7",
"@angular-devkit/core": "15.2.6", "@angular-devkit/core": "15.2.7",
"@angular-devkit/schematics": "15.2.6", "@angular-devkit/schematics": "15.2.7",
"@schematics/angular": "15.2.6", "@schematics/angular": "15.2.7",
"@yarnpkg/lockfile": "1.1.0", "@yarnpkg/lockfile": "1.1.0",
"ansi-colors": "4.1.3", "ansi-colors": "4.1.3",
"ini": "3.0.1", "ini": "3.0.1",
@ -734,9 +734,9 @@
} }
}, },
"node_modules/@angular/common": { "node_modules/@angular/common": {
"version": "15.2.7", "version": "15.2.8",
"resolved": "https://registry.npmjs.org/@angular/common/-/common-15.2.7.tgz", "resolved": "https://registry.npmjs.org/@angular/common/-/common-15.2.8.tgz",
"integrity": "sha512-CbmrQeZ0yChQrF/ab3v+gv6x2uLbv/s1wZNUBSO/p1STz6BZzHRJqObVlfPlQvyBx5btBBy/+I1sUh1yumARDA==", "integrity": "sha512-yLDQihiRcVl38HrWMPbqgzOaSUw85AQH5BsGdjbS6BpoBQj3EXOpccCMFsuxOKxPG4toatgawNqrEnK0Jpv9Mw==",
"dependencies": { "dependencies": {
"tslib": "^2.3.0" "tslib": "^2.3.0"
}, },
@ -744,14 +744,14 @@
"node": "^14.20.0 || ^16.13.0 || >=18.10.0" "node": "^14.20.0 || ^16.13.0 || >=18.10.0"
}, },
"peerDependencies": { "peerDependencies": {
"@angular/core": "15.2.7", "@angular/core": "15.2.8",
"rxjs": "^6.5.3 || ^7.4.0" "rxjs": "^6.5.3 || ^7.4.0"
} }
}, },
"node_modules/@angular/compiler": { "node_modules/@angular/compiler": {
"version": "15.2.7", "version": "15.2.8",
"resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-15.2.7.tgz", "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-15.2.8.tgz",
"integrity": "sha512-SesyYI2ExUa13XukXgIsmfg3ar90HbWeWDJTgmzsIfph0M9t6+SaPGpf3FCtdBgNADIpUFp3cieCOJgLESzxYQ==", "integrity": "sha512-+dvspIDvuGoYqdL7r/3o9ojkR3fH1zevgC0ISJivcIrMi+WcJ0FV2JmJdnm8V52oNsHy+sMF9eEZGEbCbACE/A==",
"dependencies": { "dependencies": {
"tslib": "^2.3.0" "tslib": "^2.3.0"
}, },
@ -759,7 +759,7 @@
"node": "^14.20.0 || ^16.13.0 || >=18.10.0" "node": "^14.20.0 || ^16.13.0 || >=18.10.0"
}, },
"peerDependencies": { "peerDependencies": {
"@angular/core": "15.2.7" "@angular/core": "15.2.8"
}, },
"peerDependenciesMeta": { "peerDependenciesMeta": {
"@angular/core": { "@angular/core": {
@ -768,9 +768,9 @@
} }
}, },
"node_modules/@angular/compiler-cli": { "node_modules/@angular/compiler-cli": {
"version": "15.2.7", "version": "15.2.8",
"resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-15.2.7.tgz", "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-15.2.8.tgz",
"integrity": "sha512-4v51dOaT8GDUzRh6+mCLZOaYuU9FYX6vOHaLod9np3tVWPhcpoF2ZklRSiQDeFqrhr5B4vuCp/Lh9N2wzc22XQ==", "integrity": "sha512-fFxaDlbILo0t2t662qA0cjgn+kWItGlc1tFYKU6X7bvYb3t2e0cd9FzrFPLXUQVboGis83ULcJ2zkDxScnuPuQ==",
"dependencies": { "dependencies": {
"@babel/core": "7.19.3", "@babel/core": "7.19.3",
"@jridgewell/sourcemap-codec": "^1.4.14", "@jridgewell/sourcemap-codec": "^1.4.14",
@ -792,7 +792,7 @@
"node": "^14.20.0 || ^16.13.0 || >=18.10.0" "node": "^14.20.0 || ^16.13.0 || >=18.10.0"
}, },
"peerDependencies": { "peerDependencies": {
"@angular/compiler": "15.2.7", "@angular/compiler": "15.2.8",
"typescript": ">=4.8.2 <5.0" "typescript": ">=4.8.2 <5.0"
} }
}, },
@ -834,9 +834,9 @@
} }
}, },
"node_modules/@angular/core": { "node_modules/@angular/core": {
"version": "15.2.7", "version": "15.2.8",
"resolved": "https://registry.npmjs.org/@angular/core/-/core-15.2.7.tgz", "resolved": "https://registry.npmjs.org/@angular/core/-/core-15.2.8.tgz",
"integrity": "sha512-iS7JCJubRFqdndoUdAnvNkQRT3tY5tNFupBQS/sytkwxVrdBg+Is5jpdgk741n824vTMsE+CnuY0SETar8rN6g==", "integrity": "sha512-NDs+g4uM4EhyCvluf8a0YBCFXsDAEfCMHOD5cS00Bl+liTQ7JwtmepkWXMyjLB92irC9JaR79kdy4BoIKOh8WA==",
"dependencies": { "dependencies": {
"tslib": "^2.3.0" "tslib": "^2.3.0"
}, },
@ -849,9 +849,9 @@
} }
}, },
"node_modules/@angular/forms": { "node_modules/@angular/forms": {
"version": "15.2.7", "version": "15.2.8",
"resolved": "https://registry.npmjs.org/@angular/forms/-/forms-15.2.7.tgz", "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-15.2.8.tgz",
"integrity": "sha512-rzrebDIrtxxOeMcBzRBxqaOBZ+T1DJrysG/6YWZy428W/Z3MfPxUarPxgfx/oZI+x5uUsDaZmyoRdhVPJ2KhZg==", "integrity": "sha512-VyevVj20DdQWjAQUyiFTe+DAzqG9GqfAOWn376Y/lhPcwxAojXePTGNgtQud566/urDrNrP5haaLD6O36/3n+w==",
"dependencies": { "dependencies": {
"tslib": "^2.3.0" "tslib": "^2.3.0"
}, },
@ -859,16 +859,16 @@
"node": "^14.20.0 || ^16.13.0 || >=18.10.0" "node": "^14.20.0 || ^16.13.0 || >=18.10.0"
}, },
"peerDependencies": { "peerDependencies": {
"@angular/common": "15.2.7", "@angular/common": "15.2.8",
"@angular/core": "15.2.7", "@angular/core": "15.2.8",
"@angular/platform-browser": "15.2.7", "@angular/platform-browser": "15.2.8",
"rxjs": "^6.5.3 || ^7.4.0" "rxjs": "^6.5.3 || ^7.4.0"
} }
}, },
"node_modules/@angular/localize": { "node_modules/@angular/localize": {
"version": "15.2.7", "version": "15.2.8",
"resolved": "https://registry.npmjs.org/@angular/localize/-/localize-15.2.7.tgz", "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-15.2.8.tgz",
"integrity": "sha512-ySuy35QKApWH9sW3PfnAAnZjLl3NT+SacvlEWigrTeCqfBEuDPUG57ugvc1/Lzuo09UOh3HQkrQBbdWAILd8JA==", "integrity": "sha512-wJLBp0MUnET9kHzBtqIlZ3RQ56JFItXSgmBXagQq+MU+uJZmGvuw6fez0i5wkgv9Rgnr25oCULVtpTF+T5RGYA==",
"dependencies": { "dependencies": {
"@babel/core": "7.19.3", "@babel/core": "7.19.3",
"glob": "8.1.0", "glob": "8.1.0",
@ -883,8 +883,8 @@
"node": "^14.20.0 || ^16.13.0 || >=18.10.0" "node": "^14.20.0 || ^16.13.0 || >=18.10.0"
}, },
"peerDependencies": { "peerDependencies": {
"@angular/compiler": "15.2.7", "@angular/compiler": "15.2.8",
"@angular/compiler-cli": "15.2.7" "@angular/compiler-cli": "15.2.8"
} }
}, },
"node_modules/@angular/localize/node_modules/@babel/core": { "node_modules/@angular/localize/node_modules/@babel/core": {
@ -925,9 +925,9 @@
} }
}, },
"node_modules/@angular/platform-browser": { "node_modules/@angular/platform-browser": {
"version": "15.2.7", "version": "15.2.8",
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-15.2.7.tgz", "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-15.2.8.tgz",
"integrity": "sha512-aCbd7xyuP7c2eDITkOTDO2mqP550WHCBN8U6VnjysqtB5ocbJtR6z/MIRItN/Zx+xj3piiaKei//XIkb3Q5fXQ==", "integrity": "sha512-8sKFUld54inj0FnQ1ydhFxnDgsbbf43W9FALye/5uEtLgwwE/ZvkNYMaQ7hq1JPuQRMDj3gJkFqaLeFjplpHDA==",
"dependencies": { "dependencies": {
"tslib": "^2.3.0" "tslib": "^2.3.0"
}, },
@ -935,9 +935,9 @@
"node": "^14.20.0 || ^16.13.0 || >=18.10.0" "node": "^14.20.0 || ^16.13.0 || >=18.10.0"
}, },
"peerDependencies": { "peerDependencies": {
"@angular/animations": "15.2.7", "@angular/animations": "15.2.8",
"@angular/common": "15.2.7", "@angular/common": "15.2.8",
"@angular/core": "15.2.7" "@angular/core": "15.2.8"
}, },
"peerDependenciesMeta": { "peerDependenciesMeta": {
"@angular/animations": { "@angular/animations": {
@ -946,9 +946,9 @@
} }
}, },
"node_modules/@angular/platform-browser-dynamic": { "node_modules/@angular/platform-browser-dynamic": {
"version": "15.2.7", "version": "15.2.8",
"resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-15.2.7.tgz", "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-15.2.8.tgz",
"integrity": "sha512-t1Nf7hgbcYvhmxuzgUtsV47jrI5CXUBqrtz5I0ilWG92zZTig5qvfd1/2Ub8NHz87uHNrnggyZpL2+4MJ26nyQ==", "integrity": "sha512-75HyoZNibA3u/FvdK4Aw5KMzUmS/nDk5N8s7gfM09fe1resSPgFiW8JJEkr1xiUdA2WtSRbHs34y5rHLDe7n1Q==",
"dependencies": { "dependencies": {
"tslib": "^2.3.0" "tslib": "^2.3.0"
}, },
@ -956,16 +956,16 @@
"node": "^14.20.0 || ^16.13.0 || >=18.10.0" "node": "^14.20.0 || ^16.13.0 || >=18.10.0"
}, },
"peerDependencies": { "peerDependencies": {
"@angular/common": "15.2.7", "@angular/common": "15.2.8",
"@angular/compiler": "15.2.7", "@angular/compiler": "15.2.8",
"@angular/core": "15.2.7", "@angular/core": "15.2.8",
"@angular/platform-browser": "15.2.7" "@angular/platform-browser": "15.2.8"
} }
}, },
"node_modules/@angular/router": { "node_modules/@angular/router": {
"version": "15.2.7", "version": "15.2.8",
"resolved": "https://registry.npmjs.org/@angular/router/-/router-15.2.7.tgz", "resolved": "https://registry.npmjs.org/@angular/router/-/router-15.2.8.tgz",
"integrity": "sha512-Wkk+oJSUrVafJjmv9uE1SoY4wDE9bjX7ald+UXePz+QyM/PFoLkm/CzLYjFBkJnsOkOVxw1VmvacoUjWN6BCTQ==", "integrity": "sha512-C62QBEeJSBTNTrQHZiklPrxwJwuENoZzWX22MMJ7dxl+7VjRgnmj8J7mcX9fLjHlL+mC3RvesMlX7sGZRQV1cg==",
"dependencies": { "dependencies": {
"tslib": "^2.3.0" "tslib": "^2.3.0"
}, },
@ -973,9 +973,9 @@
"node": "^14.20.0 || ^16.13.0 || >=18.10.0" "node": "^14.20.0 || ^16.13.0 || >=18.10.0"
}, },
"peerDependencies": { "peerDependencies": {
"@angular/common": "15.2.7", "@angular/common": "15.2.8",
"@angular/core": "15.2.7", "@angular/core": "15.2.8",
"@angular/platform-browser": "15.2.7", "@angular/platform-browser": "15.2.8",
"rxjs": "^6.5.3 || ^7.4.0" "rxjs": "^6.5.3 || ^7.4.0"
} }
}, },
@ -3262,9 +3262,9 @@
} }
}, },
"node_modules/@eslint/js": { "node_modules/@eslint/js": {
"version": "8.38.0", "version": "8.39.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.38.0.tgz", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.39.0.tgz",
"integrity": "sha512-IoD2MfUnOV58ghIHCiil01PcohxjbYR/qCxsoC+xNgUwh1EY8jOOrYmu3d3a71+tJJ23uscEV4X2HJWMsPJu4g==", "integrity": "sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng==",
"dev": true, "dev": true,
"engines": { "engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@ -4119,9 +4119,9 @@
} }
}, },
"node_modules/@ngtools/webpack": { "node_modules/@ngtools/webpack": {
"version": "15.2.6", "version": "15.2.7",
"resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-15.2.6.tgz", "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-15.2.7.tgz",
"integrity": "sha512-I+kekKItfsCLdX+ZjjmsWqd0AyoYGTQPjlbQAiPtmdH73/rfPOF4Q/3AU4tzTdn0n0GXqZWv6VOs91w99ydi0A==", "integrity": "sha512-iUCSR03PzGSpwwZ5soioTIWsTPBayzkZfhKMkfz1RqtkbcxC4I07NRoQ1djofhsYyW2I1n7XS8w3K7NILtN3gQ==",
"dev": true, "dev": true,
"engines": { "engines": {
"node": "^14.20.0 || ^16.13.0 || >=18.10.0", "node": "^14.20.0 || ^16.13.0 || >=18.10.0",
@ -4332,13 +4332,13 @@
} }
}, },
"node_modules/@schematics/angular": { "node_modules/@schematics/angular": {
"version": "15.2.6", "version": "15.2.7",
"resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-15.2.6.tgz", "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-15.2.7.tgz",
"integrity": "sha512-OcBUvVAxZEMBX+fi0ytybeAdmStra+GwtlvipS70yOxcAgJ84ZrnZGN7a072cCVQcq7AgqUfssnyqCx1wu+yCg==", "integrity": "sha512-5fC6Es6HWpvmCnpPwTxHQq6KQuxtPaheFgoElHJM6uBgJDTr993MIw/3FsZvqLkO9hv/yWbr4gilqjEoesJSWg==",
"devOptional": true, "devOptional": true,
"dependencies": { "dependencies": {
"@angular-devkit/core": "15.2.6", "@angular-devkit/core": "15.2.7",
"@angular-devkit/schematics": "15.2.6", "@angular-devkit/schematics": "15.2.7",
"jsonc-parser": "3.2.0" "jsonc-parser": "3.2.0"
}, },
"engines": { "engines": {
@ -4495,9 +4495,9 @@
} }
}, },
"node_modules/@types/connect-history-api-fallback": { "node_modules/@types/connect-history-api-fallback": {
"version": "1.3.5", "version": "1.5.0",
"resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz", "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz",
"integrity": "sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==", "integrity": "sha512-4x5FkPpLipqwthjPsF7ZRbOv3uoLUFkTA9G9v583qi4pACvq0uTELrB8OLUzPWUI4IJIyvM85vzkV1nyiI2Lig==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@types/express-serve-static-core": "*", "@types/express-serve-static-core": "*",
@ -4543,14 +4543,15 @@
} }
}, },
"node_modules/@types/express-serve-static-core": { "node_modules/@types/express-serve-static-core": {
"version": "4.17.33", "version": "4.17.34",
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz", "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.34.tgz",
"integrity": "sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==", "integrity": "sha512-fvr49XlCGoUj2Pp730AItckfjat4WNb0lb3kfrLWffd+RLeoGAMsq7UOy04PAPtoL01uKwcp6u8nhzpgpDYr3w==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@types/node": "*", "@types/node": "*",
"@types/qs": "*", "@types/qs": "*",
"@types/range-parser": "*" "@types/range-parser": "*",
"@types/send": "*"
} }
}, },
"node_modules/@types/graceful-fs": { "node_modules/@types/graceful-fs": {
@ -4563,9 +4564,9 @@
} }
}, },
"node_modules/@types/http-proxy": { "node_modules/@types/http-proxy": {
"version": "1.17.10", "version": "1.17.11",
"resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.10.tgz", "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.11.tgz",
"integrity": "sha512-Qs5aULi+zV1bwKAg5z1PWnDXWmsn+LxIvUGv6E2+OOMYhclZMO+OXd9pYVf2gLykf2I7IV2u7oTHwChPNsvJ7g==", "integrity": "sha512-HC8G7c1WmaF2ekqpnFq626xd3Zz0uvaqFmBJNRZCGEZCXkvSdJoNFn/8Ygbd9fKNQj8UzLdCETaI0UWPAjK7IA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@types/node": "*" "@types/node": "*"
@ -4891,15 +4892,15 @@
"dev": true "dev": true
}, },
"node_modules/@types/mime": { "node_modules/@types/mime": {
"version": "3.0.1", "version": "1.3.2",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
"integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==", "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==",
"dev": true "dev": true
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "18.15.11", "version": "18.16.3",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.3.tgz",
"integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==", "integrity": "sha512-OPs5WnnT1xkCBiuQrZA4+YAV4HEJejmHneyraIaxsbev5yCEr6KMwINNFP9wQeFIw8FWcoTqF3vQsa5CDaI+8Q==",
"devOptional": true "devOptional": true
}, },
"node_modules/@types/parse-json": { "node_modules/@types/parse-json": {
@ -4944,6 +4945,16 @@
"integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==",
"dev": true "dev": true
}, },
"node_modules/@types/send": {
"version": "0.17.1",
"resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz",
"integrity": "sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==",
"dev": true,
"dependencies": {
"@types/mime": "^1",
"@types/node": "*"
}
},
"node_modules/@types/serve-index": { "node_modules/@types/serve-index": {
"version": "1.9.1", "version": "1.9.1",
"resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz",
@ -5030,15 +5041,15 @@
} }
}, },
"node_modules/@typescript-eslint/eslint-plugin": { "node_modules/@typescript-eslint/eslint-plugin": {
"version": "5.58.0", "version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.58.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.2.tgz",
"integrity": "sha512-vxHvLhH0qgBd3/tW6/VccptSfc8FxPQIkmNTVLWcCOVqSBvqpnKkBTYrhcGlXfSnd78azwe+PsjYFj0X34/njA==", "integrity": "sha512-yVrXupeHjRxLDcPKL10sGQ/QlVrA8J5IYOEWVqk0lJaSZP7X5DfnP7Ns3cc74/blmbipQ1htFNVGsHX6wsYm0A==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@eslint-community/regexpp": "^4.4.0", "@eslint-community/regexpp": "^4.4.0",
"@typescript-eslint/scope-manager": "5.58.0", "@typescript-eslint/scope-manager": "5.59.2",
"@typescript-eslint/type-utils": "5.58.0", "@typescript-eslint/type-utils": "5.59.2",
"@typescript-eslint/utils": "5.58.0", "@typescript-eslint/utils": "5.59.2",
"debug": "^4.3.4", "debug": "^4.3.4",
"grapheme-splitter": "^1.0.4", "grapheme-splitter": "^1.0.4",
"ignore": "^5.2.0", "ignore": "^5.2.0",
@ -5064,13 +5075,13 @@
} }
}, },
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/type-utils": { "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/type-utils": {
"version": "5.58.0", "version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.58.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.2.tgz",
"integrity": "sha512-FF5vP/SKAFJ+LmR9PENql7fQVVgGDOS+dq3j+cKl9iW/9VuZC/8CFmzIP0DLKXfWKpRHawJiG70rVH+xZZbp8w==", "integrity": "sha512-b1LS2phBOsEy/T381bxkkywfQXkV1dWda/z0PhnIy3bC5+rQWQDS7fk9CSpcXBccPY27Z6vBEuaPBCKCgYezyQ==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/typescript-estree": "5.58.0", "@typescript-eslint/typescript-estree": "5.59.2",
"@typescript-eslint/utils": "5.58.0", "@typescript-eslint/utils": "5.59.2",
"debug": "^4.3.4", "debug": "^4.3.4",
"tsutils": "^3.21.0" "tsutils": "^3.21.0"
}, },
@ -5091,17 +5102,17 @@
} }
}, },
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": {
"version": "5.58.0", "version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.58.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.2.tgz",
"integrity": "sha512-gAmLOTFXMXOC+zP1fsqm3VceKSBQJNzV385Ok3+yzlavNHZoedajjS4UyS21gabJYcobuigQPs/z71A9MdJFqQ==", "integrity": "sha512-kSuF6/77TZzyGPhGO4uVp+f0SBoYxCDf+lW3GKhtKru/L8k/Hd7NFQxyWUeY7Z/KGB2C6Fe3yf2vVi4V9TsCSQ==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/eslint-utils": "^4.2.0",
"@types/json-schema": "^7.0.9", "@types/json-schema": "^7.0.9",
"@types/semver": "^7.3.12", "@types/semver": "^7.3.12",
"@typescript-eslint/scope-manager": "5.58.0", "@typescript-eslint/scope-manager": "5.59.2",
"@typescript-eslint/types": "5.58.0", "@typescript-eslint/types": "5.59.2",
"@typescript-eslint/typescript-estree": "5.58.0", "@typescript-eslint/typescript-estree": "5.59.2",
"eslint-scope": "^5.1.1", "eslint-scope": "^5.1.1",
"semver": "^7.3.7" "semver": "^7.3.7"
}, },
@ -5139,14 +5150,14 @@
} }
}, },
"node_modules/@typescript-eslint/parser": { "node_modules/@typescript-eslint/parser": {
"version": "5.58.0", "version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.58.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.2.tgz",
"integrity": "sha512-ixaM3gRtlfrKzP8N6lRhBbjTow1t6ztfBvQNGuRM8qH1bjFFXIJ35XY+FC0RRBKn3C6cT+7VW1y8tNm7DwPHDQ==", "integrity": "sha512-uq0sKyw6ao1iFOZZGk9F8Nro/8+gfB5ezl1cA06SrqbgJAt0SRoFhb9pXaHvkrxUpZaoLxt8KlovHNk8Gp6/HQ==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/scope-manager": "5.58.0", "@typescript-eslint/scope-manager": "5.59.2",
"@typescript-eslint/types": "5.58.0", "@typescript-eslint/types": "5.59.2",
"@typescript-eslint/typescript-estree": "5.58.0", "@typescript-eslint/typescript-estree": "5.59.2",
"debug": "^4.3.4" "debug": "^4.3.4"
}, },
"engines": { "engines": {
@ -5166,13 +5177,13 @@
} }
}, },
"node_modules/@typescript-eslint/scope-manager": { "node_modules/@typescript-eslint/scope-manager": {
"version": "5.58.0", "version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.58.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.2.tgz",
"integrity": "sha512-b+w8ypN5CFvrXWQb9Ow9T4/6LC2MikNf1viLkYTiTbkQl46CnR69w7lajz1icW0TBsYmlpg+mRzFJ4LEJ8X9NA==", "integrity": "sha512-dB1v7ROySwQWKqQ8rEWcdbTsFjh2G0vn8KUyvTXdPoyzSL6lLGkiXEV5CvpJsEe9xIdKV+8Zqb7wif2issoOFA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/types": "5.58.0", "@typescript-eslint/types": "5.59.2",
"@typescript-eslint/visitor-keys": "5.58.0" "@typescript-eslint/visitor-keys": "5.59.2"
}, },
"engines": { "engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@ -5267,9 +5278,9 @@
} }
}, },
"node_modules/@typescript-eslint/types": { "node_modules/@typescript-eslint/types": {
"version": "5.58.0", "version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.58.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.2.tgz",
"integrity": "sha512-JYV4eITHPzVQMnHZcYJXl2ZloC7thuUHrcUmxtzvItyKPvQ50kb9QXBkgNAt90OYMqwaodQh2kHutWZl1fc+1g==", "integrity": "sha512-LbJ/HqoVs2XTGq5shkiKaNTuVv5tTejdHgfdjqRUGdYhjW1crm/M7og2jhVskMt8/4wS3T1+PfFvL1K3wqYj4w==",
"dev": true, "dev": true,
"engines": { "engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@ -5280,13 +5291,13 @@
} }
}, },
"node_modules/@typescript-eslint/typescript-estree": { "node_modules/@typescript-eslint/typescript-estree": {
"version": "5.58.0", "version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.58.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.2.tgz",
"integrity": "sha512-cRACvGTodA+UxnYM2uwA2KCwRL7VAzo45syNysqlMyNyjw0Z35Icc9ihPJZjIYuA5bXJYiJ2YGUB59BqlOZT1Q==", "integrity": "sha512-+j4SmbwVmZsQ9jEyBMgpuBD0rKwi9RxRpjX71Brr73RsYnEr3Lt5QZ624Bxphp8HUkSKfqGnPJp1kA5nl0Sh7Q==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/types": "5.58.0", "@typescript-eslint/types": "5.59.2",
"@typescript-eslint/visitor-keys": "5.58.0", "@typescript-eslint/visitor-keys": "5.59.2",
"debug": "^4.3.4", "debug": "^4.3.4",
"globby": "^11.1.0", "globby": "^11.1.0",
"is-glob": "^4.0.3", "is-glob": "^4.0.3",
@ -5429,12 +5440,12 @@
} }
}, },
"node_modules/@typescript-eslint/visitor-keys": { "node_modules/@typescript-eslint/visitor-keys": {
"version": "5.58.0", "version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.58.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.2.tgz",
"integrity": "sha512-/fBraTlPj0jwdyTwLyrRTxv/3lnU2H96pNTVM6z3esTWLtA5MZ9ghSMJ7Rb+TtUAdtEw9EyJzJ0EydIMKxQ9gA==", "integrity": "sha512-EEpsO8m3RASrKAHI9jpavNv9NlEUebV4qmF1OWxSTtKSFBpC1NCmWazDQHFivRf0O1DV11BA645yrLEVQ0/Lig==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/types": "5.58.0", "@typescript-eslint/types": "5.59.2",
"eslint-visitor-keys": "^3.3.0" "eslint-visitor-keys": "^3.3.0"
}, },
"engines": { "engines": {
@ -6988,9 +6999,9 @@
} }
}, },
"node_modules/commander": { "node_modules/commander": {
"version": "5.1.0", "version": "6.2.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
"integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==",
"optional": true, "optional": true,
"engines": { "engines": {
"node": ">= 6" "node": ">= 6"
@ -7563,9 +7574,9 @@
"dev": true "dev": true
}, },
"node_modules/cypress": { "node_modules/cypress": {
"version": "12.9.0", "version": "12.11.0",
"resolved": "https://registry.npmjs.org/cypress/-/cypress-12.9.0.tgz", "resolved": "https://registry.npmjs.org/cypress/-/cypress-12.11.0.tgz",
"integrity": "sha512-Ofe09LbHKgSqX89Iy1xen2WvpgbvNxDzsWx3mgU1mfILouELeXYGwIib3ItCwoRrRifoQwcBFmY54Vs0zw7QCg==", "integrity": "sha512-TJE+CCWI26Hwr5Msb9GpQhFLubdYooW0fmlPwTsfiyxmngqc7+SZGLPeIkj2dTSSZSEtpQVzOzvcnzH0o8G7Vw==",
"hasInstallScript": true, "hasInstallScript": true,
"optional": true, "optional": true,
"dependencies": { "dependencies": {
@ -7583,7 +7594,7 @@
"check-more-types": "^2.24.0", "check-more-types": "^2.24.0",
"cli-cursor": "^3.1.0", "cli-cursor": "^3.1.0",
"cli-table3": "~0.6.1", "cli-table3": "~0.6.1",
"commander": "^5.1.0", "commander": "^6.2.1",
"common-tags": "^1.8.0", "common-tags": "^1.8.0",
"dayjs": "^1.10.4", "dayjs": "^1.10.4",
"debug": "^4.3.4", "debug": "^4.3.4",
@ -7601,7 +7612,7 @@
"listr2": "^3.8.3", "listr2": "^3.8.3",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"log-symbols": "^4.0.0", "log-symbols": "^4.0.0",
"minimist": "^1.2.6", "minimist": "^1.2.8",
"ospath": "^1.2.2", "ospath": "^1.2.2",
"pretty-bytes": "^5.6.0", "pretty-bytes": "^5.6.0",
"proxy-from-env": "1.0.0", "proxy-from-env": "1.0.0",
@ -8013,9 +8024,9 @@
"dev": true "dev": true
}, },
"node_modules/dns-packet": { "node_modules/dns-packet": {
"version": "5.5.0", "version": "5.6.0",
"resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.5.0.tgz", "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.0.tgz",
"integrity": "sha512-USawdAUzRkV6xrqTjiAEp6M9YagZEzWcSUaZTcIFAiyQWW1SoI6KyId8y2+/71wbgHKQAKd+iupLv4YvEwYWvA==", "integrity": "sha512-rza3UH1LwdHh9qyPXp8lkwpjSNk/AMD3dPytUoRoqnypDUhY0xvbdmVhWOfxO68frEfV9BU8V12Ez7ZsHGZpCQ==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@leichtgewicht/ip-codec": "^2.0.1" "@leichtgewicht/ip-codec": "^2.0.1"
@ -8447,15 +8458,15 @@
} }
}, },
"node_modules/eslint": { "node_modules/eslint": {
"version": "8.38.0", "version": "8.39.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.38.0.tgz", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.39.0.tgz",
"integrity": "sha512-pIdsD2jwlUGf/U38Jv97t8lq6HpaU/G9NKbYmpWpZGw3LdTNhZLbJePqxOXGB5+JEKfOPU/XLxYxFh03nr1KTg==", "integrity": "sha512-mwiok6cy7KTW7rBpo05k6+p4YVZByLNjAZ/ACB9DRCu4YDRwjXI01tWHp6KAUWelsBetTxKK/2sHB0vdS8Z2Og==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.4.0", "@eslint-community/regexpp": "^4.4.0",
"@eslint/eslintrc": "^2.0.2", "@eslint/eslintrc": "^2.0.2",
"@eslint/js": "8.38.0", "@eslint/js": "8.39.0",
"@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/config-array": "^0.11.8",
"@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8", "@nodelib/fs.walk": "^1.2.8",
@ -8465,7 +8476,7 @@
"debug": "^4.3.2", "debug": "^4.3.2",
"doctrine": "^3.0.0", "doctrine": "^3.0.0",
"escape-string-regexp": "^4.0.0", "escape-string-regexp": "^4.0.0",
"eslint-scope": "^7.1.1", "eslint-scope": "^7.2.0",
"eslint-visitor-keys": "^3.4.0", "eslint-visitor-keys": "^3.4.0",
"espree": "^9.5.1", "espree": "^9.5.1",
"esquery": "^1.4.2", "esquery": "^1.4.2",
@ -8504,9 +8515,9 @@
} }
}, },
"node_modules/eslint-scope": { "node_modules/eslint-scope": {
"version": "7.1.1", "version": "7.2.0",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz",
"integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"esrecurse": "^4.3.0", "esrecurse": "^4.3.0",
@ -8514,6 +8525,9 @@
}, },
"engines": { "engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
} }
}, },
"node_modules/eslint-utils": { "node_modules/eslint-utils": {
@ -14071,9 +14085,9 @@
} }
}, },
"node_modules/minimist": { "node_modules/minimist": {
"version": "1.2.7", "version": "1.2.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
"integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
"devOptional": true, "devOptional": true,
"funding": { "funding": {
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
@ -16249,9 +16263,9 @@
} }
}, },
"node_modules/rxjs": { "node_modules/rxjs": {
"version": "7.8.0", "version": "7.8.1",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
"integrity": "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==", "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
"dependencies": { "dependencies": {
"tslib": "^2.1.0" "tslib": "^2.1.0"
} }

View File

@ -13,14 +13,14 @@
}, },
"private": true, "private": true,
"dependencies": { "dependencies": {
"@angular/common": "~15.2.7", "@angular/common": "~15.2.8",
"@angular/compiler": "~15.2.7", "@angular/compiler": "~15.2.8",
"@angular/core": "~15.2.7", "@angular/core": "~15.2.8",
"@angular/forms": "~15.2.7", "@angular/forms": "~15.2.8",
"@angular/localize": "~15.2.7", "@angular/localize": "~15.2.8",
"@angular/platform-browser": "~15.2.7", "@angular/platform-browser": "~15.2.8",
"@angular/platform-browser-dynamic": "~15.2.7", "@angular/platform-browser-dynamic": "~15.2.8",
"@angular/router": "~15.2.7", "@angular/router": "~15.2.8",
"@ng-bootstrap/ng-bootstrap": "^14.1.0", "@ng-bootstrap/ng-bootstrap": "^14.1.0",
"@ng-select/ng-select": "^10.0.4", "@ng-select/ng-select": "^10.0.4",
"@ngneat/dirty-check-forms": "^3.0.3", "@ngneat/dirty-check-forms": "^3.0.3",
@ -33,7 +33,7 @@
"ngx-cookie-service": "^15.0.0", "ngx-cookie-service": "^15.0.0",
"ngx-file-drop": "^15.0.0", "ngx-file-drop": "^15.0.0",
"ngx-ui-tour-ng-bootstrap": "^12.6.0", "ngx-ui-tour-ng-bootstrap": "^12.6.0",
"rxjs": "^7.8.0", "rxjs": "^7.8.1",
"tslib": "^2.4.1", "tslib": "^2.4.1",
"uuid": "^9.0.0", "uuid": "^9.0.0",
"zone.js": "^0.13.0" "zone.js": "^0.13.0"
@ -46,14 +46,14 @@
"@angular-eslint/eslint-plugin-template": "15.2.1", "@angular-eslint/eslint-plugin-template": "15.2.1",
"@angular-eslint/schematics": "15.2.1", "@angular-eslint/schematics": "15.2.1",
"@angular-eslint/template-parser": "15.2.1", "@angular-eslint/template-parser": "15.2.1",
"@angular/cli": "~15.2.6", "@angular/cli": "~15.2.7",
"@angular/compiler-cli": "~15.2.7", "@angular/compiler-cli": "~15.2.8",
"@types/jest": "^29.5.0", "@types/jest": "^29.5.0",
"@types/node": "^18.15.11", "@types/node": "^18.16.3",
"@typescript-eslint/eslint-plugin": "^5.58.0", "@typescript-eslint/eslint-plugin": "^5.59.2",
"@typescript-eslint/parser": "^5.58.0", "@typescript-eslint/parser": "^5.59.2",
"concurrently": "^8.0.1", "concurrently": "^8.0.1",
"eslint": "^8.38.0", "eslint": "^8.39.0",
"jest": "28.1.3", "jest": "28.1.3",
"jest-environment-jsdom": "^29.5.0", "jest-environment-jsdom": "^29.5.0",
"jest-preset-angular": "^12.2.6", "jest-preset-angular": "^12.2.6",
@ -63,6 +63,6 @@
}, },
"optionalDependencies": { "optionalDependencies": {
"@cypress/schematic": "^2.1.1", "@cypress/schematic": "^2.1.1",
"cypress": "^12.9.0" "cypress": "^12.11.0"
} }
} }

View File

@ -44,7 +44,7 @@
<use xlink:href="assets/bootstrap-icons.svg#gear"/> <use xlink:href="assets/bootstrap-icons.svg#gear"/>
</svg><ng-container i18n>Settings</ng-container> </svg><ng-container i18n>Settings</ng-container>
</a> </a>
<a ngbDropdownItem class="nav-link" href="accounts/logout/"> <a ngbDropdownItem class="nav-link" href="accounts/logout/" (click)="onLogout()">
<svg class="sidebaricon me-2" fill="currentColor"> <svg class="sidebaricon me-2" fill="currentColor">
<use xlink:href="assets/bootstrap-icons.svg#door-open"/> <use xlink:href="assets/bootstrap-icons.svg#door-open"/>
</svg><ng-container i18n>Logout</ng-container> </svg><ng-container i18n>Logout</ng-container>

View File

@ -243,4 +243,8 @@ export class AppFrameComponent
this.checkForUpdates() this.checkForUpdates()
} }
} }
onLogout() {
this.openDocumentsService.closeAll()
}
} }

View File

@ -1,4 +1,4 @@
<div class="btn-group w-100" ngbDropdown role="group" (openChange)="dropdownOpenChange($event)" #dropdown="ngbDropdown"> <div class="btn-group w-100" ngbDropdown role="group" (openChange)="dropdownOpenChange($event)" #dropdown="ngbDropdown" (keydown)="listKeyDown($event)">
<button class="btn btn-sm" id="dropdown_{{name}}" ngbDropdownToggle [ngClass]="!editing && selectionModel.selectionSize() > 0 ? 'btn-primary' : 'btn-outline-primary'" [disabled]="disabled"> <button class="btn btn-sm" id="dropdown_{{name}}" ngbDropdownToggle [ngClass]="!editing && selectionModel.selectionSize() > 0 ? 'btn-primary' : 'btn-outline-primary'" [disabled]="disabled">
<svg class="toolbaricon" fill="currentColor"> <svg class="toolbaricon" fill="currentColor">
<use attr.xlink:href="assets/bootstrap-icons.svg#{{icon}}" /> <use attr.xlink:href="assets/bootstrap-icons.svg#{{icon}}" />
@ -31,9 +31,11 @@
<input class="form-control" type="text" [(ngModel)]="filterText" [placeholder]="filterPlaceholder" (keyup.enter)="listFilterEnter()" #listFilterTextInput> <input class="form-control" type="text" [(ngModel)]="filterText" [placeholder]="filterPlaceholder" (keyup.enter)="listFilterEnter()" #listFilterTextInput>
</div> </div>
</div> </div>
<div *ngIf="selectionModel.items" class="items"> <div *ngIf="selectionModel.items" class="items" #buttonItems>
<ng-container *ngFor="let item of selectionModel.itemsSorted | filter: filterText"> <ng-container *ngFor="let item of selectionModel.itemsSorted | filter: filterText; let i = index">
<app-toggleable-dropdown-button *ngIf="allowSelectNone || item.id" [item]="item" [state]="selectionModel.get(item.id)" [count]="getUpdatedDocumentCount(item.id)" (toggle)="selectionModel.toggle(item.id)" (exclude)="excludeClicked(item.id)" [disabled]="disabled"></app-toggleable-dropdown-button> <app-toggleable-dropdown-button
*ngIf="allowSelectNone || item.id" [item]="item" [state]="selectionModel.get(item.id)" [count]="getUpdatedDocumentCount(item.id)" (toggle)="selectionModel.toggle(item.id)" (exclude)="excludeClicked(item.id)" (click)="setButtonItemIndex(i)" [disabled]="disabled">
</app-toggleable-dropdown-button>
</ng-container> </ng-container>
</div> </div>
<button *ngIf="editing" class="list-group-item list-group-item-action bg-light" (click)="applyClicked()" [disabled]="!modelIsDirty || disabled"> <button *ngIf="editing" class="list-group-item list-group-item-action bg-light" (click)="applyClicked()" [disabled]="!modelIsDirty || disabled">

View File

@ -324,6 +324,7 @@ export class FilterableDropdownSelectionModel {
export class FilterableDropdownComponent { export class FilterableDropdownComponent {
@ViewChild('listFilterTextInput') listFilterTextInput: ElementRef @ViewChild('listFilterTextInput') listFilterTextInput: ElementRef
@ViewChild('dropdown') dropdown: NgbDropdown @ViewChild('dropdown') dropdown: NgbDropdown
@ViewChild('buttonItems') buttonItems: ElementRef
filterText: string filterText: string
@ -416,14 +417,10 @@ export class FilterableDropdownComponent {
return this.title ? this.title.replace(/\s/g, '_').toLowerCase() : null return this.title ? this.title.replace(/\s/g, '_').toLowerCase() : null
} }
getUpdatedDocumentCount(id: number) {
if (this.documentCounts) {
return this.documentCounts.find((c) => c.id === id)?.document_count
}
}
modelIsDirty: boolean = false modelIsDirty: boolean = false
private keyboardIndex: number
constructor(private filterPipe: FilterPipe) { constructor(private filterPipe: FilterPipe) {
this.selectionModelChange.subscribe((updatedModel) => { this.selectionModelChange.subscribe((updatedModel) => {
this.modelIsDirty = updatedModel.isDirty() this.modelIsDirty = updatedModel.isDirty()
@ -461,11 +458,13 @@ export class FilterableDropdownComponent {
let filtered = this.filterPipe.transform(this.items, this.filterText) let filtered = this.filterPipe.transform(this.items, this.filterText)
if (filtered.length == 1) { if (filtered.length == 1) {
this.selectionModel.toggle(filtered[0].id) this.selectionModel.toggle(filtered[0].id)
if (this.editing) { setTimeout(() => {
this.applyClicked() if (this.editing) {
} else { this.applyClicked()
this.dropdown.close() } else {
} this.dropdown.close()
}
}, 200)
} }
} }
@ -481,4 +480,76 @@ export class FilterableDropdownComponent {
this.selectionModel.reset(true) this.selectionModel.reset(true)
this.selectionModelChange.emit(this.selectionModel) this.selectionModelChange.emit(this.selectionModel)
} }
getUpdatedDocumentCount(id: number) {
if (this.documentCounts) {
return this.documentCounts.find((c) => c.id === id)?.document_count
}
}
listKeyDown(event: KeyboardEvent) {
switch (event.key) {
case 'ArrowDown':
if (event.target instanceof HTMLInputElement) {
if (
!this.filterText ||
event.target.selectionStart === this.filterText.length
) {
this.keyboardIndex = -1
this.focusNextButtonItem()
event.preventDefault()
}
} else if (event.target instanceof HTMLButtonElement) {
this.focusNextButtonItem()
event.preventDefault()
}
break
case 'ArrowUp':
if (event.target instanceof HTMLButtonElement) {
if (this.keyboardIndex === 0) {
this.listFilterTextInput.nativeElement.focus()
} else {
this.focusPreviousButtonItem()
}
event.preventDefault()
}
break
case 'Tab':
// just track the index in case user uses arrows
if (event.target instanceof HTMLInputElement) {
this.keyboardIndex = 0
} else if (event.target instanceof HTMLButtonElement) {
if (event.shiftKey) {
if (this.keyboardIndex > 0) {
this.focusPreviousButtonItem(false)
}
} else {
this.focusNextButtonItem(false)
}
}
default:
break
}
}
focusNextButtonItem(setFocus: boolean = true) {
this.keyboardIndex = Math.min(this.items.length - 1, this.keyboardIndex + 1)
if (setFocus) this.setButtonItemFocus()
}
focusPreviousButtonItem(setFocus: boolean = true) {
this.keyboardIndex = Math.max(0, this.keyboardIndex - 1)
if (setFocus) this.setButtonItemFocus()
}
setButtonItemFocus() {
this.buttonItems.nativeElement.children[
this.keyboardIndex
]?.children[0].focus()
}
setButtonItemIndex(index: number) {
// just track the index in case user uses arrows
this.keyboardIndex = index
}
} }

View File

@ -100,7 +100,7 @@
<a ngbNavLink i18n>Metadata</a> <a ngbNavLink i18n>Metadata</a>
<ng-template ngbNavContent> <ng-template ngbNavContent>
<table class="table table-borderless"> <table class="table table-borderless" *ngIf="document">
<tbody> <tbody>
<tr> <tr>
<td i18n>Date modified</td> <td i18n>Date modified</td>

View File

@ -236,10 +236,21 @@ export class DocumentDetailComponent
true true
) )
this.suggestions = null this.suggestions = null
if (this.openDocumentService.getOpenDocument(this.documentId)) { const openDocument = this.openDocumentService.getOpenDocument(
this.updateComponent( this.documentId
this.openDocumentService.getOpenDocument(this.documentId) )
) if (openDocument) {
if (this.documentForm.dirty) {
Object.assign(openDocument, this.documentForm.value)
openDocument['owner'] =
this.documentForm.get('permissions_form').value['owner']
openDocument['permissions'] =
this.documentForm.get('permissions_form').value[
'set_permissions'
]
delete openDocument['permissions_form']
}
this.updateComponent(openDocument)
} else { } else {
this.openDocumentService.openDocument(doc) this.openDocumentService.openDocument(doc)
this.updateComponent(doc) this.updateComponent(doc)
@ -317,6 +328,10 @@ export class DocumentDetailComponent
if (navIDKey) { if (navIDKey) {
this.activeNavID = DocumentDetailNavIDs[navIDKey] this.activeNavID = DocumentDetailNavIDs[navIDKey]
} }
} else if (paramMap.get('id')) {
this.router.navigate(['documents', +paramMap.get('id'), 'details'], {
replaceUrl: true,
})
} }
}) })
} }

View File

@ -86,7 +86,7 @@ export class DocumentNotesComponent extends ComponentWithPermissions {
displayName(note: PaperlessDocumentNote): string { displayName(note: PaperlessDocumentNote): string {
if (!note.user) return '' if (!note.user) return ''
const user = this.users.find((u) => u.id === note.user) const user = this.users?.find((u) => u.id === note.user)
if (!user) return '' if (!user) return ''
const nameComponents = [] const nameComponents = []
if (user.first_name) nameComponents.unshift(user.first_name) if (user.first_name) nameComponents.unshift(user.first_name)

View File

@ -5,7 +5,7 @@ export const environment = {
apiBaseUrl: document.baseURI + 'api/', apiBaseUrl: document.baseURI + 'api/',
apiVersion: '2', apiVersion: '2',
appTitle: 'Paperless-ngx', appTitle: 'Paperless-ngx',
version: '1.14.2', version: '1.14.2-dev',
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

@ -5671,7 +5671,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">177</context> <context context-type="linenumber">177</context>
</context-group> </context-group>
<target state="needs-translation">Catalan</target> <target state="translated">اللغة الكتالونية</target>
</trans-unit> </trans-unit>
<trans-unit id="2719780722934172508" datatype="html"> <trans-unit id="2719780722934172508" datatype="html">
<source>Czech</source> <source>Czech</source>
@ -5719,7 +5719,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">213</context> <context context-type="linenumber">213</context>
</context-group> </context-group>
<target state="needs-translation">Finnish</target> <target state="translated">الفنلندية</target>
</trans-unit> </trans-unit>
<trans-unit id="7633754075223722162" datatype="html"> <trans-unit id="7633754075223722162" datatype="html">
<source>French</source> <source>French</source>

View File

@ -5719,7 +5719,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">213</context> <context context-type="linenumber">213</context>
</context-group> </context-group>
<target state="needs-translation">Finnish</target> <target state="translated">Finès</target>
</trans-unit> </trans-unit>
<trans-unit id="7633754075223722162" datatype="html"> <trans-unit id="7633754075223722162" datatype="html">
<source>French</source> <source>French</source>

View File

@ -5719,7 +5719,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">213</context> <context context-type="linenumber">213</context>
</context-group> </context-group>
<target state="needs-translation">Finnish</target> <target state="translated">Finnisch</target>
</trans-unit> </trans-unit>
<trans-unit id="7633754075223722162" datatype="html" approved="yes"> <trans-unit id="7633754075223722162" datatype="html" approved="yes">
<source>French</source> <source>French</source>

View File

@ -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="needs-translation">Increment hours</target> <target state="translated">Penambahan jam</target>
</trans-unit> </trans-unit>
<trans-unit id="ngb.pagination.first-aria" datatype="html"> <trans-unit id="ngb.pagination.first-aria" datatype="html">
<source>First</source> <source>First</source>
@ -194,7 +194,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="needs-translation">Decrement hours</target> <target state="translated">Pengurangan jam</target>
</trans-unit> </trans-unit>
<trans-unit id="ngb.pagination.next-aria" datatype="html"> <trans-unit id="ngb.pagination.next-aria" datatype="html">
<source>Next</source> <source>Next</source>
@ -210,7 +210,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="needs-translation">Increment minutes</target> <target state="translated">Penambahan menit</target>
</trans-unit> </trans-unit>
<trans-unit id="ngb.pagination.last-aria" datatype="html"> <trans-unit id="ngb.pagination.last-aria" datatype="html">
<source>Last</source> <source>Last</source>
@ -226,7 +226,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="needs-translation">Decrement minutes</target> <target state="translated">Pengurangan menit</target>
</trans-unit> </trans-unit>
<trans-unit id="ngb.timepicker.SS" datatype="html"> <trans-unit id="ngb.timepicker.SS" datatype="html">
<source>SS</source> <source>SS</source>
@ -250,7 +250,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="needs-translation">Increment seconds</target> <target state="translated">Penambahan detik</target>
</trans-unit> </trans-unit>
<trans-unit id="ngb.timepicker.decrement-seconds" datatype="html"> <trans-unit id="ngb.timepicker.decrement-seconds" datatype="html">
<source>Decrement seconds</source> <source>Decrement seconds</source>
@ -258,7 +258,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="needs-translation">Decrement seconds</target> <target state="translated">Pengurangan detik</target>
</trans-unit> </trans-unit>
<trans-unit id="ngb.timepicker.PM" datatype="html"> <trans-unit id="ngb.timepicker.PM" datatype="html">
<source> <source>
@ -284,7 +284,7 @@
<context context-type="sourcefile">src/app/app.component.html</context> <context context-type="sourcefile">src/app/app.component.html</context>
<context context-type="linenumber">7</context> <context context-type="linenumber">7</context>
</context-group> </context-group>
<target state="needs-translation">Drop files to begin upload</target> <target state="translated">Jatuhkan file untuk mulai mengunggah</target>
</trans-unit> </trans-unit>
<trans-unit id="9103526311244275943" datatype="html"> <trans-unit id="9103526311244275943" datatype="html">
<source>Document added</source> <source>Document added</source>
@ -308,7 +308,7 @@
<context context-type="sourcefile">src/app/app.component.ts</context> <context context-type="sourcefile">src/app/app.component.ts</context>
<context context-type="linenumber">102</context> <context context-type="linenumber">102</context>
</context-group> </context-group>
<target state="needs-translation">Document <x id="PH" equiv-text="status.filename"/> was added to paperless.</target> <target state="translated">Dokumen <x id="PH" equiv-text="status.filename"/> telah ditambahkan ke paperless.</target>
</trans-unit> </trans-unit>
<trans-unit id="1931214133925051574" datatype="html"> <trans-unit id="1931214133925051574" datatype="html">
<source>Open document</source> <source>Open document</source>
@ -380,7 +380,7 @@
<context context-type="sourcefile">src/app/app.component.ts</context> <context context-type="sourcefile">src/app/app.component.ts</context>
<context context-type="linenumber">145</context> <context context-type="linenumber">145</context>
</context-group> </context-group>
<target state="needs-translation">The dashboard can be used to show saved views, such as an 'Inbox'. Those settings are found under Settings &gt; Saved Views once you have created some.</target> <target state="translated">Dasbor dapat digunakan untuk menampilkan tampilan tersimpan, seperti sebagai 'Kotak Masuk'. Pengaturan tersebut ditemukan di bawah Pengaturan &gt; Tampilan tersimpan setelah Anda membuatnya.</target>
</trans-unit> </trans-unit>
<trans-unit id="9075755296812854717" datatype="html"> <trans-unit id="9075755296812854717" datatype="html">
<source>Drag-and-drop documents here to start uploading or place them in the consume folder. You can also drag-and-drop documents anywhere on all other pages of the web app. Once you do, Paperless-ngx will start training its machine learning algorithms.</source> <source>Drag-and-drop documents here to start uploading or place them in the consume folder. You can also drag-and-drop documents anywhere on all other pages of the web app. Once you do, Paperless-ngx will start training its machine learning algorithms.</source>
@ -460,7 +460,7 @@
<context context-type="sourcefile">src/app/app.component.ts</context> <context context-type="sourcefile">src/app/app.component.ts</context>
<context context-type="linenumber">233</context> <context context-type="linenumber">233</context>
</context-group> </context-group>
<target state="needs-translation">Lastly, on behalf of every contributor to this community-supported project, thank you for using Paperless-ngx!</target> <target state="translated">Terakhir, atas nama setiap kontributor untuk proyek yang didukung komunitas ini, terima kasih telah menggunakan Paperless-ngx!</target>
</trans-unit> </trans-unit>
<trans-unit id="5749300816154614125" datatype="html"> <trans-unit id="5749300816154614125" datatype="html">
<source>Initiating upload...</source> <source>Initiating upload...</source>
@ -493,7 +493,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">39</context> <context context-type="linenumber">39</context>
</context-group> </context-group>
<target state="needs-translation">Logged in as <x id="INTERPOLATION" equiv-text="{{this.settingsService.displayName}}"/></target> <target state="translated">Masuk sebagai <x id="INTERPOLATION" equiv-text="{{this.settingsService.displayName}}"/></target>
</trans-unit> </trans-unit>
<trans-unit id="4930506384627295710" datatype="html"> <trans-unit id="4930506384627295710" datatype="html">
<source>Settings</source> <source>Settings</source>
@ -517,7 +517,7 @@
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context>
<context context-type="linenumber">192</context> <context context-type="linenumber">192</context>
</context-group> </context-group>
<target state="needs-translation">Settings</target> <target state="translated">Pengaturan</target>
</trans-unit> </trans-unit>
<trans-unit id="3797778920049399855" datatype="html"> <trans-unit id="3797778920049399855" datatype="html">
<source>Logout</source> <source>Logout</source>
@ -585,7 +585,7 @@
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context>
<context context-type="linenumber">189</context> <context context-type="linenumber">189</context>
</context-group> </context-group>
<target state="needs-translation">Saved views</target> <target state="translated">Tampilan disimpan</target>
</trans-unit> </trans-unit>
<trans-unit id="6988090220128974198" datatype="html"> <trans-unit id="6988090220128974198" datatype="html">
<source>Open documents</source> <source>Open documents</source>
@ -613,7 +613,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">127</context> <context context-type="linenumber">127</context>
</context-group> </context-group>
<target state="needs-translation">Manage</target> <target state="translated">Kelola</target>
</trans-unit> </trans-unit>
<trans-unit id="7437910965833684826" datatype="html"> <trans-unit id="7437910965833684826" datatype="html">
<source>Correspondents</source> <source>Correspondents</source>
@ -673,7 +673,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">155</context> <context context-type="linenumber">155</context>
</context-group> </context-group>
<target state="needs-translation">Storage paths</target> <target state="translated">Lokasi penyimpanan</target>
</trans-unit> </trans-unit>
<trans-unit id="2991443309752293110" datatype="html"> <trans-unit id="2991443309752293110" datatype="html">
<source>File Tasks</source> <source>File Tasks</source>
@ -685,7 +685,7 @@
<context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.html</context>
<context context-type="linenumber">1</context> <context context-type="linenumber">1</context>
</context-group> </context-group>
<target state="needs-translation">File Tasks</target> <target state="translated">Tugas File</target>
</trans-unit> </trans-unit>
<trans-unit id="5537285341303594392" datatype="html"> <trans-unit id="5537285341303594392" datatype="html">
<source>File Tasks<x id="START_TAG_SPAN_1" ctype="x-span_1" equiv-text="&lt;span *ngIf=&quot;tasksService.failedFileTasks.length &gt; 0&quot;&gt;"/><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_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></source> <source>File Tasks<x id="START_TAG_SPAN_1" ctype="x-span_1" equiv-text="&lt;span *ngIf=&quot;tasksService.failedFileTasks.length &gt; 0&quot;&gt;"/><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_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></source>
@ -693,7 +693,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">163</context> <context context-type="linenumber">163</context>
</context-group> </context-group>
<target state="needs-translation">File Tasks<x id="START_TAG_SPAN_1" ctype="x-span_1" equiv-text="&lt;span *ngIf=&quot;tasksService.failedFileTasks.length &gt; 0&quot;&gt;"/><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_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></target> <target state="translated">Tugas File<x id="START_TAG_SPAN_1" ctype="x-span_1" equiv-text="&lt;span *ngIf=&quot;tasksService.failedFileTasks.length &gt; 0&quot;&gt;"/><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_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></target>
</trans-unit> </trans-unit>
<trans-unit id="4804785061014590286" datatype="html"> <trans-unit id="4804785061014590286" datatype="html">
<source>Logs</source> <source>Logs</source>
@ -709,7 +709,7 @@
<context context-type="sourcefile">src/app/components/manage/logs/logs.component.html</context> <context context-type="sourcefile">src/app/components/manage/logs/logs.component.html</context>
<context context-type="linenumber">1</context> <context context-type="linenumber">1</context>
</context-group> </context-group>
<target state="needs-translation">Logs</target> <target state="translated">Log</target>
</trans-unit> </trans-unit>
<trans-unit id="314315645942131479" datatype="html"> <trans-unit id="314315645942131479" datatype="html">
<source>Info</source> <source>Info</source>
@ -781,7 +781,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">217</context> <context context-type="linenumber">217</context>
</context-group> </context-group>
<target state="needs-translation">Paperless-ngx can automatically check for updates</target> <target state="translated">Paperless-ngx dapat secara otomatis memeriksa pembaruan</target>
</trans-unit> </trans-unit>
<trans-unit id="894819944961861800" datatype="html"> <trans-unit id="894819944961861800" datatype="html">
<source> How does this work? </source> <source> How does this work? </source>
@ -809,7 +809,7 @@
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.ts</context> <context context-type="sourcefile">src/app/components/manage/settings/settings.component.ts</context>
<context context-type="linenumber">593</context> <context context-type="linenumber">593</context>
</context-group> </context-group>
<target state="needs-translation">An error occurred while saving settings.</target> <target state="translated">Terjadi kesalahan saat menyimpan setelan.</target>
</trans-unit> </trans-unit>
<trans-unit id="2526035785704676448" datatype="html"> <trans-unit id="2526035785704676448" datatype="html">
<source>An error occurred while saving update checking settings.</source> <source>An error occurred while saving update checking settings.</source>
@ -817,7 +817,7 @@
<context context-type="sourcefile">src/app/components/app-frame/app-frame.component.ts</context> <context context-type="sourcefile">src/app/components/app-frame/app-frame.component.ts</context>
<context context-type="linenumber">222</context> <context context-type="linenumber">222</context>
</context-group> </context-group>
<target state="needs-translation">An error occurred while saving update checking settings.</target> <target state="translated">Terjadi kesalahan saat menyimpan setelan pemeriksaan pembaruan.</target>
</trans-unit> </trans-unit>
<trans-unit id="8700121026680200191" datatype="html"> <trans-unit id="8700121026680200191" datatype="html">
<source>Clear</source> <source>Clear</source>
@ -833,7 +833,7 @@
<context context-type="sourcefile">src/app/components/common/date-dropdown/date-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/date-dropdown/date-dropdown.component.html</context>
<context context-type="linenumber">47</context> <context context-type="linenumber">47</context>
</context-group> </context-group>
<target state="needs-translation">Clear</target> <target state="translated">Bersihkan</target>
</trans-unit> </trans-unit>
<trans-unit id="5000042972069710005" datatype="html"> <trans-unit id="5000042972069710005" datatype="html">
<source><x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;d-inline-block&quot; style=&quot;padding-bottom: 1px;&quot; &gt;"/>Cancel<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></source> <source><x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;d-inline-block&quot; style=&quot;padding-bottom: 1px;&quot; &gt;"/>Cancel<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></source>
@ -877,7 +877,7 @@
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context> <context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">440</context> <context context-type="linenumber">440</context>
</context-group> </context-group>
<target state="needs-translation">Confirm</target> <target state="translated">Konfirmasi</target>
</trans-unit> </trans-unit>
<trans-unit id="6371576811194810854" datatype="html"> <trans-unit id="6371576811194810854" datatype="html">
<source>After</source> <source>After</source>
@ -1017,7 +1017,7 @@
<context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/manage/tasks/tasks.component.html</context>
<context context-type="linenumber">40</context> <context context-type="linenumber">40</context>
</context-group> </context-group>
<target state="needs-translation">Name</target> <target state="translated">Nama</target>
</trans-unit> </trans-unit>
<trans-unit id="8743659855412792665" datatype="html"> <trans-unit id="8743659855412792665" datatype="html">
<source>Matching algorithm</source> <source>Matching algorithm</source>
@ -1037,7 +1037,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component.html</context>
<context context-type="linenumber">13</context> <context context-type="linenumber">13</context>
</context-group> </context-group>
<target state="needs-translation">Matching algorithm</target> <target state="translated">Mencocokkan algoritma</target>
</trans-unit> </trans-unit>
<trans-unit id="2656329676292524585" datatype="html"> <trans-unit id="2656329676292524585" datatype="html">
<source>Matching pattern</source> <source>Matching pattern</source>
@ -1193,7 +1193,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/correspondent-edit-dialog/correspondent-edit-dialog.component.ts</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/correspondent-edit-dialog/correspondent-edit-dialog.component.ts</context>
<context context-type="linenumber">29</context> <context context-type="linenumber">29</context>
</context-group> </context-group>
<target state="needs-translation">Edit correspondent</target> <target state="translated">Ubah koresponden</target>
</trans-unit> </trans-unit>
<trans-unit id="6672809941092516947" datatype="html"> <trans-unit id="6672809941092516947" datatype="html">
<source>Create new document type</source> <source>Create new document type</source>
@ -1201,7 +1201,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component.ts</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component.ts</context>
<context context-type="linenumber">25</context> <context context-type="linenumber">25</context>
</context-group> </context-group>
<target state="needs-translation">Create new document type</target> <target state="translated">Buat jenis dokumen baru</target>
</trans-unit> </trans-unit>
<trans-unit id="36335016091244220" datatype="html"> <trans-unit id="36335016091244220" datatype="html">
<source>Edit document type</source> <source>Edit document type</source>
@ -1217,7 +1217,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/edit-dialog.component.ts</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/edit-dialog.component.ts</context>
<context context-type="linenumber">71</context> <context context-type="linenumber">71</context>
</context-group> </context-group>
<target state="needs-translation">Create new item</target> <target state="translated">Buat barang baru</target>
</trans-unit> </trans-unit>
<trans-unit id="5324147361912094446" datatype="html"> <trans-unit id="5324147361912094446" datatype="html">
<source>Edit item</source> <source>Edit item</source>
@ -1225,7 +1225,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/edit-dialog.component.ts</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/edit-dialog.component.ts</context>
<context context-type="linenumber">75</context> <context context-type="linenumber">75</context>
</context-group> </context-group>
<target state="needs-translation">Edit item</target> <target state="translated">Sunting barang</target>
</trans-unit> </trans-unit>
<trans-unit id="1699589597032579396" datatype="html"> <trans-unit id="1699589597032579396" datatype="html">
<source>Could not save element: <x id="PH" equiv-text="error"/></source> <source>Could not save element: <x id="PH" equiv-text="error"/></source>
@ -1257,7 +1257,7 @@
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.html</context> <context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.html</context>
<context context-type="linenumber">81</context> <context context-type="linenumber">81</context>
</context-group> </context-group>
<target state="needs-translation">Permissions</target> <target state="translated">Akses</target>
</trans-unit> </trans-unit>
<trans-unit id="7878445132438733225" datatype="html"> <trans-unit id="7878445132438733225" datatype="html">
<source>Create new user group</source> <source>Create new user group</source>
@ -1265,7 +1265,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/group-edit-dialog/group-edit-dialog.component.ts</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/group-edit-dialog/group-edit-dialog.component.ts</context>
<context context-type="linenumber">24</context> <context context-type="linenumber">24</context>
</context-group> </context-group>
<target state="needs-translation">Create new user group</target> <target state="translated">Membuat grup pengguna baru</target>
</trans-unit> </trans-unit>
<trans-unit id="200893957904793797" datatype="html"> <trans-unit id="200893957904793797" datatype="html">
<source>Edit user group</source> <source>Edit user group</source>
@ -1273,7 +1273,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/group-edit-dialog/group-edit-dialog.component.ts</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/group-edit-dialog/group-edit-dialog.component.ts</context>
<context context-type="linenumber">28</context> <context context-type="linenumber">28</context>
</context-group> </context-group>
<target state="needs-translation">Edit user group</target> <target state="translated">Ubah grup pengguna</target>
</trans-unit> </trans-unit>
<trans-unit id="1505107477868159986" datatype="html"> <trans-unit id="1505107477868159986" datatype="html">
<source>IMAP Server</source> <source>IMAP Server</source>
@ -1281,7 +1281,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html</context>
<context context-type="linenumber">11</context> <context context-type="linenumber">11</context>
</context-group> </context-group>
<target state="needs-translation">IMAP Server</target> <target state="translated">Server IMAP</target>
</trans-unit> </trans-unit>
<trans-unit id="6575044156016560168" datatype="html"> <trans-unit id="6575044156016560168" datatype="html">
<source>IMAP Port</source> <source>IMAP Port</source>
@ -1289,7 +1289,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html</context>
<context context-type="linenumber">12</context> <context context-type="linenumber">12</context>
</context-group> </context-group>
<target state="needs-translation">IMAP Port</target> <target state="translated">Port IMAP</target>
</trans-unit> </trans-unit>
<trans-unit id="5418425343712813426" datatype="html"> <trans-unit id="5418425343712813426" datatype="html">
<source>IMAP Security</source> <source>IMAP Security</source>
@ -1297,7 +1297,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html</context>
<context context-type="linenumber">13</context> <context context-type="linenumber">13</context>
</context-group> </context-group>
<target state="needs-translation">IMAP Security</target> <target state="translated">Keamanan IMAP</target>
</trans-unit> </trans-unit>
<trans-unit id="5248717555542428023" datatype="html"> <trans-unit id="5248717555542428023" datatype="html">
<source>Username</source> <source>Username</source>
@ -1313,7 +1313,7 @@
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context>
<context context-type="linenumber">344</context> <context context-type="linenumber">344</context>
</context-group> </context-group>
<target state="needs-translation">Username</target> <target state="translated">Nama pengguna</target>
</trans-unit> </trans-unit>
<trans-unit id="1431416938026210429" datatype="html"> <trans-unit id="1431416938026210429" datatype="html">
<source>Password</source> <source>Password</source>
@ -1417,7 +1417,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts</context>
<context context-type="linenumber">14</context> <context context-type="linenumber">14</context>
</context-group> </context-group>
<target state="needs-translation">SSL</target> <target state="translated">SSL</target>
</trans-unit> </trans-unit>
<trans-unit id="2620794666957669114" datatype="html"> <trans-unit id="2620794666957669114" datatype="html">
<source>STARTTLS</source> <source>STARTTLS</source>
@ -1425,7 +1425,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts</context>
<context context-type="linenumber">15</context> <context context-type="linenumber">15</context>
</context-group> </context-group>
<target state="needs-translation">STARTTLS</target> <target state="translated">STARTTLS</target>
</trans-unit> </trans-unit>
<trans-unit id="8758081884575368561" datatype="html"> <trans-unit id="8758081884575368561" datatype="html">
<source>Create new mail account</source> <source>Create new mail account</source>
@ -1501,7 +1501,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">14</context> <context context-type="linenumber">14</context>
</context-group> </context-group>
<target state="needs-translation">Attachment type</target> <target state="translated">Jenis lampiran</target>
</trans-unit> </trans-unit>
<trans-unit id="559099472394646919" datatype="html"> <trans-unit id="559099472394646919" datatype="html">
<source>Consumption scope</source> <source>Consumption scope</source>
@ -1565,7 +1565,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">23</context> <context context-type="linenumber">23</context>
</context-group> </context-group>
<target state="needs-translation">Filter body</target> <target state="translated">Saring badan</target>
</trans-unit> </trans-unit>
<trans-unit id="5031687746498952417" datatype="html"> <trans-unit id="5031687746498952417" datatype="html">
<source>Filter attachment filename</source> <source>Filter attachment filename</source>
@ -1573,7 +1573,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">24</context> <context context-type="linenumber">24</context>
</context-group> </context-group>
<target state="needs-translation">Filter attachment filename</target> <target state="translated">Saring nama file lampiran</target>
</trans-unit> </trans-unit>
<trans-unit id="4245210767172267486" datatype="html"> <trans-unit id="4245210767172267486" datatype="html">
<source>Only consume documents which entirely match this filename if specified. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive.</source> <source>Only consume documents which entirely match this filename if specified. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive.</source>
@ -1685,7 +1685,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts</context>
<context context-type="linenumber">45</context> <context context-type="linenumber">45</context>
</context-group> </context-group>
<target state="needs-translation">Process message as .eml and attachments separately</target> <target state="translated">Proses pesan sebagai .eml dan lampiran terpisah</target>
</trans-unit> </trans-unit>
<trans-unit id="7022070615528435141" datatype="html"> <trans-unit id="7022070615528435141" datatype="html">
<source>Delete</source> <source>Delete</source>
@ -1909,7 +1909,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.ts</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.ts</context>
<context context-type="linenumber">39</context> <context context-type="linenumber">39</context>
</context-group> </context-group>
<target state="needs-translation">Edit storage path</target> <target state="translated">Ubah lokasi penyimpanan</target>
</trans-unit> </trans-unit>
<trans-unit id="9011959596901584887" datatype="html"> <trans-unit id="9011959596901584887" datatype="html">
<source>Color</source> <source>Color</source>
@ -2069,7 +2069,7 @@
<context context-type="sourcefile">src/app/components/common/filterable-dropdown/filterable-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/filterable-dropdown/filterable-dropdown.component.html</context>
<context context-type="linenumber">24</context> <context context-type="linenumber">24</context>
</context-group> </context-group>
<target state="needs-translation">Include</target> <target state="translated">Sertakan</target>
</trans-unit> </trans-unit>
<trans-unit id="5668077948386857930" datatype="html"> <trans-unit id="5668077948386857930" datatype="html">
<source>Exclude</source> <source>Exclude</source>
@ -2077,7 +2077,7 @@
<context context-type="sourcefile">src/app/components/common/filterable-dropdown/filterable-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/filterable-dropdown/filterable-dropdown.component.html</context>
<context context-type="linenumber">26</context> <context context-type="linenumber">26</context>
</context-group> </context-group>
<target state="needs-translation">Exclude</target> <target state="translated">Kecuali</target>
</trans-unit> </trans-unit>
<trans-unit id="4391289919356861627" datatype="html"> <trans-unit id="4391289919356861627" datatype="html">
<source>Apply</source> <source>Apply</source>
@ -2093,7 +2093,7 @@
<context context-type="sourcefile">src/app/components/common/filterable-dropdown/filterable-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/filterable-dropdown/filterable-dropdown.component.html</context>
<context context-type="linenumber">46</context> <context context-type="linenumber">46</context>
</context-group> </context-group>
<target state="needs-translation">Click again to exclude items.</target> <target state="translated">Klik lagi untuk mengecualikan barang.</target>
</trans-unit> </trans-unit>
<trans-unit id="7593728289020204896" datatype="html"> <trans-unit id="7593728289020204896" datatype="html">
<source>Not assigned</source> <source>Not assigned</source>
@ -2110,7 +2110,7 @@
<context context-type="sourcefile">src/app/components/common/input/date/date.component.html</context> <context context-type="sourcefile">src/app/components/common/input/date/date.component.html</context>
<context context-type="linenumber">13</context> <context context-type="linenumber">13</context>
</context-group> </context-group>
<target state="needs-translation">Invalid date.</target> <target state="translated">Tanggal tidak valid.</target>
</trans-unit> </trans-unit>
<trans-unit id="524422427194414813" datatype="html"> <trans-unit id="524422427194414813" datatype="html">
<source>Suggestions:</source> <source>Suggestions:</source>
@ -2126,7 +2126,7 @@
<context context-type="sourcefile">src/app/components/common/input/tags/tags.component.html</context> <context context-type="sourcefile">src/app/components/common/input/tags/tags.component.html</context>
<context context-type="linenumber">43</context> <context context-type="linenumber">43</context>
</context-group> </context-group>
<target state="needs-translation">Suggestions:</target> <target state="translated">Saran:</target>
</trans-unit> </trans-unit>
<trans-unit id="594042705136125260" datatype="html"> <trans-unit id="594042705136125260" datatype="html">
<source>Edit Permissions</source> <source>Edit Permissions</source>
@ -2134,7 +2134,7 @@
<context context-type="sourcefile">src/app/components/common/input/permissions/permissions-form/permissions-form.component.html</context> <context context-type="sourcefile">src/app/components/common/input/permissions/permissions-form/permissions-form.component.html</context>
<context context-type="linenumber">7</context> <context context-type="linenumber">7</context>
</context-group> </context-group>
<target state="needs-translation">Edit Permissions</target> <target state="translated">Ubah akses</target>
</trans-unit> </trans-unit>
<trans-unit id="6035283612400841811" datatype="html"> <trans-unit id="6035283612400841811" datatype="html">
<source>Owner:</source> <source>Owner:</source>
@ -2166,7 +2166,7 @@
<context context-type="sourcefile">src/app/components/document-list/document-card-large/document-card-large.component.html</context> <context context-type="sourcefile">src/app/components/document-list/document-card-large/document-card-large.component.html</context>
<context context-type="linenumber">56</context> <context context-type="linenumber">56</context>
</context-group> </context-group>
<target state="needs-translation">View</target> <target state="translated">Lihat</target>
</trans-unit> </trans-unit>
<trans-unit id="2191775412581217688" datatype="html"> <trans-unit id="2191775412581217688" datatype="html">
<source>Users:</source> <source>Users:</source>
@ -2271,7 +2271,7 @@
<context context-type="linenumber">12</context> <context context-type="linenumber">12</context>
</context-group> </context-group>
<note priority="1" from="description">Used for both types, correspondents, storage paths</note> <note priority="1" from="description">Used for both types, correspondents, storage paths</note>
<target state="needs-translation">Add item</target> <target state="translated">Tambah barang</target>
</trans-unit> </trans-unit>
<trans-unit id="3686284950598311784" datatype="html"> <trans-unit id="3686284950598311784" datatype="html">
<source>Private</source> <source>Private</source>
@ -2319,7 +2319,7 @@
<context context-type="sourcefile">src/app/components/common/permissions-select/permissions-select.component.html</context> <context context-type="sourcefile">src/app/components/common/permissions-select/permissions-select.component.html</context>
<context context-type="linenumber">5</context> <context context-type="linenumber">5</context>
</context-group> </context-group>
<target state="needs-translation">Type</target> <target state="translated">Jenis</target>
</trans-unit> </trans-unit>
<trans-unit id="3249513483374643425" datatype="html"> <trans-unit id="3249513483374643425" datatype="html">
<source>Add</source> <source>Add</source>
@ -2327,7 +2327,7 @@
<context context-type="sourcefile">src/app/components/common/permissions-select/permissions-select.component.html</context> <context context-type="sourcefile">src/app/components/common/permissions-select/permissions-select.component.html</context>
<context context-type="linenumber">7</context> <context context-type="linenumber">7</context>
</context-group> </context-group>
<target state="needs-translation">Add</target> <target state="translated">Tambah</target>
</trans-unit> </trans-unit>
<trans-unit id="1230154438678955604" datatype="html"> <trans-unit id="1230154438678955604" datatype="html">
<source>Change</source> <source>Change</source>
@ -2335,7 +2335,7 @@
<context context-type="sourcefile">src/app/components/common/permissions-select/permissions-select.component.html</context> <context context-type="sourcefile">src/app/components/common/permissions-select/permissions-select.component.html</context>
<context context-type="linenumber">8</context> <context context-type="linenumber">8</context>
</context-group> </context-group>
<target state="needs-translation">Change</target> <target state="translated">Ubah</target>
</trans-unit> </trans-unit>
<trans-unit id="187187500641108332" datatype="html"> <trans-unit id="187187500641108332" datatype="html">
<source> <source>
@ -2389,7 +2389,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">36</context> <context context-type="linenumber">36</context>
</context-group> </context-group>
<target state="needs-translation">Hello <x id="PH" equiv-text="this.settingsService.displayName"/>, welcome to Paperless-ngx</target> <target state="translated">Halo <x id="PH" equiv-text="this.settingsService.displayName"/>, selamat datang ke Paperless-ngx</target>
</trans-unit> </trans-unit>
<trans-unit id="5334686081082652461" datatype="html"> <trans-unit id="5334686081082652461" datatype="html">
<source>Welcome to Paperless-ngx</source> <source>Welcome to Paperless-ngx</source>
@ -2397,7 +2397,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">38</context> <context context-type="linenumber">38</context>
</context-group> </context-group>
<target state="needs-translation">Welcome to Paperless-ngx</target> <target state="translated">Selamat datang ke Paperless-ngx</target>
</trans-unit> </trans-unit>
<trans-unit id="2946624699882754313" datatype="html"> <trans-unit id="2946624699882754313" datatype="html">
<source>Show all</source> <source>Show all</source>
@ -2433,7 +2433,7 @@
<context context-type="sourcefile">src/app/services/rest/document.service.ts</context> <context context-type="sourcefile">src/app/services/rest/document.service.ts</context>
<context context-type="linenumber">22</context> <context context-type="linenumber">22</context>
</context-group> </context-group>
<target state="needs-translation">Created</target> <target state="translated">Dibuat</target>
</trans-unit> </trans-unit>
<trans-unit id="5701618810648052610" datatype="html"> <trans-unit id="5701618810648052610" datatype="html">
<source>Title</source> <source>Title</source>
@ -2473,7 +2473,7 @@
<context context-type="sourcefile">src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html</context> <context context-type="sourcefile">src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html</context>
<context context-type="linenumber">4</context> <context context-type="linenumber">4</context>
</context-group> </context-group>
<target state="needs-translation">Go to inbox</target> <target state="translated">Pergi ke kotak masuk</target>
</trans-unit> </trans-unit>
<trans-unit id="3497361602348932709" datatype="html"> <trans-unit id="3497361602348932709" datatype="html">
<source>Documents in inbox</source> <source>Documents in inbox</source>
@ -2481,7 +2481,7 @@
<context context-type="sourcefile">src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html</context> <context context-type="sourcefile">src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html</context>
<context context-type="linenumber">5</context> <context context-type="linenumber">5</context>
</context-group> </context-group>
<target state="needs-translation">Documents in inbox</target> <target state="translated">Dokumen dalam kotak masuk</target>
</trans-unit> </trans-unit>
<trans-unit id="8809281703097241399" datatype="html"> <trans-unit id="8809281703097241399" datatype="html">
<source>Go to documents</source> <source>Go to documents</source>
@ -2489,7 +2489,7 @@
<context context-type="sourcefile">src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html</context> <context context-type="sourcefile">src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html</context>
<context context-type="linenumber">8</context> <context context-type="linenumber">8</context>
</context-group> </context-group>
<target state="needs-translation">Go to documents</target> <target state="translated">Pergi ke dokumen</target>
</trans-unit> </trans-unit>
<trans-unit id="3823413855067727192" datatype="html"> <trans-unit id="3823413855067727192" datatype="html">
<source>Total documents</source> <source>Total documents</source>
@ -2538,7 +2538,7 @@
<context context-type="sourcefile">src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html</context> <context context-type="sourcefile">src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html</context>
<context context-type="linenumber">13</context> <context context-type="linenumber">13</context>
</context-group> </context-group>
<target state="needs-translation">Drop documents here or</target> <target state="translated">Jatuhkan dokumen di sini atau</target>
</trans-unit> </trans-unit>
<trans-unit id="8133800334834354642" datatype="html"> <trans-unit id="8133800334834354642" datatype="html">
<source>Browse files</source> <source>Browse files</source>
@ -2592,7 +2592,7 @@
<context context-type="linenumber">269</context> <context context-type="linenumber">269</context>
</context-group> </context-group>
<note priority="1" from="description">this string is used to separate processing, failed and added on the file upload widget</note> <note priority="1" from="description">this string is used to separate processing, failed and added on the file upload widget</note>
<target state="needs-translation">, </target> <target state="translated">, </target>
</trans-unit> </trans-unit>
<trans-unit id="7915903586014997661" datatype="html"> <trans-unit id="7915903586014997661" datatype="html">
<source>Paperless-ngx is running!</source> <source>Paperless-ngx is running!</source>
@ -2608,7 +2608,7 @@
<context context-type="sourcefile">src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html</context> <context context-type="sourcefile">src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html</context>
<context context-type="linenumber">4</context> <context context-type="linenumber">4</context>
</context-group> </context-group>
<target state="needs-translation">You're ready to start uploading documents! Explore the various features of this web app on your own, or start a quick tour using the button below.</target> <target state="translated">Anda siap untuk mulai mengunggah dokumen! Jelajahi berbagai fitur aplikasi web ini, atau mulai tur singkat menggunakan tombol di bawah ini.</target>
</trans-unit> </trans-unit>
<trans-unit id="4474647174688421179" datatype="html"> <trans-unit id="4474647174688421179" datatype="html">
<source>More detail on how to use and configure Paperless-ngx is always available in the <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://docs.paperless-ngx.com&quot; target=&quot;_blank&quot;&gt;"/>documentation<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</source> <source>More detail on how to use and configure Paperless-ngx is always available in the <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://docs.paperless-ngx.com&quot; target=&quot;_blank&quot;&gt;"/>documentation<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</source>
@ -2616,7 +2616,7 @@
<context context-type="sourcefile">src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html</context> <context context-type="sourcefile">src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html</context>
<context context-type="linenumber">5</context> <context context-type="linenumber">5</context>
</context-group> </context-group>
<target state="needs-translation">More detail on how to use and configure Paperless-ngx is always available in the <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://docs.paperless-ngx.com&quot; target=&quot;_blank&quot;&gt;"/>documentation<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</target> <target state="translated">Detail lebih lanjut tentang cara menggunakan dan mengonfigurasi Paperless-ngx selalu tersedia di <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://docs.paperless-ngx.com&quot; target=&quot;_blank&quot;&gt;"/>dokumentasi<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</target>
</trans-unit> </trans-unit>
<trans-unit id="4294899532887357745" datatype="html"> <trans-unit id="4294899532887357745" datatype="html">
<source>Thanks for being a part of the Paperless-ngx community!</source> <source>Thanks for being a part of the Paperless-ngx community!</source>
@ -2624,7 +2624,7 @@
<context context-type="sourcefile">src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html</context> <context context-type="sourcefile">src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html</context>
<context context-type="linenumber">8</context> <context context-type="linenumber">8</context>
</context-group> </context-group>
<target state="needs-translation">Thanks for being a part of the Paperless-ngx community!</target> <target state="translated">Terima kasih telah menjadi bagian dalam komunitas Paperless-ngx!</target>
</trans-unit> </trans-unit>
<trans-unit id="1415832194529539652" datatype="html"> <trans-unit id="1415832194529539652" datatype="html">
<source>Start the tour</source> <source>Start the tour</source>
@ -2640,7 +2640,7 @@
<context context-type="sourcefile">src/app/components/document-asn/document-asn.component.html</context> <context context-type="sourcefile">src/app/components/document-asn/document-asn.component.html</context>
<context context-type="linenumber">1</context> <context context-type="linenumber">1</context>
</context-group> </context-group>
<target state="needs-translation">Searching document with asn <x id="INTERPOLATION" equiv-text="{{asn}}"/></target> <target state="translated">Mencari dokumen dengan asn <x id="INTERPOLATION" equiv-text="{{asn}}"/></target>
</trans-unit> </trans-unit>
<trans-unit id="1407560924967345762" datatype="html"> <trans-unit id="1407560924967345762" datatype="html">
<source>Page</source> <source>Page</source>
@ -2660,7 +2660,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">5,6</context> <context context-type="linenumber">5,6</context>
</context-group> </context-group>
<target state="needs-translation">of <x id="INTERPOLATION" equiv-text="{{previewNumPages}}"/></target> <target state="translated">dari <x id="INTERPOLATION" equiv-text="{{previewNumPages}}"/></target>
</trans-unit> </trans-unit>
<trans-unit id="3099741642167775297" datatype="html"> <trans-unit id="3099741642167775297" datatype="html">
<source>Download</source> <source>Download</source>
@ -2700,7 +2700,7 @@
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.html</context> <context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.html</context>
<context context-type="linenumber">92</context> <context context-type="linenumber">92</context>
</context-group> </context-group>
<target state="needs-translation">Redo OCR</target> <target state="translated">Lakukan ulang pengenalan karakter</target>
</trans-unit> </trans-unit>
<trans-unit id="1418444397960583910" datatype="html"> <trans-unit id="1418444397960583910" datatype="html">
<source>More like this</source> <source>More like this</source>
@ -2712,7 +2712,7 @@
<context context-type="sourcefile">src/app/components/document-list/document-card-large/document-card-large.component.html</context> <context context-type="sourcefile">src/app/components/document-list/document-card-large/document-card-large.component.html</context>
<context context-type="linenumber">44</context> <context context-type="linenumber">44</context>
</context-group> </context-group>
<target state="needs-translation">More like this</target> <target state="translated">Lebih seperti ini</target>
</trans-unit> </trans-unit>
<trans-unit id="7819314041543176992" datatype="html"> <trans-unit id="7819314041543176992" datatype="html">
<source>Close</source> <source>Close</source>
@ -2748,7 +2748,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">76</context> <context context-type="linenumber">76</context>
</context-group> </context-group>
<target state="needs-translation">Archive serial number</target> <target state="translated">Nomor serial arsip</target>
</trans-unit> </trans-unit>
<trans-unit id="5114742157723900905" datatype="html"> <trans-unit id="5114742157723900905" datatype="html">
<source>Date created</source> <source>Date created</source>
@ -2780,7 +2780,7 @@
<context context-type="sourcefile">src/app/services/rest/document.service.ts</context> <context context-type="sourcefile">src/app/services/rest/document.service.ts</context>
<context context-type="linenumber">19</context> <context context-type="linenumber">19</context>
</context-group> </context-group>
<target state="needs-translation">Correspondent</target> <target state="translated">Koresponden</target>
</trans-unit> </trans-unit>
<trans-unit id="5066119607229701477" datatype="html"> <trans-unit id="5066119607229701477" datatype="html">
<source>Document type</source> <source>Document type</source>
@ -2804,7 +2804,7 @@
<context context-type="sourcefile">src/app/services/rest/document.service.ts</context> <context context-type="sourcefile">src/app/services/rest/document.service.ts</context>
<context context-type="linenumber">21</context> <context context-type="linenumber">21</context>
</context-group> </context-group>
<target state="needs-translation">Document type</target> <target state="translated">Jenis dokumen</target>
</trans-unit> </trans-unit>
<trans-unit id="2091353339965748767" datatype="html"> <trans-unit id="2091353339965748767" datatype="html">
<source>Storage path</source> <source>Storage path</source>
@ -2824,7 +2824,7 @@
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.html</context> <context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.html</context>
<context context-type="linenumber">52</context> <context context-type="linenumber">52</context>
</context-group> </context-group>
<target state="needs-translation">Storage path</target> <target state="translated">Lokasi penyimpanan</target>
</trans-unit> </trans-unit>
<trans-unit id="5607669932062416162" datatype="html"> <trans-unit id="5607669932062416162" datatype="html">
<source>Default</source> <source>Default</source>
@ -2852,7 +2852,7 @@
<context context-type="sourcefile">src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts</context>
<context context-type="linenumber">17</context> <context context-type="linenumber">17</context>
</context-group> </context-group>
<target state="needs-translation">Metadata</target> <target state="translated">Metadata</target>
</trans-unit> </trans-unit>
<trans-unit id="1826652001816486190" datatype="html"> <trans-unit id="1826652001816486190" datatype="html">
<source>Date modified</source> <source>Date modified</source>
@ -2924,7 +2924,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">138</context> <context context-type="linenumber">138</context>
</context-group> </context-group>
<target state="needs-translation">Archive file size</target> <target state="translated">Ukuran file arsip</target>
</trans-unit> </trans-unit>
<trans-unit id="6992781481378431874" datatype="html"> <trans-unit id="6992781481378431874" datatype="html">
<source>Original document metadata</source> <source>Original document metadata</source>
@ -2948,7 +2948,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">151</context> <context context-type="linenumber">151</context>
</context-group> </context-group>
<target state="needs-translation">Preview</target> <target state="translated">Pratinjau</target>
</trans-unit> </trans-unit>
<trans-unit id="8191371354890763172" datatype="html"> <trans-unit id="8191371354890763172" datatype="html">
<source>Enter Password</source> <source>Enter Password</source>
@ -2960,7 +2960,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">215</context> <context context-type="linenumber">215</context>
</context-group> </context-group>
<target state="needs-translation">Enter Password</target> <target state="translated">Masukan Kata Sandi</target>
</trans-unit> </trans-unit>
<trans-unit id="8460995830263484763" datatype="html"> <trans-unit id="8460995830263484763" datatype="html">
<source>Notes <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span *ngIf=&quot;document?.notes.length&quot; class=&quot;badge text-bg-secondary ms-1&quot;&gt;"/><x id="INTERPOLATION" equiv-text="ngth}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/a&gt;"/></source> <source>Notes <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span *ngIf=&quot;document?.notes.length&quot; class=&quot;badge text-bg-secondary ms-1&quot;&gt;"/><x id="INTERPOLATION" equiv-text="ngth}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/a&gt;"/></source>
@ -2976,7 +2976,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">194</context> <context context-type="linenumber">194</context>
</context-group> </context-group>
<target state="needs-translation">Discard</target> <target state="translated">Batalkan</target>
</trans-unit> </trans-unit>
<trans-unit id="5129524307369213584" datatype="html"> <trans-unit id="5129524307369213584" datatype="html">
<source>Save &amp; next</source> <source>Save &amp; next</source>
@ -2984,7 +2984,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">195</context> <context context-type="linenumber">195</context>
</context-group> </context-group>
<target state="needs-translation">Save &amp; next</target> <target state="translated">Simpan &amp; lanjut</target>
</trans-unit> </trans-unit>
<trans-unit id="2218903673684131427" datatype="html"> <trans-unit id="2218903673684131427" datatype="html">
<source>An error occurred loading content: <x id="PH" equiv-text="err.message ?? err.toString()"/></source> <source>An error occurred loading content: <x id="PH" equiv-text="err.message ?? err.toString()"/></source>
@ -2992,7 +2992,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">226,228</context> <context context-type="linenumber">226,228</context>
</context-group> </context-group>
<target state="needs-translation">An error occurred loading content: <x id="PH" equiv-text="err.message ?? err.toString()"/></target> <target state="translated">Terjadi masalah saat memuat konten: <x id="PH" equiv-text="err.message ?? err.toString()"/></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>
@ -3000,7 +3000,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">354</context> <context context-type="linenumber">354</context>
</context-group> </context-group>
<target state="needs-translation">Error retrieving metadata</target> <target state="translated">Kesalahan saat mendapatkan metadata</target>
</trans-unit> </trans-unit>
<trans-unit id="2374084708811774419" datatype="html"> <trans-unit id="2374084708811774419" datatype="html">
<source>Error retrieving suggestions</source> <source>Error retrieving suggestions</source>
@ -3032,7 +3032,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">542</context> <context context-type="linenumber">542</context>
</context-group> </context-group>
<target state="needs-translation">Error saving document</target> <target state="translated">Kesalahan saat menyimpan dokumen</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>
@ -3044,7 +3044,7 @@
<context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.ts</context> <context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.ts</context>
<context context-type="linenumber">210</context> <context context-type="linenumber">210</context>
</context-group> </context-group>
<target state="needs-translation">Confirm delete</target> <target state="translated">Konfirmasi hapus</target>
</trans-unit> </trans-unit>
<trans-unit id="5382975254277698192" datatype="html"> <trans-unit id="5382975254277698192" datatype="html">
<source>Do you really want to delete document &quot;<x id="PH" equiv-text="this.document.title"/>&quot;?</source> <source>Do you really want to delete document &quot;<x id="PH" equiv-text="this.document.title"/>&quot;?</source>
@ -3052,7 +3052,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">572</context> <context context-type="linenumber">572</context>
</context-group> </context-group>
<target state="needs-translation">Do you really want to delete document "<x id="PH" equiv-text="this.document.title"/>"?</target> <target state="translated">Apakah Anda yakin ingin menghapus dokumen "<x id="PH" equiv-text="this.document.title"/>"?</target>
</trans-unit> </trans-unit>
<trans-unit id="6691075929777935948" datatype="html"> <trans-unit id="6691075929777935948" datatype="html">
<source>The files for this document will be deleted permanently. This operation cannot be undone.</source> <source>The files for this document will be deleted permanently. This operation cannot be undone.</source>
@ -3060,7 +3060,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">573</context> <context context-type="linenumber">573</context>
</context-group> </context-group>
<target state="needs-translation">The files for this document will be deleted permanently. This operation cannot be undone.</target> <target state="translated">File untuk dokumen akan dihapus secara permanen. Operasi ini tidak dapat diurungkan.</target>
</trans-unit> </trans-unit>
<trans-unit id="719892092227206532" datatype="html"> <trans-unit id="719892092227206532" datatype="html">
<source>Delete document</source> <source>Delete document</source>
@ -3076,7 +3076,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">595,597</context> <context context-type="linenumber">595,597</context>
</context-group> </context-group>
<target state="needs-translation">Error deleting document: <x id="PH" equiv-text="error.error?.detail ?? error.message ?? JSON.stringify(error)"/></target> <target state="translated">Kesalahan saat menghapus dokumen: <x id="PH" equiv-text="error.error?.detail ?? error.message ?? JSON.stringify(error)"/></target>
</trans-unit> </trans-unit>
<trans-unit id="7362691899087997122" datatype="html"> <trans-unit id="7362691899087997122" datatype="html">
<source>Redo OCR confirm</source> <source>Redo OCR confirm</source>
@ -3172,7 +3172,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">641,643</context> <context context-type="linenumber">641,643</context>
</context-group> </context-group>
<target state="needs-translation">Error executing operation: <x id="PH" equiv-text="JSON.stringify( error.error )"/></target> <target state="translated">Kesalahan menjalankan operasi: <x id="PH" equiv-text="JSON.stringify( error.error )"/></target>
</trans-unit> </trans-unit>
<trans-unit id="6857598786757174736" datatype="html"> <trans-unit id="6857598786757174736" datatype="html">
<source>Select:</source> <source>Select:</source>
@ -4474,7 +4474,7 @@
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context>
<context context-type="linenumber">72</context> <context context-type="linenumber">72</context>
</context-group> </context-group>
<target state="needs-translation">Items per page</target> <target state="translated">Barang per halaman</target>
</trans-unit> </trans-unit>
<trans-unit id="8028535997917730106" datatype="html"> <trans-unit id="8028535997917730106" datatype="html">
<source>Document editor</source> <source>Document editor</source>

View File

@ -1825,7 +1825,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts</context>
<context context-type="linenumber">90</context> <context context-type="linenumber">90</context>
</context-group> </context-group>
<target state="needs-translation">Use mail address</target> <target state="translated">Użyj adresu e-mail</target>
</trans-unit> </trans-unit>
<trans-unit id="445154175758965852" datatype="html"> <trans-unit id="445154175758965852" datatype="html">
<source>Use name (or mail address if not available)</source> <source>Use name (or mail address if not available)</source>

View File

@ -789,7 +789,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">224,226</context> <context context-type="linenumber">224,226</context>
</context-group> </context-group>
<target state="translated"> Como é que isso funciona? </target> <target state="translated"> Como isto funciona? </target>
</trans-unit> </trans-unit>
<trans-unit id="509090351011426949" datatype="html"> <trans-unit id="509090351011426949" datatype="html">
<source>Update available</source> <source>Update available</source>

View File

@ -5719,7 +5719,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">213</context> <context context-type="linenumber">213</context>
</context-group> </context-group>
<target state="needs-translation">Finnish</target> <target state="translated">Finski</target>
</trans-unit> </trans-unit>
<trans-unit id="7633754075223722162" datatype="html"> <trans-unit id="7633754075223722162" datatype="html">
<source>French</source> <source>French</source>

View File

@ -225,15 +225,19 @@ class DelayedQuery:
user_criterias = [query.Term("has_owner", False)] user_criterias = [query.Term("has_owner", False)]
if "user" in self.query_params: if "user" in self.query_params:
user_criterias.append(query.Term("owner_id", self.query_params["user"])) if self.query_params["is_superuser"]: # superusers see all docs
user_criterias.append( user_criterias = []
query.Term("viewer_id", str(self.query_params["user"])), else:
) user_criterias.append(query.Term("owner_id", self.query_params["user"]))
user_criterias.append(
query.Term("viewer_id", str(self.query_params["user"])),
)
if len(criterias) > 0: if len(criterias) > 0:
criterias.append(query.Or(user_criterias)) if len(user_criterias) > 0:
criterias.append(query.Or(user_criterias))
return query.And(criterias) return query.And(criterias)
else: else:
return query.Or(user_criterias) return query.Or(user_criterias) if len(user_criterias) > 0 else None
def _get_query_sortedby(self): def _get_query_sortedby(self):
if "ordering" not in self.query_params: if "ordering" not in self.query_params:

View File

@ -10,8 +10,8 @@ from documents.models import Document
from documents.parsers import get_parser_class_for_mime_type from documents.parsers import get_parser_class_for_mime_type
def _process_document(doc_in): def _process_document(doc_id):
document: Document = Document.objects.get(id=doc_in) document: Document = Document.objects.get(id=doc_id)
parser_class = get_parser_class_for_mime_type(document.mime_type) parser_class = get_parser_class_for_mime_type(document.mime_type)
if parser_class: if parser_class:

View File

@ -429,12 +429,12 @@ def update_filename_and_move_files(sender, instance: Document, **kwargs):
if move_original: if move_original:
validate_move(instance, old_source_path, instance.source_path) validate_move(instance, old_source_path, instance.source_path)
create_source_path_directory(instance.source_path) create_source_path_directory(instance.source_path)
os.rename(old_source_path, instance.source_path) shutil.move(old_source_path, instance.source_path)
if move_archive: if move_archive:
validate_move(instance, old_archive_path, instance.archive_path) validate_move(instance, old_archive_path, instance.archive_path)
create_source_path_directory(instance.archive_path) create_source_path_directory(instance.archive_path)
os.rename(old_archive_path, instance.archive_path) shutil.move(old_archive_path, instance.archive_path)
# Don't save() here to prevent infinite recursion. # Don't save() here to prevent infinite recursion.
Document.objects.filter(pk=instance.pk).update( Document.objects.filter(pk=instance.pk).update(
@ -453,11 +453,11 @@ def update_filename_and_move_files(sender, instance: Document, **kwargs):
try: try:
if move_original and os.path.isfile(instance.source_path): if move_original and os.path.isfile(instance.source_path):
logger.info("Restoring previous original path") logger.info("Restoring previous original path")
os.rename(instance.source_path, old_source_path) shutil.move(instance.source_path, old_source_path)
if move_archive and os.path.isfile(instance.archive_path): if move_archive and os.path.isfile(instance.archive_path):
logger.info("Restoring previous archive path") logger.info("Restoring previous archive path")
os.rename(instance.archive_path, old_archive_path) shutil.move(instance.archive_path, old_archive_path)
except Exception: except Exception:
# This is fine, since: # This is fine, since:

View File

@ -27,6 +27,7 @@ from django.contrib.auth.models import Permission
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.test import override_settings from django.test import override_settings
from django.utils import timezone from django.utils import timezone
from guardian.shortcuts import assign_perm
from rest_framework import status from rest_framework import status
from rest_framework.test import APITestCase from rest_framework.test import APITestCase
from whoosh.writing import AsyncWriter from whoosh.writing import AsyncWriter
@ -253,8 +254,6 @@ class TestDocumentApi(DirectoriesMixin, DocumentConsumeDelayMixin, APITestCase):
response = self.client.get(f"/api/documents/{doc.pk}/thumb/") response = self.client.get(f"/api/documents/{doc.pk}/thumb/")
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
from guardian.shortcuts import assign_perm
assign_perm("view_document", user2, doc) assign_perm("view_document", user2, doc)
response = self.client.get(f"/api/documents/{doc.pk}/download/") response = self.client.get(f"/api/documents/{doc.pk}/download/")
@ -1064,6 +1063,92 @@ class TestDocumentApi(DirectoriesMixin, DocumentConsumeDelayMixin, APITestCase):
), ),
) )
def test_search_filtering_respect_owner(self):
"""
GIVEN:
- Documents with owners set & without
WHEN:
- API reuqest for advanced query (search) is made by non-superuser
- API reuqest for advanced query (search) is made by superuser
THEN:
- Only owned docs are returned for regular users
- All docs are returned for superuser
"""
superuser = User.objects.create_superuser("superuser")
u1 = User.objects.create_user("user1")
u2 = User.objects.create_user("user2")
u1.user_permissions.add(*Permission.objects.filter(codename="view_document"))
u2.user_permissions.add(*Permission.objects.filter(codename="view_document"))
Document.objects.create(checksum="1", content="test 1", owner=u1)
Document.objects.create(checksum="2", content="test 2", owner=u2)
Document.objects.create(checksum="3", content="test 3", owner=u2)
Document.objects.create(checksum="4", content="test 4")
with AsyncWriter(index.open_index()) as writer:
for doc in Document.objects.all():
index.update_document(writer, doc)
self.client.force_authenticate(user=u1)
r = self.client.get("/api/documents/?query=test")
self.assertEqual(r.data["count"], 2)
r = self.client.get("/api/documents/?query=test&document_type__id__none=1")
self.assertEqual(r.data["count"], 2)
self.client.force_authenticate(user=u2)
r = self.client.get("/api/documents/?query=test")
self.assertEqual(r.data["count"], 3)
r = self.client.get("/api/documents/?query=test&document_type__id__none=1")
self.assertEqual(r.data["count"], 3)
self.client.force_authenticate(user=superuser)
r = self.client.get("/api/documents/?query=test")
self.assertEqual(r.data["count"], 4)
r = self.client.get("/api/documents/?query=test&document_type__id__none=1")
self.assertEqual(r.data["count"], 4)
def test_search_filtering_with_object_perms(self):
"""
GIVEN:
- Documents with granted view permissions to others
WHEN:
- API reuqest for advanced query (search) is made by user
THEN:
- Only docs with granted view permissions are returned
"""
u1 = User.objects.create_user("user1")
u2 = User.objects.create_user("user2")
u1.user_permissions.add(*Permission.objects.filter(codename="view_document"))
u2.user_permissions.add(*Permission.objects.filter(codename="view_document"))
Document.objects.create(checksum="1", content="test 1", owner=u1)
d2 = Document.objects.create(checksum="2", content="test 2", owner=u2)
d3 = Document.objects.create(checksum="3", content="test 3", owner=u2)
Document.objects.create(checksum="4", content="test 4")
with AsyncWriter(index.open_index()) as writer:
for doc in Document.objects.all():
index.update_document(writer, doc)
self.client.force_authenticate(user=u1)
r = self.client.get("/api/documents/?query=test")
self.assertEqual(r.data["count"], 2)
r = self.client.get("/api/documents/?query=test&document_type__id__none=1")
self.assertEqual(r.data["count"], 2)
assign_perm("view_document", u1, d2)
assign_perm("view_document", u1, d3)
with AsyncWriter(index.open_index()) as writer:
for doc in [d2, d3]:
index.update_document(writer, doc)
self.client.force_authenticate(user=u1)
r = self.client.get("/api/documents/?query=test")
self.assertEqual(r.data["count"], 4)
r = self.client.get("/api/documents/?query=test&document_type__id__none=1")
self.assertEqual(r.data["count"], 4)
def test_search_sorting(self): def test_search_sorting(self):
c1 = Correspondent.objects.create(name="corres Ax") c1 = Correspondent.objects.create(name="corres Ax")
c2 = Correspondent.objects.create(name="corres Cx") c2 = Correspondent.objects.create(name="corres Cx")

View File

@ -697,7 +697,7 @@ class TestFileHandlingWithArchive(DirectoriesMixin, FileSystemAssertsMixin, Test
self.assertIsFile(doc.archive_path) self.assertIsFile(doc.archive_path)
@override_settings(FILENAME_FORMAT="{correspondent}/{title}") @override_settings(FILENAME_FORMAT="{correspondent}/{title}")
@mock.patch("documents.signals.handlers.os.rename") @mock.patch("documents.signals.handlers.shutil.move")
def test_move_archive_error(self, m): def test_move_archive_error(self, m):
def fake_rename(src, dst): def fake_rename(src, dst):
if "archive" in str(src): if "archive" in str(src):
@ -748,7 +748,7 @@ class TestFileHandlingWithArchive(DirectoriesMixin, FileSystemAssertsMixin, Test
self.assertIsFile(doc.archive_path) self.assertIsFile(doc.archive_path)
@override_settings(FILENAME_FORMAT="{correspondent}/{title}") @override_settings(FILENAME_FORMAT="{correspondent}/{title}")
@mock.patch("documents.signals.handlers.os.rename") @mock.patch("documents.signals.handlers.shutil.move")
def test_move_file_error(self, m): def test_move_file_error(self, m):
def fake_rename(src, dst): def fake_rename(src, dst):
if "original" in str(src): if "original" in str(src):

View File

@ -47,12 +47,16 @@ class TestMakeThumbnails(DirectoriesMixin, FileSystemAssertsMixin, TestCase):
self.assertIsFile(self.d1.thumbnail_path) self.assertIsFile(self.d1.thumbnail_path)
@mock.patch("documents.management.commands.document_thumbnails.shutil.move") @mock.patch("documents.management.commands.document_thumbnails.shutil.move")
def test_process_document_invalid_mime_type(self, m): def test_process_document_invalid_mime_type(self, m: mock.Mock):
self.d1.mime_type = "asdasdasd" self.d1.mime_type = "asdasdasd"
self.d1.save() self.d1.save()
# .save() triggers filename handling
m.reset_mock()
_process_document(self.d1.id) _process_document(self.d1.id)
# Not called during processing of document
m.assert_not_called() m.assert_not_called()
def test_command(self): def test_command(self):

View File

@ -604,6 +604,9 @@ class UnifiedSearchViewSet(DocumentViewSet):
# pass user to query for perms # pass user to query for perms
self.request.query_params._mutable = True self.request.query_params._mutable = True
self.request.query_params["user"] = self.request.user.id self.request.query_params["user"] = self.request.user.id
self.request.query_params[
"is_superuser"
] = self.request.user.is_superuser
self.request.query_params._mutable = False self.request.query_params._mutable = False
if "query" in self.request.query_params: if "query" in self.request.query_params:

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: 2023-03-03 19:15+0000\n" "POT-Creation-Date: 2023-03-03 19:15+0000\n"
"PO-Revision-Date: 2023-03-07 19:40\n" "PO-Revision-Date: 2023-05-01 13:00\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: Arabic\n" "Language-Team: Arabic\n"
"Language: ar_SA\n" "Language: ar_SA\n"
@ -420,7 +420,7 @@ msgstr "اسم ملف المهمة"
#: documents/models.py:577 #: documents/models.py:577
msgid "Name of the file which the Task was run for" msgid "Name of the file which the Task was run for"
msgstr "اسم الملف الذي وكل بالمهمة" msgstr "اسم المِلَفّ الذي وكل بالمهمة"
#: documents/models.py:583 #: documents/models.py:583
msgid "Task Name" msgid "Task Name"
@ -670,7 +670,7 @@ msgstr "إجراءات"
#: paperless_mail/admin.py:69 #: paperless_mail/admin.py:69
msgid "The action applied to the mail. This action is only performed when the mail body or attachments were consumed from the mail." msgid "The action applied to the mail. This action is only performed when the mail body or attachments were consumed from the mail."
msgstr "الإجراء المطبق على البريد. يتم تنفيذ هذا الإجراء فقط عندما يتم إستهلاك البريد أو المرفقات من البريد." msgstr "الإجراء المطبق على البريد. يتم تنفيذ هذا الإجراء فقط عندما يتم أستهلاك البريد أو المرفقات من البريد."
#: paperless_mail/admin.py:77 #: paperless_mail/admin.py:77
msgid "Metadata" msgid "Metadata"
@ -834,11 +834,11 @@ msgstr "تصفية الجسم"
#: paperless_mail/models.py:130 #: paperless_mail/models.py:130
msgid "filter attachment filename" msgid "filter attachment filename"
msgstr "تصفية اسم الملف المرفق" msgstr "تصفية اسم المِلَفّ المرفق"
#: paperless_mail/models.py:135 #: paperless_mail/models.py:135
msgid "Only consume documents which entirely match this filename if specified. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive." msgid "Only consume documents which entirely match this filename if specified. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive."
msgstr "فقط المستندات التي تتطابق تماما مع اسم هذا الملف إذا تم تحديدها. المحارف البديلة مثل *.pdf أو *الفواتير* مسموح بها. لأنها غير حساسة." msgstr "فقط المستندات التي تتطابق تماما مع اسم هذا المِلَفّ إذا تم تحديدها. المحارف البديلة مثل *.pdf أو *الفواتير* مسموح بها. لأنها غير حساسة."
#: paperless_mail/models.py:142 #: paperless_mail/models.py:142
msgid "maximum age" msgid "maximum age"

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: 2023-03-03 19:15+0000\n" "POT-Creation-Date: 2023-03-03 19:15+0000\n"
"PO-Revision-Date: 2023-04-20 13:20\n" "PO-Revision-Date: 2023-04-28 09:40\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: Indonesian\n" "Language-Team: Indonesian\n"
"Language: id_ID\n" "Language: id_ID\n"
@ -212,7 +212,7 @@ msgstr "dokumen"
#: documents/models.py:269 #: documents/models.py:269
msgid "documents" msgid "documents"
msgstr "" msgstr "dokumen"
#: documents/models.py:359 #: documents/models.py:359
msgid "debug" msgid "debug"
@ -224,7 +224,7 @@ msgstr "informasi"
#: documents/models.py:361 #: documents/models.py:361
msgid "warning" msgid "warning"
msgstr "" msgstr "peringatan"
#: documents/models.py:362 paperless_mail/models.py:276 #: documents/models.py:362 paperless_mail/models.py:276
msgid "error" msgid "error"
@ -232,7 +232,7 @@ msgstr "kesalahan"
#: documents/models.py:363 #: documents/models.py:363
msgid "critical" msgid "critical"
msgstr "" msgstr "kritis"
#: documents/models.py:366 #: documents/models.py:366
msgid "group" msgid "group"
@ -244,7 +244,7 @@ msgstr "pesan"
#: documents/models.py:371 #: documents/models.py:371
msgid "level" msgid "level"
msgstr "" msgstr "tingkat"
#: documents/models.py:380 #: documents/models.py:380
msgid "log" msgid "log"
@ -276,15 +276,15 @@ msgstr ""
#: documents/models.py:409 #: documents/models.py:409
msgid "sort reverse" msgid "sort reverse"
msgstr "" msgstr "urutkan terbalik"
#: documents/models.py:414 #: documents/models.py:414
msgid "title contains" msgid "title contains"
msgstr "" msgstr "judul memiliki"
#: documents/models.py:415 #: documents/models.py:415
msgid "content contains" msgid "content contains"
msgstr "" msgstr "konten memiliki"
#: documents/models.py:416 #: documents/models.py:416
msgid "ASN is" msgid "ASN is"
@ -300,7 +300,7 @@ msgstr ""
#: documents/models.py:419 #: documents/models.py:419
msgid "is in inbox" msgid "is in inbox"
msgstr "" msgstr "di dalam kotak masuk"
#: documents/models.py:420 #: documents/models.py:420
msgid "has tag" msgid "has tag"
@ -380,11 +380,11 @@ msgstr ""
#: documents/models.py:439 #: documents/models.py:439
msgid "storage path is" msgid "storage path is"
msgstr "" msgstr "lokasi penyimpanan"
#: documents/models.py:449 #: documents/models.py:449
msgid "rule type" msgid "rule type"
msgstr "" msgstr "jenis peraturan"
#: documents/models.py:451 #: documents/models.py:451
msgid "value" msgid "value"
@ -392,15 +392,15 @@ msgstr "nilai"
#: documents/models.py:454 #: documents/models.py:454
msgid "filter rule" msgid "filter rule"
msgstr "" msgstr "saring aturan"
#: documents/models.py:455 #: documents/models.py:455
msgid "filter rules" msgid "filter rules"
msgstr "" msgstr "saring aturan"
#: documents/models.py:563 #: documents/models.py:563
msgid "Task ID" msgid "Task ID"
msgstr "" msgstr "ID Tugas"
#: documents/models.py:564 #: documents/models.py:564
msgid "Celery ID for the Task that was run" msgid "Celery ID for the Task that was run"
@ -432,11 +432,11 @@ msgstr ""
#: documents/models.py:591 #: documents/models.py:591
msgid "Task State" msgid "Task State"
msgstr "" msgstr "Status Tugas"
#: documents/models.py:592 #: documents/models.py:592
msgid "Current state of the task being run" msgid "Current state of the task being run"
msgstr "" msgstr "Status tugas sekarang yang sedang dijalankan"
#: documents/models.py:597 #: documents/models.py:597
msgid "Created DateTime" msgid "Created DateTime"
@ -464,53 +464,53 @@ msgstr ""
#: documents/models.py:615 #: documents/models.py:615
msgid "Result Data" msgid "Result Data"
msgstr "" msgstr "Data Hasil"
#: documents/models.py:617 #: documents/models.py:617
msgid "The data returned by the task" msgid "The data returned by the task"
msgstr "" msgstr "Data yang dikembalikan dari tugas"
#: documents/models.py:626 #: documents/models.py:626
msgid "Comment for the document" msgid "Comment for the document"
msgstr "" msgstr "Komentar pada dokumen"
#: documents/models.py:650 #: documents/models.py:650
msgid "user" msgid "user"
msgstr "" msgstr "pengguna"
#: documents/models.py:655 #: documents/models.py:655
msgid "comment" msgid "comment"
msgstr "" msgstr "komentar"
#: documents/models.py:656 #: documents/models.py:656
msgid "comments" msgid "comments"
msgstr "" msgstr "komentar"
#: documents/serialisers.py:80 #: documents/serialisers.py:80
#, python-format #, python-format
msgid "Invalid regular expression: %(error)s" msgid "Invalid regular expression: %(error)s"
msgstr "" msgstr "Ekspresi reguler tidak valid: %(error)s"
#: documents/serialisers.py:320 #: documents/serialisers.py:320
msgid "Invalid color." msgid "Invalid color."
msgstr "" msgstr "Warna tidak valid."
#: documents/serialisers.py:700 #: documents/serialisers.py:700
#, python-format #, python-format
msgid "File type %(type)s not supported" msgid "File type %(type)s not supported"
msgstr "" msgstr "Jenis file %(type)s tidak didukung"
#: documents/serialisers.py:794 #: documents/serialisers.py:794
msgid "Invalid variable detected." msgid "Invalid variable detected."
msgstr "" msgstr "Variabel ilegal terdeteksi."
#: documents/templates/index.html:78 #: documents/templates/index.html:78
msgid "Paperless-ngx is loading..." msgid "Paperless-ngx is loading..."
msgstr "" msgstr "Paperless-ngx sedang memuat..."
#: documents/templates/index.html:79 #: documents/templates/index.html:79
msgid "Still here?! Hmm, something might be wrong." msgid "Still here?! Hmm, something might be wrong."
msgstr "" msgstr "Masih disini?! Hmm, sepertinya ada yang salah."
#: documents/templates/index.html:79 #: documents/templates/index.html:79
msgid "Here's a link to the docs." msgid "Here's a link to the docs."
@ -526,7 +526,7 @@ msgstr ""
#: documents/templates/registration/logged_out.html:60 #: documents/templates/registration/logged_out.html:60
msgid "Sign in again" msgid "Sign in again"
msgstr "" msgstr "Masuk lagi"
#: documents/templates/registration/login.html:15 #: documents/templates/registration/login.html:15
msgid "Paperless-ngx sign in" msgid "Paperless-ngx sign in"
@ -534,23 +534,23 @@ msgstr ""
#: documents/templates/registration/login.html:61 #: documents/templates/registration/login.html:61
msgid "Please sign in." msgid "Please sign in."
msgstr "" msgstr "Mohon masuk."
#: documents/templates/registration/login.html:64 #: documents/templates/registration/login.html:64
msgid "Your username and password didn't match. Please try again." msgid "Your username and password didn't match. Please try again."
msgstr "" msgstr "Nama pengguna dan sandi tidak cocok. Silahkan coba kembali."
#: documents/templates/registration/login.html:67 #: documents/templates/registration/login.html:67
msgid "Username" msgid "Username"
msgstr "" msgstr "Nama pengguna"
#: documents/templates/registration/login.html:68 #: documents/templates/registration/login.html:68
msgid "Password" msgid "Password"
msgstr "" msgstr "Kata sandi"
#: documents/templates/registration/login.html:73 #: documents/templates/registration/login.html:73
msgid "Sign in" msgid "Sign in"
msgstr "" msgstr "Masuk"
#: paperless/apps.py:9 #: paperless/apps.py:9
msgid "Paperless" msgid "Paperless"
@ -558,15 +558,15 @@ msgstr ""
#: paperless/settings.py:521 #: paperless/settings.py:521
msgid "English (US)" msgid "English (US)"
msgstr "" msgstr "Inggris (AS)"
#: paperless/settings.py:522 #: paperless/settings.py:522
msgid "Arabic" msgid "Arabic"
msgstr "" msgstr "Arab"
#: paperless/settings.py:523 #: paperless/settings.py:523
msgid "Belarusian" msgid "Belarusian"
msgstr "" msgstr "Belarusia"
#: paperless/settings.py:524 #: paperless/settings.py:524
msgid "Czech" msgid "Czech"
@ -582,11 +582,11 @@ msgstr ""
#: paperless/settings.py:527 #: paperless/settings.py:527
msgid "English (GB)" msgid "English (GB)"
msgstr "" msgstr "Inggris (GB)"
#: paperless/settings.py:528 #: paperless/settings.py:528
msgid "Spanish" msgid "Spanish"
msgstr "" msgstr "Spanyol"
#: paperless/settings.py:529 #: paperless/settings.py:529
msgid "French" msgid "French"
@ -602,71 +602,71 @@ msgstr ""
#: paperless/settings.py:532 #: paperless/settings.py:532
msgid "Dutch" msgid "Dutch"
msgstr "" msgstr "Belanda"
#: paperless/settings.py:533 #: paperless/settings.py:533
msgid "Polish" msgid "Polish"
msgstr "" msgstr "Polandia"
#: paperless/settings.py:534 #: paperless/settings.py:534
msgid "Portuguese (Brazil)" msgid "Portuguese (Brazil)"
msgstr "" msgstr "Portugis (Brasil)"
#: paperless/settings.py:535 #: paperless/settings.py:535
msgid "Portuguese" msgid "Portuguese"
msgstr "" msgstr "Portugis"
#: paperless/settings.py:536 #: paperless/settings.py:536
msgid "Romanian" msgid "Romanian"
msgstr "" msgstr "Rumania"
#: paperless/settings.py:537 #: paperless/settings.py:537
msgid "Russian" msgid "Russian"
msgstr "" msgstr "Rusia"
#: paperless/settings.py:538 #: paperless/settings.py:538
msgid "Slovenian" msgid "Slovenian"
msgstr "" msgstr "Slovenia"
#: paperless/settings.py:539 #: paperless/settings.py:539
msgid "Serbian" msgid "Serbian"
msgstr "" msgstr "Serbia"
#: paperless/settings.py:540 #: paperless/settings.py:540
msgid "Swedish" msgid "Swedish"
msgstr "" msgstr "Swedia"
#: paperless/settings.py:541 #: paperless/settings.py:541
msgid "Turkish" msgid "Turkish"
msgstr "" msgstr "Turki"
#: paperless/settings.py:542 #: paperless/settings.py:542
msgid "Chinese Simplified" msgid "Chinese Simplified"
msgstr "" msgstr "Mandarin Sederhana"
#: paperless/urls.py:169 #: paperless/urls.py:169
msgid "Paperless-ngx administration" msgid "Paperless-ngx administration"
msgstr "" msgstr "Administrasi Paperless-ngx"
#: paperless_mail/admin.py:30 #: paperless_mail/admin.py:30
msgid "Authentication" msgid "Authentication"
msgstr "" msgstr "Autentikasi"
#: paperless_mail/admin.py:31 #: paperless_mail/admin.py:31
msgid "Advanced settings" msgid "Advanced settings"
msgstr "" msgstr "Pengaturan lanjutan"
#: paperless_mail/admin.py:48 #: paperless_mail/admin.py:48
msgid "Filter" msgid "Filter"
msgstr "" msgstr "Saring"
#: paperless_mail/admin.py:51 #: paperless_mail/admin.py:51
msgid "Paperless will only process mails that match ALL of the filters given below." msgid "Paperless will only process mails that match ALL of the filters given below."
msgstr "" msgstr "Paperless hanya akan memproses SEMUA surat yang cocok dengan filter yang diberikan."
#: paperless_mail/admin.py:66 #: paperless_mail/admin.py:66
msgid "Actions" msgid "Actions"
msgstr "" msgstr "Aksi"
#: paperless_mail/admin.py:69 #: paperless_mail/admin.py:69
msgid "The action applied to the mail. This action is only performed when the mail body or attachments were consumed from the mail." msgid "The action applied to the mail. This action is only performed when the mail body or attachments were consumed from the mail."
@ -682,35 +682,35 @@ msgstr ""
#: paperless_mail/apps.py:10 #: paperless_mail/apps.py:10
msgid "Paperless mail" msgid "Paperless mail"
msgstr "" msgstr "Surat Paperless"
#: paperless_mail/models.py:9 #: paperless_mail/models.py:9
msgid "mail account" msgid "mail account"
msgstr "" msgstr "akun surat"
#: paperless_mail/models.py:10 #: paperless_mail/models.py:10
msgid "mail accounts" msgid "mail accounts"
msgstr "" msgstr "akun surat"
#: paperless_mail/models.py:13 #: paperless_mail/models.py:13
msgid "No encryption" msgid "No encryption"
msgstr "" msgstr "Tanpa enkripsi"
#: paperless_mail/models.py:14 #: paperless_mail/models.py:14
msgid "Use SSL" msgid "Use SSL"
msgstr "" msgstr "Gunakan SSL"
#: paperless_mail/models.py:15 #: paperless_mail/models.py:15
msgid "Use STARTTLS" msgid "Use STARTTLS"
msgstr "" msgstr "Gunakan STARTTLS"
#: paperless_mail/models.py:19 #: paperless_mail/models.py:19
msgid "IMAP server" msgid "IMAP server"
msgstr "" msgstr "Server IMAP"
#: paperless_mail/models.py:22 #: paperless_mail/models.py:22
msgid "IMAP port" msgid "IMAP port"
msgstr "" msgstr "Port IMAP"
#: paperless_mail/models.py:26 #: paperless_mail/models.py:26
msgid "This is usually 143 for unencrypted and STARTTLS connections, and 993 for SSL connections." msgid "This is usually 143 for unencrypted and STARTTLS connections, and 993 for SSL connections."
@ -722,11 +722,11 @@ msgstr ""
#: paperless_mail/models.py:37 #: paperless_mail/models.py:37
msgid "username" msgid "username"
msgstr "" msgstr "nama pengguna"
#: paperless_mail/models.py:39 #: paperless_mail/models.py:39
msgid "password" msgid "password"
msgstr "" msgstr "kata sandi"
#: paperless_mail/models.py:42 #: paperless_mail/models.py:42
msgid "character set" msgid "character set"
@ -738,11 +738,11 @@ msgstr ""
#: paperless_mail/models.py:57 #: paperless_mail/models.py:57
msgid "mail rule" msgid "mail rule"
msgstr "" msgstr "peraturan surat"
#: paperless_mail/models.py:58 #: paperless_mail/models.py:58
msgid "mail rules" msgid "mail rules"
msgstr "" msgstr "peraturan surat"
#: paperless_mail/models.py:61 paperless_mail/models.py:69 #: paperless_mail/models.py:61 paperless_mail/models.py:69
msgid "Only process attachments." msgid "Only process attachments."
@ -762,7 +762,7 @@ msgstr ""
#: paperless_mail/models.py:73 #: paperless_mail/models.py:73
msgid "Delete" msgid "Delete"
msgstr "" msgstr "Hapus"
#: paperless_mail/models.py:74 #: paperless_mail/models.py:74
msgid "Move to specified folder" msgid "Move to specified folder"
@ -794,11 +794,11 @@ msgstr ""
#: paperless_mail/models.py:85 #: paperless_mail/models.py:85
msgid "Use mail address" msgid "Use mail address"
msgstr "" msgstr "Gunakan alamat surat"
#: paperless_mail/models.py:86 #: paperless_mail/models.py:86
msgid "Use name (or mail address if not available)" msgid "Use name (or mail address if not available)"
msgstr "" msgstr "Gunakan nama (atau alamat surat jika tidak tersedia)"
#: paperless_mail/models.py:87 #: paperless_mail/models.py:87
msgid "Use correspondent selected below" msgid "Use correspondent selected below"
@ -806,15 +806,15 @@ msgstr ""
#: paperless_mail/models.py:91 #: paperless_mail/models.py:91
msgid "order" msgid "order"
msgstr "" msgstr "urut"
#: paperless_mail/models.py:97 #: paperless_mail/models.py:97
msgid "account" msgid "account"
msgstr "" msgstr "akun"
#: paperless_mail/models.py:101 paperless_mail/models.py:231 #: paperless_mail/models.py:101 paperless_mail/models.py:231
msgid "folder" msgid "folder"
msgstr "" msgstr "direktori"
#: paperless_mail/models.py:105 #: paperless_mail/models.py:105
msgid "Subfolders must be separated by a delimiter, often a dot ('.') or slash ('/'), but it varies by mail server." msgid "Subfolders must be separated by a delimiter, often a dot ('.') or slash ('/'), but it varies by mail server."
@ -822,19 +822,19 @@ msgstr ""
#: paperless_mail/models.py:111 #: paperless_mail/models.py:111
msgid "filter from" msgid "filter from"
msgstr "" msgstr "saring dari"
#: paperless_mail/models.py:117 #: paperless_mail/models.py:117
msgid "filter subject" msgid "filter subject"
msgstr "" msgstr "saring subjek"
#: paperless_mail/models.py:123 #: paperless_mail/models.py:123
msgid "filter body" msgid "filter body"
msgstr "" msgstr "saring badan"
#: paperless_mail/models.py:130 #: paperless_mail/models.py:130
msgid "filter attachment filename" msgid "filter attachment filename"
msgstr "" msgstr "saring nama file lampiran"
#: paperless_mail/models.py:135 #: paperless_mail/models.py:135
msgid "Only consume documents which entirely match this filename if specified. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive." msgid "Only consume documents which entirely match this filename if specified. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive."
@ -842,7 +842,7 @@ msgstr ""
#: paperless_mail/models.py:142 #: paperless_mail/models.py:142
msgid "maximum age" msgid "maximum age"
msgstr "" msgstr "umur maksimal"
#: paperless_mail/models.py:144 #: paperless_mail/models.py:144
msgid "Specified in days." msgid "Specified in days."
@ -850,7 +850,7 @@ msgstr ""
#: paperless_mail/models.py:148 #: paperless_mail/models.py:148
msgid "attachment type" msgid "attachment type"
msgstr "" msgstr "jenis lampiran"
#: paperless_mail/models.py:152 #: paperless_mail/models.py:152
msgid "Inline attachments include embedded images, so it's best to combine this option with a filename filter." msgid "Inline attachments include embedded images, so it's best to combine this option with a filename filter."
@ -862,11 +862,11 @@ msgstr ""
#: paperless_mail/models.py:164 #: paperless_mail/models.py:164
msgid "action" msgid "action"
msgstr "" msgstr "aksi"
#: paperless_mail/models.py:170 #: paperless_mail/models.py:170
msgid "action parameter" msgid "action parameter"
msgstr "" msgstr "parameter aksi"
#: paperless_mail/models.py:175 #: paperless_mail/models.py:175
msgid "Additional parameter for the action selected above, i.e., the target folder of the move to folder action. Subfolders must be separated by dots." msgid "Additional parameter for the action selected above, i.e., the target folder of the move to folder action. Subfolders must be separated by dots."
@ -898,17 +898,17 @@ msgstr ""
#: paperless_mail/models.py:247 #: paperless_mail/models.py:247
msgid "subject" msgid "subject"
msgstr "" msgstr "subjek"
#: paperless_mail/models.py:255 #: paperless_mail/models.py:255
msgid "received" msgid "received"
msgstr "" msgstr "diterima"
#: paperless_mail/models.py:262 #: paperless_mail/models.py:262
msgid "processed" msgid "processed"
msgstr "" msgstr "diproses"
#: paperless_mail/models.py:268 #: paperless_mail/models.py:268
msgid "status" msgid "status"
msgstr "" msgstr "status"

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: 2023-03-03 19:15+0000\n" "POT-Creation-Date: 2023-03-03 19:15+0000\n"
"PO-Revision-Date: 2023-03-04 19:07\n" "PO-Revision-Date: 2023-05-02 19:20\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: Portuguese, Brazilian\n" "Language-Team: Portuguese, Brazilian\n"
"Language: pt_BR\n" "Language: pt_BR\n"
@ -368,15 +368,15 @@ msgstr "mais como este"
#: documents/models.py:436 #: documents/models.py:436
msgid "has tags in" msgid "has tags in"
msgstr "contém etiqueta em" msgstr "contém etiquetas em"
#: documents/models.py:437 #: documents/models.py:437
msgid "ASN greater than" msgid "ASN greater than"
msgstr "" msgstr "NSA maior que"
#: documents/models.py:438 #: documents/models.py:438
msgid "ASN less than" msgid "ASN less than"
msgstr "" msgstr "NSA menor que"
#: documents/models.py:439 #: documents/models.py:439
msgid "storage path is" msgid "storage path is"
@ -400,55 +400,55 @@ msgstr "regras de filtragem"
#: documents/models.py:563 #: documents/models.py:563
msgid "Task ID" msgid "Task ID"
msgstr "" msgstr "ID da tarefa"
#: documents/models.py:564 #: documents/models.py:564
msgid "Celery ID for the Task that was run" msgid "Celery ID for the Task that was run"
msgstr "" msgstr "ID da Celery para a tarefa que foi executada"
#: documents/models.py:569 #: documents/models.py:569
msgid "Acknowledged" msgid "Acknowledged"
msgstr "" msgstr "Confirmado"
#: documents/models.py:570 #: documents/models.py:570
msgid "If the task is acknowledged via the frontend or API" msgid "If the task is acknowledged via the frontend or API"
msgstr "" msgstr "Se a tarefa é reconhecida através do frontend ou API"
#: documents/models.py:576 #: documents/models.py:576
msgid "Task Filename" msgid "Task Filename"
msgstr "" msgstr "Nome do arquivo da tarefa"
#: documents/models.py:577 #: documents/models.py:577
msgid "Name of the file which the Task was run for" msgid "Name of the file which the Task was run for"
msgstr "" msgstr "Nome do arquivo para o qual a tarefa foi executada"
#: documents/models.py:583 #: documents/models.py:583
msgid "Task Name" msgid "Task Name"
msgstr "" msgstr "Nome da tarefa"
#: documents/models.py:584 #: documents/models.py:584
msgid "Name of the Task which was run" msgid "Name of the Task which was run"
msgstr "" msgstr "Nome da tarefa executada"
#: documents/models.py:591 #: documents/models.py:591
msgid "Task State" msgid "Task State"
msgstr "" msgstr "Estado da tarefa"
#: documents/models.py:592 #: documents/models.py:592
msgid "Current state of the task being run" msgid "Current state of the task being run"
msgstr "" msgstr "Estado atual da tarefa sendo executada"
#: documents/models.py:597 #: documents/models.py:597
msgid "Created DateTime" msgid "Created DateTime"
msgstr "" msgstr "Data/Hora de criação"
#: documents/models.py:598 #: documents/models.py:598
msgid "Datetime field when the task result was created in UTC" msgid "Datetime field when the task result was created in UTC"
msgstr "" msgstr "Campo Data/Hora quando o resultado da tarefa foi criado, em UTC"
#: documents/models.py:603 #: documents/models.py:603
msgid "Started DateTime" msgid "Started DateTime"
msgstr "" msgstr "Data/Hora de início"
#: documents/models.py:604 #: documents/models.py:604
msgid "Datetime field when the task was started in UTC" msgid "Datetime field when the task was started in UTC"
@ -472,7 +472,7 @@ msgstr ""
#: documents/models.py:626 #: documents/models.py:626
msgid "Comment for the document" msgid "Comment for the document"
msgstr "" msgstr "Comentário para o documento"
#: documents/models.py:650 #: documents/models.py:650
msgid "user" msgid "user"
@ -562,11 +562,11 @@ msgstr "Inglês (EUA)"
#: paperless/settings.py:522 #: paperless/settings.py:522
msgid "Arabic" msgid "Arabic"
msgstr "" msgstr "Árabe"
#: paperless/settings.py:523 #: paperless/settings.py:523
msgid "Belarusian" msgid "Belarusian"
msgstr "" msgstr "Bielorrusso"
#: paperless/settings.py:524 #: paperless/settings.py:524
msgid "Czech" msgid "Czech"
@ -626,11 +626,11 @@ msgstr "Russo"
#: paperless/settings.py:538 #: paperless/settings.py:538
msgid "Slovenian" msgid "Slovenian"
msgstr "" msgstr "Esloveno"
#: paperless/settings.py:539 #: paperless/settings.py:539
msgid "Serbian" msgid "Serbian"
msgstr "" msgstr "Sérvio"
#: paperless/settings.py:540 #: paperless/settings.py:540
msgid "Swedish" msgid "Swedish"
@ -638,11 +638,11 @@ msgstr "Sueco"
#: paperless/settings.py:541 #: paperless/settings.py:541
msgid "Turkish" msgid "Turkish"
msgstr "" msgstr "Turco"
#: paperless/settings.py:542 #: paperless/settings.py:542
msgid "Chinese Simplified" msgid "Chinese Simplified"
msgstr "" msgstr "Chinês Simplificado"
#: paperless/urls.py:169 #: paperless/urls.py:169
msgid "Paperless-ngx administration" msgid "Paperless-ngx administration"
@ -670,7 +670,7 @@ msgstr "Ações"
#: paperless_mail/admin.py:69 #: paperless_mail/admin.py:69
msgid "The action applied to the mail. This action is only performed when the mail body or attachments were consumed from the mail." msgid "The action applied to the mail. This action is only performed when the mail body or attachments were consumed from the mail."
msgstr "" msgstr "A ação aplicada ao e-mail. Essa ação só é executada quando o corpo do e-mail ou anexos forem consumidos."
#: paperless_mail/admin.py:77 #: paperless_mail/admin.py:77
msgid "Metadata" msgid "Metadata"
@ -750,11 +750,11 @@ msgstr "Processar somente anexos."
#: paperless_mail/models.py:62 #: paperless_mail/models.py:62
msgid "Process full Mail (with embedded attachments in file) as .eml" msgid "Process full Mail (with embedded attachments in file) as .eml"
msgstr "" msgstr "Processar e-mail completo (com anexos incorporados no arquivo) como .eml"
#: paperless_mail/models.py:64 #: paperless_mail/models.py:64
msgid "Process full Mail (with embedded attachments in file) as .eml + process attachments as separate documents" msgid "Process full Mail (with embedded attachments in file) as .eml + process attachments as separate documents"
msgstr "" msgstr "Processar e-mail completo (com anexos incorporados no arquivo) como .eml + processar anexos como documentos separados"
#: paperless_mail/models.py:70 #: paperless_mail/models.py:70
msgid "Process all files, including 'inline' attachments." msgid "Process all files, including 'inline' attachments."
@ -778,7 +778,7 @@ msgstr "Sinalizar o e-mail, não processar e-mails sinalizados"
#: paperless_mail/models.py:77 #: paperless_mail/models.py:77
msgid "Tag the mail with specified tag, don't process tagged mails" msgid "Tag the mail with specified tag, don't process tagged mails"
msgstr "" msgstr "Marcar o e-mail com a etiqueta especificada, não processar e-mails marcados"
#: paperless_mail/models.py:80 #: paperless_mail/models.py:80
msgid "Use subject as title" msgid "Use subject as title"
@ -818,7 +818,7 @@ msgstr "pasta"
#: paperless_mail/models.py:105 #: paperless_mail/models.py:105
msgid "Subfolders must be separated by a delimiter, often a dot ('.') or slash ('/'), but it varies by mail server." msgid "Subfolders must be separated by a delimiter, often a dot ('.') or slash ('/'), but it varies by mail server."
msgstr "" msgstr "Subpastas devem ser separadas por um delimitador, muitas vezes um ponto ('.') ou uma barra ('/'), mas varia de acordo com o servidor de e-mail."
#: paperless_mail/models.py:111 #: paperless_mail/models.py:111
msgid "filter from" msgid "filter from"
@ -859,7 +859,7 @@ msgstr "Anexos inline incluem imagens inseridas, por isso é melhor combinar ess
#: paperless_mail/models.py:158 #: paperless_mail/models.py:158
msgid "consumption scope" msgid "consumption scope"
msgstr "" msgstr "escopo do consumo"
#: paperless_mail/models.py:164 #: paperless_mail/models.py:164
msgid "action" msgid "action"

View File

@ -422,11 +422,12 @@ if _paperless_url:
_paperless_uri = urlparse(_paperless_url) _paperless_uri = urlparse(_paperless_url)
CSRF_TRUSTED_ORIGINS.append(_paperless_url) CSRF_TRUSTED_ORIGINS.append(_paperless_url)
CORS_ALLOWED_ORIGINS.append(_paperless_url) CORS_ALLOWED_ORIGINS.append(_paperless_url)
if ["*"] != ALLOWED_HOSTS:
if ["*"] != ALLOWED_HOSTS:
# always allow localhost. Necessary e.g. for healthcheck in docker.
ALLOWED_HOSTS.append("localhost")
if _paperless_url:
ALLOWED_HOSTS.append(_paperless_uri.hostname) ALLOWED_HOSTS.append(_paperless_uri.hostname)
else:
# always allow localhost. Necessary e.g. for healthcheck in docker.
ALLOWED_HOSTS = [_paperless_uri.hostname] + ["localhost"]
# For use with trusted proxies # For use with trusted proxies
TRUSTED_PROXIES = __get_list("PAPERLESS_TRUSTED_PROXIES") TRUSTED_PROXIES = __get_list("PAPERLESS_TRUSTED_PROXIES")

View File

@ -2,7 +2,6 @@ import datetime
import itertools import itertools
import logging import logging
import os import os
import re
import tempfile import tempfile
import traceback import traceback
from datetime import date from datetime import date
@ -145,7 +144,7 @@ class TagMailAction(BaseMailAction):
A mail action that tags mails after processing. A mail action that tags mails after processing.
""" """
def __init__(self, parameter): def __init__(self, parameter: str, supports_gmail_labels: bool):
# The custom tag should look like "apple:<color>" # The custom tag should look like "apple:<color>"
if "apple:" in parameter.lower(): if "apple:" in parameter.lower():
_, self.color = parameter.split(":") _, self.color = parameter.split(":")
@ -159,18 +158,22 @@ class TagMailAction(BaseMailAction):
else: else:
self.keyword = parameter self.keyword = parameter
self.color = None self.color = None
self.supports_gmail_labels = supports_gmail_labels
def get_criteria(self): def get_criteria(self):
# AppleMail: We only need to check if mails are \Flagged # AppleMail: We only need to check if mails are \Flagged
if self.color: if self.color:
return {"flagged": False} return {"flagged": False}
elif self.keyword: elif self.keyword:
return AND(NOT(gmail_label=self.keyword), no_keyword=self.keyword) if self.supports_gmail_labels:
return AND(NOT(gmail_label=self.keyword), no_keyword=self.keyword)
else:
return NOT(no_keyword=self.keyword)
else: # pragma: nocover else: # pragma: nocover
raise ValueError("This should never happen.") raise ValueError("This should never happen.")
def post_consume(self, M: MailBox, message_uid: str, parameter: str): def post_consume(self, M: MailBox, message_uid: str, parameter: str):
if re.search(r"gmail\.com$|googlemail\.com$", M._host): if self.supports_gmail_labels:
M.client.uid("STORE", message_uid, "+X-GM-LABELS", self.keyword) M.client.uid("STORE", message_uid, "+X-GM-LABELS", self.keyword)
# AppleMail # AppleMail
@ -248,15 +251,18 @@ def apply_mail_action(
message_date = make_aware(message_date) message_date = make_aware(message_date)
try: try:
action = get_rule_action(rule)
with get_mailbox( with get_mailbox(
server=account.imap_server, server=account.imap_server,
port=account.imap_port, port=account.imap_port,
security=account.imap_security, security=account.imap_security,
) as M: ) as M:
# Need to know the support for the possible tagging
supports_gmail_labels = "X-GM-EXT-1" in M.client.capabilities
mailbox_login(M, account) mailbox_login(M, account)
M.folder.set(rule.folder) M.folder.set(rule.folder)
action = get_rule_action(rule, supports_gmail_labels)
action.post_consume(M, message_uid, rule.action_parameter) action.post_consume(M, message_uid, rule.action_parameter)
ProcessedMail.objects.create( ProcessedMail.objects.create(
@ -337,7 +343,7 @@ def queue_consumption_tasks(
).delay() ).delay()
def get_rule_action(rule) -> BaseMailAction: def get_rule_action(rule: MailRule, supports_gmail_labels: bool) -> BaseMailAction:
""" """
Returns a BaseMailAction instance for the given rule. Returns a BaseMailAction instance for the given rule.
""" """
@ -351,12 +357,12 @@ def get_rule_action(rule) -> BaseMailAction:
elif rule.action == MailRule.MailAction.MARK_READ: elif rule.action == MailRule.MailAction.MARK_READ:
return MarkReadMailAction() return MarkReadMailAction()
elif rule.action == MailRule.MailAction.TAG: elif rule.action == MailRule.MailAction.TAG:
return TagMailAction(rule.action_parameter) return TagMailAction(rule.action_parameter, supports_gmail_labels)
else: else:
raise NotImplementedError("Unknown action.") # pragma: nocover raise NotImplementedError("Unknown action.") # pragma: nocover
def make_criterias(rule): def make_criterias(rule: MailRule, supports_gmail_labels: bool):
""" """
Returns criteria to be applied to MailBox.fetch for the given rule. Returns criteria to be applied to MailBox.fetch for the given rule.
""" """
@ -374,7 +380,7 @@ def make_criterias(rule):
if rule.filter_body: if rule.filter_body:
criterias["body"] = rule.filter_body criterias["body"] = rule.filter_body
rule_query = get_rule_action(rule).get_criteria() rule_query = get_rule_action(rule, supports_gmail_labels).get_criteria()
if isinstance(rule_query, dict): if isinstance(rule_query, dict):
if len(rule_query) or len(criterias): if len(rule_query) or len(criterias):
return AND(**rule_query, **criterias) return AND(**rule_query, **criterias)
@ -490,6 +496,7 @@ class MailAccountHandler(LoggingMixin):
total_processed_files += self._handle_mail_rule( total_processed_files += self._handle_mail_rule(
M, M,
rule, rule,
supports_gmail_labels,
) )
except Exception as e: except Exception as e:
self.log( self.log(
@ -512,6 +519,7 @@ class MailAccountHandler(LoggingMixin):
self, self,
M: MailBox, M: MailBox,
rule: MailRule, rule: MailRule,
supports_gmail_labels: bool,
): ):
self.log("debug", f"Rule {rule}: Selecting folder {rule.folder}") self.log("debug", f"Rule {rule}: Selecting folder {rule.folder}")
@ -537,7 +545,7 @@ class MailAccountHandler(LoggingMixin):
f"does not exist in account {rule.account}", f"does not exist in account {rule.account}",
) from err ) from err
criterias = make_criterias(rule) criterias = make_criterias(rule, supports_gmail_labels)
self.log( self.log(
"debug", "debug",

View File

@ -737,6 +737,7 @@ class TestMail(
MailError, MailError,
TagMailAction, TagMailAction,
"apple:black", "apple:black",
False,
) )
def test_handle_mail_account_tag_applemail(self): def test_handle_mail_account_tag_applemail(self):