Compare commits

..
Author SHA1 Message Date
dependabot[bot] 8e31d8f4d6 Chore(deps-dev): Bump types-markdown (#13982)
Bumps [types-markdown](https://github.com/python/typeshed) from 3.10.2.20260518 to 3.10.2.20260712.
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-markdown
  dependency-version: 3.10.2.20260712
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-04 16:00:04 -07:00
dependabot[bot] 97c59df620 Chore(deps): Bump the utilities-patch group across 1 directory with 6 updates (#13980)
Bumps the utilities-patch group with 6 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [dateparser](https://github.com/scrapinghub/dateparser) | `1.4.1` | `1.4.2` |
| [django-cachalot](https://github.com/noripyt/django-cachalot) | `2.9.0` | `2.9.1` |
| [filelock](https://github.com/tox-dev/py-filelock) | `3.32.0` | `3.32.4` |
| [llama-index-core](https://github.com/run-llama/llama_index) | `0.14.23` | `0.14.24` |
| [python-dotenv](https://github.com/theskumar/python-dotenv) | `1.2.2` | `1.2.3` |
| [types-dateparser](https://github.com/python/typeshed) | `1.4.1.20260617` | `1.4.2.20260813` |



Updates `dateparser` from 1.4.1 to 1.4.2
- [Release notes](https://github.com/scrapinghub/dateparser/releases)
- [Changelog](https://github.com/scrapinghub/dateparser/blob/master/HISTORY.rst)
- [Commits](https://github.com/scrapinghub/dateparser/compare/v1.4.1...v1.4.2)

Updates `django-cachalot` from 2.9.0 to 2.9.1
- [Release notes](https://github.com/noripyt/django-cachalot/releases)
- [Changelog](https://github.com/noripyt/django-cachalot/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/noripyt/django-cachalot/compare/v2.9.0...v2.9.1)

Updates `filelock` from 3.32.0 to 3.32.4
- [Release notes](https://github.com/tox-dev/py-filelock/releases)
- [Changelog](https://github.com/tox-dev/filelock/blob/main/docs/changelog.rst)
- [Commits](https://github.com/tox-dev/py-filelock/compare/3.32.0...3.32.4)

Updates `llama-index-core` from 0.14.23 to 0.14.24
- [Release notes](https://github.com/run-llama/llama_index/releases)
- [Changelog](https://github.com/run-llama/llama_index/blob/main/CHANGELOG.md)
- [Commits](https://github.com/run-llama/llama_index/compare/v0.14.23...v0.14.24)

Updates `python-dotenv` from 1.2.2 to 1.2.3
- [Release notes](https://github.com/theskumar/python-dotenv/releases)
- [Changelog](https://github.com/theskumar/python-dotenv/blob/main/CHANGELOG.md)
- [Commits](https://github.com/theskumar/python-dotenv/compare/v1.2.2...v1.2.3)

Updates `types-dateparser` from 1.4.1.20260617 to 1.4.2.20260813
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: dateparser
  dependency-version: 1.4.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: utilities-patch
- dependency-name: django-cachalot
  dependency-version: 2.9.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: utilities-patch
- dependency-name: filelock
  dependency-version: 3.32.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: utilities-patch
- dependency-name: llama-index-core
  dependency-version: 0.14.24
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: utilities-patch
- dependency-name: python-dotenv
  dependency-version: 1.2.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: utilities-patch
- dependency-name: types-dateparser
  dependency-version: 1.4.2.20260813
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: utilities-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-04 22:24:58 +00:00
dependabot[bot] e76ba49d86 Chore(deps): Update granian[uvloop] requirement (#13984)
Updates the requirements on [granian[uvloop]](https://github.com/emmett-framework/granian) to permit the latest version.
- [Release notes](https://github.com/emmett-framework/granian/releases)
- [Commits](https://github.com/emmett-framework/granian/compare/v2.7.0...v2.8.2)

---
updated-dependencies:
- dependency-name: granian[uvloop]
  dependency-version: 2.8.2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-04 21:57:01 +00:00
Trenton H 0e5d5022a1 Chore: Updates our direct Redis pin (#13986) 2026-09-04 14:28:27 -07:00
shamoon b24f2cbfa7 Fix: enforce the overflow hidden rule on pdf editor thumbnails (#13976) 2026-09-04 14:08:09 -07:00
shamoon 59e8ebd42c Fix: also correct unbroken long names on small cards (#13974) 2026-09-04 13:17:26 -07:00
dependabot[bot] d18ada1e4c Chore(deps-dev): Bump the frontend-eslint-dependencies group across 1 directory with 4 updates (#13918)
Bumps the frontend-eslint-dependencies group with 4 updates in the /src-ui directory: [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin), [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser), [@typescript-eslint/utils](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/utils) and [eslint](https://github.com/eslint/eslint).


Updates `@typescript-eslint/eslint-plugin` from 8.67.0 to 8.68.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.68.0/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 8.67.0 to 8.68.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.68.0/packages/parser)

Updates `@typescript-eslint/utils` from 8.67.0 to 8.68.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/utils/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.68.0/packages/utils)

Updates `eslint` from 10.8.1 to 10.9.1
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](https://github.com/eslint/eslint/compare/v10.8.1...v10.9.1)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-version: 8.68.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: frontend-eslint-dependencies
- dependency-name: "@typescript-eslint/parser"
  dependency-version: 8.68.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: frontend-eslint-dependencies
- dependency-name: "@typescript-eslint/utils"
  dependency-version: 8.68.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: frontend-eslint-dependencies
- dependency-name: eslint
  dependency-version: 10.9.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: frontend-eslint-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-04 20:06:56 +00:00
dependabot[bot] 0d8f07a5bc Chore(deps): Bump uuid from 14.0.1 to 14.0.2 in /src-ui (#13921)
Bumps [uuid](https://github.com/uuidjs/uuid) from 14.0.1 to 14.0.2.
- [Release notes](https://github.com/uuidjs/uuid/releases)
- [Changelog](https://github.com/uuidjs/uuid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/uuidjs/uuid/compare/v14.0.1...v14.0.2)

---
updated-dependencies:
- dependency-name: uuid
  dependency-version: 14.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-04 19:54:48 +00:00
dependabot[bot] 0bbc4f5372 Chore(deps-dev): Bump @types/node from 26.2.0 to 26.4.0 in /src-ui (#13919)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 26.2.0 to 26.4.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 26.3.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-04 19:43:15 +00:00
GitHub Actions 0b6c00085a Auto translate strings 2026-09-04 19:28:35 +00:00
shamoon 3fe3dda3a1 Chore: update ng-select to v24, handle breaking changes (#13951) 2026-09-04 12:26:47 -07:00
dependabot[bot] 7b5eb80d64 Chore(deps): Bump djangorestframework (#13912)
Bumps the django-ecosystem group with 1 update in the / directory: [djangorestframework](https://github.com/encode/django-rest-framework).


Updates `djangorestframework` from 3.17.2 to 3.18.0
- [Release notes](https://github.com/encode/django-rest-framework/releases)
- [Commits](https://github.com/encode/django-rest-framework/compare/3.17.2...3.18.0)

---
updated-dependencies:
- dependency-name: djangorestframework
  dependency-version: 3.18.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: django-ecosystem
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-04 12:12:47 -07:00
dependabot[bot]andstumpylog a1f407cc9e Chore(deps): Bump the pre-commit-dependencies group across 1 directory with 3 updates (#13922)
* Chore(deps): Bump the pre-commit-dependencies group across 1 directory with 3 updates

Bumps the pre-commit-dependencies group with 3 updates in the / directory: [https://github.com/astral-sh/ruff-pre-commit](https://github.com/astral-sh/ruff-pre-commit), [https://github.com/tox-dev/pyproject-fmt](https://github.com/tox-dev/pyproject-fmt) and [https://github.com/AleksaC/hadolint-py](https://github.com/AleksaC/hadolint-py).


Updates `https://github.com/astral-sh/ruff-pre-commit` from v0.16.1 to 0.16.5
- [Release notes](https://github.com/astral-sh/ruff-pre-commit/releases)
- [Commits](https://github.com/astral-sh/ruff-pre-commit/compare/v0.16.1...v0.16.5)

Updates `https://github.com/tox-dev/pyproject-fmt` from v2.26.0 to 2.28.1
- [Release notes](https://github.com/tox-dev/pyproject-fmt/releases)
- [Commits](https://github.com/tox-dev/pyproject-fmt/compare/v2.26.0...v2.28.1)

Updates `https://github.com/AleksaC/hadolint-py` from v2.14.0 to 2.15.1
- [Commits](https://github.com/AleksaC/hadolint-py/compare/v2.14.0...v2.15.1)

---
updated-dependencies:
- dependency-name: https://github.com/AleksaC/hadolint-py
  dependency-version: 2.15.1
  dependency-type: direct:production
  dependency-group: pre-commit-dependencies
- dependency-name: https://github.com/astral-sh/ruff-pre-commit
  dependency-version: 0.16.4
  dependency-type: direct:production
  dependency-group: pre-commit-dependencies
- dependency-name: https://github.com/tox-dev/pyproject-fmt
  dependency-version: 2.28.1
  dependency-type: direct:production
  dependency-group: pre-commit-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>

* Runs the linting

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: stumpylog <797416+stumpylog@users.noreply.github.com>
2026-09-04 18:38:40 +00:00
dependabot[bot]andstumpylog cf34844168 Chore(deps): Bump the document-processing group across 1 directory with 4 updates (#13916)
* Chore(deps): Bump the document-processing group across 1 directory with 4 updates

Bumps the document-processing group with 4 updates in the / directory: [gotenberg-client](https://github.com/stumpylog/gotenberg-client), [ocrmypdf](https://github.com/ocrmypdf/OCRmyPDF), [tika-client](https://github.com/stumpylog/tika-client) and [zxing-cpp](https://github.com/zxing-cpp/zxing-cpp).


Updates `gotenberg-client` from 0.14.0 to 1.0.0
- [Release notes](https://github.com/stumpylog/gotenberg-client/releases)
- [Changelog](https://github.com/stumpylog/gotenberg-client/blob/main/CHANGELOG.md)
- [Commits](https://github.com/stumpylog/gotenberg-client/compare/0.14.0...1.0.0)

Updates `ocrmypdf` from 17.7.1 to 17.10.0
- [Release notes](https://github.com/ocrmypdf/OCRmyPDF/releases)
- [Commits](https://github.com/ocrmypdf/OCRmyPDF/compare/v17.7.1...v17.10.0)

Updates `tika-client` from 0.11.0 to 1.0.0
- [Release notes](https://github.com/stumpylog/tika-client/releases)
- [Changelog](https://github.com/stumpylog/tika-client/blob/main/CHANGELOG.md)
- [Commits](https://github.com/stumpylog/tika-client/compare/0.11.0...1.0.0)

Updates `zxing-cpp` from 3.1.0 to 3.1.1
- [Release notes](https://github.com/zxing-cpp/zxing-cpp/releases)
- [Commits](https://github.com/zxing-cpp/zxing-cpp/compare/v3.1.0...v3.1.1)

---
updated-dependencies:
- dependency-name: gotenberg-client
  dependency-version: 1.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: document-processing
- dependency-name: ocrmypdf
  dependency-version: 17.10.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: document-processing
- dependency-name: tika-client
  dependency-version: 1.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: document-processing
- dependency-name: zxing-cpp
  dependency-version: 3.1.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: document-processing
...

Signed-off-by: dependabot[bot] <support@github.com>

* Install the httpx extra of gotenberg-client v1

* Did the same thing here, forgot

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: stumpylog <797416+stumpylog@users.noreply.github.com>
2026-09-04 18:02:34 +00:00
dependabot[bot]andstumpylog 3c575b5202 Chore(deps): Bump flower from 2.0.1 to 2.1.0 in the async-tasks group across 1 directory (#13913)
* Chore(deps): Bump flower in the async-tasks group across 1 directory

Bumps the async-tasks group with 1 update in the / directory: [flower](https://github.com/mher/flower).


Updates `flower` from 2.0.1 to 2.1.0
- [Release notes](https://github.com/mher/flower/releases)
- [Changelog](https://github.com/mher/flower/blob/v2.1.0/CHANGELOG.md)
- [Commits](https://github.com/mher/flower/compare/v2.0.1...v2.1.0)

---
updated-dependencies:
- dependency-name: flower
  dependency-version: 2.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: async-tasks
...

Signed-off-by: dependabot[bot] <support@github.com>

* Linting

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: stumpylog <797416+stumpylog@users.noreply.github.com>
2026-09-04 16:58:05 +00:00
dependabot[bot] e5eda02c16 Chore(deps): Bump the actions group across 1 directory with 15 updates (#13920)
Bumps the actions group with 15 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [dorny/paths-filter](https://github.com/dorny/paths-filter) | `4.0.2` | `4.0.3` |
| [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) | `9.0.0` | `10.0.1` |
| [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) | `4.2.0` | `4.3.0` |
| [docker/login-action](https://github.com/docker/login-action) | `4.5.1` | `4.6.0` |
| [pnpm/action-setup](https://github.com/pnpm/action-setup) | `6.0.9` | `6.0.10` |
| [j178/prek-action](https://github.com/j178/prek-action) | `2.0.6` | `3.0.0` |
| [lewagon/wait-on-check-action](https://github.com/lewagon/wait-on-check-action) | `1.9.0` | `1.9.1` |
| [release-drafter/release-drafter](https://github.com/release-drafter/release-drafter) | `7.6.0` | `7.7.0` |
| [shogo82148/actions-upload-release-asset](https://github.com/shogo82148/actions-upload-release-asset) | `1.10.2` | `1.10.4` |
| [zizmorcore/zizmor-action](https://github.com/zizmorcore/zizmor-action) | `0.6.1` | `0.6.2` |
| [github/codeql-action/upload-sarif](https://github.com/github/codeql-action) | `4.37.3` | `4.37.9` |
| [github/codeql-action/init](https://github.com/github/codeql-action) | `4.37.3` | `4.37.9` |
| [github/codeql-action/analyze](https://github.com/github/codeql-action) | `4.37.3` | `4.37.9` |
| [crowdin/github-action](https://github.com/crowdin/github-action) | `2.17.0` | `3.0.0` |
| [actions/stale](https://github.com/actions/stale) | `10.4.0` | `11.0.0` |



Updates `dorny/paths-filter` from 4.0.2 to 4.0.3
- [Release notes](https://github.com/dorny/paths-filter/releases)
- [Changelog](https://github.com/dorny/paths-filter/blob/master/CHANGELOG.md)
- [Commits](https://github.com/dorny/paths-filter/compare/7b450fff21473bca461d4b92ce414b9d0420d706...ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d)

Updates `astral-sh/setup-uv` from 9.0.0 to 10.0.1
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](https://github.com/astral-sh/setup-uv/compare/c771a70e6277c0a99b617c7a806ffedaca235ff9...20cfd1bf945f4377ade1205e4dbc17946fc9a30d)

Updates `docker/setup-buildx-action` from 4.2.0 to 4.3.0
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/bb05f3f5519dd87d3ba754cc423b652a5edd6d2c...37fe631027851001ddb9b187196cc803df7f5f0e)

Updates `docker/login-action` from 4.5.1 to 4.6.0
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/abd2ef45e78c5afb21d64d4ca52ee8550d9572c7...dbcb813823bdd20940b903addbd779551569679f)

Updates `pnpm/action-setup` from 6.0.9 to 6.0.10
- [Release notes](https://github.com/pnpm/action-setup/releases)
- [Commits](https://github.com/pnpm/action-setup/compare/0ebf47130e4866e96fce0953f49152a61190b271...0977fd99725f1db4007ccb2928dbb4e90d06cc86)

Updates `j178/prek-action` from 2.0.6 to 3.0.0
- [Release notes](https://github.com/j178/prek-action/releases)
- [Commits](https://github.com/j178/prek-action/compare/5337cb91e0fa35a7ff31b9ca345126d8bbbcdf16...4e14d07f9231acabce116ccfca13b13dd9755ece)

Updates `lewagon/wait-on-check-action` from 1.9.0 to 1.9.1
- [Release notes](https://github.com/lewagon/wait-on-check-action/releases)
- [Changelog](https://github.com/lewagon/wait-on-check-action/blob/master/CHANGELOG.md)
- [Commits](https://github.com/lewagon/wait-on-check-action/compare/2271c86c146b96545b4e871b855e10ffa6f50773...369769072fe522a3a8a85c03c96af1e5242a1994)

Updates `release-drafter/release-drafter` from 7.6.0 to 7.7.0
- [Release notes](https://github.com/release-drafter/release-drafter/releases)
- [Commits](https://github.com/release-drafter/release-drafter/compare/eada3c96a64734dd381cfbda23511034e328ddb0...34d80673e067bdc0c24568d3af899c216adcfaa9)

Updates `shogo82148/actions-upload-release-asset` from 1.10.2 to 1.10.4
- [Release notes](https://github.com/shogo82148/actions-upload-release-asset/releases)
- [Commits](https://github.com/shogo82148/actions-upload-release-asset/compare/394b3c11c3cfc038b5396ad265c074065cf875c3...aaba0f56bdbc1071f4af234d5cb16055e8a400de)

Updates `zizmorcore/zizmor-action` from 0.6.1 to 0.6.2
- [Release notes](https://github.com/zizmorcore/zizmor-action/releases)
- [Commits](https://github.com/zizmorcore/zizmor-action/compare/6fc4b006235f201fdab3722e17240ab420d580e5...3dc1ecc9bcb9e94e9b2c709687979e1298497054)

Updates `github/codeql-action/upload-sarif` from 4.37.3 to 4.37.9
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81...cdf488f595d80d6e07e03d4674febd5ab45fa938)

Updates `github/codeql-action/init` from 4.37.3 to 4.37.9
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81...cdf488f595d80d6e07e03d4674febd5ab45fa938)

Updates `github/codeql-action/analyze` from 4.37.3 to 4.37.9
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81...cdf488f595d80d6e07e03d4674febd5ab45fa938)

Updates `crowdin/github-action` from 2.17.0 to 3.0.0
- [Release notes](https://github.com/crowdin/github-action/releases)
- [Commits](https://github.com/crowdin/github-action/compare/c7af9bc98b01694653031fef2a0dc6c7888ce9bc...e4a6c1338b4063c77d46a81875265f9e8bd76f95)

Updates `actions/stale` from 10.4.0 to 11.0.0
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/stale/compare/1e223db275d687790206a7acac4d1a11bd6fe629...4391f3da665fdf50b6810c1a66712fb9ba21aa93)

---
updated-dependencies:
- dependency-name: actions/stale
  dependency-version: 11.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions
- dependency-name: astral-sh/setup-uv
  dependency-version: 10.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions
- dependency-name: crowdin/github-action
  dependency-version: 2.17.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
- dependency-name: docker/login-action
  dependency-version: 4.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions
- dependency-name: docker/setup-buildx-action
  dependency-version: 4.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions
- dependency-name: dorny/paths-filter
  dependency-version: 4.0.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
- dependency-name: github/codeql-action/analyze
  dependency-version: 4.37.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
- dependency-name: github/codeql-action/init
  dependency-version: 4.37.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
- dependency-name: github/codeql-action/upload-sarif
  dependency-version: 4.37.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
- dependency-name: j178/prek-action
  dependency-version: 3.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions
- dependency-name: lewagon/wait-on-check-action
  dependency-version: 1.9.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
- dependency-name: pnpm/action-setup
  dependency-version: 6.0.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
- dependency-name: release-drafter/release-drafter
  dependency-version: 7.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions
- dependency-name: shogo82148/actions-upload-release-asset
  dependency-version: 1.10.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
- dependency-name: zizmorcore/zizmor-action
  dependency-version: 0.6.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-04 09:39:54 -07:00
dependabot[bot] a07e1cea75 docker-compose(deps): Bump gotenberg/gotenberg in /docker/compose (#13910)
Bumps gotenberg/gotenberg from 8.34 to 8.36.

---
updated-dependencies:
- dependency-name: gotenberg/gotenberg
  dependency-version: '8.36'
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-04 09:18:04 -07:00
dependabot[bot] 99f2ef9b89 Chore(deps-dev): Bump the development group across 1 directory with 2 updates (#13911)
Bumps the development group with 2 updates in the / directory: [zensical](https://github.com/zensical/zensical) and [ruff](https://github.com/astral-sh/ruff).


Updates `zensical` from 0.0.51 to 0.0.57
- [Release notes](https://github.com/zensical/zensical/releases)
- [Commits](https://github.com/zensical/zensical/compare/v0.0.51...v0.0.57)

Updates `ruff` from 0.16.1 to 0.16.5
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/0.16.1...0.16.5)

---
updated-dependencies:
- dependency-name: ruff
  dependency-version: 0.16.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development
- dependency-name: zensical
  dependency-version: 0.0.57
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-04 15:52:43 +00:00
dependabot[bot] 705b45e507 docker(deps): Bump astral-sh/uv (#13914)
Bumps [astral-sh/uv](https://github.com/astral-sh/uv) from 0.12.5-python3.14-trixie-slim to 0.12.9-python3.14-trixie-slim.
- [Release notes](https://github.com/astral-sh/uv/releases)
- [Changelog](https://github.com/astral-sh/uv/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/uv/compare/0.12.5...0.12.9)

---
updated-dependencies:
- dependency-name: astral-sh/uv
  dependency-version: 0.12.8-python3.14-trixie-slim
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-04 15:38:19 +00:00
GitHub Actions 0a392a2efa Auto translate strings 2026-09-04 15:27:13 +00:00
shamoon ac381d2344 Fix: ensure parent + child tags change together in bulk editor (#13972) 2026-09-04 08:24:17 -07:00
GitHub Actions 16568439c0 Auto translate strings 2026-09-04 14:17:01 +00:00
shamoon 3f4d2a4b5a And the backend 2026-09-04 07:14:58 -07:00
shamoon 8da770c3d7 Fix: enure emit parent tag when re-added 2026-09-04 07:11:28 -07:00
github-actions[bot] ae9529551d Documentation: Add v3.1.3 changelog (#13962) 2026-09-03 20:21:39 -07:00
shamoon d48663e9eb Bump version to 3.1.3 2026-09-03 18:59:18 -07:00
github-actions[bot]andCrowdin Bot a28a6fe23b New Crowdin translations by GitHub Action (#13894)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-09-03 18:58:02 -07:00
Trenton H e75a9d8c55 Chore: Drops the LSIO option from bug report install types (#13961) 2026-09-03 14:32:40 -07:00
dependabot[bot] 93ec102156 Chore(deps): Bump the uv group across 1 directory with 2 updates (#13958)
Bumps the uv group with 2 updates in the / directory: [banks](https://github.com/masci/banks) and [tornado](https://github.com/tornadoweb/tornado).


Updates `banks` from 2.4.2 to 2.4.5
- [Release notes](https://github.com/masci/banks/releases)
- [Commits](https://github.com/masci/banks/compare/v2.4.2...v2.4.5)

Updates `tornado` from 6.5.7 to 6.5.8
- [Changelog](https://github.com/tornadoweb/tornado/blob/master/docs/releases.rst)
- [Commits](https://github.com/tornadoweb/tornado/compare/v6.5.7...v6.5.8)

---
updated-dependencies:
- dependency-name: banks
  dependency-version: 2.4.5
  dependency-type: indirect
  dependency-group: uv
- dependency-name: tornado
  dependency-version: 6.5.8
  dependency-type: indirect
  dependency-group: uv
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-03 16:54:47 +00:00
dependabot[bot] 1806141983 docker-compose(deps): bump nginx in /docker/compose (#13909)
Bumps nginx from 1.31.3-alpine to 1.31.5-alpine.

---
updated-dependencies:
- dependency-name: nginx
  dependency-version: 1.31.4-alpine
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-03 16:07:06 +00:00
dependabot[bot] 593a65c157 docker-compose(deps): Bump greenmail/standalone in /docker/compose (#13907)
Bumps greenmail/standalone from 2.1.11 to 2.1.13.

---
updated-dependencies:
- dependency-name: greenmail/standalone
  dependency-version: 2.1.13
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-03 08:53:52 -07:00
dependabot[bot] a3851c157a Chore(deps-dev): Bump postcss-selector-parser from 6.1.2 to 6.1.4 in /src/paperless_mail/templates in the npm_and_yarn group across 1 directory (#13905)
Signed-off-by: dependabot[bot] <support@github.com>
2026-09-03 02:49:45 +00:00
dependabot[bot] 853b57c71d Chore(deps): Bump nltk in the data-nlp-search group across 1 directory (#13917)
Bumps the data-nlp-search group with 1 update in the / directory: [nltk](https://github.com/nltk/nltk).


Updates `nltk` from 3.10.0 to 3.10.3
- [Release notes](https://github.com/nltk/nltk/releases)
- [Changelog](https://github.com/nltk/nltk/blob/develop/ChangeLog)
- [Commits](https://github.com/nltk/nltk/compare/v3.10.0...v3.10.3)

---
updated-dependencies:
- dependency-name: nltk
  dependency-version: 3.10.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: data-nlp-search
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-03 02:17:57 +00:00
GitHub Actions 1e5afe0968 Auto translate strings 2026-09-02 23:59:57 +00:00
shamoon 78ea120e0e Fix: use the header loading indicator on tasks page (#13949) 2026-09-02 16:58:14 -07:00
GitHub Actions 6b2a5e1a2e Auto translate strings 2026-09-02 23:51:42 +00:00
dependabot[bot]andshamoon bb88453a5f Chore(deps): Bump the frontend-angular-dependencies group across 1 directory with 14 updates (#13915)
Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
Signed-off-by: dependabot[bot] <support@github.com>
2026-09-02 23:50:05 +00:00
dependabot[bot] 135f9f6251 Chore(deps): Bump djangorestframework in the uv group across 1 directory (#13904)
Bumps the uv group with 1 update in the / directory: [djangorestframework](https://github.com/encode/django-rest-framework).


Updates `djangorestframework` from 3.17.1 to 3.17.2
- [Release notes](https://github.com/encode/django-rest-framework/releases)
- [Commits](https://github.com/encode/django-rest-framework/compare/3.17.1...3.17.2)

---
updated-dependencies:
- dependency-name: djangorestframework
  dependency-version: 3.17.2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-02 22:48:44 +00:00
shamoon 1c0fbeb6f3 Fix: fix load sidebar size animating (#13947) 2026-09-02 15:25:24 -07:00
shamoon 1ba1f2b9c2 Fix: wrap long words without spaces in dropdowns (#13945) 2026-09-02 13:33:48 -07:00
shamoon 07f1a356f8 Fix: tweak tool calling localzation prompt (#13943) 2026-09-02 19:45:11 +00:00
GitHub Actions 8d41d31bd7 Auto translate strings 2026-09-02 18:10:21 +00:00
Trenton Handshamoon 351892bbab Fix: skip vector store document id filter for unrestricted chat users (#13937)
* Fix: skip vector store document id filter for unrestricted chat users

ChatStreamingView built an IN filter from every permitted document id
for the "chat over all documents" case, which exceeds the vector
store's SQLite bound-parameter safety limit on installs with more
than ~32700 documents, silently returning no context. For a user who
can see every document (an active superuser), that filter never
narrows anything, so skip it and let the retriever search the whole
index instead.

* Minor improvements from a Claude review

* When a user is unrestricted chatting, still exclude trashed documents using a 'NOT IN' SQL statement.  Wire that up where we need it

* Update src/paperless_ai/chat.py

Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
2026-09-02 18:08:54 +00:00
Thomas Steinbachandshamoon 5d6ea11828 Fix: adopt the request stream when pinning an outbound host (#13927)
Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
2026-09-02 17:04:09 +00:00
shamoon c5765a50a1 Fix: ensure apply ai suggestions always runs after document created (#13940) 2026-09-02 16:12:49 +00:00
Trenton H c2a9532b8f Fix: Handle Celery enqueue failures when enqueuing files for consumption (#13935) 2026-09-02 15:58:27 +00:00
Trenton H 713c857a08 Fix: Handle Celery mail task chord errors (#13936)
* Fix: mail rule loops forever when all attachments are duplicates

When every attachment in a mail is rejected as a duplicate, the chord's
header tasks all fail. Celery's default task_allow_error_cb_on_chord_header
skips the error callback in that case, so no ProcessedMail row is ever
created, and the same mail is refetched and reprocessed on every poll for
as long as it stays in the rule's maximum_age window.

* Minor simplifications and cleanup
2026-09-02 08:41:30 -07:00
168 changed files with 28161 additions and 28255 deletions
-1
View File
@@ -38,7 +38,6 @@ body:
label: Installation method label: Installation method
options: options:
- Docker - official image - Docker - official image
- Docker - linuxserver.io image
- Bare metal - Bare metal
- Other (please describe above) - Other (please describe above)
- type: textarea - type: textarea
-2
View File
@@ -87,10 +87,8 @@ body:
label: Installation method label: Installation method
options: options:
- Docker - official image - Docker - official image
- Docker - linuxserver.io image
- Bare metal - Bare metal
- Other (please describe above) - Other (please describe above)
description: Note there are significant differences from the official image and linuxserver.io, please check if your issue is specific to the third-party image.
validations: validations:
required: true required: true
- type: textarea - type: textarea
+3 -3
View File
@@ -63,7 +63,7 @@ jobs:
- name: Detect changes - name: Detect changes
id: filter id: filter
if: steps.force.outputs.run_all != 'true' if: steps.force.outputs.run_all != 'true'
uses: dorny/paths-filter@7b450fff21473bca461d4b92ce414b9d0420d706 # v4.0.2 uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
with: with:
base: ${{ steps.range.outputs.base }} base: ${{ steps.range.outputs.base }}
ref: ${{ steps.range.outputs.ref }} ref: ${{ steps.range.outputs.ref }}
@@ -100,7 +100,7 @@ jobs:
with: with:
python-version: "${{ matrix.python-version }}" python-version: "${{ matrix.python-version }}"
- name: Install uv - name: Install uv
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
with: with:
version: ${{ env.DEFAULT_UV_VERSION }} version: ${{ env.DEFAULT_UV_VERSION }}
enable-cache: true enable-cache: true
@@ -178,7 +178,7 @@ jobs:
with: with:
python-version: "${{ env.DEFAULT_PYTHON }}" python-version: "${{ env.DEFAULT_PYTHON }}"
- name: Install uv - name: Install uv
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
with: with:
version: ${{ env.DEFAULT_UV_VERSION }} version: ${{ env.DEFAULT_UV_VERSION }}
enable-cache: true enable-cache: true
+6 -6
View File
@@ -106,9 +106,9 @@ jobs:
echo "repository=${repo_name}" echo "repository=${repo_name}"
echo "name=${repo_name}" >> $GITHUB_OUTPUT echo "name=${repo_name}" >> $GITHUB_OUTPUT
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0 uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0
- name: Login to GitHub Container Registry - name: Login to GitHub Container Registry
uses: docker/login-action@abd2ef45e78c5afb21d64d4ca52ee8550d9572c7 # v4.5.1 uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with: with:
registry: ${{ env.REGISTRY }} registry: ${{ env.REGISTRY }}
username: ${{ github.actor }} username: ${{ github.actor }}
@@ -182,22 +182,22 @@ jobs:
echo "Downloaded digests:" echo "Downloaded digests:"
ls -la /tmp/digests/ ls -la /tmp/digests/
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0 uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0
- name: Login to GitHub Container Registry - name: Login to GitHub Container Registry
uses: docker/login-action@abd2ef45e78c5afb21d64d4ca52ee8550d9572c7 # v4.5.1 uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with: with:
registry: ${{ env.REGISTRY }} registry: ${{ env.REGISTRY }}
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to Docker Hub - name: Login to Docker Hub
if: needs.build-arch.outputs.push-external == 'true' if: needs.build-arch.outputs.push-external == 'true'
uses: docker/login-action@abd2ef45e78c5afb21d64d4ca52ee8550d9572c7 # v4.5.1 uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with: with:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to Quay.io - name: Login to Quay.io
if: needs.build-arch.outputs.push-external == 'true' if: needs.build-arch.outputs.push-external == 'true'
uses: docker/login-action@abd2ef45e78c5afb21d64d4ca52ee8550d9572c7 # v4.5.1 uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with: with:
registry: quay.io registry: quay.io
username: ${{ secrets.QUAY_USERNAME }} username: ${{ secrets.QUAY_USERNAME }}
+2 -2
View File
@@ -50,7 +50,7 @@ jobs:
- name: Detect changes - name: Detect changes
id: filter id: filter
if: steps.force.outputs.run_all != 'true' if: steps.force.outputs.run_all != 'true'
uses: dorny/paths-filter@7b450fff21473bca461d4b92ce414b9d0420d706 # v4.0.2 uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
with: with:
base: ${{ steps.range.outputs.base }} base: ${{ steps.range.outputs.base }}
ref: ${{ steps.range.outputs.ref }} ref: ${{ steps.range.outputs.ref }}
@@ -78,7 +78,7 @@ jobs:
with: with:
python-version: ${{ env.DEFAULT_PYTHON_VERSION }} python-version: ${{ env.DEFAULT_PYTHON_VERSION }}
- name: Install uv - name: Install uv
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
with: with:
version: ${{ env.DEFAULT_UV_VERSION }} version: ${{ env.DEFAULT_UV_VERSION }}
enable-cache: true enable-cache: true
+7 -7
View File
@@ -60,7 +60,7 @@ jobs:
- name: Detect changes - name: Detect changes
id: filter id: filter
if: steps.force.outputs.run_all != 'true' if: steps.force.outputs.run_all != 'true'
uses: dorny/paths-filter@7b450fff21473bca461d4b92ce414b9d0420d706 # v4.0.2 uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
with: with:
base: ${{ steps.range.outputs.base }} base: ${{ steps.range.outputs.base }}
ref: ${{ steps.range.outputs.ref }} ref: ${{ steps.range.outputs.ref }}
@@ -81,7 +81,7 @@ jobs:
with: with:
persist-credentials: false persist-credentials: false
- name: Install pnpm - name: Install pnpm
uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10
with: with:
package_json_file: src-ui/package.json package_json_file: src-ui/package.json
- name: Use Node.js 24 - name: Use Node.js 24
@@ -113,7 +113,7 @@ jobs:
with: with:
persist-credentials: false persist-credentials: false
- name: Install pnpm - name: Install pnpm
uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10
with: with:
package_json_file: src-ui/package.json package_json_file: src-ui/package.json
- name: Use Node.js 24 - name: Use Node.js 24
@@ -152,7 +152,7 @@ jobs:
with: with:
persist-credentials: false persist-credentials: false
- name: Install pnpm - name: Install pnpm
uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10
with: with:
package_json_file: src-ui/package.json package_json_file: src-ui/package.json
- name: Use Node.js 24 - name: Use Node.js 24
@@ -201,7 +201,7 @@ jobs:
with: with:
persist-credentials: false persist-credentials: false
- name: Install pnpm - name: Install pnpm
uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10
with: with:
package_json_file: src-ui/package.json package_json_file: src-ui/package.json
- name: Use Node.js 24 - name: Use Node.js 24
@@ -216,7 +216,7 @@ jobs:
with: with:
python-version: '3.12' python-version: '3.12'
- name: Install uv - name: Install uv
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
with: with:
version: '0.12.x' version: '0.12.x'
enable-cache: false enable-cache: false
@@ -255,7 +255,7 @@ jobs:
fetch-depth: 2 fetch-depth: 2
persist-credentials: false persist-credentials: false
- name: Install pnpm - name: Install pnpm
uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10
with: with:
package_json_file: src-ui/package.json package_json_file: src-ui/package.json
- name: Use Node.js 24 - name: Use Node.js 24
+1 -1
View File
@@ -25,4 +25,4 @@ jobs:
with: with:
python-version: "3.14" python-version: "3.14"
- name: Run prek - name: Run prek
uses: j178/prek-action@5337cb91e0fa35a7ff31b9ca345126d8bbbcdf16 # v2.0.6 uses: j178/prek-action@4e14d07f9231acabce116ccfca13b13dd9755ece # v3.0.0
+6 -6
View File
@@ -20,7 +20,7 @@ jobs:
statuses: read statuses: read
steps: steps:
- name: Wait for Docker build - name: Wait for Docker build
uses: lewagon/wait-on-check-action@2271c86c146b96545b4e871b855e10ffa6f50773 # v1.9.0 uses: lewagon/wait-on-check-action@369769072fe522a3a8a85c03c96af1e5242a1994 # v1.9.1
with: with:
ref: ${{ github.sha }} ref: ${{ github.sha }}
check-name: 'Merge and Push Manifest' check-name: 'Merge and Push Manifest'
@@ -40,7 +40,7 @@ jobs:
persist-credentials: false persist-credentials: false
# ---- Frontend Build ---- # ---- Frontend Build ----
- name: Install pnpm - name: Install pnpm
uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10
with: with:
package_json_file: src-ui/package.json package_json_file: src-ui/package.json
- name: Use Node.js 24 - name: Use Node.js 24
@@ -59,7 +59,7 @@ jobs:
with: with:
python-version: ${{ env.DEFAULT_PYTHON_VERSION }} python-version: ${{ env.DEFAULT_PYTHON_VERSION }}
- name: Install uv - name: Install uv
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
with: with:
version: ${{ env.DEFAULT_UV_VERSION }} version: ${{ env.DEFAULT_UV_VERSION }}
enable-cache: false enable-cache: false
@@ -171,7 +171,7 @@ jobs:
fi fi
- name: Create release and changelog - name: Create release and changelog
id: create-release id: create-release
uses: release-drafter/release-drafter@eada3c96a64734dd381cfbda23511034e328ddb0 # v7.6.0 uses: release-drafter/release-drafter@34d80673e067bdc0c24568d3af899c216adcfaa9 # v7.7.0
with: with:
name: Paperless-ngx ${{ steps.get-version.outputs.version }} name: Paperless-ngx ${{ steps.get-version.outputs.version }}
tag: ${{ steps.get-version.outputs.version }} tag: ${{ steps.get-version.outputs.version }}
@@ -182,7 +182,7 @@ jobs:
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload release archive - name: Upload release archive
uses: shogo82148/actions-upload-release-asset@394b3c11c3cfc038b5396ad265c074065cf875c3 # v1.10.2 uses: shogo82148/actions-upload-release-asset@aaba0f56bdbc1071f4af234d5cb16055e8a400de # v1.10.4
with: with:
github_token: ${{ secrets.GITHUB_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }}
upload_url: ${{ steps.create-release.outputs.upload_url }} upload_url: ${{ steps.create-release.outputs.upload_url }}
@@ -212,7 +212,7 @@ jobs:
with: with:
python-version: ${{ env.DEFAULT_PYTHON_VERSION }} python-version: ${{ env.DEFAULT_PYTHON_VERSION }}
- name: Install uv - name: Install uv
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
with: with:
version: ${{ env.DEFAULT_UV_VERSION }} version: ${{ env.DEFAULT_UV_VERSION }}
enable-cache: false enable-cache: false
+2 -2
View File
@@ -26,7 +26,7 @@ jobs:
with: with:
persist-credentials: false persist-credentials: false
- name: Run zizmor - name: Run zizmor
uses: zizmorcore/zizmor-action@6fc4b006235f201fdab3722e17240ab420d580e5 # v0.6.1 uses: zizmorcore/zizmor-action@3dc1ecc9bcb9e94e9b2c709687979e1298497054 # v0.6.2
semgrep: semgrep:
name: Semgrep CE name: Semgrep CE
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
@@ -44,7 +44,7 @@ jobs:
- name: Run Semgrep - name: Run Semgrep
run: semgrep scan --config auto --sarif-output results.sarif run: semgrep scan --config auto --sarif-output results.sarif
- name: Upload results to GitHub code scanning - name: Upload results to GitHub code scanning
uses: github/codeql-action/upload-sarif@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4.37.3 uses: github/codeql-action/upload-sarif@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4.37.9
if: always() if: always()
with: with:
sarif_file: results.sarif sarif_file: results.sarif
+2 -2
View File
@@ -39,7 +39,7 @@ jobs:
persist-credentials: false persist-credentials: false
# Initializes the CodeQL tools for scanning. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4.37.3 uses: github/codeql-action/init@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4.37.9
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file. # If you wish to specify custom queries, you can do so here or in a config file.
@@ -47,4 +47,4 @@ jobs:
# Prefix the list here with "+" to use these queries and those in the config file. # Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main # queries: ./path/to/local/query, your-org/your-repo/queries@main
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4.37.3 uses: github/codeql-action/analyze@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4.37.9
+1 -1
View File
@@ -22,7 +22,7 @@ jobs:
token: ${{ secrets.PNGX_BOT_PAT }} token: ${{ secrets.PNGX_BOT_PAT }}
persist-credentials: false persist-credentials: false
- name: crowdin action - name: crowdin action
uses: crowdin/github-action@c7af9bc98b01694653031fef2a0dc6c7888ce9bc # v2.17.0 uses: crowdin/github-action@e4a6c1338b4063c77d46a81875265f9e8bd76f95 # v3.0.0
with: with:
upload_translations: false upload_translations: false
download_translations: true download_translations: true
+1 -1
View File
@@ -19,6 +19,6 @@ jobs:
if: github.event_name == 'pull_request_target' && (github.event.action == 'opened' || github.event.action == 'reopened') && github.event.pull_request.user.login != 'dependabot' if: github.event_name == 'pull_request_target' && (github.event.action == 'opened' || github.event.action == 'reopened') && github.event.pull_request.user.login != 'dependabot'
steps: steps:
- name: Label PR with release-drafter - name: Label PR with release-drafter
uses: release-drafter/release-drafter@eada3c96a64734dd381cfbda23511034e328ddb0 # v7.6.0 uses: release-drafter/release-drafter@34d80673e067bdc0c24568d3af899c216adcfaa9 # v7.7.0
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+1 -1
View File
@@ -14,7 +14,7 @@ jobs:
issues: write issues: write
pull-requests: write pull-requests: write
steps: steps:
- uses: actions/stale@1e223db275d687790206a7acac4d1a11bd6fe629 # v10.4.0 - uses: actions/stale@4391f3da665fdf50b6810c1a66712fb9ba21aa93 # v11.0.0
with: with:
days-before-stale: 7 days-before-stale: 7
days-before-close: 14 days-before-close: 14
+2 -2
View File
@@ -29,7 +29,7 @@ jobs:
sudo apt-get update -qq sudo apt-get update -qq
sudo apt-get install -qq --no-install-recommends gettext sudo apt-get install -qq --no-install-recommends gettext
- name: Install uv - name: Install uv
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
with: with:
version: ${{ env.DEFAULT_UV_VERSION }} version: ${{ env.DEFAULT_UV_VERSION }}
enable-cache: true enable-cache: true
@@ -43,7 +43,7 @@ jobs:
PAPERLESS_SECRET_KEY: "ci-translate-not-a-real-secret" PAPERLESS_SECRET_KEY: "ci-translate-not-a-real-secret"
run: cd src/ && uv run manage.py makemessages -l en_US -i "samples*" run: cd src/ && uv run manage.py makemessages -l en_US -i "samples*"
- name: Install pnpm - name: Install pnpm
uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10
with: with:
package_json_file: src-ui/package.json package_json_file: src-ui/package.json
- name: Use Node.js 24 - name: Use Node.js 24
+3 -3
View File
@@ -50,18 +50,18 @@ repos:
- 'prettier-plugin-organize-imports@4.3.0' - 'prettier-plugin-organize-imports@4.3.0'
# Python hooks # Python hooks
- repo: https://github.com/astral-sh/ruff-pre-commit - repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.16.1 rev: v0.16.5
hooks: hooks:
- id: ruff-check - id: ruff-check
- id: ruff-format - id: ruff-format
- repo: https://github.com/tox-dev/pyproject-fmt - repo: https://github.com/tox-dev/pyproject-fmt
rev: "v2.26.0" rev: "v2.28.1"
hooks: hooks:
- id: pyproject-fmt - id: pyproject-fmt
additional_dependencies: [tomli] additional_dependencies: [tomli]
# Dockerfile hooks # Dockerfile hooks
- repo: https://github.com/AleksaC/hadolint-py - repo: https://github.com/AleksaC/hadolint-py
rev: v2.14.0 rev: v2.15.1
hooks: hooks:
- id: hadolint - id: hadolint
# Shell script hooks # Shell script hooks
+1 -1
View File
@@ -30,7 +30,7 @@ RUN set -eux \
# Purpose: Installs s6-overlay and rootfs # Purpose: Installs s6-overlay and rootfs
# Comments: # Comments:
# - Don't leave anything extra in here either # - Don't leave anything extra in here either
FROM ghcr.io/astral-sh/uv:0.12.5-python3.14-trixie-slim AS s6-overlay-base FROM ghcr.io/astral-sh/uv:0.12.9-python3.14-trixie-slim AS s6-overlay-base
WORKDIR /usr/src/s6 WORKDIR /usr/src/s6
+3 -3
View File
@@ -4,7 +4,7 @@
# correct networking for the tests # correct networking for the tests
services: services:
gotenberg: gotenberg:
image: docker.io/gotenberg/gotenberg:8.34 image: docker.io/gotenberg/gotenberg:8.36
hostname: gotenberg hostname: gotenberg
container_name: gotenberg container_name: gotenberg
network_mode: host network_mode: host
@@ -24,7 +24,7 @@ services:
network_mode: host network_mode: host
restart: unless-stopped restart: unless-stopped
greenmail: greenmail:
image: docker.io/greenmail/standalone:2.1.11 image: docker.io/greenmail/standalone:2.1.13
hostname: greenmail hostname: greenmail
container_name: greenmail container_name: greenmail
environment: environment:
@@ -35,7 +35,7 @@ services:
- "3143:3143" # IMAP - "3143:3143" # IMAP
restart: unless-stopped restart: unless-stopped
nginx: nginx:
image: docker.io/nginx:1.31.3-alpine image: docker.io/nginx:1.31.5-alpine
hostname: nginx hostname: nginx
container_name: nginx container_name: nginx
ports: ports:
@@ -72,7 +72,7 @@ services:
PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://gotenberg:3000 PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://gotenberg:3000
PAPERLESS_TIKA_ENDPOINT: http://tika:9998 PAPERLESS_TIKA_ENDPOINT: http://tika:9998
gotenberg: gotenberg:
image: docker.io/gotenberg/gotenberg:8.34 image: docker.io/gotenberg/gotenberg:8.36
restart: unless-stopped restart: unless-stopped
# The gotenberg chromium route is used to convert .eml files. We do not # The gotenberg chromium route is used to convert .eml files. We do not
# want to allow external content like tracking pixels or even javascript. # want to allow external content like tracking pixels or even javascript.
@@ -67,7 +67,7 @@ services:
PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://gotenberg:3000 PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://gotenberg:3000
PAPERLESS_TIKA_ENDPOINT: http://tika:9998 PAPERLESS_TIKA_ENDPOINT: http://tika:9998
gotenberg: gotenberg:
image: docker.io/gotenberg/gotenberg:8.34 image: docker.io/gotenberg/gotenberg:8.36
restart: unless-stopped restart: unless-stopped
# The gotenberg chromium route is used to convert .eml files. We do not # The gotenberg chromium route is used to convert .eml files. We do not
# want to allow external content like tracking pixels or even javascript. # want to allow external content like tracking pixels or even javascript.
@@ -56,7 +56,7 @@ services:
PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://gotenberg:3000 PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://gotenberg:3000
PAPERLESS_TIKA_ENDPOINT: http://tika:9998 PAPERLESS_TIKA_ENDPOINT: http://tika:9998
gotenberg: gotenberg:
image: docker.io/gotenberg/gotenberg:8.34 image: docker.io/gotenberg/gotenberg:8.36
restart: unless-stopped restart: unless-stopped
# The gotenberg chromium route is used to convert .eml files. We do not # The gotenberg chromium route is used to convert .eml files. We do not
# want to allow external content like tracking pixels or even javascript. # want to allow external content like tracking pixels or even javascript.
+64
View File
@@ -1,5 +1,69 @@
# Changelog # Changelog
## paperless-ngx 3.1.3
### Bug Fixes
- Fix: use the header loading indicator on tasks page [@shamoon](https://github.com/shamoon) ([#13949](https://github.com/paperless-ngx/paperless-ngx/pull/13949))
- Fix: fix load sidebar size animating [@shamoon](https://github.com/shamoon) ([#13947](https://github.com/paperless-ngx/paperless-ngx/pull/13947))
- Fix: wrap long words without spaces in dropdowns [@shamoon](https://github.com/shamoon) ([#13945](https://github.com/paperless-ngx/paperless-ngx/pull/13945))
- Fix: tweak tool calling localization prompt [@shamoon](https://github.com/shamoon) ([#13943](https://github.com/paperless-ngx/paperless-ngx/pull/13943))
- Fix: skip vector store document id filter for unrestricted chat users [@stumpylog](https://github.com/stumpylog) ([#13937](https://github.com/paperless-ngx/paperless-ngx/pull/13937))
- Fix: adopt the request stream when pinning an outbound host [@ThomasSteinbach](https://github.com/ThomasSteinbach) ([#13927](https://github.com/paperless-ngx/paperless-ngx/pull/13927))
- Fix: ensure apply ai suggestions always runs after document created [@shamoon](https://github.com/shamoon) ([#13940](https://github.com/paperless-ngx/paperless-ngx/pull/13940))
- Fix: Handle failures when enqueuing files for consumption [@stumpylog](https://github.com/stumpylog) ([#13935](https://github.com/paperless-ngx/paperless-ngx/pull/13935))
- Fix: Handle Celery mail task chord errors [@stumpylog](https://github.com/stumpylog) ([#13936](https://github.com/paperless-ngx/paperless-ngx/pull/13936))
- Fix/chore: refactor some signal-backed conversion technical debt [@shamoon](https://github.com/shamoon) ([#13902](https://github.com/paperless-ngx/paperless-ngx/pull/13902))
- Fix: fix slim sidebar saved view dragging appearance [@shamoon](https://github.com/shamoon) ([#13906](https://github.com/paperless-ngx/paperless-ngx/pull/13906))
- Fix: use signal-backed queries input in CF dropdown to reflect changes immediately under zoneless [@shamoon](https://github.com/shamoon) ([#13901](https://github.com/paperless-ngx/paperless-ngx/pull/13901))
- Fix: use root doc metadata for filename generation [@shamoon](https://github.com/shamoon) ([#13893](https://github.com/paperless-ngx/paperless-ngx/pull/13893))
- Fix: some css cleanup [@shamoon](https://github.com/shamoon) ([#13891](https://github.com/paperless-ngx/paperless-ngx/pull/13891))
### Dependencies
<details>
<summary>7 changes</summary>
- Chore(deps): Bump the uv group across 1 directory with 2 updates @[dependabot[bot]](https://github.com/apps/dependabot) ([#13958](https://github.com/paperless-ngx/paperless-ngx/pull/13958))
- docker-compose(deps): bump nginx from 1.31.3-alpine to 1.31.5-alpine in /docker/compose @[dependabot[bot]](https://github.com/apps/dependabot) ([#13909](https://github.com/paperless-ngx/paperless-ngx/pull/13909))
- docker-compose(deps): Bump greenmail/standalone from 2.1.11 to 2.1.13 in /docker/compose @[dependabot[bot]](https://github.com/apps/dependabot) ([#13907](https://github.com/paperless-ngx/paperless-ngx/pull/13907))
- Chore(deps-dev): Bump postcss-selector-parser from 6.1.2 to 6.1.4 in /src/paperless\_mail/templates in the npm\_and\_yarn group across 1 directory @[dependabot[bot]](https://github.com/apps/dependabot) ([#13905](https://github.com/paperless-ngx/paperless-ngx/pull/13905))
- Chore(deps): Bump nltk from 3.10.0 to 3.10.3 in the data-nlp-search group across 1 directory @[dependabot[bot]](https://github.com/apps/dependabot) ([#13917](https://github.com/paperless-ngx/paperless-ngx/pull/13917))
- Chore(deps): Bump the frontend-angular-dependencies group across 1 directory with 14 updates @[dependabot[bot]](https://github.com/apps/dependabot) ([#13915](https://github.com/paperless-ngx/paperless-ngx/pull/13915))
- Chore(deps): Bump djangorestframework from 3.17.1 to 3.17.2 in the uv group across 1 directory @[dependabot[bot]](https://github.com/apps/dependabot) ([#13904](https://github.com/paperless-ngx/paperless-ngx/pull/13904))
</details>
### All App Changes
<details>
<summary>22 changes</summary>
- Chore(deps): Bump the uv group across 1 directory with 2 updates @[dependabot[bot]](https://github.com/apps/dependabot) ([#13958](https://github.com/paperless-ngx/paperless-ngx/pull/13958))
- Chore(deps-dev): Bump postcss-selector-parser from 6.1.2 to 6.1.4 in /src/paperless\_mail/templates in the npm\_and\_yarn group across 1 directory @[dependabot[bot]](https://github.com/apps/dependabot) ([#13905](https://github.com/paperless-ngx/paperless-ngx/pull/13905))
- Chore(deps): Bump nltk from 3.10.0 to 3.10.3 in the data-nlp-search group across 1 directory @[dependabot[bot]](https://github.com/apps/dependabot) ([#13917](https://github.com/paperless-ngx/paperless-ngx/pull/13917))
- Fix: use the header loading indicator on tasks page [@shamoon](https://github.com/shamoon) ([#13949](https://github.com/paperless-ngx/paperless-ngx/pull/13949))
- Chore(deps): Bump the frontend-angular-dependencies group across 1 directory with 14 updates @[dependabot[bot]](https://github.com/apps/dependabot) ([#13915](https://github.com/paperless-ngx/paperless-ngx/pull/13915))
- Chore(deps): Bump djangorestframework from 3.17.1 to 3.17.2 in the uv group across 1 directory @[dependabot[bot]](https://github.com/apps/dependabot) ([#13904](https://github.com/paperless-ngx/paperless-ngx/pull/13904))
- Fix: fix load sidebar size animating [@shamoon](https://github.com/shamoon) ([#13947](https://github.com/paperless-ngx/paperless-ngx/pull/13947))
- Fix: wrap long words without spaces in dropdowns [@shamoon](https://github.com/shamoon) ([#13945](https://github.com/paperless-ngx/paperless-ngx/pull/13945))
- Fix: tweak tool calling localization prompt [@shamoon](https://github.com/shamoon) ([#13943](https://github.com/paperless-ngx/paperless-ngx/pull/13943))
- Fix: skip vector store document id filter for unrestricted chat users [@stumpylog](https://github.com/stumpylog) ([#13937](https://github.com/paperless-ngx/paperless-ngx/pull/13937))
- Fix: adopt the request stream when pinning an outbound host [@ThomasSteinbach](https://github.com/ThomasSteinbach) ([#13927](https://github.com/paperless-ngx/paperless-ngx/pull/13927))
- Fix: ensure apply ai suggestions always runs after document created [@shamoon](https://github.com/shamoon) ([#13940](https://github.com/paperless-ngx/paperless-ngx/pull/13940))
- Fix: Handle failures when enqueuing files for consumption [@stumpylog](https://github.com/stumpylog) ([#13935](https://github.com/paperless-ngx/paperless-ngx/pull/13935))
- Fix: Handle Celery mail task chord errors [@stumpylog](https://github.com/stumpylog) ([#13936](https://github.com/paperless-ngx/paperless-ngx/pull/13936))
- Fix/chore: refactor some signal-backed conversion technical debt [@shamoon](https://github.com/shamoon) ([#13902](https://github.com/paperless-ngx/paperless-ngx/pull/13902))
- Security: validate remote OCR endpoint [@stumpylog](https://github.com/stumpylog) ([#13897](https://github.com/paperless-ngx/paperless-ngx/pull/13897))
- Fix: fix slim sidebar saved view dragging appearance [@shamoon](https://github.com/shamoon) ([#13906](https://github.com/paperless-ngx/paperless-ngx/pull/13906))
- Security: Minor additional hardening [@stumpylog](https://github.com/stumpylog) ([#13898](https://github.com/paperless-ngx/paperless-ngx/pull/13898))
- Chore: consolidate pickle hmac signing [@shamoon](https://github.com/shamoon) ([#13899](https://github.com/paperless-ngx/paperless-ngx/pull/13899))
- Fix: use signal-backed queries input in CF dropdown to reflect changes immediately under zoneless [@shamoon](https://github.com/shamoon) ([#13901](https://github.com/paperless-ngx/paperless-ngx/pull/13901))
- Fix: use root doc metadata for filename generation [@shamoon](https://github.com/shamoon) ([#13893](https://github.com/paperless-ngx/paperless-ngx/pull/13893))
- Fix: some css cleanup [@shamoon](https://github.com/shamoon) ([#13891](https://github.com/paperless-ngx/paperless-ngx/pull/13891))
</details>
## paperless-ngx 3.1.2 ## paperless-ngx 3.1.2
### Bug Fixes ### Bug Fixes
+28 -14
View File
@@ -415,10 +415,10 @@ plain class attributes (not instance attributes or properties):
```python ```python
class MyCustomParser: class MyCustomParser:
name = "My Format Parser" # human-readable name shown in logs name = "My Format Parser" # human-readable name shown in logs
version = "1.0.0" # semantic version string version = "1.0.0" # semantic version string
author = "Acme Corp" # author / organisation author = "Acme Corp" # author / organisation
url = "https://example.com/my-parser" # docs or issue tracker url = "https://example.com/my-parser" # docs or issue tracker
``` ```
**Declaring supported MIME types** **Declaring supported MIME types**
@@ -482,7 +482,8 @@ attribute are treated as fully local and are always considered.
@property @property
def can_produce_archive(self) -> bool: def can_produce_archive(self) -> bool:
"""True if parse() can produce a searchable PDF archive copy.""" """True if parse() can produce a searchable PDF archive copy."""
return True # or False if your parser doesn't produce PDFs return True # or False if your parser doesn't produce PDFs
@property @property
def requires_pdf_rendition(self) -> bool: def requires_pdf_rendition(self) -> bool:
@@ -507,6 +508,7 @@ from types import TracebackType
from django.conf import settings from django.conf import settings
class MyCustomParser: class MyCustomParser:
... ...
@@ -539,8 +541,9 @@ implementation is fine:
```python ```python
from paperless.parsers import ParserContext from paperless.parsers import ParserContext
def configure(self, context: ParserContext) -> None: def configure(self, context: ParserContext) -> None:
pass # override if you need context.mailrule_id, etc. pass # override if you need context.mailrule_id, etc.
``` ```
**Parsing** **Parsing**
@@ -552,6 +555,7 @@ Raise `documents.parsers.ParseError` on any unrecoverable failure.
```python ```python
from documents.parsers import ParseError from documents.parsers import ParseError
def parse( def parse(
self, self,
document_path: Path, document_path: Path,
@@ -577,18 +581,20 @@ def get_text(self) -> str:
# Return the extracted text, or an empty string if none was found. # Return the extracted text, or an empty string if none was found.
return self._text return self._text
def get_date(self) -> "datetime.datetime | None": def get_date(self) -> "datetime.datetime | None":
# Return a datetime extracted from the document, or None to let # Return a datetime extracted from the document, or None to let
# Paperless-ngx use its default date-guessing logic. # Paperless-ngx use its default date-guessing logic.
return None return None
def get_archive_path(self) -> Path | None: def get_archive_path(self) -> Path | None:
return self._archive_path return self._archive_path
def get_page_count(self, document_path: Path, mime_type: str) -> int | None: def get_page_count(self, document_path: Path, mime_type: str) -> int | None:
# If the format doesn't have the concept of pages, return None # If the format doesn't have the concept of pages, return None
return count_pages(document_path) return count_pages(document_path)
``` ```
**Thumbnail** **Thumbnail**
@@ -611,7 +617,6 @@ Implement them if your format supports the information; otherwise return
`None` / `[]`. `None` / `[]`.
```python ```python
def extract_metadata( def extract_metadata(
self, self,
document_path: Path, document_path: Path,
@@ -619,6 +624,7 @@ def extract_metadata(
) -> "list[MetadataEntry]": ) -> "list[MetadataEntry]":
# Must never raise. Return [] if metadata cannot be read. # Must never raise. Return [] if metadata cannot be read.
from paperless.parsers import MetadataEntry from paperless.parsers import MetadataEntry
return [ return [
MetadataEntry( MetadataEntry(
namespace="https://example.com/ns/", namespace="https://example.com/ns/",
@@ -681,17 +687,19 @@ from paperless.parsers import ParserContext
class XmlDocumentParser: class XmlDocumentParser:
name = "XML Parser" name = "XML Parser"
version = "1.0.0" version = "1.0.0"
author = "Acme Corp" author = "Acme Corp"
url = "https://example.com/xml-parser" url = "https://example.com/xml-parser"
@classmethod @classmethod
def supported_mime_types(cls) -> dict[str, str]: def supported_mime_types(cls) -> dict[str, str]:
return {"application/xml": ".xml", "text/xml": ".xml"} return {"application/xml": ".xml", "text/xml": ".xml"}
@classmethod @classmethod
def score(cls, mime_type: str, filename: str, path: Path | None = None) -> int | None: def score(
cls, mime_type: str, filename: str, path: Path | None = None
) -> int | None:
return 10 return 10
@property @property
@@ -704,7 +712,9 @@ class XmlDocumentParser:
def __init__(self, logging_group: object = None) -> None: def __init__(self, logging_group: object = None) -> None:
settings.SCRATCH_DIR.mkdir(parents=True, exist_ok=True) settings.SCRATCH_DIR.mkdir(parents=True, exist_ok=True)
self._tempdir = Path(tempfile.mkdtemp(prefix="paperless-", dir=settings.SCRATCH_DIR)) self._tempdir = Path(
tempfile.mkdtemp(prefix="paperless-", dir=settings.SCRATCH_DIR)
)
self._text: str = "" self._text: str = ""
def __enter__(self) -> Self: def __enter__(self) -> Self:
@@ -716,7 +726,9 @@ class XmlDocumentParser:
def configure(self, context: ParserContext) -> None: def configure(self, context: ParserContext) -> None:
pass pass
def parse(self, document_path: Path, mime_type: str, *, produce_archive: bool = True) -> None: def parse(
self, document_path: Path, mime_type: str, *, produce_archive: bool = True
) -> None:
try: try:
tree = ET.parse(document_path) tree = ET.parse(document_path)
self._text = " ".join(tree.getroot().itertext()) self._text = " ".join(tree.getroot().itertext())
@@ -734,6 +746,7 @@ class XmlDocumentParser:
def get_thumbnail(self, document_path: Path, mime_type: str) -> Path: def get_thumbnail(self, document_path: Path, mime_type: str) -> Path:
from PIL import Image, ImageDraw from PIL import Image, ImageDraw
img = Image.new("RGB", (500, 700), color="white") img = Image.new("RGB", (500, 700), color="white")
ImageDraw.Draw(img).text((10, 10), "XML Document", fill="black") ImageDraw.Draw(img).text((10, 10), "XML Document", fill="black")
out = self._tempdir / "thumb.webp" out = self._tempdir / "thumb.webp"
@@ -822,6 +835,7 @@ def _parse_string(
Parse a single date string using dateparser with configured settings. Parse a single date string using dateparser with configured settings.
""" """
def _filter_date( def _filter_date(
self, self,
date: datetime.datetime | None, date: datetime.datetime | None,
+17 -17
View File
@@ -1,6 +1,6 @@
[project] [project]
name = "paperless-ngx" name = "paperless-ngx"
version = "3.1.2" version = "3.1.3"
description = "A community-supported supercharged document management system: scan, index and archive all your physical documents" description = "A community-supported supercharged document management system: scan, index and archive all your physical documents"
readme = "README.md" readme = "README.md"
requires-python = ">=3.11" requires-python = ">=3.11"
@@ -42,8 +42,8 @@ dependencies = [
"drf-spectacular-sidecar~=2026.7.1", "drf-spectacular-sidecar~=2026.7.1",
"drf-writable-nested~=0.7.1", "drf-writable-nested~=0.7.1",
"filelock~=3.32.0", "filelock~=3.32.0",
"flower~=2.0.1", "flower>=2.0.1,<2.2",
"gotenberg-client~=0.14.0", "gotenberg-client[httpx]~=1.0",
"httpx-oauth~=0.17", "httpx-oauth~=0.17",
"ijson>=3.5.1", "ijson>=3.5.1",
"imap-tools~=1.14.0", "imap-tools~=1.14.0",
@@ -56,7 +56,7 @@ dependencies = [
"llama-index-llms-ollama>=0.9.1", "llama-index-llms-ollama>=0.9.1",
"llama-index-llms-openai-like>=0.7.1", "llama-index-llms-openai-like>=0.7.1",
"nltk~=3.10.0", "nltk~=3.10.0",
"ocrmypdf~=17.7.0", "ocrmypdf>=17.7,<17.11",
"openai>=2.48", "openai>=2.48",
"pathvalidate~=3.3.1", "pathvalidate~=3.3.1",
"pdf2image~=1.17.0", "pdf2image~=1.17.0",
@@ -66,14 +66,14 @@ dependencies = [
"python-ipware~=3.0.0", "python-ipware~=3.0.0",
"python-magic~=0.4.27", "python-magic~=0.4.27",
"rapidfuzz~=3.14.5", "rapidfuzz~=3.14.5",
"redis[hiredis]~=5.2.1", "redis[hiredis]~=6.4.0",
"regex>=2026.7.19", "regex>=2026.7.19",
"scikit-learn~=1.9.0", "scikit-learn~=1.9.0",
"sentence-transformers>=5.6.1", "sentence-transformers>=5.6.1",
"setproctitle~=1.3.4", "setproctitle~=1.3.4",
"sqlite-vec==0.1.9", "sqlite-vec==0.1.9",
"tantivy~=0.26.0", "tantivy~=0.26.0",
"tika-client~=0.11.0", "tika-client[httpx]~=1.0",
"torch~=2.13.0", "torch~=2.13.0",
"watchfiles>=1.2", "watchfiles>=1.2",
"whitenoise~=6.11", "whitenoise~=6.11",
@@ -90,7 +90,7 @@ postgres = [
"psycopg-pool==3.3.1", "psycopg-pool==3.3.1",
] ]
webserver = [ webserver = [
"granian[uvloop]~=2.7.0", "granian[uvloop]>=2.7,<2.9",
] ]
[dependency-groups] [dependency-groups]
@@ -153,10 +153,6 @@ environments = [
"sys_platform == 'linux'", "sys_platform == 'linux'",
] ]
package = false package = false
[[tool.uv.index]]
name = "pytorch-cpu"
url = "https://download.pytorch.org/whl/cpu"
explicit = true
[tool.uv.sources] [tool.uv.sources]
# Markers are chosen to select these almost exclusively when building the Docker image # Markers are chosen to select these almost exclusively when building the Docker image
psycopg-c = [ psycopg-c = [
@@ -168,6 +164,10 @@ psycopg-c = [
torch = [ torch = [
{ index = "pytorch-cpu" }, { index = "pytorch-cpu" },
] ]
[[tool.uv.index]]
name = "pytorch-cpu"
url = "https://download.pytorch.org/whl/cpu"
explicit = true
[tool.ruff] [tool.ruff]
target-version = "py311" target-version = "py311"
@@ -327,12 +327,6 @@ PAPERLESS_CHANNELS_BACKEND = "channels.layers.InMemoryChannelLayer"
# I don't think anything hits this, but just in case, basically infinite # I don't think anything hits this, but just in case, basically infinite
PAPERLESS_TOKEN_THROTTLE_RATE = "1000/min" PAPERLESS_TOKEN_THROTTLE_RATE = "1000/min"
[tool.coverage.report]
exclude_also = [
"if settings.AUDIT_LOG_ENABLED:",
"if AUDIT_LOG_ENABLED:",
"if TYPE_CHECKING:",
]
[tool.coverage.run] [tool.coverage.run]
source = [ source = [
"src/", "src/",
@@ -343,6 +337,12 @@ omit = [
"paperless/wsgi.py", "paperless/wsgi.py",
"paperless/auth.py", "paperless/auth.py",
] ]
[tool.coverage.report]
exclude_also = [
"if settings.AUDIT_LOG_ENABLED:",
"if AUDIT_LOG_ENABLED:",
"if TYPE_CHECKING:",
]
[tool.mypy-baseline] [tool.mypy-baseline]
baseline_path = ".mypy-baseline.txt" baseline_path = ".mypy-baseline.txt"
+11
View File
@@ -48,6 +48,7 @@ def seed_database() -> None:
from django.utils import timezone from django.utils import timezone
from documents.models import Correspondent from documents.models import Correspondent
from documents.models import CustomField
from documents.models import Document from documents.models import Document
from documents.models import DocumentType from documents.models import DocumentType
from documents.models import Note from documents.models import Note
@@ -81,6 +82,16 @@ def seed_database() -> None:
path="e2e/{created_year}/{title}", path="e2e/{created_year}/{title}",
owner=admin, owner=admin,
) )
CustomField.objects.create(
name="Test Select Field",
data_type=CustomField.FieldDataType.SELECT,
extra_data={
"select_options": [
{"id": "abc123", "label": "Alpha"},
{"id": "def456", "label": "Beta"},
],
},
)
today = timezone.localdate() today = timezone.localdate()
documents = [] documents = []
@@ -207,3 +207,41 @@ test('bulk edit', async ({ page }) => {
await page.getByRole('button', { name: 'Confirm' }).click() await page.getByRole('button', { name: 'Confirm' }).click()
await bulkEditPromise await bulkEditPromise
}) })
test('permissions dropdown stays open when selecting a user', async ({
page,
}) => {
await page.goto('/documents')
await page.getByRole('button', { name: 'Permissions' }).click()
const dropdown = page.locator(
'pngx-permissions-filter-dropdown .dropdown-menu'
)
await expect(dropdown).toBeVisible()
await dropdown.locator('ng-select').click()
await page.getByRole('option', { name: 'playwright' }).click()
await expect(dropdown).toBeVisible()
await expect(dropdown.locator('.ng-value-label')).toHaveText('playwright')
})
test('custom fields query dropdown stays open when building a query', async ({
page,
}) => {
await page.goto('/documents')
await page.getByRole('button', { name: 'Custom fields' }).click()
const dropdown = page.locator(
'pngx-custom-fields-query-dropdown .dropdown-menu'
)
await expect(dropdown).toBeVisible()
// field picker
await dropdown.locator('ng-select').first().click()
await page.getByRole('option', { name: 'Test Select Field' }).click()
await expect(dropdown).toBeVisible()
// value picker, shown once the operator takes a list of options
await dropdown.locator('select').first().selectOption({ label: 'In' })
await dropdown.locator('ng-select').last().click()
await page.getByRole('option', { name: 'Alpha' }).click()
await expect(dropdown).toBeVisible()
await expect(dropdown.locator('.ng-value-label').last()).toHaveText('Alpha')
})
+135 -132
View File
@@ -5,14 +5,14 @@
<trans-unit id="ngb.alert.close" datatype="html"> <trans-unit id="ngb.alert.close" datatype="html">
<source>Close</source> <source>Close</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/alert/alert.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/alert/alert.ts</context>
<context context-type="linenumber">39</context> <context context-type="linenumber">39</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ngb.carousel.slide-number" datatype="html"> <trans-unit id="ngb.carousel.slide-number" datatype="html">
<source> Slide <x id="INTERPOLATION"/> of <x id="INTERPOLATION_1"/> </source> <source> Slide <x id="INTERPOLATION"/> of <x id="INTERPOLATION_1"/> </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/carousel/carousel.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/carousel/carousel.ts</context>
<context context-type="linenumber">129</context> <context context-type="linenumber">129</context>
</context-group> </context-group>
<note priority="1" from="description">Currently selected slide number read by screen reader</note> <note priority="1" from="description">Currently selected slide number read by screen reader</note>
@@ -20,219 +20,219 @@
<trans-unit id="ngb.carousel.previous" datatype="html"> <trans-unit id="ngb.carousel.previous" datatype="html">
<source>Previous</source> <source>Previous</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/carousel/carousel.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/carousel/carousel.ts</context>
<context context-type="linenumber">147,148</context> <context context-type="linenumber">147,148</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ngb.carousel.next" datatype="html"> <trans-unit id="ngb.carousel.next" datatype="html">
<source>Next</source> <source>Next</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/carousel/carousel.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/carousel/carousel.ts</context>
<context context-type="linenumber">187</context> <context context-type="linenumber">187</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ngb.datepicker.select-month" datatype="html"> <trans-unit id="ngb.datepicker.select-month" datatype="html">
<source>Select month</source> <source>Select month</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/datepicker/datepicker-navigation-select.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/datepicker/datepicker-navigation-select.ts</context>
<context context-type="linenumber">89</context> <context context-type="linenumber">89</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/datepicker/datepicker-navigation-select.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/datepicker/datepicker-navigation-select.ts</context>
<context context-type="linenumber">89</context> <context context-type="linenumber">89</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ngb.datepicker.select-year" datatype="html"> <trans-unit id="ngb.datepicker.select-year" datatype="html">
<source>Select year</source> <source>Select year</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/datepicker/datepicker-navigation-select.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/datepicker/datepicker-navigation-select.ts</context>
<context context-type="linenumber">89</context> <context context-type="linenumber">89</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/datepicker/datepicker-navigation-select.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/datepicker/datepicker-navigation-select.ts</context>
<context context-type="linenumber">89</context> <context context-type="linenumber">89</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ngb.datepicker.previous-month" datatype="html"> <trans-unit id="ngb.datepicker.previous-month" datatype="html">
<source>Previous month</source> <source>Previous month</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/datepicker/datepicker-navigation.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/datepicker/datepicker-navigation.ts</context>
<context context-type="linenumber">74,76</context> <context context-type="linenumber">74,76</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/datepicker/datepicker-navigation.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/datepicker/datepicker-navigation.ts</context>
<context context-type="linenumber">103</context> <context context-type="linenumber">103</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ngb.datepicker.next-month" datatype="html"> <trans-unit id="ngb.datepicker.next-month" datatype="html">
<source>Next month</source> <source>Next month</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/datepicker/datepicker-navigation.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/datepicker/datepicker-navigation.ts</context>
<context context-type="linenumber">103</context> <context context-type="linenumber">103</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/datepicker/datepicker-navigation.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/datepicker/datepicker-navigation.ts</context>
<context context-type="linenumber">103</context> <context context-type="linenumber">103</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ngb.pagination.first" datatype="html"> <trans-unit id="ngb.pagination.first" datatype="html">
<source>««</source> <source>««</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/pagination/pagination.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/pagination/pagination.ts</context>
<context context-type="linenumber">297</context> <context context-type="linenumber">297</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ngb.pagination.previous" datatype="html"> <trans-unit id="ngb.pagination.previous" datatype="html">
<source>«</source> <source>«</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/pagination/pagination.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/pagination/pagination.ts</context>
<context context-type="linenumber">322</context> <context context-type="linenumber">322</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ngb.pagination.next" datatype="html"> <trans-unit id="ngb.pagination.next" datatype="html">
<source>»</source> <source>»</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/pagination/pagination.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/pagination/pagination.ts</context>
<context context-type="linenumber">358</context> <context context-type="linenumber">358</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ngb.pagination.last" datatype="html"> <trans-unit id="ngb.pagination.last" datatype="html">
<source>»»</source> <source>»»</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/pagination/pagination.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/pagination/pagination.ts</context>
<context context-type="linenumber">396</context> <context context-type="linenumber">396</context>
</context-group> </context-group>
</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>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/pagination/pagination.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/pagination/pagination.ts</context>
<context context-type="linenumber">414,415</context> <context context-type="linenumber">414,415</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ngb.pagination.previous-aria" datatype="html"> <trans-unit id="ngb.pagination.previous-aria" datatype="html">
<source>Previous</source> <source>Previous</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/pagination/pagination.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/pagination/pagination.ts</context>
<context context-type="linenumber">444,445</context> <context context-type="linenumber">444,445</context>
</context-group> </context-group>
</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>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/pagination/pagination.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/pagination/pagination.ts</context>
<context context-type="linenumber">479,480</context> <context context-type="linenumber">479,480</context>
</context-group> </context-group>
</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>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/pagination/pagination.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/pagination/pagination.ts</context>
<context context-type="linenumber">506</context> <context context-type="linenumber">506</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ngb.progressbar.value" datatype="html"> <trans-unit id="ngb.progressbar.value" datatype="html">
<source><x id="INTERPOLATION"/></source> <source><x id="INTERPOLATION"/></source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/progressbar/progressbar.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/progressbar/progressbar.ts</context>
<context context-type="linenumber">40</context> <context context-type="linenumber">40</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ngb.timepicker.HH" datatype="html"> <trans-unit id="ngb.timepicker.HH" datatype="html">
<source>HH</source> <source>HH</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/timepicker/timepicker.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/timepicker/timepicker.ts</context>
<context context-type="linenumber">256,259</context> <context context-type="linenumber">256,259</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ngb.timepicker.hours" datatype="html"> <trans-unit id="ngb.timepicker.hours" datatype="html">
<source>Hours</source> <source>Hours</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/timepicker/timepicker.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/timepicker/timepicker.ts</context>
<context context-type="linenumber">293,295</context> <context context-type="linenumber">293,295</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ngb.timepicker.MM" datatype="html"> <trans-unit id="ngb.timepicker.MM" datatype="html">
<source>MM</source> <source>MM</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/timepicker/timepicker.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/timepicker/timepicker.ts</context>
<context context-type="linenumber">322</context> <context context-type="linenumber">322</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ngb.timepicker.minutes" datatype="html"> <trans-unit id="ngb.timepicker.minutes" datatype="html">
<source>Minutes</source> <source>Minutes</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/timepicker/timepicker.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/timepicker/timepicker.ts</context>
<context context-type="linenumber">360</context> <context context-type="linenumber">360</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ngb.timepicker.increment-hours" datatype="html"> <trans-unit id="ngb.timepicker.increment-hours" datatype="html">
<source>Increment hours</source> <source>Increment hours</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/timepicker/timepicker.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/timepicker/timepicker.ts</context>
<context context-type="linenumber">397,399</context> <context context-type="linenumber">397,399</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ngb.timepicker.decrement-hours" datatype="html"> <trans-unit id="ngb.timepicker.decrement-hours" datatype="html">
<source>Decrement hours</source> <source>Decrement hours</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/timepicker/timepicker.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/timepicker/timepicker.ts</context>
<context context-type="linenumber">435,438</context> <context context-type="linenumber">435,438</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ngb.timepicker.increment-minutes" datatype="html"> <trans-unit id="ngb.timepicker.increment-minutes" datatype="html">
<source>Increment minutes</source> <source>Increment minutes</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/timepicker/timepicker.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/timepicker/timepicker.ts</context>
<context context-type="linenumber">442</context> <context context-type="linenumber">442</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ngb.timepicker.decrement-minutes" datatype="html"> <trans-unit id="ngb.timepicker.decrement-minutes" datatype="html">
<source>Decrement minutes</source> <source>Decrement minutes</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/timepicker/timepicker.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/timepicker/timepicker.ts</context>
<context context-type="linenumber">442</context> <context context-type="linenumber">442</context>
</context-group> </context-group>
</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>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/timepicker/timepicker.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/timepicker/timepicker.ts</context>
<context context-type="linenumber">442</context> <context context-type="linenumber">442</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ngb.timepicker.seconds" datatype="html"> <trans-unit id="ngb.timepicker.seconds" datatype="html">
<source>Seconds</source> <source>Seconds</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/timepicker/timepicker.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/timepicker/timepicker.ts</context>
<context context-type="linenumber">442</context> <context context-type="linenumber">442</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ngb.timepicker.increment-seconds" datatype="html"> <trans-unit id="ngb.timepicker.increment-seconds" datatype="html">
<source>Increment seconds</source> <source>Increment seconds</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/timepicker/timepicker.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/timepicker/timepicker.ts</context>
<context context-type="linenumber">442</context> <context context-type="linenumber">442</context>
</context-group> </context-group>
</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>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/timepicker/timepicker.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/timepicker/timepicker.ts</context>
<context context-type="linenumber">442</context> <context context-type="linenumber">442</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ngb.timepicker.PM" datatype="html"> <trans-unit id="ngb.timepicker.PM" datatype="html">
<source><x id="INTERPOLATION"/></source> <source><x id="INTERPOLATION"/></source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/timepicker/timepicker.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/timepicker/timepicker.ts</context>
<context context-type="linenumber">442</context> <context context-type="linenumber">442</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ngb.toast.close-aria" datatype="html"> <trans-unit id="ngb.toast.close-aria" datatype="html">
<source>Close</source> <source>Close</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.1_@angular+core@22.1.1_@angular+_69897756b3f091add524dceba470da9d/node_modules/src/toast/toast.ts</context> <context context-type="sourcefile">node_modules/.pnpm/@ng-bootstrap+ng-bootstrap@21.0.0_@angular+common@22.1.3_@angular+core@22.1.3_@angular+_6e980a1a1b6a042b5112673ade17a76b/node_modules/src/toast/toast.ts</context>
<context context-type="linenumber">110,112</context> <context context-type="linenumber">110,112</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
@@ -775,7 +775,7 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">19,20</context> <context context-type="linenumber">20,21</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="3894950702316166331" datatype="html"> <trans-unit id="3894950702316166331" datatype="html">
@@ -788,10 +788,6 @@
<context context-type="sourcefile">src/app/components/admin/logs/logs.component.html</context> <context context-type="sourcefile">src/app/components/admin/logs/logs.component.html</context>
<context context-type="linenumber">49</context> <context context-type="linenumber">49</context>
</context-group> </context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">26,29</context>
</context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/trash/trash.component.html</context> <context context-type="sourcefile">src/app/components/admin/trash/trash.component.html</context>
<context context-type="linenumber">47</context> <context context-type="linenumber">47</context>
@@ -810,7 +806,7 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/input/document-link/document-link.component.html</context> <context context-type="sourcefile">src/app/components/common/input/document-link/document-link.component.html</context>
<context context-type="linenumber">58,59</context> <context context-type="linenumber">59,60</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/page-header/page-header.component.html</context> <context context-type="sourcefile">src/app/components/common/page-header/page-header.component.html</context>
@@ -1854,7 +1850,7 @@
<source>Clear selection</source> <source>Clear selection</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">9</context> <context context-type="linenumber">10</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/trash/trash.component.html</context> <context context-type="sourcefile">src/app/components/admin/trash/trash.component.html</context>
@@ -1869,14 +1865,14 @@
<source>Dismiss all</source> <source>Dismiss all</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">15</context> <context context-type="linenumber">16</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1616102757855967475" datatype="html"> <trans-unit id="1616102757855967475" datatype="html">
<source>All</source> <source>All</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">39</context> <context context-type="linenumber">35</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
@@ -1884,7 +1880,7 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context>
<context context-type="linenumber">159,160</context> <context context-type="linenumber">162,163</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<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>
@@ -1915,14 +1911,14 @@
<source>Filter by</source> <source>Filter by</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">59</context> <context context-type="linenumber">55</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="424356320420294719" datatype="html"> <trans-unit id="424356320420294719" datatype="html">
<source>All types</source> <source>All types</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">64,65</context> <context context-type="linenumber">60,61</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
@@ -1933,7 +1929,7 @@
<source>All sources</source> <source>All sources</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">73,74</context> <context context-type="linenumber">69,70</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
@@ -1944,7 +1940,7 @@
<source>Clear search</source> <source>Clear search</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">92</context> <context context-type="linenumber">88</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<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>
@@ -1955,14 +1951,14 @@
<source>Search tasks</source> <source>Search tasks</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">96,97</context> <context context-type="linenumber">92,93</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="6849725902312323996" datatype="html"> <trans-unit id="6849725902312323996" datatype="html">
<source>Reset filters</source> <source>Reset filters</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">105,106</context> <context context-type="linenumber">101,102</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context> <context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
@@ -1977,14 +1973,14 @@
<source>{VAR_PLURAL, plural, =1 {1 task} other {<x id="INTERPOLATION"/> tasks}}</source> <source>{VAR_PLURAL, plural, =1 {1 task} other {<x id="INTERPOLATION"/> tasks}}</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">126</context> <context context-type="linenumber">122</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="8953033926734869941" datatype="html"> <trans-unit id="8953033926734869941" datatype="html">
<source>Name</source> <source>Name</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">148,149</context> <context context-type="linenumber">144,145</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
@@ -2095,7 +2091,7 @@
<source>Created</source> <source>Created</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">149,150</context> <context context-type="linenumber">145,146</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context>
@@ -2126,21 +2122,21 @@
<source>Results</source> <source>Results</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">151,152</context> <context context-type="linenumber">147,148</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="314315645942131479" datatype="html"> <trans-unit id="314315645942131479" datatype="html">
<source>Info</source> <source>Info</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">153,154</context> <context context-type="linenumber">149,150</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="3193976279273491157" datatype="html"> <trans-unit id="3193976279273491157" datatype="html">
<source>Actions</source> <source>Actions</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">154,155</context> <context context-type="linenumber">150,151</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/trash/trash.component.html</context> <context context-type="sourcefile">src/app/components/admin/trash/trash.component.html</context>
@@ -2255,21 +2251,21 @@
<source>click for full output</source> <source>click for full output</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">205</context> <context context-type="linenumber">201</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="8946500279334661567" datatype="html"> <trans-unit id="8946500279334661567" datatype="html">
<source>View task details</source> <source>View task details</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">211</context> <context context-type="linenumber">207</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1536087519743707362" datatype="html"> <trans-unit id="1536087519743707362" datatype="html">
<source>Dismiss</source> <source>Dismiss</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">218</context> <context context-type="linenumber">214</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
@@ -2292,28 +2288,28 @@
<source>Open Document</source> <source>Open Document</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">223</context> <context context-type="linenumber">219</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="5404759957685833020" datatype="html"> <trans-unit id="5404759957685833020" datatype="html">
<source>Result message</source> <source>Result message</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">236,237</context> <context context-type="linenumber">232,233</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="6621329748219109148" datatype="html"> <trans-unit id="6621329748219109148" datatype="html">
<source>Duplicate</source> <source>Duplicate</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">243,244</context> <context context-type="linenumber">239,240</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="7593555694782789615" datatype="html"> <trans-unit id="7593555694782789615" datatype="html">
<source>Open</source> <source>Open</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">251</context> <context context-type="linenumber">247</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/app-frame/global-search/global-search.component.html</context> <context context-type="sourcefile">src/app/components/app-frame/global-search/global-search.component.html</context>
@@ -2344,21 +2340,21 @@
<source>Input data</source> <source>Input data</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">261,262</context> <context context-type="linenumber">257,258</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1585185618099050920" datatype="html"> <trans-unit id="1585185618099050920" datatype="html">
<source>Result data</source> <source>Result data</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">267,268</context> <context context-type="linenumber">263,264</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="7976920528153858271" datatype="html"> <trans-unit id="7976920528153858271" datatype="html">
<source>No tasks match the current filters.</source> <source>No tasks match the current filters.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">289,291</context> <context context-type="linenumber">285,287</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="2525230676386818985" datatype="html"> <trans-unit id="2525230676386818985" datatype="html">
@@ -3000,7 +2996,7 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.html</context>
<context context-type="linenumber">77</context> <context context-type="linenumber">81</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="2941198503117307737" datatype="html"> <trans-unit id="2941198503117307737" datatype="html">
@@ -4123,23 +4119,23 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context>
<context context-type="linenumber">51,52</context> <context context-type="linenumber">52,53</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context>
<context context-type="linenumber">75,76</context> <context context-type="linenumber">76,77</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context>
<context context-type="linenumber">127,128</context> <context context-type="linenumber">129,130</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context>
<context context-type="linenumber">151,152</context> <context context-type="linenumber">153,154</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.ts</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.ts</context>
<context context-type="linenumber">113</context> <context context-type="linenumber">118</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<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>
@@ -4154,19 +4150,19 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context>
<context context-type="linenumber">52,53</context> <context context-type="linenumber">53,54</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context>
<context context-type="linenumber">76,77</context> <context context-type="linenumber">77,78</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context>
<context context-type="linenumber">128,129</context> <context context-type="linenumber">130,131</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context>
<context context-type="linenumber">152,153</context> <context context-type="linenumber">154,155</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<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>
@@ -4193,11 +4189,11 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context>
<context context-type="linenumber">101,102</context> <context context-type="linenumber">103,104</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context>
<context context-type="linenumber">107,108</context> <context context-type="linenumber">109,110</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="3800326155195149498" datatype="html"> <trans-unit id="3800326155195149498" datatype="html">
@@ -4208,36 +4204,36 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context>
<context context-type="linenumber">102,103</context> <context context-type="linenumber">104,105</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context>
<context context-type="linenumber">108,109</context> <context context-type="linenumber">110,111</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="7551700625201096185" datatype="html"> <trans-unit id="7551700625201096185" datatype="html">
<source>Search docs...</source> <source>Search docs...</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context>
<context context-type="linenumber">70</context> <context context-type="linenumber">71</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context>
<context context-type="linenumber">124</context> <context context-type="linenumber">126</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="2328549728463836983" datatype="html"> <trans-unit id="2328549728463836983" datatype="html">
<source>Remove query</source> <source>Remove query</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context>
<context context-type="linenumber">146</context> <context context-type="linenumber">149</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="3184700926171002527" datatype="html"> <trans-unit id="3184700926171002527" datatype="html">
<source>Any</source> <source>Any</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context>
<context context-type="linenumber">157,158</context> <context context-type="linenumber">160,161</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<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>
@@ -4248,28 +4244,28 @@
<source>Not</source> <source>Not</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context>
<context context-type="linenumber">162,163</context> <context context-type="linenumber">165,166</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="6548676277933116532" datatype="html"> <trans-unit id="6548676277933116532" datatype="html">
<source>Add query</source> <source>Add query</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context>
<context context-type="linenumber">181</context> <context context-type="linenumber">184</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="5599577087865387184" datatype="html"> <trans-unit id="5599577087865387184" datatype="html">
<source>Add expression</source> <source>Add expression</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context>
<context context-type="linenumber">184</context> <context context-type="linenumber">187</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="7394978038852129121" datatype="html"> <trans-unit id="7394978038852129121" datatype="html">
<source>Remove expression</source> <source>Remove expression</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context>
<context context-type="linenumber">188</context> <context context-type="linenumber">191</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="6630533861307510614" datatype="html"> <trans-unit id="6630533861307510614" datatype="html">
@@ -4283,68 +4279,68 @@
<source>Relative dates</source> <source>Relative dates</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context>
<context context-type="linenumber">24,25</context> <context context-type="linenumber">25,26</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context>
<context context-type="linenumber">100,101</context> <context context-type="linenumber">102,103</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="6189418687568178489" datatype="html"> <trans-unit id="6189418687568178489" datatype="html">
<source>Clear created from date</source> <source>Clear created from date</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context>
<context context-type="linenumber">36</context> <context context-type="linenumber">37</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="5203279511751768967" datatype="html"> <trans-unit id="5203279511751768967" datatype="html">
<source>From</source> <source>From</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context>
<context context-type="linenumber">43,44</context> <context context-type="linenumber">44,45</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context>
<context context-type="linenumber">119,120</context> <context context-type="linenumber">121,122</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="7415688196405432276" datatype="html"> <trans-unit id="7415688196405432276" datatype="html">
<source>Open created from date picker</source> <source>Open created from date picker</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context>
<context context-type="linenumber">46</context> <context context-type="linenumber">47</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="5714803496005897828" datatype="html"> <trans-unit id="5714803496005897828" datatype="html">
<source>Clear created to date</source> <source>Clear created to date</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context>
<context context-type="linenumber">60</context> <context context-type="linenumber">61</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1640609344969975994" datatype="html"> <trans-unit id="1640609344969975994" datatype="html">
<source>To</source> <source>To</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context>
<context context-type="linenumber">67,68</context> <context context-type="linenumber">68,69</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context>
<context context-type="linenumber">143,144</context> <context context-type="linenumber">145,146</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="7799679004299963481" datatype="html"> <trans-unit id="7799679004299963481" datatype="html">
<source>Open created to date picker</source> <source>Open created to date picker</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context>
<context context-type="linenumber">70</context> <context context-type="linenumber">71</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="231679111972850796" datatype="html"> <trans-unit id="231679111972850796" datatype="html">
<source>Added</source> <source>Added</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context>
<context context-type="linenumber">83,84</context> <context context-type="linenumber">84,85</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context>
@@ -4367,91 +4363,91 @@
<source>Clear added relative date</source> <source>Clear added relative date</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context>
<context context-type="linenumber">88</context> <context context-type="linenumber">89</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="8527347906195580369" datatype="html"> <trans-unit id="8527347906195580369" datatype="html">
<source>Clear added from date</source> <source>Clear added from date</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context>
<context context-type="linenumber">112</context> <context context-type="linenumber">114</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="5711531903664147782" datatype="html"> <trans-unit id="5711531903664147782" datatype="html">
<source>Open added from date picker</source> <source>Open added from date picker</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context>
<context context-type="linenumber">122</context> <context context-type="linenumber">124</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="6559691063013749167" datatype="html"> <trans-unit id="6559691063013749167" datatype="html">
<source>Clear added to date</source> <source>Clear added to date</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context>
<context context-type="linenumber">136</context> <context context-type="linenumber">138</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="6072383085349258752" datatype="html"> <trans-unit id="6072383085349258752" datatype="html">
<source>Open added to date picker</source> <source>Open added to date picker</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context>
<context context-type="linenumber">146</context> <context context-type="linenumber">148</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="6052766076365105714" datatype="html"> <trans-unit id="6052766076365105714" datatype="html">
<source>now</source> <source>now</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context>
<context context-type="linenumber">168</context> <context context-type="linenumber">170</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="9129856334122659953" datatype="html"> <trans-unit id="9129856334122659953" datatype="html">
<source>Within 1 week</source> <source>Within 1 week</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.ts</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.ts</context>
<context context-type="linenumber">81</context> <context context-type="linenumber">86</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="123064370501514576" datatype="html"> <trans-unit id="123064370501514576" datatype="html">
<source>Within 1 month</source> <source>Within 1 month</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.ts</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.ts</context>
<context context-type="linenumber">86</context> <context context-type="linenumber">91</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1027161426440526546" datatype="html"> <trans-unit id="1027161426440526546" datatype="html">
<source>Within 3 months</source> <source>Within 3 months</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.ts</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.ts</context>
<context context-type="linenumber">91</context> <context context-type="linenumber">96</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="226779700214642230" datatype="html"> <trans-unit id="226779700214642230" datatype="html">
<source>Within 1 year</source> <source>Within 1 year</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.ts</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.ts</context>
<context context-type="linenumber">96</context> <context context-type="linenumber">101</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="8462417627724236320" datatype="html"> <trans-unit id="8462417627724236320" datatype="html">
<source>This year</source> <source>This year</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.ts</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.ts</context>
<context context-type="linenumber">101</context> <context context-type="linenumber">106</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="842657237693374355" datatype="html"> <trans-unit id="842657237693374355" datatype="html">
<source>This month</source> <source>This month</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.ts</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.ts</context>
<context context-type="linenumber">107</context> <context context-type="linenumber">112</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="4498682414491138092" datatype="html"> <trans-unit id="4498682414491138092" datatype="html">
<source>Yesterday</source> <source>Yesterday</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.ts</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.ts</context>
<context context-type="linenumber">118</context> <context context-type="linenumber">123</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/pipes/custom-date.pipe.ts</context> <context context-type="sourcefile">src/app/pipes/custom-date.pipe.ts</context>
@@ -4462,28 +4458,28 @@
<source>Previous week</source> <source>Previous week</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.ts</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.ts</context>
<context context-type="linenumber">123</context> <context context-type="linenumber">128</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="8586908745456864217" datatype="html"> <trans-unit id="8586908745456864217" datatype="html">
<source>Previous month</source> <source>Previous month</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.ts</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.ts</context>
<context context-type="linenumber">137</context> <context context-type="linenumber">142</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="357608474534295480" datatype="html"> <trans-unit id="357608474534295480" datatype="html">
<source>Previous quarter</source> <source>Previous quarter</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.ts</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.ts</context>
<context context-type="linenumber">143</context> <context context-type="linenumber">148</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="100513227838842152" datatype="html"> <trans-unit id="100513227838842152" datatype="html">
<source>Previous year</source> <source>Previous year</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.ts</context> <context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.ts</context>
<context context-type="linenumber">157</context> <context context-type="linenumber">162</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="8743659855412792665" datatype="html"> <trans-unit id="8743659855412792665" datatype="html">
@@ -6387,7 +6383,7 @@
<source>Open <x id="PH" equiv-text="this.title"/> filter</source> <source>Open <x id="PH" equiv-text="this.title"/> filter</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts</context> <context context-type="sourcefile">src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts</context>
<context context-type="linenumber">856</context> <context context-type="linenumber">874</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="7005745151564974365" datatype="html"> <trans-unit id="7005745151564974365" datatype="html">
@@ -6510,14 +6506,14 @@
<source>Remove link</source> <source>Remove link</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/input/document-link/document-link.component.html</context> <context context-type="sourcefile">src/app/components/common/input/document-link/document-link.component.html</context>
<context context-type="linenumber">43</context> <context context-type="linenumber">44</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1388712764439031120" datatype="html"> <trans-unit id="1388712764439031120" datatype="html">
<source>Open link</source> <source>Open link</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/input/document-link/document-link.component.html</context> <context context-type="sourcefile">src/app/components/common/input/document-link/document-link.component.html</context>
<context context-type="linenumber">46</context> <context context-type="linenumber">47</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/input/url/url.component.html</context> <context context-type="sourcefile">src/app/components/common/input/url/url.component.html</context>
@@ -6528,7 +6524,7 @@
<source>Unavailable</source> <source>Unavailable</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/input/document-link/document-link.component.html</context> <context context-type="sourcefile">src/app/components/common/input/document-link/document-link.component.html</context>
<context context-type="linenumber">51,52</context> <context context-type="linenumber">52,53</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="5676637575587497817" datatype="html"> <trans-unit id="5676637575587497817" datatype="html">
@@ -6842,81 +6838,88 @@
<context context-type="linenumber">55,56</context> <context context-type="linenumber">55,56</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="7789618798958221204" datatype="html">
<source>Clear selected users</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.html</context>
<context context-type="linenumber">61</context>
</context-group>
</trans-unit>
<trans-unit id="8999708063434507268" datatype="html"> <trans-unit id="8999708063434507268" datatype="html">
<source>Hide unowned</source> <source>Hide unowned</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.html</context> <context context-type="sourcefile">src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.html</context>
<context context-type="linenumber">86</context> <context context-type="linenumber">90</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="5947558132119506443" datatype="html"> <trans-unit id="5947558132119506443" datatype="html">
<source>My documents</source> <source>My documents</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.ts</context> <context context-type="sourcefile">src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.ts</context>
<context context-type="linenumber">99</context> <context context-type="linenumber">105</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1930869169119109336" datatype="html"> <trans-unit id="1930869169119109336" datatype="html">
<source>Owned by <x id="PH" equiv-text="username"/></source> <source>Owned by <x id="PH" equiv-text="username"/></source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.ts</context> <context context-type="sourcefile">src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.ts</context>
<context context-type="linenumber">104</context> <context context-type="linenumber">110</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="5339682692608120628" datatype="html"> <trans-unit id="5339682692608120628" datatype="html">
<source>Owned by another user</source> <source>Owned by another user</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.ts</context> <context context-type="sourcefile">src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.ts</context>
<context context-type="linenumber">105</context> <context context-type="linenumber">111</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="231920238966427751" datatype="html"> <trans-unit id="231920238966427751" datatype="html">
<source>Shared with me</source> <source>Shared with me</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.ts</context> <context context-type="sourcefile">src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.ts</context>
<context context-type="linenumber">115</context> <context context-type="linenumber">121</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1894556100995563325" datatype="html"> <trans-unit id="1894556100995563325" datatype="html">
<source>Not owned by <x id="PH" equiv-text="usernames.join(&apos;, &apos;)"/></source> <source>Not owned by <x id="PH" equiv-text="usernames.join(&apos;, &apos;)"/></source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.ts</context> <context context-type="sourcefile">src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.ts</context>
<context context-type="linenumber">122</context> <context context-type="linenumber">128</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="4647949080250052038" datatype="html"> <trans-unit id="4647949080250052038" datatype="html">
<source>Not owned by another user</source> <source>Not owned by another user</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.ts</context> <context context-type="sourcefile">src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.ts</context>
<context context-type="linenumber">125</context> <context context-type="linenumber">131</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="8858352775080403297" datatype="html"> <trans-unit id="8858352775080403297" datatype="html">
<source>Not owned by selected users</source> <source>Not owned by selected users</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.ts</context> <context context-type="sourcefile">src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.ts</context>
<context context-type="linenumber">126</context> <context context-type="linenumber">132</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="175385209536581523" datatype="html"> <trans-unit id="175385209536581523" datatype="html">
<source>Shared by me</source> <source>Shared by me</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.ts</context> <context context-type="sourcefile">src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.ts</context>
<context context-type="linenumber">134</context> <context context-type="linenumber">140</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="5140574576358170412" datatype="html"> <trans-unit id="5140574576358170412" datatype="html">
<source>Shared by <x id="PH" equiv-text="username"/></source> <source>Shared by <x id="PH" equiv-text="username"/></source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.ts</context> <context context-type="sourcefile">src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.ts</context>
<context context-type="linenumber">139</context> <context context-type="linenumber">145</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="391557549689505150" datatype="html"> <trans-unit id="391557549689505150" datatype="html">
<source>Shared by another user</source> <source>Shared by another user</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.ts</context> <context context-type="sourcefile">src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.ts</context>
<context context-type="linenumber">140</context> <context context-type="linenumber">146</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="941924371433275463" datatype="html"> <trans-unit id="941924371433275463" datatype="html">
+21 -21
View File
@@ -1,6 +1,6 @@
{ {
"name": "paperless-ngx-ui", "name": "paperless-ngx-ui",
"version": "3.1.2", "version": "3.1.3",
"scripts": { "scripts": {
"preinstall": "npx only-allow pnpm", "preinstall": "npx only-allow pnpm",
"ng": "ng", "ng": "ng",
@@ -15,16 +15,16 @@
}, },
"private": true, "private": true,
"dependencies": { "dependencies": {
"@angular/cdk": "^22.1.1", "@angular/cdk": "^22.1.4",
"@angular/common": "~22.1.1", "@angular/common": "~22.1.3",
"@angular/compiler": "~22.1.1", "@angular/compiler": "~22.1.3",
"@angular/core": "~22.1.1", "@angular/core": "~22.1.3",
"@angular/forms": "~22.1.1", "@angular/forms": "~22.1.3",
"@angular/localize": "~22.1.1", "@angular/localize": "~22.1.3",
"@angular/platform-browser": "~22.1.1", "@angular/platform-browser": "~22.1.3",
"@angular/router": "~22.1.1", "@angular/router": "~22.1.3",
"@ng-bootstrap/ng-bootstrap": "^21.0.0", "@ng-bootstrap/ng-bootstrap": "^21.0.0",
"@ng-select/ng-select": "~23.6.0", "@ng-select/ng-select": "~24.0.2",
"@ngneat/dirty-check-forms": "^3.0.3", "@ngneat/dirty-check-forms": "^3.0.3",
"@popperjs/core": "^2.11.8", "@popperjs/core": "^2.11.8",
"bootstrap": "^5.3.8", "bootstrap": "^5.3.8",
@@ -41,27 +41,27 @@
"rxjs": "^7.8.2", "rxjs": "^7.8.2",
"tslib": "^2.8.1", "tslib": "^2.8.1",
"utif": "^3.1.0", "utif": "^3.1.0",
"uuid": "^14.0.1" "uuid": "^14.0.2"
}, },
"devDependencies": { "devDependencies": {
"@angular-builders/jest": "^22.0.1", "@angular-builders/jest": "^22.0.1",
"@angular-devkit/core": "^22.1.3", "@angular-devkit/core": "^22.1.6",
"@angular-devkit/schematics": "^22.1.3", "@angular-devkit/schematics": "^22.1.6",
"@angular-eslint/builder": "22.1.0", "@angular-eslint/builder": "22.1.0",
"@angular-eslint/eslint-plugin": "22.1.0", "@angular-eslint/eslint-plugin": "22.1.0",
"@angular-eslint/eslint-plugin-template": "22.1.0", "@angular-eslint/eslint-plugin-template": "22.1.0",
"@angular-eslint/schematics": "22.1.0", "@angular-eslint/schematics": "22.1.0",
"@angular-eslint/template-parser": "22.1.0", "@angular-eslint/template-parser": "22.1.0",
"@angular/build": "22.1.3", "@angular/build": "22.1.6",
"@angular/cli": "22.1.3", "@angular/cli": "22.1.6",
"@angular/compiler-cli": "~22.1.1", "@angular/compiler-cli": "~22.1.3",
"@playwright/test": "^1.62.1", "@playwright/test": "^1.62.1",
"@types/jest": "^30.0.0", "@types/jest": "^30.0.0",
"@types/node": "^26.2.0", "@types/node": "^26.4.0",
"@typescript-eslint/eslint-plugin": "^8.67.0", "@typescript-eslint/eslint-plugin": "^8.68.0",
"@typescript-eslint/parser": "^8.67.0", "@typescript-eslint/parser": "^8.68.0",
"@typescript-eslint/utils": "^8.67.0", "@typescript-eslint/utils": "^8.68.0",
"eslint": "^10.8.1", "eslint": "^10.9.1",
"jest": "30.4.2", "jest": "30.4.2",
"jest-environment-jsdom": "^30.4.1", "jest-environment-jsdom": "^30.4.1",
"jest-junit": "^17.0.0", "jest-junit": "^17.0.0",
+621 -811
View File
File diff suppressed because it is too large Load Diff
@@ -3,6 +3,7 @@
i18n-title i18n-title
info="Tasks shows detailed information about document consumption and system tasks." info="Tasks shows detailed information about document consumption and system tasks."
i18n-info i18n-info
[loading]="loading() && pagedTasks().length === 0"
> >
<div class="btn-toolbar col col-md-auto align-items-center gap-2"> <div class="btn-toolbar col col-md-auto align-items-center gap-2">
<button class="btn btn-sm btn-outline-secondary me-2" (click)="clearSelection()" [hidden]="selectedTasks.size === 0"> <button class="btn btn-sm btn-outline-secondary me-2" (click)="clearSelection()" [hidden]="selectedTasks.size === 0">
@@ -21,11 +22,6 @@
</div> </div>
</pngx-page-header> </pngx-page-header>
@if (loading() && pagedTasks().length === 0) {
<div class="spinner-border spinner-border-sm fw-normal ms-2 me-auto" role="status"></div>
<div class="visually-hidden" i18n>Loading...</div>
}
<div class="task-controls mb-3 gap-3 btn-toolbar align-items-center" role="toolbar"> <div class="task-controls mb-3 gap-3 btn-toolbar align-items-center" role="toolbar">
<div class="task-view-scope btn-group btn-group-sm" role="group"> <div class="task-view-scope btn-group btn-group-sm" role="group">
<input <input
@@ -285,6 +281,6 @@
<ng-container [ngTemplateOutlet]="tasksTemplate" [ngTemplateOutletContext]="{tasks: tasksForSection(section), section: section}"></ng-container> <ng-container [ngTemplateOutlet]="tasksTemplate" [ngTemplateOutletContext]="{tasks: tasksForSection(section), section: section}"></ng-container>
</div> </div>
} }
} @else { } @else if (!loading() || pagedTasks().length > 0) {
<div class="alert alert-secondary fst-italic" i18n>No tasks match the current filters.</div> <div class="alert alert-secondary fst-italic" i18n>No tasks match the current filters.</div>
} }
@@ -34,9 +34,7 @@
} }
@media (min-width: 768px) { @media (min-width: 768px) {
&.expanded { --pngx-sidebar-width: var(--pngx-sidebar-expanded-width);
--pngx-sidebar-width: var(--pngx-sidebar-expanded-width);
}
} }
} }
@media (max-width: 767.98px) { @media (max-width: 767.98px) {
@@ -113,6 +111,13 @@ main {
} }
} }
// only animate when the user toggles slim mode
.sidebar:not(.animating),
.sidebar:not(.animating) ~ main,
.sidebar:not(.animating) .sidebar-slim-toggler {
transition: none;
}
.sidebar.slim { .sidebar.slim {
max-width: 55px; max-width: 55px;
@@ -123,8 +128,6 @@ main {
} }
.sidebar.slim:not(.animating) { .sidebar.slim:not(.animating) {
transition: none;
li.nav-item span, li.nav-item span,
.sidebar-heading span { .sidebar-heading span {
display: none; display: none;
@@ -144,10 +147,6 @@ main {
} }
} }
.sidebar.slim:not(.animating) ~ main.col-slim {
transition: none;
}
.sidebar.animating { .sidebar.animating {
li.nav-item span, li.nav-item span,
.sidebar-heading span { .sidebar-heading span {
@@ -196,6 +195,26 @@ main {
--bs-popover-body-padding-y: .5rem; --bs-popover-body-padding-y: .5rem;
} }
@media (prefers-reduced-motion: no-preference) {
.sidebar-sticky > ul,
.sidebar-sticky > .nav-group {
animation: sidebar-nav-in .3s cubic-bezier(.22, .61, .36, 1) backwards;
}
@for $i from 2 through 5 {
.sidebar-sticky > :nth-child(#{$i}) {
animation-delay: #{($i - 1) * 0.04}s;
}
}
}
@keyframes sidebar-nav-in {
from {
opacity: 0;
transform: translateY(6px);
}
}
.sidebar-sticky { .sidebar-sticky {
position: relative; position: relative;
top: 0; top: 0;
@@ -6,7 +6,7 @@
<pngx-clearable-badge [selected]="isActive" (cleared)="reset()"></pngx-clearable-badge> <pngx-clearable-badge [selected]="isActive" (cleared)="reset()"></pngx-clearable-badge>
} }
</button> </button>
<div class="px-3 shadow" ngbDropdownMenu attr.aria-labelledby="dropdown_{{name}}"> <div [id]="dropdownMenuId" class="px-3 shadow" ngbDropdownMenu attr.aria-labelledby="dropdown_{{name}}">
<ng-container *ngTemplateOutlet="list; context: { queries: selectionModel.queries }"></ng-container> <ng-container *ngTemplateOutlet="list; context: { queries: selectionModel.queries }"></ng-container>
</div> </div>
</div> </div>
@@ -64,10 +64,11 @@
[disabled]="disabled" [disabled]="disabled"
[virtualScroll]="getSelectOptionsForField(atom.field)?.length > 100" [virtualScroll]="getSelectOptionsForField(atom.field)?.length > 100"
[searchFn]="selectOptionSearchFn" [searchFn]="selectOptionSearchFn"
[appendTo]="selectAppendTo"
(mousedown)="$event.stopImmediatePropagation()" (mousedown)="$event.stopImmediatePropagation()"
></ng-select> ></ng-select>
} @else if (getCustomFieldByID(atom.field)?.data_type === CustomFieldDataType.DocumentLink) { } @else if (getCustomFieldByID(atom.field)?.data_type === CustomFieldDataType.DocumentLink) {
<pngx-input-document-link [(ngModel)]="atom.value" class="w-25 form-select doc-link-select p-0" placeholder="Search docs..." i18n-placeholder [minimal]="true"></pngx-input-document-link> <pngx-input-document-link [(ngModel)]="atom.value" class="w-25 form-select doc-link-select p-0" placeholder="Search docs..." i18n-placeholder [minimal]="true" [appendTo]="selectAppendTo"></pngx-input-document-link>
} @else if (getCustomFieldByID(atom.field)?.data_type === CustomFieldDataType.Monetary) { } @else if (getCustomFieldByID(atom.field)?.data_type === CustomFieldDataType.Monetary) {
<input class="w-25 form-control rounded-end" type="text" inputmode="decimal" <input class="w-25 form-control rounded-end" type="text" inputmode="decimal"
[ngModel]="atom.value" [ngModel]="atom.value"
@@ -88,6 +89,7 @@
bindLabel="name" bindLabel="name"
bindValue="id" bindValue="id"
[searchFn]="customFieldSearchFn" [searchFn]="customFieldSearchFn"
[appendTo]="selectAppendTo"
(mousedown)="$event.stopImmediatePropagation()" (mousedown)="$event.stopImmediatePropagation()"
></ng-select> ></ng-select>
<select class="w-25 form-select" [(ngModel)]="atom.operator" [disabled]="disabled"> <select class="w-25 form-select" [(ngModel)]="atom.operator" [disabled]="disabled">
@@ -121,7 +123,7 @@
<ng-container *ngTemplateOutlet="comparisonValueTemplate; context: { atom: atom }"></ng-container> <ng-container *ngTemplateOutlet="comparisonValueTemplate; context: { atom: atom }"></ng-container>
} }
@case (CustomFieldQueryOperator.Contains) { @case (CustomFieldQueryOperator.Contains) {
<pngx-input-document-link [(ngModel)]="atom.value" class="w-25 form-select doc-link-select p-0" placeholder="Search docs..." i18n-placeholder [minimal]="true"></pngx-input-document-link> <pngx-input-document-link [(ngModel)]="atom.value" class="w-25 form-select doc-link-select p-0" placeholder="Search docs..." i18n-placeholder [minimal]="true" [appendTo]="selectAppendTo"></pngx-input-document-link>
} }
@case (CustomFieldQueryOperator.In) { @case (CustomFieldQueryOperator.In) {
<ng-select <ng-select
@@ -133,6 +135,7 @@
[disabled]="disabled" [disabled]="disabled"
[multiple]="true" [multiple]="true"
[searchFn]="selectOptionSearchFn" [searchFn]="selectOptionSearchFn"
[appendTo]="selectAppendTo"
(mousedown)="$event.stopImmediatePropagation()" (mousedown)="$event.stopImmediatePropagation()"
></ng-select> ></ng-select>
} }
@@ -1,3 +1,4 @@
import { _IdGenerator } from '@angular/cdk/a11y'
import { import {
getLocaleNumberSymbol, getLocaleNumberSymbol,
NgClass, NgClass,
@@ -250,6 +251,18 @@ export class CustomFieldsQueryDropdownComponent extends LoadingComponentWithPerm
@Input() @Input()
useDropdown: boolean = true useDropdown: boolean = true
private readonly idGenerator = inject(_IdGenerator)
public readonly dropdownMenuId = this.idGenerator.getId(
'pngx-custom-fields-query-dropdown-'
)
/**
* Keep ng-select dropdown panels inside the dropdown menu
*/
get selectAppendTo(): string {
return this.useDropdown ? `#${this.dropdownMenuId}` : null
}
get name(): string { get name(): string {
return this.title ? this.title.replace(/\s/g, '_').toLowerCase() : null return this.title ? this.title.replace(/\s/g, '_').toLowerCase() : null
} }
@@ -3,7 +3,7 @@
<i-bs width="1em" height="1em" name="calendar-event-fill"></i-bs><div class="d-none d-sm-inline ms-1">{{title}}</div> <i-bs width="1em" height="1em" name="calendar-event-fill"></i-bs><div class="d-none d-sm-inline ms-1">{{title}}</div>
<pngx-clearable-badge [selected]="isActive" (cleared)="reset()"></pngx-clearable-badge><span class="visually-hidden">selected</span> <pngx-clearable-badge [selected]="isActive" (cleared)="reset()"></pngx-clearable-badge><span class="visually-hidden">selected</span>
</button> </button>
<div class="dropdown-menu date-dropdown shadow p-2" ngbDropdownMenu attr.aria-labelledby="dropdown{{title}}"> <div [id]="dropdownMenuId" class="dropdown-menu date-dropdown shadow p-2" ngbDropdownMenu attr.aria-labelledby="dropdown{{title}}">
<h6 class="dropdown-header border-bottom" i18n>Created</h6> <h6 class="dropdown-header border-bottom" i18n>Created</h6>
<div class="list-group list-group-flush"> <div class="list-group list-group-flush">
<div class="list-group-item d-flex p-2 select-item" role="menuitem"> <div class="list-group-item d-flex p-2 select-item" role="menuitem">
@@ -21,6 +21,7 @@
bindValue="id" bindValue="id"
bindLabel="name" bindLabel="name"
clearable="false" clearable="false"
[appendTo]="'#' + dropdownMenuId"
placeholder="Relative dates" placeholder="Relative dates"
i18n-placeholder i18n-placeholder
(change)="onSetCreatedRelativeDate($event)"> (change)="onSetCreatedRelativeDate($event)">
@@ -97,6 +98,7 @@
bindValue="id" bindValue="id"
bindLabel="name" bindLabel="name"
clearable="false" clearable="false"
[appendTo]="'#' + dropdownMenuId"
placeholder="Relative dates" placeholder="Relative dates"
i18n-placeholder i18n-placeholder
(change)="onSetAddedRelativeDate($event)"> (change)="onSetAddedRelativeDate($event)">
@@ -23,6 +23,7 @@ import { SettingsService } from 'src/app/services/settings.service'
import { ISODateAdapter } from 'src/app/utils/ngb-iso-date-adapter' import { ISODateAdapter } from 'src/app/utils/ngb-iso-date-adapter'
import { pngxPopperOptions } from 'src/app/utils/popper-options' import { pngxPopperOptions } from 'src/app/utils/popper-options'
import { ClearableBadgeComponent } from '../clearable-badge/clearable-badge.component' import { ClearableBadgeComponent } from '../clearable-badge/clearable-badge.component'
import { _IdGenerator } from '@angular/cdk/a11y'
export interface DateSelection { export interface DateSelection {
createdTo?: string createdTo?: string
@@ -68,6 +69,10 @@ export enum RelativeDate {
}) })
export class DatesDropdownComponent implements OnInit, OnDestroy { export class DatesDropdownComponent implements OnInit, OnDestroy {
public popperOptions = pngxPopperOptions public popperOptions = pngxPopperOptions
private readonly idGenerator = inject(_IdGenerator)
public readonly dropdownMenuId = this.idGenerator.getId(
'pngx-dates-dropdown-'
)
constructor() { constructor() {
const settings = inject(SettingsService) const settings = inject(SettingsService)
@@ -703,6 +703,40 @@ describe('FilterableDropdownComponent & FilterableDropdownSelectionModel', () =>
expect(selectionModel.getSelectedItems()).toEqual([other]) expect(selectionModel.getSelectedItems()).toEqual([other])
}) })
it('re-selects ancestors when a child is re-selected while editing', () => {
// https://github.com/paperless-ngx/paperless-ngx/issues/13970
const inbox: Tag = { id: 200, name: 'Inbox' }
const parent: Tag = { id: 201, name: 'Parent Tag' }
const child: Tag = { id: 202, name: 'Child Tag', parent: parent.id }
selectionModel.editing = true
selectionModel.items = [inbox, parent, child]
selectionModel.init(
new Map([
[inbox.id, ToggleableItemState.Selected],
[parent.id, ToggleableItemState.Selected],
[child.id, ToggleableItemState.Selected],
])
)
// deselecting the parent also deselects the child
selectionModel.toggle(parent.id, false)
expect(selectionModel.getSelectedItems()).toEqual([inbox])
// re-selecting the child brings its parent back, so nothing is changed
selectionModel.toggle(child.id, false)
expect(
selectionModel
.getSelectedItems()
.map((item) => item.id)
.sort((a, b) => a - b)
).toEqual([inbox.id, parent.id, child.id])
expect(selectionModel.diff()).toEqual({
itemsToAdd: [],
itemsToRemove: [],
})
})
it('un-excluding a parent clears excluded descendants', () => { it('un-excluding a parent clears excluded descendants', () => {
const root: Tag = { id: 110, name: 'Root Tag' } const root: Tag = { id: 110, name: 'Root Tag' }
const child: Tag = { id: 111, name: 'Child Tag', parent: root.id } const child: Tag = { id: 111, name: 'Child Tag', parent: root.id }
@@ -739,7 +773,7 @@ describe('FilterableDropdownComponent & FilterableDropdownSelectionModel', () =>
const apple: Tag = { id: 55, name: 'Apple' } const apple: Tag = { id: 55, name: 'Apple' }
const zebra: Tag = { id: 56, name: 'Zebra' } const zebra: Tag = { id: 56, name: 'Zebra' }
selectionModel.documentCountSortingEnabled = true selectionModel.editing = true
selectionModel.items = [apple, zebra] selectionModel.items = [apple, zebra]
expect(selectionModel.items.map((item) => item?.id ?? null)).toEqual([ expect(selectionModel.items.map((item) => item?.id ?? null)).toEqual([
null, null,
@@ -78,7 +78,7 @@ export class FilterableDropdownSelectionModel {
new Map<number, ToggleableItemState>() new Map<number, ToggleableItemState>()
) )
public documentCountSortingEnabled = false public editing = false
private get selectionStates(): ReadonlyMap<number, ToggleableItemState> { private get selectionStates(): ReadonlyMap<number, ToggleableItemState> {
return this._selectionStates() return this._selectionStates()
@@ -93,7 +93,7 @@ export class FilterableDropdownSelectionModel {
public set documentCounts(counts: SelectionDataItem[]) { public set documentCounts(counts: SelectionDataItem[]) {
this._documentCounts.set(counts) this._documentCounts.set(counts)
if (this.documentCountSortingEnabled) { if (this.editing) {
this._items.set(this.sortItems(this.items)) this._items.set(this.sortItems(this.items))
} }
} }
@@ -242,6 +242,9 @@ export class FilterableDropdownSelectionModel {
} }
states.set(id, newState) states.set(id, newState)
} }
if (this.editing && states.get(id) == ToggleableItemState.Selected) {
this.addAncestorSelections(states, id)
}
} else if ( } else if (
state == ToggleableItemState.Selected || state == ToggleableItemState.Selected ||
state == ToggleableItemState.Excluded state == ToggleableItemState.Excluded
@@ -327,6 +330,21 @@ export class FilterableDropdownSelectionModel {
} }
} }
private addAncestorSelections(
states: Map<number, ToggleableItemState>,
id: number
) {
const parentById = this.buildParentById(this.items)
const seen = new Set<number>([id])
let parentID = parentById.get(id)
while (typeof parentID === 'number' && !seen.has(parentID)) {
seen.add(parentID)
states.set(parentID, ToggleableItemState.Selected)
parentID = parentById.get(parentID)
}
}
private getDescendantIDs(id: number): number[] { private getDescendantIDs(id: number): number[] {
const descendants: number[] = [] const descendants: number[] = []
const queue: number[] = [id] const queue: number[] = [id]
@@ -731,7 +749,7 @@ export class FilterableDropdownComponent
model.manyToOne = this.selectionModel.manyToOne model.manyToOne = this.selectionModel.manyToOne
model.singleSelect = this._editing && !model.manyToOne model.singleSelect = this._editing && !model.manyToOne
} }
model.documentCountSortingEnabled = this._editing model.editing = this._editing
model.changed.subscribe((updatedModel) => { model.changed.subscribe((updatedModel) => {
this.selectionModelChange.next(updatedModel) this.selectionModelChange.next(updatedModel)
}) })
@@ -769,7 +787,7 @@ export class FilterableDropdownComponent
if (this.selectionModel) { if (this.selectionModel) {
this.selectionModel.singleSelect = this.selectionModel.singleSelect =
this._editing && !this.selectionModel.manyToOne this._editing && !this.selectionModel.manyToOne
this.selectionModel.documentCountSortingEnabled = this._editing this.selectionModel.editing = this._editing
} }
} }
@@ -7,6 +7,8 @@
padding-left: calc(calc(var(--depth) - 2) * 1rem); padding-left: calc(calc(var(--depth) - 2) * 1rem);
display: flex; display: flex;
align-items: center; align-items: center;
min-width: 0;
overflow-wrap: anywhere;
.indicator { .indicator {
display: inline-block; display: inline-block;
@@ -18,3 +20,7 @@
margin-left: .5rem; margin-left: .5rem;
} }
} }
.badge {
flex-shrink: 0;
}
@@ -33,6 +33,7 @@
[compareWith]="compareDocuments" [compareWith]="compareDocuments"
[trackByFn]="trackByFn" [trackByFn]="trackByFn"
[minTermLength]="2" [minTermLength]="2"
[appendTo]="appendTo"
[loading]="loading()" [loading]="loading()"
[typeahead]="documentsInput$" [typeahead]="documentsInput$"
(mousedown)="$event.stopImmediatePropagation()" (mousedown)="$event.stopImmediatePropagation()"
@@ -81,6 +81,12 @@ export class DocumentLinkComponent
@Input() @Input()
placeholder: string = $localize`Search for documents` placeholder: string = $localize`Search for documents`
/**
* Parent for ng-select dropdown, needed to prevent close on click.
*/
@Input()
appendTo: string = null
get selectedDocumentIDs(): number[] { get selectedDocumentIDs(): number[] {
return this.selectedDocuments.map((d) => d.id) return this.selectedDocuments.map((d) => d.id)
} }
@@ -22,7 +22,7 @@
} }
// Dropdown hierarchy reveal for ng-select options // Dropdown hierarchy reveal for ng-select options
:host ::ng-deep .ng-dropdown-panel .ng-option { ::ng-deep .ng-dropdown-panel .ng-option {
overflow-x: auto !important; overflow-x: auto !important;
.tag-option-row { .tag-option-row {
@@ -41,12 +41,12 @@
} }
} }
:host ::ng-deep .ng-dropdown-panel .ng-option:hover .hierarchy-reveal, ::ng-deep .ng-dropdown-panel .ng-option:hover .hierarchy-reveal,
:host ::ng-deep .ng-dropdown-panel .ng-option.ng-option-marked .hierarchy-reveal { ::ng-deep .ng-dropdown-panel .ng-option.ng-option-marked .hierarchy-reveal {
max-width: 1000px; max-width: 1000px;
} }
::ng-deep .ng-dropdown-panel .ng-option:hover .hierarchy-indicator, ::ng-deep .ng-dropdown-panel .ng-option:hover .hierarchy-indicator,
:host ::ng-deep .ng-dropdown-panel .ng-option.ng-option-marked .hierarchy-indicator { ::ng-deep .ng-dropdown-panel .ng-option.ng-option-marked .hierarchy-indicator {
background: transparent; background: transparent;
} }
@@ -207,6 +207,21 @@ describe('TagsComponent', () => {
expect(component.value).toEqual([2, 1]) expect(component.value).toEqual([2, 1])
}) })
it('should propagate parents added via ng-select selection', () => {
const parent: Tag = { id: 1, name: 'parent' }
const child: Tag = { id: 2, name: 'child', parent: 1 }
component.tags = [parent, child]
fixture.detectChanges()
let propagated: number[]
component.registerOnChange((value: number[]) => (propagated = value))
component.value = []
component.select.select(component.select.itemsList.findItem(child.id))
expect(component.value).toEqual([2, 1])
expect(propagated).toEqual([2, 1])
})
it('should not duplicate parents when adding sibling nested tags', () => { it('should not duplicate parents when adding sibling nested tags', () => {
const root: Tag = { id: 1, name: 'root' } const root: Tag = { id: 1, name: 'root' }
const parent: Tag = { id: 2, name: 'parent', parent: 1 } const parent: Tag = { id: 2, name: 'parent', parent: 1 }
@@ -173,6 +173,7 @@ export class TagsComponent implements OnInit, ControlValueAccessor {
if (parent && !this.value.includes(parent.id)) { if (parent && !this.value.includes(parent.id)) {
this.value = [...this.value, parent.id] this.value = [...this.value, parent.id]
this.onAdd(parent) this.onAdd(parent)
this.onChange(this.value) // re-emit for ng-select
} }
} }
} }
@@ -22,7 +22,7 @@
} }
::ng-deep .pngx-pdf-viewer-container { ::ng-deep .pngx-pdf-viewer-container {
overflow: hidden; overflow: hidden !important;
} }
.hover-actions { .hover-actions {
@@ -3,7 +3,7 @@
<i-bs name="person-fill-lock"></i-bs><div class="d-none d-sm-inline ms-1">{{title}}</div> <i-bs name="person-fill-lock"></i-bs><div class="d-none d-sm-inline ms-1">{{title}}</div>
<pngx-clearable-badge [selected]="isActive" (cleared)="reset()"></pngx-clearable-badge><span class="visually-hidden">selected</span> <pngx-clearable-badge [selected]="isActive" (cleared)="reset()"></pngx-clearable-badge><span class="visually-hidden">selected</span>
</button> </button>
<div class="dropdown-menu permission-filter-dropdown shadow py-0 w-2" ngbDropdownMenu attr.aria-labelledby="dropdown{{title}}"> <div [id]="dropdownMenuId" class="dropdown-menu permission-filter-dropdown shadow py-0 w-2" ngbDropdownMenu attr.aria-labelledby="dropdown{{title}}">
<div class="list-group list-group-flush"> <div class="list-group list-group-flush">
<button class="list-group-item list-group-item-action d-flex align-items-center p-2 border-top-0 border-start-0 border-end-0 border-bottom" role="menuitem" (click)="setFilter(OwnerFilterType.NONE)" [disabled]="disabled"> <button class="list-group-item list-group-item-action d-flex align-items-center p-2 border-top-0 border-start-0 border-end-0 border-bottom" role="menuitem" (click)="setFilter(OwnerFilterType.NONE)" [disabled]="disabled">
<div class="selected-icon me-1"> <div class="selected-icon me-1">
@@ -58,7 +58,10 @@
<button *pngxIfPermissions="{ action: PermissionAction.View, type: PermissionType.User }" class="list-group-item list-group-item-action d-flex align-items-center p-2 border-top-0 border-start-0 border-end-0 border-bottom" role="menuitem" [disabled]="disabled"> <button *pngxIfPermissions="{ action: PermissionAction.View, type: PermissionType.User }" class="list-group-item list-group-item-action d-flex align-items-center p-2 border-top-0 border-start-0 border-end-0 border-bottom" role="menuitem" [disabled]="disabled">
<div class="selected-icon me-1"> <div class="selected-icon me-1">
@if (selectionModel.ownerFilter() === OwnerFilterType.OTHERS) { @if (selectionModel.ownerFilter() === OwnerFilterType.OTHERS) {
<i-bs width="1em" height="1em" name="check"></i-bs> <a class="text-reset focus-variants" href="javascript:void(0)" (click)="clearIncludeUsers()" aria-label="Clear selected users" i18n-aria-label>
<i-bs width="1em" height="1em" name="check" class="variant-unfocused"></i-bs>
<i-bs width="1em" height="1em" name="x" class="variant-focused text-primary"></i-bs>
</a>
} }
</div> </div>
<div class="me-1 w-100"> <div class="me-1 w-100">
@@ -69,6 +72,7 @@
(ngModelChange)="selectionModel.includeUsers.set($event)" (ngModelChange)="selectionModel.includeUsers.set($event)"
[disabled]="disabled" [disabled]="disabled"
[clearable]="false" [clearable]="false"
[appendTo]="'#' + dropdownMenuId"
[items]="users()" [items]="users()"
bindLabel="username" bindLabel="username"
multiple="true" multiple="true"
@@ -6,3 +6,18 @@
min-width: 1em; min-width: 1em;
min-height: 1em; min-height: 1em;
} }
.focus-variants {
.variant-focused {
display: none;
}
&:hover, &:focus {
.variant-unfocused {
display: none;
}
.variant-focused {
display: block;
}
}
}
@@ -171,6 +171,21 @@ describe('PermissionsFilterDropdownComponent', () => {
expect(component.selectionModel.ownerFilter()).toEqual(OwnerFilterType.NONE) expect(component.selectionModel.ownerFilter()).toEqual(OwnerFilterType.NONE)
}) })
it('should clear selected users', () => {
component.selectionModel.includeUsers.set([12])
component.onUserSelect()
component.selectionModel.hideUnowned.set(true)
expect(component.selectionModel.ownerFilter()).toEqual(
OwnerFilterType.OTHERS
)
component.clearIncludeUsers()
expect(component.selectionModel.includeUsers()).toEqual([])
expect(component.selectionModel.ownerFilter()).toEqual(OwnerFilterType.NONE)
expect(component.selectionModel.hideUnowned()).toBeTruthy()
})
it('should emit a selection model depending on the type of owner filter set', () => { it('should emit a selection model depending on the type of owner filter set', () => {
const emitted = () => ({ const emitted = () => ({
excludeUsers: ownerFilterSetResult.excludeUsers(), excludeUsers: ownerFilterSetResult.excludeUsers(),
@@ -1,3 +1,4 @@
import { _IdGenerator } from '@angular/cdk/a11y'
import { NgClass } from '@angular/common' import { NgClass } from '@angular/common'
import { import {
Component, Component,
@@ -70,6 +71,11 @@ export class PermissionsFilterDropdownComponent extends ComponentWithPermissions
public OwnerFilterType = OwnerFilterType public OwnerFilterType = OwnerFilterType
private readonly idGenerator = inject(_IdGenerator)
public readonly dropdownMenuId = this.idGenerator.getId(
'pngx-permissions-filter-dropdown-'
)
@Input() @Input()
title: string title: string
@@ -205,6 +211,11 @@ export class PermissionsFilterDropdownComponent extends ComponentWithPermissions
this.ownerFilterSet.emit(this.selectionModel) this.ownerFilterSet.emit(this.selectionModel)
} }
clearIncludeUsers() {
this.selectionModel.includeUsers.set([])
this.onUserSelect()
}
onUserSelect() { onUserSelect() {
this.selectionModel.ownerFilter.set( this.selectionModel.ownerFilter.set(
this.selectionModel.includeUsers()?.length this.selectionModel.includeUsers()?.length
@@ -60,16 +60,16 @@
<div class="list-group list-group-flush border-0 pt-1 pb-2 card-info"> <div class="list-group list-group-flush border-0 pt-1 pb-2 card-info">
@if (document()) { @if (document()) {
@if (displayFields().includes(DisplayField.DOCUMENT_TYPE) && document().document_type) { @if (displayFields().includes(DisplayField.DOCUMENT_TYPE) && document().document_type) {
<button type="button" class="list-group-item list-group-item-action bg-transparent ps-0 p-1 border-0" title="Toggle document type filter" i18n-title <button type="button" class="list-group-item list-group-item-action bg-transparent ps-0 p-1 border-0 d-flex align-items-start" title="Toggle document type filter" i18n-title
(click)="clickDocumentType.emit(document().document_type);$event.stopPropagation()"> (click)="clickDocumentType.emit(document().document_type);$event.stopPropagation()">
<i-bs width="1em" height="1em" class="me-2 text-muted" name="file-earmark"></i-bs> <i-bs width="1em" height="1em" class="me-2 text-muted flex-shrink-0" name="file-earmark"></i-bs>
<small>{{document().document_type | documentTypeName | async}}</small> <small>{{document().document_type | documentTypeName | async}}</small>
</button> </button>
} }
@if (displayFields().includes(DisplayField.STORAGE_PATH) && document().storage_path) { @if (displayFields().includes(DisplayField.STORAGE_PATH) && document().storage_path) {
<button type="button" class="list-group-item list-group-item-action bg-transparent ps-0 p-1 border-0" title="Toggle storage path filter" i18n-title <button type="button" class="list-group-item list-group-item-action bg-transparent ps-0 p-1 border-0 d-flex align-items-start" title="Toggle storage path filter" i18n-title
(click)="clickStoragePath.emit(document().storage_path);$event.stopPropagation()"> (click)="clickStoragePath.emit(document().storage_path);$event.stopPropagation()">
<i-bs width="1em" height="1em" class="me-2 text-muted" name="folder"></i-bs> <i-bs width="1em" height="1em" class="me-2 text-muted flex-shrink-0" name="folder"></i-bs>
<small>{{document().storage_path | storagePathName | async}}</small> <small>{{document().storage_path | storagePathName | async}}</small>
</button> </button>
} }
@@ -69,6 +69,11 @@
button { button {
line-height: 1; line-height: 1;
small {
min-width: 0;
overflow-wrap: anywhere;
}
&:hover, &:hover,
&:focus { &:focus {
background-color: transparent !important; background-color: transparent !important;
+1 -1
View File
@@ -8,7 +8,7 @@ export const environment = {
apiVersion: '10', // match src/paperless/settings.py apiVersion: '10', // match src/paperless/settings.py
appTitle: DEFAULT_APP_TITLE, appTitle: DEFAULT_APP_TITLE,
tag: 'prod', tag: 'prod',
version: '3.1.2', version: '3.1.3',
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/',
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+16 -11
View File
@@ -374,17 +374,6 @@ th[pngxSortable] {
} }
} }
.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-marked {
background-color: var(--pngx-bg-darker) !important;
color: var(--pngx-body-color-accent) !important;
}
.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-selected,
.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-selected.ng-option-marked {
font-weight: bold;
background-color: var(--pngx-bg-alt2) !important;
}
&.ng-select-multiple .ng-select-container .ng-value-container .ng-placeholder, &.ng-select-multiple .ng-select-container .ng-value-container .ng-placeholder,
.ng-select-container .ng-value-container .ng-placeholder { .ng-select-container .ng-value-container .ng-placeholder {
top: 7px; top: 7px;
@@ -402,6 +391,22 @@ th[pngxSortable] {
} }
} }
// ng-select renders the dropdown panel in a CDK overlay outside the component
.ng-dropdown-panel {
font-size: var(--pngx-body-font-size);
.ng-dropdown-panel-items .ng-option.ng-option-marked {
background-color: var(--pngx-bg-darker) !important;
color: var(--pngx-body-color-accent) !important;
}
.ng-dropdown-panel-items .ng-option.ng-option-selected,
.ng-dropdown-panel-items .ng-option.ng-option-selected.ng-option-marked {
font-weight: bold;
background-color: var(--pngx-bg-alt2) !important;
}
}
.paperless-input-tags { .paperless-input-tags {
.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value { .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value {
background-color: transparent; background-color: transparent;
+2 -2
View File
@@ -237,8 +237,8 @@ $form-check-radio-checked-bg-image-dark: url("data:image/svg+xml,%3csvg xmlns='h
mix-blend-mode: luminosity; mix-blend-mode: luminosity;
} }
.paperless-input-select .ng-select .ng-dropdown-panel .ng-dropdown-panel-items .ng-option:not(.ng-option-selected):hover, .ng-dropdown-panel .ng-dropdown-panel-items .ng-option:not(.ng-option-selected):hover,
.paperless-input-select .ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-marked { .ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-marked {
background-color: var(--bs-light) !important; background-color: var(--bs-light) !important;
} }
@@ -314,7 +314,7 @@ def _consume_file(
consumption_dir: Path, consumption_dir: Path,
*, *,
subdirs_as_tags: bool, subdirs_as_tags: bool,
) -> None: ) -> bool:
""" """
Queue a file for consumption. Queue a file for consumption.
@@ -322,15 +322,20 @@ def _consume_file(
filepath: Path to the file to consume. filepath: Path to the file to consume.
consumption_dir: Base consumption directory. consumption_dir: Base consumption directory.
subdirs_as_tags: Whether to create tags from subdirectory names. subdirs_as_tags: Whether to create tags from subdirectory names.
Returns:
True if the file was successfully handed to Celery, False otherwise.
Callers must not record the file as queued on failure, or the rescan
will never retry it.
""" """
# Verify file still exists and is accessible # Verify file still exists and is accessible
try: try:
if not filepath.is_file(): if not filepath.is_file():
logger.debug(f"Not consuming {filepath}: not a file or doesn't exist") logger.debug(f"Not consuming {filepath}: not a file or doesn't exist")
return return False
except OSError as e: except OSError as e:
logger.warning(f"Not consuming {filepath}: {e}") logger.warning(f"Not consuming {filepath}: {e}")
return return False
# Get tags from path if configured # Get tags from path if configured
tag_ids: list[int] | None = None tag_ids: list[int] | None = None
@@ -355,6 +360,9 @@ def _consume_file(
) )
except Exception: except Exception:
logger.exception(f"Error while queuing document {filepath}") logger.exception(f"Error while queuing document {filepath}")
return False
return True
class Command(BaseCommand): class Command(BaseCommand):
@@ -492,12 +500,12 @@ class Command(BaseCommand):
if not consumer_filter(Change.added, str(filepath)): if not consumer_filter(Change.added, str(filepath)):
continue continue
_consume_file( if _consume_file(
filepath=filepath, filepath=filepath,
consumption_dir=directory, consumption_dir=directory,
subdirs_as_tags=subdirs_as_tags, subdirs_as_tags=subdirs_as_tags,
) ):
queued.add(filepath.resolve()) queued.add(filepath.resolve())
return queued return queued
@@ -651,14 +659,16 @@ class Command(BaseCommand):
# Check for stable files # Check for stable files
for stable_path in tracker.get_stable_files(): for stable_path in tracker.get_stable_files():
_consume_file( # Only remember files that were actually queued, so the
# rescan does not re-queue them while the consume task
# has yet to remove them from disk, but does retry a
# failed publish instead of stranding it
if _consume_file(
filepath=stable_path, filepath=stable_path,
consumption_dir=directory, consumption_dir=directory,
subdirs_as_tags=subdirs_as_tags, subdirs_as_tags=subdirs_as_tags,
) ):
# Remember it so the rescan does not re-queue it while queued.add(stable_path)
# the consume task has yet to remove it from disk
queued.add(stable_path)
# Exit watch loop to reconfigure timeout # Exit watch loop to reconfigure timeout
break break

Some files were not shown because too many files have changed in this diff Show More