Compare commits

..

115 Commits

Author SHA1 Message Date
shamoon
19dfaf1b94 Bump version to 2.11.3 2024-08-08 07:46:22 -07:00
shamoon
183ea24c9f Merge branch 'dev' 2024-08-08 07:45:49 -07:00
shamoon
99693b6d30 Update frontend translation strings 2024-08-08 07:45:30 -07:00
shamoon
c0ad82b695 Fix: clear selection after reload for management lists (#7421) 2024-08-08 07:38:45 -07:00
dependabot[bot]
fd36323d1c Chore(deps): Bump django from 4.2.14 to 4.2.15 (#7412)
Bumps [django](https://github.com/django/django) from 4.2.14 to 4.2.15.
- [Commits](https://github.com/django/django/compare/4.2.14...4.2.15)

---
updated-dependencies:
- dependency-name: django
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-07 12:49:51 -07:00
shamoon
4059c83a21 Documentation: correct DO logo URL 2024-08-07 12:19:50 -07:00
shamoon
b25c015516 Documentation: fix config formatting 2024-08-06 08:31:48 -07:00
shamoon
8fa52046e4 Enhancement: optimize tasks / stats reload (#7402) 2024-08-05 23:25:55 -07:00
shamoon
15554322dd Enhancement: allow specifying default currency for Monetary custom field (#7381) 2024-08-05 17:02:03 -07:00
shamoon
0ee85aae21 Enhancement: log when pre-check fails for documents in trash (#7355) 2024-08-05 17:01:01 -07:00
dependabot[bot]
839fb34c8e Chore(deps-dev): Bump the development group with 3 updates (#7394)
* Chore(deps-dev): Bump the development group with 3 updates

Bumps the development group with 3 updates: [ruff](https://github.com/astral-sh/ruff), [pytest](https://github.com/pytest-dev/pytest) and [mkdocs-material](https://github.com/squidfunk/mkdocs-material).


Updates `ruff` from 0.5.4 to 0.5.6
- [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.5.4...0.5.6)

Updates `pytest` from 8.3.1 to 8.3.2
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/8.3.1...8.3.2)

Updates `mkdocs-material` from 9.5.29 to 9.5.31
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.29...9.5.31)

---
updated-dependencies:
- dependency-name: ruff
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development
- dependency-name: pytest
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development
- dependency-name: mkdocs-material
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development
...

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

* Update .pre-commit-config.yaml

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
2024-08-05 23:56:16 +00:00
shamoon
928580bf4f Fix: disable inline create buttons if insufficient permissions (#7401) 2024-08-05 16:45:48 -07:00
dependabot[bot]
9cca7aaa08 Chore(deps): Bump the small-changes group with 5 updates (#7397)
Bumps the small-changes group with 5 updates:

| Package | From | To |
| --- | --- | --- |
| [imap-tools](https://github.com/ikvk/imap_tools) | `1.7.0` | `1.7.2` |
| [rapidfuzz](https://github.com/rapidfuzz/RapidFuzz) | `3.9.4` | `3.9.5` |
| [redis](https://github.com/redis/redis-py) | `5.0.7` | `5.0.8` |
| [tqdm](https://github.com/tqdm/tqdm) | `4.66.4` | `4.66.5` |
| [pre-commit](https://github.com/pre-commit/pre-commit) | `3.7.1` | `3.8.0` |


Updates `imap-tools` from 1.7.0 to 1.7.2
- [Release notes](https://github.com/ikvk/imap_tools/releases)
- [Changelog](https://github.com/ikvk/imap_tools/blob/master/docs/release_notes.rst)
- [Commits](https://github.com/ikvk/imap_tools/compare/v1.7.0...v1.7.2)

Updates `rapidfuzz` from 3.9.4 to 3.9.5
- [Release notes](https://github.com/rapidfuzz/RapidFuzz/releases)
- [Changelog](https://github.com/rapidfuzz/RapidFuzz/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/rapidfuzz/RapidFuzz/compare/v3.9.4...v3.9.5)

Updates `redis` from 5.0.7 to 5.0.8
- [Release notes](https://github.com/redis/redis-py/releases)
- [Changelog](https://github.com/redis/redis-py/blob/master/CHANGES)
- [Commits](https://github.com/redis/redis-py/compare/v5.0.7...v5.0.8)

Updates `tqdm` from 4.66.4 to 4.66.5
- [Release notes](https://github.com/tqdm/tqdm/releases)
- [Commits](https://github.com/tqdm/tqdm/compare/v4.66.4...v4.66.5)

Updates `pre-commit` from 3.7.1 to 3.8.0
- [Release notes](https://github.com/pre-commit/pre-commit/releases)
- [Changelog](https://github.com/pre-commit/pre-commit/blob/main/CHANGELOG.md)
- [Commits](https://github.com/pre-commit/pre-commit/compare/v3.7.1...v3.8.0)

---
updated-dependencies:
- dependency-name: imap-tools
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: small-changes
- dependency-name: rapidfuzz
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: small-changes
- dependency-name: redis
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: small-changes
- dependency-name: tqdm
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: small-changes
- dependency-name: pre-commit
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: small-changes
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-05 15:53:29 -07:00
dependabot[bot]
38560cf13a Chore(deps-dev): Bump @playwright/test from 1.42.1 to 1.45.3 in /src-ui (#7367)
* Chore(deps-dev): Bump @playwright/test from 1.42.1 to 1.45.3 in /src-ui

Bumps [@playwright/test](https://github.com/microsoft/playwright) from 1.42.1 to 1.45.3.
- [Release notes](https://github.com/microsoft/playwright/releases)
- [Commits](https://github.com/microsoft/playwright/compare/v1.42.1...v1.45.3)

---
updated-dependencies:
- dependency-name: "@playwright/test"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

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

* Fix failing test

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
2024-08-01 23:59:56 +00:00
dependabot[bot]
474ca08ef9 Chore(deps-dev): Bump @types/node from 20.12.2 to 22.0.2 in /src-ui (#7366)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.12.2 to 22.0.2.
- [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-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-01 23:32:05 +00:00
dependabot[bot]
d4fd529e49 Chore(deps-dev): Bump the frontend-eslint-dependencies group (#7365)
Bumps the frontend-eslint-dependencies group in /src-ui with 4 updates: [@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 7.4.0 to 8.0.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.0.0/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 7.4.0 to 8.0.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.0.0/packages/parser)

Updates `@typescript-eslint/utils` from 7.13.0 to 8.0.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.0.0/packages/utils)

Updates `eslint` from 8.57.0 to 9.8.0
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v8.57.0...v9.8.0)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: frontend-eslint-dependencies
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: frontend-eslint-dependencies
- dependency-name: "@typescript-eslint/utils"
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: frontend-eslint-dependencies
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-major
  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>
2024-08-01 16:24:30 -07:00
dependabot[bot]
2260617447 Chore(deps): Bump uuid from 9.0.1 to 10.0.0 in /src-ui (#7370)
Bumps [uuid](https://github.com/uuidjs/uuid) from 9.0.1 to 10.0.0.
- [Changelog](https://github.com/uuidjs/uuid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/uuidjs/uuid/compare/v9.0.1...v10.0.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-01 23:07:17 +00:00
dependabot[bot]
7c3ba3e518 Chore(deps): Bump stumpylog/image-cleaner-action in the actions group (#7371)
Bumps the actions group with 1 update: [stumpylog/image-cleaner-action](https://github.com/stumpylog/image-cleaner-action).


Updates `stumpylog/image-cleaner-action` from 0.7.0 to 0.8.0
- [Release notes](https://github.com/stumpylog/image-cleaner-action/releases)
- [Changelog](https://github.com/stumpylog/image-cleaner-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/stumpylog/image-cleaner-action/compare/v0.7.0...v0.8.0)

---
updated-dependencies:
- dependency-name: stumpylog/image-cleaner-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-01 15:57:46 -07:00
dependabot[bot]
849e3a10ac Chore(deps): Bump zone.js from 0.14.4 to 0.14.8 in /src-ui (#7368)
Bumps [zone.js](https://github.com/angular/angular/tree/HEAD/packages/zone.js) from 0.14.4 to 0.14.8.
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/packages/zone.js/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/zone.js-0.14.8/packages/zone.js)

---
updated-dependencies:
- dependency-name: zone.js
  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>
2024-08-01 15:57:24 -07:00
dependabot[bot]
bdceeef3fb Chore(deps-dev): Bump jest-preset-angular (#7364)
Bumps the frontend-jest-dependencies group in /src-ui with 1 update: [jest-preset-angular](https://github.com/thymikee/jest-preset-angular).


Updates `jest-preset-angular` from 14.1.1 to 14.2.2
- [Release notes](https://github.com/thymikee/jest-preset-angular/releases)
- [Changelog](https://github.com/thymikee/jest-preset-angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/thymikee/jest-preset-angular/compare/v14.1.1...v14.2.2)

---
updated-dependencies:
- dependency-name: jest-preset-angular
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: frontend-jest-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-01 21:48:13 +00:00
dependabot[bot]
8630e5f5b6 Chore(deps): Bump the frontend-angular-dependencies group (#7363)
Bumps the frontend-angular-dependencies group in /src-ui with 20 updates:

| Package | From | To |
| --- | --- | --- |
| [@angular/cdk](https://github.com/angular/components) | `18.1.0` | `18.1.3` |
| [@angular/common](https://github.com/angular/angular/tree/HEAD/packages/common) | `18.0.6` | `18.1.3` |
| [@angular/compiler](https://github.com/angular/angular/tree/HEAD/packages/compiler) | `18.0.6` | `18.1.3` |
| [@angular/core](https://github.com/angular/angular/tree/HEAD/packages/core) | `18.0.6` | `18.1.3` |
| [@angular/forms](https://github.com/angular/angular/tree/HEAD/packages/forms) | `18.0.6` | `18.1.3` |
| [@angular/localize](https://github.com/angular/angular) | `18.0.6` | `18.1.3` |
| [@angular/platform-browser](https://github.com/angular/angular/tree/HEAD/packages/platform-browser) | `18.0.6` | `18.1.3` |
| [@angular/platform-browser-dynamic](https://github.com/angular/angular/tree/HEAD/packages/platform-browser-dynamic) | `18.0.6` | `18.1.3` |
| [@angular/router](https://github.com/angular/angular/tree/HEAD/packages/router) | `18.0.6` | `18.1.3` |
| [@ng-select/ng-select](https://github.com/ng-select/ng-select) | `13.4.1` | `13.5.0` |
| [@angular-devkit/build-angular](https://github.com/angular/angular-cli) | `18.0.7` | `18.1.3` |
| [@angular-devkit/core](https://github.com/angular/angular-cli) | `18.0.7` | `18.1.3` |
| [@angular-devkit/schematics](https://github.com/angular/angular-cli) | `18.0.7` | `18.1.3` |
| [@angular-eslint/builder](https://github.com/angular-eslint/angular-eslint/tree/HEAD/packages/builder) | `18.1.0` | `18.2.0` |
| [@angular-eslint/eslint-plugin](https://github.com/angular-eslint/angular-eslint/tree/HEAD/packages/eslint-plugin) | `18.1.0` | `18.2.0` |
| [@angular-eslint/eslint-plugin-template](https://github.com/angular-eslint/angular-eslint/tree/HEAD/packages/eslint-plugin-template) | `18.1.0` | `18.2.0` |
| [@angular-eslint/schematics](https://github.com/angular-eslint/angular-eslint/tree/HEAD/packages/schematics) | `18.1.0` | `18.2.0` |
| [@angular-eslint/template-parser](https://github.com/angular-eslint/angular-eslint/tree/HEAD/packages/template-parser) | `18.1.0` | `18.2.0` |
| [@angular/cli](https://github.com/angular/angular-cli) | `18.0.7` | `18.1.3` |
| [@angular/compiler-cli](https://github.com/angular/angular/tree/HEAD/packages/compiler-cli) | `18.0.6` | `18.1.3` |


Updates `@angular/cdk` from 18.1.0 to 18.1.3
- [Release notes](https://github.com/angular/components/releases)
- [Changelog](https://github.com/angular/components/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/components/compare/18.1.0...18.1.3)

Updates `@angular/common` from 18.0.6 to 18.1.3
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/18.1.3/packages/common)

Updates `@angular/compiler` from 18.0.6 to 18.1.3
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/18.1.3/packages/compiler)

Updates `@angular/core` from 18.0.6 to 18.1.3
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/18.1.3/packages/core)

Updates `@angular/forms` from 18.0.6 to 18.1.3
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/18.1.3/packages/forms)

Updates `@angular/localize` from 18.0.6 to 18.1.3
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/compare/18.0.6...18.1.3)

Updates `@angular/platform-browser` from 18.0.6 to 18.1.3
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/18.1.3/packages/platform-browser)

Updates `@angular/platform-browser-dynamic` from 18.0.6 to 18.1.3
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/18.1.3/packages/platform-browser-dynamic)

Updates `@angular/router` from 18.0.6 to 18.1.3
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/18.1.3/packages/router)

Updates `@ng-select/ng-select` from 13.4.1 to 13.5.0
- [Release notes](https://github.com/ng-select/ng-select/releases)
- [Changelog](https://github.com/ng-select/ng-select/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ng-select/ng-select/compare/v13.4.1...v13.5.0)

Updates `@angular-devkit/build-angular` from 18.0.7 to 18.1.3
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Changelog](https://github.com/angular/angular-cli/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular-cli/compare/18.0.7...18.1.3)

Updates `@angular-devkit/core` from 18.0.7 to 18.1.3
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Changelog](https://github.com/angular/angular-cli/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular-cli/compare/18.0.7...18.1.3)

Updates `@angular-devkit/schematics` from 18.0.7 to 18.1.3
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Changelog](https://github.com/angular/angular-cli/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular-cli/compare/18.0.7...18.1.3)

Updates `@angular-eslint/builder` from 18.1.0 to 18.2.0
- [Release notes](https://github.com/angular-eslint/angular-eslint/releases)
- [Changelog](https://github.com/angular-eslint/angular-eslint/blob/main/packages/builder/CHANGELOG.md)
- [Commits](https://github.com/angular-eslint/angular-eslint/commits/v18.2.0/packages/builder)

Updates `@angular-eslint/eslint-plugin` from 18.1.0 to 18.2.0
- [Release notes](https://github.com/angular-eslint/angular-eslint/releases)
- [Changelog](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/angular-eslint/angular-eslint/commits/v18.2.0/packages/eslint-plugin)

Updates `@angular-eslint/eslint-plugin-template` from 18.1.0 to 18.2.0
- [Release notes](https://github.com/angular-eslint/angular-eslint/releases)
- [Changelog](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin-template/CHANGELOG.md)
- [Commits](https://github.com/angular-eslint/angular-eslint/commits/v18.2.0/packages/eslint-plugin-template)

Updates `@angular-eslint/schematics` from 18.1.0 to 18.2.0
- [Release notes](https://github.com/angular-eslint/angular-eslint/releases)
- [Changelog](https://github.com/angular-eslint/angular-eslint/blob/main/packages/schematics/CHANGELOG.md)
- [Commits](https://github.com/angular-eslint/angular-eslint/commits/v18.2.0/packages/schematics)

Updates `@angular-eslint/template-parser` from 18.1.0 to 18.2.0
- [Release notes](https://github.com/angular-eslint/angular-eslint/releases)
- [Changelog](https://github.com/angular-eslint/angular-eslint/blob/main/packages/template-parser/CHANGELOG.md)
- [Commits](https://github.com/angular-eslint/angular-eslint/commits/v18.2.0/packages/template-parser)

Updates `@angular/cli` from 18.0.7 to 18.1.3
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Changelog](https://github.com/angular/angular-cli/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular-cli/compare/18.0.7...18.1.3)

Updates `@angular/compiler-cli` from 18.0.6 to 18.1.3
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/18.1.3/packages/compiler-cli)

---
updated-dependencies:
- dependency-name: "@angular/cdk"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular/common"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular/compiler"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular/core"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular/forms"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular/localize"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular/platform-browser"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular/platform-browser-dynamic"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular/router"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-angular-dependencies
- dependency-name: "@ng-select/ng-select"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular-devkit/build-angular"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular-devkit/core"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular-devkit/schematics"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular-eslint/builder"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular-eslint/eslint-plugin-template"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular-eslint/schematics"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular-eslint/template-parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular/cli"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular/compiler-cli"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: frontend-angular-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-01 14:34:29 -07:00
shamoon
2312eba5b6 Merge branch 'main' into dev 2024-07-29 07:32:04 -07:00
shamoon
ad9d654886 Documentation: Add missing change to changelog 2024-07-29 07:31:51 -07:00
fusselkater
fa19a8975e Fix: correct nltk data path (#7338) 2024-07-29 07:27:08 -07:00
shamoon
8987cd448f Fix: use entire document for dropzone (#7342) 2024-07-29 07:26:29 -07:00
github-actions[bot]
a7536e3ebf Documentation: Add v2.11.2 changelog (#7336)
* Changelog v2.11.2 - GHA

* Update changelog.md

---------

Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
2024-07-28 14:45:29 -07:00
shamoon
9c3bc2eb83 Bump version to 2.11.2 2024-07-28 14:11:20 -07:00
github-actions[bot]
d179efbd48 New Crowdin translations by GitHub Action (#7299)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2024-07-28 14:10:36 -07:00
shamoon
801df5f7bd Chore: reorganize trash location 2024-07-28 14:09:20 -07:00
shamoon
d1c3ea7faa Resolve test error 2024-07-28 14:08:16 -07:00
shamoon
dcfc53b7f2 Change: more clearly handle init permissions error (#7334) 2024-07-28 07:06:15 -07:00
shamoon
45002f8083 Merge branch 'main' into dev 2024-07-27 09:01:54 -07:00
shamoon
722a2ca1e4 Fix dashboard col width when wrapping on smaller screens with collapsed sidebar 2024-07-26 10:32:06 -07:00
shamoon
2bd8b67d02 Chore: add permissions info link from webUI (#7310) 2024-07-24 10:06:38 -07:00
shamoon
637efd5cb3 Documentation: clarify some global permissions details (#7309) 2024-07-24 10:06:08 -07:00
Jay Barker
ad3dd76c2f Fix: increase search input text contrast with light custom theme colors (#7303)
---------

Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
2024-07-24 02:57:26 +00:00
dependabot[bot]
75aba12589 Chore(deps-dev): Bump the development group with 2 updates (#7296)
* Chore(deps-dev): Bump the development group with 2 updates

Bumps the development group with 2 updates: [ruff](https://github.com/astral-sh/ruff) and [pytest](https://github.com/pytest-dev/pytest).


Updates `ruff` from 0.5.2 to 0.5.4
- [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.5.2...0.5.4)

Updates `pytest` from 8.2.2 to 8.3.1
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/8.2.2...8.3.1)

---
updated-dependencies:
- dependency-name: ruff
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development
- dependency-name: pytest
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: development
...

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

* Update ruff to match

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
2024-07-22 21:43:05 +00:00
dependabot[bot]
ec33edb2f4 Chore(deps): Bump tika-client in the small-changes group (#7297)
Bumps the small-changes group with 1 update: [tika-client](https://github.com/stumpylog/tika-rest-client).


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

---
updated-dependencies:
- dependency-name: tika-client
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: small-changes
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-22 14:31:16 -07:00
github-actions[bot]
4b706fa4dd Changelog v2.11.1 - GHA (#7295)
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
2024-07-22 11:34:29 -07:00
shamoon
98799d9a69 Bump version to 2.11.1 2024-07-22 10:29:02 -07:00
github-actions[bot]
b80070ac0b New Crowdin translations by GitHub Action (#7221)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2024-07-22 10:09:22 -07:00
shamoon
6b2e5559ca Fix: support multiple inbox tags from stats widget (#7281) 2024-07-22 10:07:51 -07:00
dependabot[bot]
82340ad6e3 Chore(deps-dev): Bump the development group with 2 updates (#7261)
* Chore(deps-dev): Bump the development group with 2 updates

Bumps the development group with 2 updates: [ruff](https://github.com/astral-sh/ruff) and [mkdocs-material](https://github.com/squidfunk/mkdocs-material).


Updates `ruff` from 0.5.1 to 0.5.2
- [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.5.1...0.5.2)

Updates `mkdocs-material` from 9.5.28 to 9.5.29
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.28...9.5.29)

---
updated-dependencies:
- dependency-name: ruff
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development
- dependency-name: mkdocs-material
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development
...

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

* Updates ruff to match

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
2024-07-22 09:56:43 -07:00
dependabot[bot]
f45ab723ae Chore(deps): Bump the small-changes group across 1 directory with 2 updates (#7266)
Bumps the small-changes group with 2 updates in the / directory: [django-allauth](https://github.com/pennersr/django-allauth) and [imap-tools](https://github.com/ikvk/imap_tools).


Updates `django-allauth` from 0.63.3 to 0.63.6
- [Changelog](https://github.com/pennersr/django-allauth/blob/main/ChangeLog.rst)
- [Commits](https://github.com/pennersr/django-allauth/compare/0.63.3...0.63.6)

Updates `imap-tools` from 1.6.0 to 1.7.0
- [Release notes](https://github.com/ikvk/imap_tools/releases)
- [Changelog](https://github.com/ikvk/imap_tools/blob/master/docs/release_notes.rst)
- [Commits](https://github.com/ikvk/imap_tools/compare/v1.6.0...v1.7.0)

---
updated-dependencies:
- dependency-name: django-allauth
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: small-changes
- dependency-name: imap-tools
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: small-changes
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-16 18:35:00 -07:00
Freddy0
8e3ca37b05 Enhancement: include owner username in post-consumption variables (#7270) 2024-07-16 15:23:29 -07:00
Trenton H
aef387ed69 Chore: Use self-documenting long options in Docker startup scripts (#7275) 2024-07-16 10:27:12 -07:00
Trenton H
b93c970635 Chore: Squash older automatic migrations (#7267) 2024-07-16 09:21:41 -07:00
shamoon
a7d8b5c960 Clarify has any tags 2024-07-15 15:37:43 -07:00
shamoon
56c9a3f270 Correct some indentation 2024-07-15 15:28:11 -07:00
shamoon
0c3dac45b5 Fix: use responsive table for compatibility with custom columns (#7255) 2024-07-15 15:17:46 -07:00
Trenton H
6965165c76 Removes Turkish from the NLTK languages (#7246) 2024-07-14 16:35:16 -07:00
shamoon
73d33ff25a Fix: include trashed docs in existing doc check (#7229) 2024-07-12 16:45:35 -07:00
github-actions[bot]
df153be30e Documentation: Add v2.11.0 changelog (#7218) 2024-07-10 21:55:01 -07:00
shamoon
9950ff2337 Bump version to 2.11.0 2024-07-10 21:21:29 -07:00
shamoon
9a9ab85baf Merge branch 'dev' 2024-07-10 21:02:57 -07:00
github-actions[bot]
eaea42334b New Crowdin translations by GitHub Action (#7124)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2024-07-10 20:29:17 -07:00
shamoon
de8ac013ee Enhancement: disable add split button when approrpriate (#7215) 2024-07-11 03:27:04 +00:00
shamoon
9e2bf4820a Enhancement: wrapping of saved view fields d-n-d UI (#7216) 2024-07-10 20:14:59 -07:00
Trenton H
9af879a2bf Bulk backend updates (#7209) 2024-07-10 12:45:29 -07:00
shamoon
ff4203938b Fix: correct card display custom field trackby variable 2024-07-09 13:06:06 -07:00
shamoon
a63f8809fa Fix: restore dashboard saved views display 2024-07-09 13:01:49 -07:00
shamoon
edcde1f142 Fix: move dashboard tour anchor to fix overlapping issues 2024-07-09 11:43:25 -07:00
shamoon
6dc094f760 Fix: unable to assign null select custom fields 2024-07-09 11:27:30 -07:00
shamoon
186f520819 Update backend translation strings 2024-07-09 11:06:18 -07:00
dependabot[bot]
0365fc5ac3 Chore(deps): Bump the frontend-angular-dependencies group (#7200)
Bumps the frontend-angular-dependencies group in /src-ui with 14 updates:

| Package | From | To |
| --- | --- | --- |
| [@angular/cdk](https://github.com/angular/components) | `18.0.5` | `18.0.6` |
| [@angular/common](https://github.com/angular/angular/tree/HEAD/packages/common) | `18.0.5` | `18.0.6` |
| [@angular/compiler](https://github.com/angular/angular/tree/HEAD/packages/compiler) | `18.0.5` | `18.0.6` |
| [@angular/core](https://github.com/angular/angular/tree/HEAD/packages/core) | `18.0.5` | `18.0.6` |
| [@angular/forms](https://github.com/angular/angular/tree/HEAD/packages/forms) | `18.0.5` | `18.0.6` |
| [@angular/localize](https://github.com/angular/angular) | `18.0.5` | `18.0.6` |
| [@angular/platform-browser](https://github.com/angular/angular/tree/HEAD/packages/platform-browser) | `18.0.5` | `18.0.6` |
| [@angular/platform-browser-dynamic](https://github.com/angular/angular/tree/HEAD/packages/platform-browser-dynamic) | `18.0.5` | `18.0.6` |
| [@angular/router](https://github.com/angular/angular/tree/HEAD/packages/router) | `18.0.5` | `18.0.6` |
| [@angular-devkit/build-angular](https://github.com/angular/angular-cli) | `18.0.6` | `18.0.7` |
| [@angular-devkit/core](https://github.com/angular/angular-cli) | `18.0.6` | `18.0.7` |
| [@angular-devkit/schematics](https://github.com/angular/angular-cli) | `18.0.6` | `18.0.7` |
| [@angular/cli](https://github.com/angular/angular-cli) | `18.0.6` | `18.0.7` |
| [@angular/compiler-cli](https://github.com/angular/angular/tree/HEAD/packages/compiler-cli) | `18.0.5` | `18.0.6` |


Updates `@angular/cdk` from 18.0.5 to 18.0.6
- [Release notes](https://github.com/angular/components/releases)
- [Changelog](https://github.com/angular/components/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/components/compare/18.0.5...18.0.6)

Updates `@angular/common` from 18.0.5 to 18.0.6
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/18.0.6/packages/common)

Updates `@angular/compiler` from 18.0.5 to 18.0.6
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/18.0.6/packages/compiler)

Updates `@angular/core` from 18.0.5 to 18.0.6
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/18.0.6/packages/core)

Updates `@angular/forms` from 18.0.5 to 18.0.6
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/18.0.6/packages/forms)

Updates `@angular/localize` from 18.0.5 to 18.0.6
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/compare/18.0.5...18.0.6)

Updates `@angular/platform-browser` from 18.0.5 to 18.0.6
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/18.0.6/packages/platform-browser)

Updates `@angular/platform-browser-dynamic` from 18.0.5 to 18.0.6
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/18.0.6/packages/platform-browser-dynamic)

Updates `@angular/router` from 18.0.5 to 18.0.6
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/18.0.6/packages/router)

Updates `@angular-devkit/build-angular` from 18.0.6 to 18.0.7
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Changelog](https://github.com/angular/angular-cli/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular-cli/compare/18.0.6...18.0.7)

Updates `@angular-devkit/core` from 18.0.6 to 18.0.7
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Changelog](https://github.com/angular/angular-cli/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular-cli/compare/18.0.6...18.0.7)

Updates `@angular-devkit/schematics` from 18.0.6 to 18.0.7
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Changelog](https://github.com/angular/angular-cli/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular-cli/compare/18.0.6...18.0.7)

Updates `@angular/cli` from 18.0.6 to 18.0.7
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Changelog](https://github.com/angular/angular-cli/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular-cli/compare/18.0.6...18.0.7)

Updates `@angular/compiler-cli` from 18.0.5 to 18.0.6
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/18.0.6/packages/compiler-cli)

---
updated-dependencies:
- dependency-name: "@angular/cdk"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular/common"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular/compiler"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular/core"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular/forms"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular/localize"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular/platform-browser"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular/platform-browser-dynamic"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular/router"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular-devkit/build-angular"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular-devkit/core"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular-devkit/schematics"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular/cli"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular/compiler-cli"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: frontend-angular-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-09 18:01:39 +00:00
shamoon
61811a4bec Enhancement: support customfield filter for select type (#7199) 2024-07-09 10:54:34 -07:00
shamoon
bb83c1eb0a Chore: upgrade to DRF 3.15 (#7134) 2024-07-09 16:57:53 +00:00
shamoon
4ad4862641 Feature: select custom field type (#7167) 2024-07-09 07:57:07 -07:00
shamoon
c03aa03ac2 Feature: automatic sso redirect (#7168) 2024-07-08 22:38:23 +00:00
shamoon
ada283441c Fix: include documents in trash for existing asn check (#7189) 2024-07-08 16:28:40 +00:00
Trenton H
3cf73a77ac Chore: Initial conversion to pytest fixtures (#7110) 2024-07-08 07:46:20 -07:00
Psychi
71fedcb466 Documentation: fix rapidfuzz link (#7176) 2024-07-07 07:08:40 -07:00
shamoon
1b9cf5121b Add missing disable autocomplete for doc type edit dialog 2024-07-06 13:24:43 -07:00
shamoon
7fe76656f2 Fix: editing of existing custom fields violates throws unique error 2024-07-06 13:05:20 -07:00
dependabot[bot]
0deb8a11d6 Chore(deps): Bump certifi from 2024.6.2 to 2024.7.4 (#7166)
Bumps [certifi](https://github.com/certifi/python-certifi) from 2024.6.2 to 2024.7.4.
- [Commits](https://github.com/certifi/python-certifi/compare/2024.06.02...2024.07.04)

---
updated-dependencies:
- dependency-name: certifi
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-05 20:48:01 -07:00
shamoon
064d384d97 Enhancement: show more columns in mail frontend admin (#7158) 2024-07-03 08:09:28 -07:00
dependabot[bot]
5045d06744 Chore(deps): Bump the frontend-angular-dependencies group (#7148)
Bumps the frontend-angular-dependencies group in /src-ui with 6 updates:

| Package | From | To |
| --- | --- | --- |
| [@ng-select/ng-select](https://github.com/ng-select/ng-select) | `13.3.0` | `13.4.1` |
| [@angular-eslint/builder](https://github.com/angular-eslint/angular-eslint/tree/HEAD/packages/builder) | `18.0.1` | `18.1.0` |
| [@angular-eslint/eslint-plugin](https://github.com/angular-eslint/angular-eslint/tree/HEAD/packages/eslint-plugin) | `18.0.1` | `18.1.0` |
| [@angular-eslint/eslint-plugin-template](https://github.com/angular-eslint/angular-eslint/tree/HEAD/packages/eslint-plugin-template) | `18.0.1` | `18.1.0` |
| [@angular-eslint/schematics](https://github.com/angular-eslint/angular-eslint/tree/HEAD/packages/schematics) | `18.0.1` | `18.1.0` |
| [@angular-eslint/template-parser](https://github.com/angular-eslint/angular-eslint/tree/HEAD/packages/template-parser) | `18.0.1` | `18.1.0` |


Updates `@ng-select/ng-select` from 13.3.0 to 13.4.1
- [Release notes](https://github.com/ng-select/ng-select/releases)
- [Changelog](https://github.com/ng-select/ng-select/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ng-select/ng-select/compare/v13.3.0...v13.4.1)

Updates `@angular-eslint/builder` from 18.0.1 to 18.1.0
- [Release notes](https://github.com/angular-eslint/angular-eslint/releases)
- [Changelog](https://github.com/angular-eslint/angular-eslint/blob/main/packages/builder/CHANGELOG.md)
- [Commits](https://github.com/angular-eslint/angular-eslint/commits/v18.1.0/packages/builder)

Updates `@angular-eslint/eslint-plugin` from 18.0.1 to 18.1.0
- [Release notes](https://github.com/angular-eslint/angular-eslint/releases)
- [Changelog](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/angular-eslint/angular-eslint/commits/v18.1.0/packages/eslint-plugin)

Updates `@angular-eslint/eslint-plugin-template` from 18.0.1 to 18.1.0
- [Release notes](https://github.com/angular-eslint/angular-eslint/releases)
- [Changelog](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin-template/CHANGELOG.md)
- [Commits](https://github.com/angular-eslint/angular-eslint/commits/v18.1.0/packages/eslint-plugin-template)

Updates `@angular-eslint/schematics` from 18.0.1 to 18.1.0
- [Release notes](https://github.com/angular-eslint/angular-eslint/releases)
- [Changelog](https://github.com/angular-eslint/angular-eslint/blob/main/packages/schematics/CHANGELOG.md)
- [Commits](https://github.com/angular-eslint/angular-eslint/commits/v18.1.0/packages/schematics)

Updates `@angular-eslint/template-parser` from 18.0.1 to 18.1.0
- [Release notes](https://github.com/angular-eslint/angular-eslint/releases)
- [Changelog](https://github.com/angular-eslint/angular-eslint/blob/main/packages/template-parser/CHANGELOG.md)
- [Commits](https://github.com/angular-eslint/angular-eslint/commits/v18.1.0/packages/template-parser)

---
updated-dependencies:
- dependency-name: "@ng-select/ng-select"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular-eslint/builder"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular-eslint/eslint-plugin-template"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular-eslint/schematics"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular-eslint/template-parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: frontend-angular-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-01 23:36:31 +00:00
dependabot[bot]
c57aa81d15 Chore(deps): Bump django-multiselectfield in the django group (#7147)
Bumps the django group with 1 update: [django-multiselectfield](https://github.com/goinnn/django-multiselectfield).


Updates `django-multiselectfield` from 0.1.12 to 0.1.13
- [Release notes](https://github.com/goinnn/django-multiselectfield/releases)
- [Changelog](https://github.com/goinnn/django-multiselectfield/blob/master/CHANGES.rst)
- [Commits](https://github.com/goinnn/django-multiselectfield/commits)

---
updated-dependencies:
- dependency-name: django-multiselectfield
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: django
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-01 16:23:09 -07:00
shamoon
d35e350c79 Fix: dont exclude documents in trash from sanity check (#7133) 2024-07-01 13:47:05 -07:00
dependabot[bot]
dd878c8d70 Chore(deps): Bump docker/build-push-action in the actions group (#7125)
Bumps the actions group with 1 update: [docker/build-push-action](https://github.com/docker/build-push-action).


Updates `docker/build-push-action` from 5 to 6
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v5...v6)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-28 07:06:48 -07:00
dependabot[bot]
9cd1945a89 Chore(deps): Bump the small-changes group across 1 directory with 4 updates (#7128)
Bumps the small-changes group with 4 updates in the / directory: [django-cors-headers](https://github.com/adamchainz/django-cors-headers), [filelock](https://github.com/tox-dev/py-filelock), [redis](https://github.com/redis/redis-py) and [whitenoise](https://github.com/evansd/whitenoise).


Updates `django-cors-headers` from 4.3.1 to 4.4.0
- [Changelog](https://github.com/adamchainz/django-cors-headers/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/adamchainz/django-cors-headers/compare/4.3.1...4.4.0)

Updates `filelock` from 3.15.1 to 3.15.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.15.1...3.15.4)

Updates `redis` from 5.0.6 to 5.0.7
- [Release notes](https://github.com/redis/redis-py/releases)
- [Changelog](https://github.com/redis/redis-py/blob/master/CHANGES)
- [Commits](https://github.com/redis/redis-py/compare/v5.0.6...v5.0.7)

Updates `whitenoise` from 6.6.0 to 6.7.0
- [Changelog](https://github.com/evansd/whitenoise/blob/main/docs/changelog.rst)
- [Commits](https://github.com/evansd/whitenoise/compare/6.6.0...6.7.0)

---
updated-dependencies:
- dependency-name: django-cors-headers
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: small-changes
- dependency-name: filelock
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: small-changes
- dependency-name: redis
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: small-changes
- dependency-name: whitenoise
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: small-changes
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-27 15:14:53 -07:00
dependabot[bot]
faab8a5560 Chore(deps): Bump the frontend-angular-dependencies group (#7126)
Bumps the frontend-angular-dependencies group in /src-ui with 16 updates:

| Package | From | To |
| --- | --- | --- |
| [@angular/cdk](https://github.com/angular/components) | `18.0.3` | `18.0.5` |
| [@angular/common](https://github.com/angular/angular/tree/HEAD/packages/common) | `18.0.3` | `18.0.5` |
| [@angular/compiler](https://github.com/angular/angular/tree/HEAD/packages/compiler) | `18.0.3` | `18.0.5` |
| [@angular/core](https://github.com/angular/angular/tree/HEAD/packages/core) | `18.0.3` | `18.0.5` |
| [@angular/forms](https://github.com/angular/angular/tree/HEAD/packages/forms) | `18.0.3` | `18.0.5` |
| [@angular/localize](https://github.com/angular/angular) | `18.0.3` | `18.0.5` |
| [@angular/platform-browser](https://github.com/angular/angular/tree/HEAD/packages/platform-browser) | `18.0.3` | `18.0.5` |
| [@angular/platform-browser-dynamic](https://github.com/angular/angular/tree/HEAD/packages/platform-browser-dynamic) | `18.0.3` | `18.0.5` |
| [@angular/router](https://github.com/angular/angular/tree/HEAD/packages/router) | `18.0.3` | `18.0.5` |
| [@ng-select/ng-select](https://github.com/ng-select/ng-select) | `13.2.0` | `13.3.0` |
| [@angular-builders/jest](https://github.com/just-jeb/angular-builders/tree/HEAD/packages/jest) | `18.0.0-beta.3` | `18.0.0` |
| [@angular-devkit/build-angular](https://github.com/angular/angular-cli) | `18.0.4` | `18.0.6` |
| [@angular-devkit/core](https://github.com/angular/angular-cli) | `18.0.4` | `18.0.6` |
| [@angular-devkit/schematics](https://github.com/angular/angular-cli) | `18.0.4` | `18.0.6` |
| [@angular/cli](https://github.com/angular/angular-cli) | `18.0.4` | `18.0.6` |
| [@angular/compiler-cli](https://github.com/angular/angular/tree/HEAD/packages/compiler-cli) | `18.0.3` | `18.0.5` |


Updates `@angular/cdk` from 18.0.3 to 18.0.5
- [Release notes](https://github.com/angular/components/releases)
- [Changelog](https://github.com/angular/components/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/components/compare/18.0.3...18.0.5)

Updates `@angular/common` from 18.0.3 to 18.0.5
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/18.0.5/packages/common)

Updates `@angular/compiler` from 18.0.3 to 18.0.5
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/18.0.5/packages/compiler)

Updates `@angular/core` from 18.0.3 to 18.0.5
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/18.0.5/packages/core)

Updates `@angular/forms` from 18.0.3 to 18.0.5
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/18.0.5/packages/forms)

Updates `@angular/localize` from 18.0.3 to 18.0.5
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/compare/18.0.3...18.0.5)

Updates `@angular/platform-browser` from 18.0.3 to 18.0.5
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/18.0.5/packages/platform-browser)

Updates `@angular/platform-browser-dynamic` from 18.0.3 to 18.0.5
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/18.0.5/packages/platform-browser-dynamic)

Updates `@angular/router` from 18.0.3 to 18.0.5
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/18.0.5/packages/router)

Updates `@ng-select/ng-select` from 13.2.0 to 13.3.0
- [Release notes](https://github.com/ng-select/ng-select/releases)
- [Changelog](https://github.com/ng-select/ng-select/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ng-select/ng-select/compare/v13.2.0...v13.3.0)

Updates `@angular-builders/jest` from 18.0.0-beta.3 to 18.0.0
- [Release notes](https://github.com/just-jeb/angular-builders/releases)
- [Changelog](https://github.com/just-jeb/angular-builders/blob/master/packages/jest/CHANGELOG.md)
- [Commits](https://github.com/just-jeb/angular-builders/commits/@angular-builders/jest@18.0.0/packages/jest)

Updates `@angular-devkit/build-angular` from 18.0.4 to 18.0.6
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Changelog](https://github.com/angular/angular-cli/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular-cli/compare/18.0.4...18.0.6)

Updates `@angular-devkit/core` from 18.0.4 to 18.0.6
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Changelog](https://github.com/angular/angular-cli/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular-cli/compare/18.0.4...18.0.6)

Updates `@angular-devkit/schematics` from 18.0.4 to 18.0.6
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Changelog](https://github.com/angular/angular-cli/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular-cli/compare/18.0.4...18.0.6)

Updates `@angular/cli` from 18.0.4 to 18.0.6
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Changelog](https://github.com/angular/angular-cli/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular-cli/compare/18.0.4...18.0.6)

Updates `@angular/compiler-cli` from 18.0.3 to 18.0.5
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/18.0.5/packages/compiler-cli)

---
updated-dependencies:
- dependency-name: "@angular/cdk"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular/common"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular/compiler"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular/core"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular/forms"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular/localize"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular/platform-browser"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular/platform-browser-dynamic"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular/router"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-angular-dependencies
- dependency-name: "@ng-select/ng-select"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular-builders/jest"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular-devkit/build-angular"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular-devkit/core"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular-devkit/schematics"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular/cli"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: frontend-angular-dependencies
- dependency-name: "@angular/compiler-cli"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: frontend-angular-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-27 15:14:32 -07:00
phail
fcc9847bc3 Development: Add VS Code Devcontainer Configuration (#7041) 2024-06-27 15:13:55 -07:00
shamoon
a64d457c30 Enhancement: use request user as owner of split / merge docs (#7112) 2024-06-27 13:46:49 -07:00
Trenton H
e799d757c2 Ignores DRF 3.15.2 (#7122) 2024-06-27 20:40:16 +00:00
shamoon
ac0ed0def8 Fix: handle errors for trash actions and only show documents user can restore or delete (#7119) 2024-06-27 20:33:39 +00:00
dependabot[bot]
f01283c309 Chore(deps-dev): Bump ruff from 0.4.9 to 0.5.0 in the development group across 1 directory (#7120)
* Chore(deps-dev): Bump ruff in the development group across 1 directory

Bumps the development group with 1 update in the / directory: [ruff](https://github.com/astral-sh/ruff).


Updates `ruff` from 0.4.9 to 0.5.0
- [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/v0.4.9...0.5.0)

---
updated-dependencies:
- dependency-name: ruff
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: development
...

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

* Update .pre-commit-config.yaml

* Lets ruff fix this new lint

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Trenton H <797416+stumpylog@users.noreply.github.com>
2024-06-27 19:06:37 +00:00
dependabot[bot]
a3c468a004 Chore(deps-dev): Bump ws from 8.17.0 to 8.17.1 in /src-ui (#7114)
Bumps [ws](https://github.com/websockets/ws) from 8.17.0 to 8.17.1.
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/8.17.0...8.17.1)

---
updated-dependencies:
- dependency-name: ws
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-27 04:33:27 +00:00
shamoon
3435ffd00c Chore: update to Angular v18 (#7106) 2024-06-26 20:57:39 -07:00
Fabien Dubuy
4f1185c65d Enhancement: improve date parsing with accented characters (#7100) 2024-06-26 20:47:37 -07:00
shamoon
2b1498cc6d Chore: display docker tag in UI for ci test builds (#7083) 2024-06-27 03:02:52 +00:00
shamoon
0643db4347 Feature: improve history display of object names etc (#7102) 2024-06-27 02:52:08 +00:00
Trenton H
29e6371cd1 Feature: Upgrade Gotenberg to v8 (#7094) 2024-06-27 02:37:50 +00:00
shamoon
80c2d90e74 Fix: dont include documents in trash in counts (#7111) 2024-06-26 19:30:12 -07:00
shamoon
f3cf608caa Fix: use temp dir for split / merge (#7105) 2024-06-26 10:46:59 -07:00
shamoon
c6d0557a3b Update configuration.md 2024-06-24 13:37:01 -07:00
github-actions[bot]
f3b7ae93f0 Changelog v2.10.2 - GHA (#7082)
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
2024-06-23 22:31:52 -07:00
shamoon
e4265d0594 Bump version to 2.10.2 2024-06-23 22:13:33 -07:00
shamoon
deda49c204 Merge branch 'dev' 2024-06-23 22:13:01 -07:00
github-actions[bot]
276abc1404 New Crowdin translations by GitHub Action (#7034)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2024-06-23 21:57:48 -07:00
shamoon
6defe24ae7 Fix: always update document modified property on bulk edit operations (#7079) 2024-06-23 12:11:24 -07:00
shamoon
6ed5d11758 Fix: correct frontend retrieval of trash delay setting (#7067) 2024-06-22 12:57:33 -07:00
Trenton H
9d34327a6d Resolves the casing warning in newer Docker versions 2024-06-22 11:30:06 -07:00
shamoon
63f164d099 Documentation: fix PAPERLESS_EMPTY_TRASH_DELAY name 2024-06-22 06:46:47 -07:00
shamoon
0f9710dc8f Fix: index fresh document data after update archive file (#7057) 2024-06-21 18:33:01 +00:00
shamoon
cccba47bd7 Fix: remove type attribute from object for Safari (#7056) 2024-06-21 11:22:18 -07:00
Trenton H
91585a1fa6 Prefer the metadata JSON file over the version JSON file (#7048) 2024-06-20 12:49:54 -07:00
shamoon
3bb6a32ab9 Update bug report note 2024-06-19 00:54:40 -07:00
shamoon
31f592453e Reset -dev version string 2024-06-18 21:23:34 -07:00
github-actions[bot]
56f5f93c48 Documentation: Add v2.10.1 changelog (#7029)
* Changelog v2.10.1 - GHA

* Update changelog.md

---------

Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
2024-06-18 21:22:59 -07:00
shamoon
e6aefd1063 Bump version to 2.10.1 2024-06-18 21:00:22 -07:00
github-actions[bot]
6187ee82af New Crowdin translations by GitHub Action (#7027)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2024-06-18 20:59:28 -07:00
shamoon
a066ccff4f Fix: dont require admin to view trash on frontend (#7028) 2024-06-18 20:17:36 -07:00
shamoon
f73be01897 Reset -dev version string 2024-06-18 16:01:37 -07:00
github-actions[bot]
07ee25be06 Changelog v2.10.0 - GHA (#7020)
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
2024-06-18 15:12:59 -07:00
307 changed files with 33094 additions and 23470 deletions

180
.devcontainer/Dockerfile Normal file
View File

@@ -0,0 +1,180 @@
# syntax=docker/dockerfile:1
FROM --platform=$BUILDPLATFORM docker.io/node:20-bookworm-slim as main-app
ARG DEBIAN_FRONTEND=noninteractive
# Buildx provided, must be defined to use though
ARG TARGETARCH
# Can be workflow provided, defaults set for manual building
ARG JBIG2ENC_VERSION=0.29
ARG QPDF_VERSION=11.9.0
ARG GS_VERSION=10.03.1
# Set Python environment variables
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
# Ignore warning from Whitenoise
PYTHONWARNINGS="ignore:::django.http.response:517" \
PNGX_CONTAINERIZED=1
#
# Begin installation and configuration
# Order the steps below from least often changed to most
#
# Packages need for running
ARG RUNTIME_PACKAGES="\
# General utils
curl \
# Docker specific
gosu \
# Timezones support
tzdata \
# fonts for text file thumbnail generation
fonts-liberation \
gettext \
ghostscript \
gnupg \
icc-profiles-free \
imagemagick \
# PostgreSQL
postgresql-client \
# MySQL / MariaDB
mariadb-client \
# OCRmyPDF dependencies
tesseract-ocr \
tesseract-ocr-eng \
tesseract-ocr-deu \
tesseract-ocr-fra \
tesseract-ocr-ita \
tesseract-ocr-spa \
unpaper \
pngquant \
jbig2dec \
# lxml
libxml2 \
libxslt1.1 \
# itself
qpdf \
# Mime type detection
file \
libmagic1 \
media-types \
zlib1g \
# Barcode splitter
libzbar0 \
poppler-utils \
htop \
sudo"
# Install basic runtime packages.
# These change very infrequently
RUN set -eux \
echo "Installing system packages" \
&& apt-get update \
&& apt-get install --yes --quiet --no-install-recommends ${RUNTIME_PACKAGES}
ARG PYTHON_PACKAGES="\
python3 \
python3-pip \
python3-wheel \
pipenv \
ca-certificates"
RUN set -eux \
echo "Installing python packages" \
&& apt-get update \
&& apt-get install --yes --quiet ${PYTHON_PACKAGES}
RUN set -eux \
&& echo "Installing pre-built updates" \
&& echo "Installing qpdf ${QPDF_VERSION}" \
&& curl --fail --silent --show-error --location \
--output libqpdf29_${QPDF_VERSION}-1_${TARGETARCH}.deb \
https://github.com/paperless-ngx/builder/releases/download/qpdf-${QPDF_VERSION}/libqpdf29_${QPDF_VERSION}-1_${TARGETARCH}.deb \
&& curl --fail --silent --show-error --location \
--output qpdf_${QPDF_VERSION}-1_${TARGETARCH}.deb \
https://github.com/paperless-ngx/builder/releases/download/qpdf-${QPDF_VERSION}/qpdf_${QPDF_VERSION}-1_${TARGETARCH}.deb \
&& dpkg --install ./libqpdf29_${QPDF_VERSION}-1_${TARGETARCH}.deb \
&& dpkg --install ./qpdf_${QPDF_VERSION}-1_${TARGETARCH}.deb \
&& echo "Installing Ghostscript ${GS_VERSION}" \
&& curl --fail --silent --show-error --location \
--output libgs10_${GS_VERSION}.dfsg-1_${TARGETARCH}.deb \
https://github.com/paperless-ngx/builder/releases/download/ghostscript-${GS_VERSION}/libgs10_${GS_VERSION}.dfsg-1_${TARGETARCH}.deb \
&& curl --fail --silent --show-error --location \
--output ghostscript_${GS_VERSION}.dfsg-1_${TARGETARCH}.deb \
https://github.com/paperless-ngx/builder/releases/download/ghostscript-${GS_VERSION}/ghostscript_${GS_VERSION}.dfsg-1_${TARGETARCH}.deb \
&& curl --fail --silent --show-error --location \
--output libgs10-common_${GS_VERSION}.dfsg-1_all.deb \
https://github.com/paperless-ngx/builder/releases/download/ghostscript-${GS_VERSION}/libgs10-common_${GS_VERSION}.dfsg-1_all.deb \
&& dpkg --install ./libgs10-common_${GS_VERSION}.dfsg-1_all.deb \
&& dpkg --install ./libgs10_${GS_VERSION}.dfsg-1_${TARGETARCH}.deb \
&& dpkg --install ./ghostscript_${GS_VERSION}.dfsg-1_${TARGETARCH}.deb \
&& echo "Installing jbig2enc" \
&& curl --fail --silent --show-error --location \
--output jbig2enc_${JBIG2ENC_VERSION}-1_${TARGETARCH}.deb \
https://github.com/paperless-ngx/builder/releases/download/jbig2enc-${JBIG2ENC_VERSION}/jbig2enc_${JBIG2ENC_VERSION}-1_${TARGETARCH}.deb \
&& dpkg --install ./jbig2enc_${JBIG2ENC_VERSION}-1_${TARGETARCH}.deb
# setup docker-specific things
# These change sometimes, but rarely
WORKDIR /usr/src/paperless/src/docker/
COPY [ \
"docker/imagemagick-policy.xml", \
"./" \
]
RUN set -eux \
&& echo "Configuring ImageMagick" \
&& mv imagemagick-policy.xml /etc/ImageMagick-6/policy.xml
# Packages needed only for building a few quick Python
# dependencies
ARG BUILD_PACKAGES="\
build-essential \
git \
# https://www.psycopg.org/docs/install.html#prerequisites
libpq-dev \
# https://github.com/PyMySQL/mysqlclient#linux
default-libmysqlclient-dev \
pkg-config \
pre-commit"
# hadolint ignore=DL3042
RUN --mount=type=cache,target=/root/.cache/pip/,id=pip-cache \
set -eux \
&& echo "Installing build system packages" \
&& apt-get update \
&& apt-get install --yes --quiet ${BUILD_PACKAGES}
RUN set -eux \
&& npm update npm -g
# add users, setup scripts
# Mount the compiled frontend to expected location
RUN set -eux \
&& echo "Setting up user/group" \
&& groupmod --new-name paperless node \
&& usermod --login paperless --home /usr/src/paperless node \
&& usermod -s /bin/bash paperless \
&& echo "paperless ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers \
&& echo "Creating volume directories" \
&& mkdir --parents --verbose /usr/src/paperless/paperless-ngx/data \
&& mkdir --parents --verbose /usr/src/paperless/paperless-ngx/media \
&& mkdir --parents --verbose /usr/src/paperless/paperless-ngx/consume \
&& mkdir --parents --verbose /usr/src/paperless/paperless-ngx/export \
&& mkdir --parents --verbose /usr/src/paperless/paperless-ngx/.venv \
&& echo "Adjusting all permissions" \
&& chown --from root:root --changes --recursive paperless:paperless /usr/src/paperless
# && echo "Collecting static files" \
# && gosu paperless python3 manage.py collectstatic --clear --no-input --link \
# && gosu paperless python3 manage.py compilemessages
VOLUME ["/usr/src/paperless/paperless-ngx/data", \
"/usr/src/paperless/paperless-ngx/media", \
"/usr/src/paperless/paperless-ngx/consume", \
"/usr/src/paperless/paperless-ngx/export", \
"/usr/src/paperless/paperless-ngx/.venv"]

117
.devcontainer/README.md Normal file
View File

@@ -0,0 +1,117 @@
# Paperless NGX Development Environment
## Overview
Welcome to the Paperless NGX development environment! This setup uses VSCode DevContainers to provide a consistent and seamless development experience.
### What are DevContainers?
DevContainers are a feature in VSCode that allows you to develop within a Docker container. This ensures that your development environment is consistent across different machines and setups. By defining a containerized environment, you can eliminate the "works on my machine" problem.
### Advantages of DevContainers
- **Consistency**: Same environment for all developers.
- **Isolation**: Separate development environment from your local machine.
- **Reproducibility**: Easily recreate the environment on any machine.
- **Pre-configured Tools**: Include all necessary tools and dependencies in the container.
## DevContainer Setup
The DevContainer configuration provides up all the necessary services for Paperless NGX, including:
- Redis
- Gotenberg
- Tika
Data is stored using Docker volumes to ensure persistence across container restarts.
## Configuration Files
The setup includes debugging configurations (`launch.json`) and tasks (`tasks.json`) to help you manage and debug various parts of the project:
- **Backend Debugging:**
- `manage.py runserver`
- `manage.py document-consumer`
- `celery`
- **Maintenance Tasks:**
- Create superuser
- Run migrations
- Recreate virtual environment (`.venv` with pipenv)
- Compile frontend assets
## Getting Started
### Step 1: Running the DevContainer
To start the DevContainer:
1. Open VSCode.
2. Open the project folder.
3. Open the command palette:
- **Windows/Linux**: `Ctrl+Shift+P`
- **Mac**: `Cmd+Shift+P`
4. Type and select `Dev Containers: Rebuild and Reopen in Container`.
VSCode will build and start the DevContainer environment.
### Step 2: Initial Setup
Once the DevContainer is up and running, perform the following steps:
1. **Compile Frontend Assets**:
- Open the command palette:
- **Windows/Linux**: `Ctrl+Shift+P`
- **Mac**: `Cmd+Shift+P`
- Select `Tasks: Run Task`.
- Choose `Frontend Compile`.
2. **Run Database Migrations**:
- Open the command palette:
- **Windows/Linux**: `Ctrl+Shift+P`
- **Mac**: `Cmd+Shift+P`
- Select `Tasks: Run Task`.
- Choose `Migrate Database`.
3. **Create Superuser**:
- Open the command palette:
- **Windows/Linux**: `Ctrl+Shift+P`
- **Mac**: `Cmd+Shift+P`
- Select `Tasks: Run Task`.
- Choose `Create Superuser`.
### Debugging and Running Services
You can start and debug backend services either as debugging sessions via `launch.json` or as tasks.
#### Using `launch.json`:
1. Press `F5` or go to the **Run and Debug** view in VSCode.
2. Select the desired configuration:
- `Runserver`
- `Document Consumer`
- `Celery`
#### Using Tasks:
1. Open the command palette:
- **Windows/Linux**: `Ctrl+Shift+P`
- **Mac**: `Cmd+Shift+P`
2. Select `Tasks: Run Task`.
3. Choose the desired task:
- `Runserver`
- `Document Consumer`
- `Celery`
### Additional Maintenance Tasks
Additional tasks are available for common maintenance operations:
- **Recreate .venv**: For setting up the virtual environment using pipenv.
- **Migrate Database**: To apply database migrations.
- **Create Superuser**: To create an admin user for the application.
## Let's Get Started!
Follow the steps above to get your development environment up and running. Happy coding!

View File

@@ -0,0 +1,16 @@
{
"name": "Paperless Development",
"dockerComposeFile": "docker-compose.devcontainer.sqlite-tika.yml",
"service": "paperless-development",
"workspaceFolder": "/usr/src/paperless/paperless-ngx",
"postCreateCommand": "/bin/bash -c pre-commit install && pipenv install --dev",
"customizations": {
"vscode": {
"extensions": [
"mhutchie.git-graph",
"ms-python.python"
]
}
},
"remoteUser": "paperless"
}

View File

@@ -0,0 +1,84 @@
# Docker Compose file for developing Paperless NGX in VSCode DevContainers.
# This file contains everything Paperless NGX needs to run.
# Paperless supports amd64, arm, and arm64 hardware.
# All compose files of Paperless configure it in the following way:
#
# - Paperless is (re)started on system boot if it was running before shutdown.
# - Docker volumes for storing data are managed by Docker.
# - Folders for importing and exporting files are created in the same directory
# as this file and mounted to the correct folders inside the container.
# - Paperless listens on port 8000.
#
# SQLite is used as the database. The SQLite file is stored in the data volume.
#
# In addition, this Docker Compose file adds the following optional
# configurations:
#
# - Apache Tika and Gotenberg servers are started with Paperless NGX and Paperless
# is configured to use these services. These provide support for consuming
# Office documents (Word, Excel, PowerPoint, and their LibreOffice counterparts).
#
# This file is intended only to be used through VSCOde devcontainers. See README.md
# in the folder .devcontainer.
services:
broker:
image: docker.io/library/redis:7
restart: unless-stopped
volumes:
- redisdata:/data
# No ports need to be exposed; the VSCode DevContainer plugin manages them.
paperless-development:
image: paperless-ngx
build:
context: ../ # Dockerfile cannot access files from parent directories if context is not set.
dockerfile: ./.devcontainer/Dockerfile
restart: unless-stopped
depends_on:
- broker
- gotenberg
- tika
volumes:
- ..:/usr/src/paperless/paperless-ngx:delegated
- ../.devcontainer/vscode:/usr/src/paperless/paperless-ngx/.vscode:delegated # VSCode config files
- pipenv:/usr/src/paperless/paperless-ngx/.venv # Pipenv environment persisted in volume
- /usr/src/paperless/paperless-ngx/src/documents/static/frontend # Static frontend files exist only in container
- /usr/src/paperless/paperless-ngx/src/.pytest_cache
- /usr/src/paperless/paperless-ngx/.ruff_cache
- /usr/src/paperless/paperless-ngx/htmlcov
- /usr/src/paperless/paperless-ngx/.coverage
- data:/usr/src/paperless/paperless-ngx/data
- media:/usr/src/paperless/paperless-ngx/media
environment:
PAPERLESS_REDIS: redis://broker:6379
PAPERLESS_TIKA_ENABLED: 1
PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://gotenberg:3000
PAPERLESS_TIKA_ENDPOINT: http://tika:9998
PAPERLESS_STATICDIR: ./src/documents/static
PAPERLESS_DEBUG: true
# Overrides default command so things don't shut down after the process ends.
command: /bin/sh -c "chown -R paperless:paperless /usr/src/paperless/paperless-ngx/src/documents/static/frontend && chown -R paperless:paperless /usr/src/paperless/paperless-ngx/.ruff_cache && while sleep 1000; do :; done"
gotenberg:
image: docker.io/gotenberg/gotenberg:7.10
restart: unless-stopped
# The Gotenberg Chromium route is used to convert .eml files. We do not
# want to allow external content like tracking pixels or even JavaScript.
command:
- "gotenberg"
- "--chromium-disable-javascript=true"
- "--chromium-allow-list=file:///tmp/.*"
tika:
image: docker.io/apache/tika:latest
restart: unless-stopped
volumes:
data:
media:
redisdata:
pipenv:

View File

@@ -0,0 +1,43 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "manage.py runserver",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/src/manage.py",
"console": "integratedTerminal",
"justMyCode": true,
"args": ["runserver"],
"django": true
},
{
"name": "manage.py document_consumer",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/src/manage.py",
"console": "integratedTerminal",
"justMyCode": true,
"args": ["document_consumer"],
"django": true
},
{
"name": "celery",
"type": "python",
"cwd": "${workspaceFolder}/src",
"request": "launch",
"module": "celery",
"console": "integratedTerminal",
"env": {
"PYTHONPATH": "${workspaceFolder}/src"
},
"args": [
"-A",
"paperless",
"worker",
"-l",
"DEBUG"
]
}
]
}

View File

@@ -0,0 +1,11 @@
{
"python.testing.pytestArgs": [
"src"
],
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true,
"files.watcherExclude": {
"**/.venv/**": true,
"**/pytest_cache/**": true
}
}

View File

@@ -0,0 +1,136 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "manage.py document_consumer",
"type": "shell",
"command": "pipenv run python manage.py document_consumer",
"group": "build",
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "shared",
"showReuseMessage": false,
"clear": true,
"revealProblems": "onProblem"
},
"options": {
"cwd": "${workspaceFolder}/src"
}
},
{
"label": "manage.py runserver",
"type": "shell",
"command": "pipenv run python manage.py runserver",
"group": "build",
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "shared",
"showReuseMessage": false,
"clear": true,
"revealProblems": "onProblem"
},
"options": {
"cwd": "${workspaceFolder}/src"
}
},
{
"label": "Maintenance: manage.py migrate",
"type": "shell",
"command": "pipenv run python manage.py migrate",
"group": "none",
"presentation": {
"echo": true,
"reveal": "always",
"focus": true,
"panel": "shared",
"showReuseMessage": false,
"clear": true,
"revealProblems": "onProblem"
},
"options": {
"cwd": "${workspaceFolder}/src"
}
},
{
"label": "Maintenance: manage.py createsuperuser",
"type": "shell",
"command": "pipenv run python manage.py createsuperuser",
"group": "none",
"presentation": {
"echo": true,
"reveal": "always",
"focus": true,
"panel": "shared",
"showReuseMessage": false,
"clear": true,
"revealProblems": "onProblem"
},
"options": {
"cwd": "${workspaceFolder}/src"
}
},
{
"label": "compile frontend",
"type": "shell",
"command": "npm ci && ./node_modules/.bin/ng build --configuration production",
"group": "none",
"presentation": {
"echo": true,
"reveal": "always",
"focus": true,
"panel": "shared",
"showReuseMessage": false,
"clear": true,
"revealProblems": "onProblem"
},
"options": {
"cwd": "${workspaceFolder}/src-ui"
}
},
{
"label": "Maintenance: recreate .venv",
"type": "shell",
"command": "rm -R -v .venv/* || pipenv install --dev",
"group": "none",
"presentation": {
"echo": true,
"reveal": "always",
"focus": true,
"panel": "shared",
"showReuseMessage": false,
"clear": true,
"revealProblems": "onProblem"
},
"options": {
"cwd": "${workspaceFolder}"
}
},
{
"label": "Celery Worker",
"type": "shell",
"command": "pipenv run celery --app paperless worker -l DEBUG",
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"echo": true,
"reveal": "always",
"focus": true,
"panel": "shared",
"showReuseMessage": false,
"clear": true,
"revealProblems": "onProblem"
},
"options": {
"cwd": "${workspaceFolder}/src"
}
}
]
}

View File

@@ -9,7 +9,7 @@ body:
### ⚠️ Please remember: issues are for *bugs*
That is, something you believe affects every single user of Paperless-ngx, not just you. If you're not sure, start with one of the other options below.
Also, note that **Paperless-ngx does not perform OCR itself**, that is handled by other tools. Problems with OCR of specific files should likely be raised 'upstream', see https://github.com/ocrmypdf/OCRmyPDF/issues or https://github.com/tesseract-ocr/tesseract/issues
Also, note that **Paperless-ngx does not perform OCR or archive file creation itself**, those are handled by other tools. Problems with OCR or archive versions of specific files should likely be raised 'upstream', see https://github.com/ocrmypdf/OCRmyPDF/issues or https://github.com/tesseract-ocr/tesseract/issues
- type: markdown
attributes:
value: |

View File

@@ -49,10 +49,6 @@ updates:
- "paperless-ngx/backend"
ignore:
- dependency-name: "uvicorn"
- dependency-name: "djangorestframework"
versions:
- "3.15.0"
- "3.15.1"
groups:
development:
patterns:

View File

@@ -398,7 +398,7 @@ jobs:
password: ${{ secrets.QUAY_ROBOT_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v5
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile
@@ -406,6 +406,8 @@ jobs:
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.docker-meta.outputs.tags }}
labels: ${{ steps.docker-meta.outputs.labels }}
build-args: |
PNGX_TAG_VERSION=${{ steps.docker-meta.outputs.version }}
# Get cache layers from this branch, then dev
# This allows new branches to get at least some cache benefits, generally from dev
cache-from: |

View File

@@ -33,7 +33,7 @@ jobs:
-
name: Clean temporary images
if: "${{ env.TOKEN != '' }}"
uses: stumpylog/image-cleaner-action/ephemeral@v0.7.0
uses: stumpylog/image-cleaner-action/ephemeral@v0.8.0
with:
token: "${{ env.TOKEN }}"
owner: "${{ github.repository_owner }}"
@@ -61,7 +61,7 @@ jobs:
-
name: Clean untagged images
if: "${{ env.TOKEN != '' }}"
uses: stumpylog/image-cleaner-action/untagged@v0.7.0
uses: stumpylog/image-cleaner-action/untagged@v0.8.0
with:
token: "${{ env.TOKEN }}"
owner: "${{ github.repository_owner }}"

2
.gitignore vendored
View File

@@ -66,6 +66,8 @@ target/
.vscode
/src-ui/.vscode
/docs/.vscode
.vscode-server
*CommandMarker
# Other stuff that doesn't belong
.virtualenv

View File

@@ -47,7 +47,7 @@ repos:
exclude: "(^Pipfile\\.lock$)"
# Python hooks
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: 'v0.4.9'
rev: 'v0.5.6'
hooks:
- id: ruff
- id: ruff-format

View File

@@ -1 +1 @@
3.9.18
3.9.19

View File

@@ -13,6 +13,16 @@ WORKDIR /src/src-ui
RUN set -eux \
&& npm update npm -g \
&& npm ci
ARG PNGX_TAG_VERSION=
# Add the tag to the environment file if its a tagged dev build
RUN set -eux && \
case "${PNGX_TAG_VERSION}" in \
dev|fix*|feature*) \
sed -i -E "s/version: '([0-9\.]+)'/version: '\1 #${PNGX_TAG_VERSION}'/g" /src/src-ui/src/environments/environment.prod.ts \
;; \
esac
RUN set -eux \
&& ./node_modules/.bin/ng build --configuration production
@@ -21,7 +31,7 @@ RUN set -eux \
# Comments:
# - pipenv dependencies are not left in the final image
# - pipenv can't touch the final image somehow
FROM --platform=$BUILDPLATFORM docker.io/python:3.11-alpine as pipenv-base
FROM --platform=$BUILDPLATFORM docker.io/python:3.11-alpine AS pipenv-base
WORKDIR /usr/src/pipenv
@@ -37,7 +47,7 @@ RUN set -eux \
# Purpose: The final image
# Comments:
# - Don't leave anything extra in here
FROM docker.io/python:3.11-slim-bookworm as main-app
FROM docker.io/python:3.11-slim-bookworm AS main-app
LABEL org.opencontainers.image.authors="paperless-ngx team <hello@paperless-ngx.com>"
LABEL org.opencontainers.image.documentation="https://docs.paperless-ngx.com/"
@@ -223,11 +233,11 @@ RUN --mount=type=cache,target=/root/.cache/pip/,id=pip-cache \
&& python3 -m pip install --no-cache-dir --upgrade wheel \
&& echo "Installing Python requirements" \
&& curl --fail --silent --show-error --location \
--output psycopg_c-3.1.19-cp311-cp311-linux_x86_64.whl \
https://github.com/paperless-ngx/builder/releases/download/psycopg-3.1.19/psycopg_c-3.1.19-cp311-cp311-linux_x86_64.whl \
--output psycopg_c-3.2.1-cp311-cp311-linux_x86_64.whl \
https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.1/psycopg_c-3.2.1-cp311-cp311-linux_x86_64.whl \
&& curl --fail --silent --show-error --location \
--output psycopg_c-3.1.19-cp311-cp311-linux_aarch64.whl \
https://github.com/paperless-ngx/builder/releases/download/psycopg-3.1.19/psycopg_c-3.1.19-cp311-cp311-linux_aarch64.whl \
--output psycopg_c-3.2.1-cp311-cp311-linux_aarch64.whl \
https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.1/psycopg_c-3.2.1-cp311-cp311-linux_aarch64.whl \
&& python3 -m pip install --default-timeout=1000 --find-links . --requirement requirements.txt \
&& echo "Patching whitenoise for compression speedup" \
&& curl --fail --silent --show-error --location --output 484.patch https://github.com/evansd/whitenoise/pull/484.patch \

10
Pipfile
View File

@@ -7,7 +7,7 @@ name = "pypi"
dateparser = "~=1.2"
# WARNING: django does not use semver.
# Only patch versions are guaranteed to not introduce breaking changes.
django = "~=4.2.13"
django = "~=4.2.15"
django-allauth = {extras = ["socialaccount"], version = "*"}
django-auditlog = "*"
django-celery-results = "*"
@@ -18,7 +18,7 @@ django-filter = "~=24.2"
django-guardian = "*"
django-multiselectfield = "*"
django-soft-delete = "*"
djangorestframework = "==3.14.0"
djangorestframework = "==3.15.2"
djangorestframework-guardian = "*"
drf-writable-nested = "*"
bleach = "*"
@@ -54,8 +54,8 @@ tqdm = "*"
# See https://github.com/paperless-ngx/paperless-ngx/issues/5494
uvicorn = {extras = ["standard"], version = "==0.25.0"}
watchdog = "~=4.0"
whitenoise = "~=6.6"
whoosh="~=2.7"
whitenoise = "~=6.7"
whoosh = "~=2.7"
zxing-cpp = {version = "*", platform_machine = "== 'x86_64'"}
[dev-packages]
@@ -71,6 +71,7 @@ pytest-httpx = "*"
pytest-env = "*"
pytest-sugar = "*"
pytest-xdist = "*"
pytest-mock = "*"
pytest-rerunfailures = "*"
imagehash = "*"
daphne = "*"
@@ -93,5 +94,4 @@ types-tqdm = "*"
types-Markdown = "*"
types-Pygments = "*"
types-colorama = "*"
types-psycopg2 = "*"
types-setuptools = "*"

1537
Pipfile.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -37,7 +37,7 @@ Thanks to the generous folks at [DigitalOcean](https://m.do.co/c/8d70b916d462),
<a href="https://m.do.co/c/8d70b916d462" style="padding-top: 4px; display: block;">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://opensource.nyc3.cdn.digitaloceanspaces.com/attribution/assets/SVG/DO_Logo_horizontal_white.svg" width="140px">
<source media="(prefers-color-scheme: light)" srcset="https://opensource.nyc3.cdn.digitaloceanspaces.com/attribution/assets/SVG/DO_Logo_horizontal_black_.svg" width="140px">
<source media="(prefers-color-scheme: light)" srcset="https://opensource.nyc3.cdn.digitaloceanspaces.com/attribution/assets/SVG/DO_Logo_horizontal_blue.svg" width="140px">
<img src="https://opensource.nyc3.cdn.digitaloceanspaces.com/attribution/assets/SVG/DO_Logo_horizontal_black_.svg" width="140px">
</picture>
</a>

View File

@@ -5,7 +5,7 @@
services:
gotenberg:
image: docker.io/gotenberg/gotenberg:7.10
image: docker.io/gotenberg/gotenberg:8.7
hostname: gotenberg
container_name: gotenberg
network_mode: host

View File

@@ -77,7 +77,7 @@ services:
PAPERLESS_TIKA_ENDPOINT: http://tika:9998
gotenberg:
image: docker.io/gotenberg/gotenberg:7.10
image: docker.io/gotenberg/gotenberg:8.7
restart: unless-stopped
# The gotenberg chromium route is used to convert .eml files. We do not
# want to allow external content like tracking pixels or even javascript.

View File

@@ -71,7 +71,7 @@ services:
PAPERLESS_TIKA_ENDPOINT: http://tika:9998
gotenberg:
image: docker.io/gotenberg/gotenberg:7.10
image: docker.io/gotenberg/gotenberg:8.7
restart: unless-stopped
# The gotenberg chromium route is used to convert .eml files. We do not

View File

@@ -59,7 +59,7 @@ services:
PAPERLESS_TIKA_ENDPOINT: http://tika:9998
gotenberg:
image: docker.io/gotenberg/gotenberg:7.10
image: docker.io/gotenberg/gotenberg:8.7
restart: unless-stopped
# The gotenberg chromium route is used to convert .eml files. We do not

View File

@@ -10,8 +10,8 @@ map_uidgid() {
local -r usermap_new_gid=${USERMAP_GID:-${usermap_original_gid:-$usermap_new_uid}}
if [[ ${usermap_new_uid} != "${usermap_original_uid}" || ${usermap_new_gid} != "${usermap_original_gid}" ]]; then
echo "Mapping UID and GID for paperless:paperless to $usermap_new_uid:$usermap_new_gid"
usermod -o -u "${usermap_new_uid}" paperless
groupmod -o -g "${usermap_new_gid}" paperless
usermod --non-unique --uid "${usermap_new_uid}" paperless
groupmod --non-unique --gid "${usermap_new_gid}" paperless
fi
}
@@ -42,7 +42,7 @@ custom_container_init() {
fi
# Make sure custom init directory has files in it
if [ -n "$(/bin/ls -A "${custom_script_dir}" 2>/dev/null)" ]; then
if [ -n "$(/bin/ls --almost-all "${custom_script_dir}" 2>/dev/null)" ]; then
echo "[custom-init] files found in ${custom_script_dir} executing"
# Loop over files in the directory
for SCRIPT in "${custom_script_dir}"/*; do
@@ -86,13 +86,13 @@ initialize() {
"${CONSUME_DIR}"; do
if [[ ! -d "${dir}" ]]; then
echo "Creating directory ${dir}"
mkdir --parents "${dir}"
mkdir --parents --verbose "${dir}"
fi
done
local -r tmp_dir="${PAPERLESS_SCRATCH_DIR:=/tmp/paperless}"
echo "Creating directory scratch directory ${tmp_dir}"
mkdir --parents "${tmp_dir}"
mkdir --parents --verbose "${tmp_dir}"
set +e
echo "Adjusting permissions of paperless files. This may take a while."
@@ -102,7 +102,7 @@ initialize() {
"${DATA_DIR}" \
"${MEDIA_ROOT_DIR}" \
"${CONSUME_DIR}"; do
find "${dir}" -not \( -user paperless -and -group paperless \) -exec chown paperless:paperless {} +
find "${dir}" -not \( -user paperless -and -group paperless \) -exec chown --changes paperless:paperless {} +
done
set -e
@@ -127,7 +127,7 @@ install_languages() {
for lang in "${langs[@]}"; do
pkg="tesseract-ocr-$lang"
if dpkg -s "$pkg" &>/dev/null; then
if dpkg --status "$pkg" &>/dev/null; then
echo "Package $pkg already installed!"
continue
fi
@@ -138,7 +138,7 @@ install_languages() {
fi
echo "Installing package $pkg..."
if ! apt-get -y install "$pkg" &>/dev/null; then
if ! apt-get --assume-yes install "$pkg" &>/dev/null; then
echo "Could not install $pkg"
exit 1
fi
@@ -148,7 +148,7 @@ install_languages() {
echo "Paperless-ngx docker container starting..."
gosu_cmd=(gosu paperless)
if [ "$(id -u)" == "$(id -u paperless)" ]; then
if [ "$(id --user)" == "$(id --user paperless)" ]; then
gosu_cmd=()
fi

View File

@@ -13,7 +13,7 @@ wait_for_postgres() {
# Disable warning, host and port can't have spaces
# shellcheck disable=SC2086
while [ ! "$(pg_isready -h ${host} -p ${port})" ]; do
while [ ! "$(pg_isready --host ${host} --port ${port})" ]; do
if [ $attempt_num -eq $max_attempts ]; then
echo "Unable to connect to database."
@@ -25,6 +25,7 @@ wait_for_postgres() {
attempt_num=$(("$attempt_num" + 1))
sleep 5
done
echo "Connected to PostgreSQL"
}
wait_for_mariadb() {
@@ -51,6 +52,7 @@ wait_for_mariadb() {
attempt_num=$(("$attempt_num" + 1))
sleep 5
done
echo "Connected to MariaDB"
}
wait_for_redis() {

View File

@@ -36,7 +36,7 @@ The following algorithms are available:
- **Regular expression:** Parses the match as a regular expression and
tries to find a match within the document.
- **Fuzzy match:** Uses a partial matching based on locating the tag text
inside the document, using a [partial ratio](https://maxbachmann.github.io/RapidFuzz/Usage/fuzz.html#partial-ratio)
inside the document, using a [partial ratio](https://rapidfuzz.github.io/RapidFuzz/Usage/fuzz.html#partial-ratio)
- **Auto:** Tries to automatically match new documents. This does not
require you to set a match. See the [notes below](#automatic-matching).
@@ -187,6 +187,7 @@ variables:
| `DOCUMENT_THUMBNAIL_PATH` | Path to the generated thumbnail |
| `DOCUMENT_DOWNLOAD_URL` | URL for document download |
| `DOCUMENT_THUMBNAIL_URL` | URL for the document thumbnail |
| `DOCUMENT_OWNER` | Username of the document owner (if any) |
| `DOCUMENT_CORRESPONDENT` | Assigned correspondent (if any) |
| `DOCUMENT_TAGS` | Comma separated list of tags applied (if any) |
| `DOCUMENT_ORIGINAL_FILENAME` | Filename of original document |
@@ -687,4 +688,5 @@ More details about configuration option for various providers can be found in th
### Disabling Regular Login
Once external auth is set up, 'regular' login can be disabled with the [PAPERLESS_DISABLE_REGULAR_LOGIN](configuration.md#PAPERLESS_DISABLE_REGULAR_LOGIN) setting.
Once external auth is set up, 'regular' login can be disabled with the [PAPERLESS_DISABLE_REGULAR_LOGIN](configuration.md#PAPERLESS_DISABLE_REGULAR_LOGIN) setting and / or users can be automatically
redirected with the [PAPERLESS_REDIRECT_LOGIN_TO_SSO](configuration.md#PAPERLESS_REDIRECT_LOGIN_TO_SSO) setting.

View File

@@ -1,5 +1,240 @@
# Changelog
## paperless-ngx 2.11.2
### Changes
- Change: more clearly handle init permissions error [@shamoon](https://github.com/shamoon) ([#7334](https://github.com/paperless-ngx/paperless-ngx/pull/7334))
- Chore: add permissions info link from webUI [@shamoon](https://github.com/shamoon) ([#7310](https://github.com/paperless-ngx/paperless-ngx/pull/7310))
- Fix: increase search input text contrast with light custom theme colors [@JayBkr](https://github.com/JayBkr) ([#7303](https://github.com/paperless-ngx/paperless-ngx/pull/7303))
### Dependencies
- Chore(deps-dev): Bump the development group with 2 updates [@dependabot](https://github.com/dependabot) ([#7296](https://github.com/paperless-ngx/paperless-ngx/pull/7296))
- Chore(deps): Bump tika-client from 0.5.0 to 0.6.0 in the small-changes group [@dependabot](https://github.com/dependabot) ([#7297](https://github.com/paperless-ngx/paperless-ngx/pull/7297))
### All App Changes
<details>
<summary>5 changes</summary>
- Change: more clearly handle init permissions error [@shamoon](https://github.com/shamoon) ([#7334](https://github.com/paperless-ngx/paperless-ngx/pull/7334))
- Chore: add permissions info link from webUI [@shamoon](https://github.com/shamoon) ([#7310](https://github.com/paperless-ngx/paperless-ngx/pull/7310))
- Fix: increase search input text contrast with light custom theme colors [@JayBkr](https://github.com/JayBkr) ([#7303](https://github.com/paperless-ngx/paperless-ngx/pull/7303))
- Chore(deps-dev): Bump the development group with 2 updates [@dependabot](https://github.com/dependabot) ([#7296](https://github.com/paperless-ngx/paperless-ngx/pull/7296))
- Chore(deps): Bump tika-client from 0.5.0 to 0.6.0 in the small-changes group [@dependabot](https://github.com/dependabot) ([#7297](https://github.com/paperless-ngx/paperless-ngx/pull/7297))
</details>
## paperless-ngx 2.11.1
### Features
- Enhancement: include owner username in post-consumption variables [@Freddy-0](https://github.com/Freddy-0) ([#7270](https://github.com/paperless-ngx/paperless-ngx/pull/7270))
### Bug Fixes
- Fix: support multiple inbox tags from stats widget [@shamoon](https://github.com/shamoon) ([#7281](https://github.com/paperless-ngx/paperless-ngx/pull/7281))
- Fix: Removes Turkish from the NLTK languages [@stumpylog](https://github.com/stumpylog) ([#7246](https://github.com/paperless-ngx/paperless-ngx/pull/7246))
- Fix: include trashed docs in existing doc check [@shamoon](https://github.com/shamoon) ([#7229](https://github.com/paperless-ngx/paperless-ngx/pull/7229))
### Dependencies
- Chore(deps-dev): Bump the development group with 2 updates [@dependabot](https://github.com/dependabot) ([#7261](https://github.com/paperless-ngx/paperless-ngx/pull/7261))
- Chore(deps): Bump the small-changes group across 1 directory with 2 updates [@dependabot](https://github.com/dependabot) ([#7266](https://github.com/paperless-ngx/paperless-ngx/pull/7266))
### All App Changes
<details>
<summary>7 changes</summary>
- Fix: support multiple inbox tags from stats widget [@shamoon](https://github.com/shamoon) ([#7281](https://github.com/paperless-ngx/paperless-ngx/pull/7281))
- Chore(deps-dev): Bump the development group with 2 updates [@dependabot](https://github.com/dependabot) ([#7261](https://github.com/paperless-ngx/paperless-ngx/pull/7261))
- Chore(deps): Bump the small-changes group across 1 directory with 2 updates [@dependabot](https://github.com/dependabot) ([#7266](https://github.com/paperless-ngx/paperless-ngx/pull/7266))
- Enhancement: include owner username in post-consumption variables [@Freddy-0](https://github.com/Freddy-0) ([#7270](https://github.com/paperless-ngx/paperless-ngx/pull/7270))
- Chore: Squash older automatic migrations [@stumpylog](https://github.com/stumpylog) ([#7267](https://github.com/paperless-ngx/paperless-ngx/pull/7267))
- Fix: Removes Turkish from the NLTK languages [@stumpylog](https://github.com/stumpylog) ([#7246](https://github.com/paperless-ngx/paperless-ngx/pull/7246))
- Fix: include trashed docs in existing doc check [@shamoon](https://github.com/shamoon) ([#7229](https://github.com/paperless-ngx/paperless-ngx/pull/7229))
</details>
## paperless-ngx 2.11.0
### Breaking Changes
- Feature: Upgrade Gotenberg to v8 [@stumpylog](https://github.com/stumpylog) ([#7094](https://github.com/paperless-ngx/paperless-ngx/pull/7094))
### Features
- Enhancement: disable add split button when appropriate [@shamoon](https://github.com/shamoon) ([#7215](https://github.com/paperless-ngx/paperless-ngx/pull/7215))
- Enhancement: wrapping of saved view fields d-n-d UI [@shamoon](https://github.com/shamoon) ([#7216](https://github.com/paperless-ngx/paperless-ngx/pull/7216))
- Enhancement: support custom field icontains filter for select type [@shamoon](https://github.com/shamoon) ([#7199](https://github.com/paperless-ngx/paperless-ngx/pull/7199))
- Feature: select custom field type [@shamoon](https://github.com/shamoon) ([#7167](https://github.com/paperless-ngx/paperless-ngx/pull/7167))
- Feature: automatic sso redirect [@shamoon](https://github.com/shamoon) ([#7168](https://github.com/paperless-ngx/paperless-ngx/pull/7168))
- Enhancement: show more columns in mail frontend admin [@shamoon](https://github.com/shamoon) ([#7158](https://github.com/paperless-ngx/paperless-ngx/pull/7158))
- Enhancement: use request user as owner of split / merge docs [@shamoon](https://github.com/shamoon) ([#7112](https://github.com/paperless-ngx/paperless-ngx/pull/7112))
- Enhancement: improve date parsing with accented characters [@fdubuy](https://github.com/fdubuy) ([#7100](https://github.com/paperless-ngx/paperless-ngx/pull/7100))
- Feature: improve history display of object names etc [@shamoon](https://github.com/shamoon) ([#7102](https://github.com/paperless-ngx/paperless-ngx/pull/7102))
- Feature: Upgrade Gotenberg to v8 [@stumpylog](https://github.com/stumpylog) ([#7094](https://github.com/paperless-ngx/paperless-ngx/pull/7094))
### Bug Fixes
- Fix: include documents in trash for existing asn check [@shamoon](https://github.com/shamoon) ([#7189](https://github.com/paperless-ngx/paperless-ngx/pull/7189))
- Fix: include documents in trash in sanity check [@shamoon](https://github.com/shamoon) ([#7133](https://github.com/paperless-ngx/paperless-ngx/pull/7133))
- Fix: handle errors for trash actions and only show documents user can restore or delete [@shamoon](https://github.com/shamoon) ([#7119](https://github.com/paperless-ngx/paperless-ngx/pull/7119))
- Fix: dont include documents in trash in counts [@shamoon](https://github.com/shamoon) ([#7111](https://github.com/paperless-ngx/paperless-ngx/pull/7111))
- Fix: use temp dir for split / merge [@shamoon](https://github.com/shamoon) ([#7105](https://github.com/paperless-ngx/paperless-ngx/pull/7105))
### Maintenance
- Chore: upgrade to DRF 3.15 [@shamoon](https://github.com/shamoon) ([#7134](https://github.com/paperless-ngx/paperless-ngx/pull/7134))
- Chore(deps): Bump docker/build-push-action from 5 to 6 in the actions group [@dependabot](https://github.com/dependabot) ([#7125](https://github.com/paperless-ngx/paperless-ngx/pull/7125))
- Chore: Ignores DRF 3.15.2 [@stumpylog](https://github.com/stumpylog) ([#7122](https://github.com/paperless-ngx/paperless-ngx/pull/7122))
- Chore: show docker tag in UI for ci test builds [@shamoon](https://github.com/shamoon) ([#7083](https://github.com/paperless-ngx/paperless-ngx/pull/7083))
### Dependencies
<details>
<summary>11 changes</summary>
- Chore: Bulk backend updates [@stumpylog](https://github.com/stumpylog) ([#7209](https://github.com/paperless-ngx/paperless-ngx/pull/7209))
- Chore(deps): Bump the frontend-angular-dependencies group in /src-ui with 14 updates [@dependabot](https://github.com/dependabot) ([#7200](https://github.com/paperless-ngx/paperless-ngx/pull/7200))
- Chore(deps): Bump certifi from 2024.6.2 to 2024.7.4 [@dependabot](https://github.com/dependabot) ([#7166](https://github.com/paperless-ngx/paperless-ngx/pull/7166))
- Chore(deps): Bump the frontend-angular-dependencies group in /src-ui with 6 updates [@dependabot](https://github.com/dependabot) ([#7148](https://github.com/paperless-ngx/paperless-ngx/pull/7148))
- Chore(deps): Bump django-multiselectfield from 0.1.12 to 0.1.13 in the django group [@dependabot](https://github.com/dependabot) ([#7147](https://github.com/paperless-ngx/paperless-ngx/pull/7147))
- Chore(deps): Bump docker/build-push-action from 5 to 6 in the actions group [@dependabot](https://github.com/dependabot) ([#7125](https://github.com/paperless-ngx/paperless-ngx/pull/7125))
- Chore(deps): Bump the small-changes group across 1 directory with 4 updates [@dependabot](https://github.com/dependabot) ([#7128](https://github.com/paperless-ngx/paperless-ngx/pull/7128))
- Chore(deps): Bump the frontend-angular-dependencies group in /src-ui with 16 updates [@dependabot](https://github.com/dependabot) ([#7126](https://github.com/paperless-ngx/paperless-ngx/pull/7126))
- Chore(deps-dev): Bump ruff from 0.4.9 to 0.5.0 in the development group across 1 directory [@dependabot](https://github.com/dependabot) ([#7120](https://github.com/paperless-ngx/paperless-ngx/pull/7120))
- Chore(deps-dev): Bump ws from 8.17.0 to 8.17.1 in /src-ui [@dependabot](https://github.com/dependabot) ([#7114](https://github.com/paperless-ngx/paperless-ngx/pull/7114))
- Chore: update to Angular v18 [@shamoon](https://github.com/shamoon) ([#7106](https://github.com/paperless-ngx/paperless-ngx/pull/7106))
</details>
### All App Changes
<details>
<summary>25 changes</summary>
- Enhancement: disable add split button when appropriate [@shamoon](https://github.com/shamoon) ([#7215](https://github.com/paperless-ngx/paperless-ngx/pull/7215))
- Enhancement: wrapping of saved view fields d-n-d UI [@shamoon](https://github.com/shamoon) ([#7216](https://github.com/paperless-ngx/paperless-ngx/pull/7216))
- Chore: Bulk backend updates [@stumpylog](https://github.com/stumpylog) ([#7209](https://github.com/paperless-ngx/paperless-ngx/pull/7209))
- Chore(deps): Bump the frontend-angular-dependencies group in /src-ui with 14 updates [@dependabot](https://github.com/dependabot) ([#7200](https://github.com/paperless-ngx/paperless-ngx/pull/7200))
- Enhancement: support custom field icontains filter for select type [@shamoon](https://github.com/shamoon) ([#7199](https://github.com/paperless-ngx/paperless-ngx/pull/7199))
- Chore: upgrade to DRF 3.15 [@shamoon](https://github.com/shamoon) ([#7134](https://github.com/paperless-ngx/paperless-ngx/pull/7134))
- Feature: select custom field type [@shamoon](https://github.com/shamoon) ([#7167](https://github.com/paperless-ngx/paperless-ngx/pull/7167))
- Feature: automatic sso redirect [@shamoon](https://github.com/shamoon) ([#7168](https://github.com/paperless-ngx/paperless-ngx/pull/7168))
- Fix: include documents in trash for existing asn check [@shamoon](https://github.com/shamoon) ([#7189](https://github.com/paperless-ngx/paperless-ngx/pull/7189))
- Chore: Initial conversion to pytest fixtures [@stumpylog](https://github.com/stumpylog) ([#7110](https://github.com/paperless-ngx/paperless-ngx/pull/7110))
- Enhancement: show more columns in mail frontend admin [@shamoon](https://github.com/shamoon) ([#7158](https://github.com/paperless-ngx/paperless-ngx/pull/7158))
- Chore(deps): Bump the frontend-angular-dependencies group in /src-ui with 6 updates [@dependabot](https://github.com/dependabot) ([#7148](https://github.com/paperless-ngx/paperless-ngx/pull/7148))
- Chore(deps): Bump django-multiselectfield from 0.1.12 to 0.1.13 in the django group [@dependabot](https://github.com/dependabot) ([#7147](https://github.com/paperless-ngx/paperless-ngx/pull/7147))
- Fix: include documents in trash in sanity check [@shamoon](https://github.com/shamoon) ([#7133](https://github.com/paperless-ngx/paperless-ngx/pull/7133))
- Chore(deps): Bump the small-changes group across 1 directory with 4 updates [@dependabot](https://github.com/dependabot) ([#7128](https://github.com/paperless-ngx/paperless-ngx/pull/7128))
- Chore(deps): Bump the frontend-angular-dependencies group in /src-ui with 16 updates [@dependabot](https://github.com/dependabot) ([#7126](https://github.com/paperless-ngx/paperless-ngx/pull/7126))
- Enhancement: use request user as owner of split / merge docs [@shamoon](https://github.com/shamoon) ([#7112](https://github.com/paperless-ngx/paperless-ngx/pull/7112))
- Fix: handle errors for trash actions and only show documents user can restore or delete [@shamoon](https://github.com/shamoon) ([#7119](https://github.com/paperless-ngx/paperless-ngx/pull/7119))
- Chore(deps-dev): Bump ruff from 0.4.9 to 0.5.0 in the development group across 1 directory [@dependabot](https://github.com/dependabot) ([#7120](https://github.com/paperless-ngx/paperless-ngx/pull/7120))
- Chore(deps-dev): Bump ws from 8.17.0 to 8.17.1 in /src-ui [@dependabot](https://github.com/dependabot) ([#7114](https://github.com/paperless-ngx/paperless-ngx/pull/7114))
- Chore: update to Angular v18 [@shamoon](https://github.com/shamoon) ([#7106](https://github.com/paperless-ngx/paperless-ngx/pull/7106))
- Enhancement: improve date parsing with accented characters [@fdubuy](https://github.com/fdubuy) ([#7100](https://github.com/paperless-ngx/paperless-ngx/pull/7100))
- Feature: improve history display of object names etc [@shamoon](https://github.com/shamoon) ([#7102](https://github.com/paperless-ngx/paperless-ngx/pull/7102))
- Fix: dont include documents in trash in counts [@shamoon](https://github.com/shamoon) ([#7111](https://github.com/paperless-ngx/paperless-ngx/pull/7111))
- Fix: use temp dir for split / merge [@shamoon](https://github.com/shamoon) ([#7105](https://github.com/paperless-ngx/paperless-ngx/pull/7105))
</details>
## paperless-ngx 2.10.2
### Bug Fixes
- Fix: always update document modified property on bulk edit operations [@shamoon](https://github.com/shamoon) ([#7079](https://github.com/paperless-ngx/paperless-ngx/pull/7079))
- Fix: correct frontend retrieval of trash delay setting [@shamoon](https://github.com/shamoon) ([#7067](https://github.com/paperless-ngx/paperless-ngx/pull/7067))
- Fix: index fresh document data after update archive file [@shamoon](https://github.com/shamoon) ([#7057](https://github.com/paperless-ngx/paperless-ngx/pull/7057))
- Fix: Safari browser PDF viewer not loading in 2.10.x [@shamoon](https://github.com/shamoon) ([#7056](https://github.com/paperless-ngx/paperless-ngx/pull/7056))
- Fix: Prefer the exporter metadata JSON file over the version JSON file [@stumpylog](https://github.com/stumpylog) ([#7048](https://github.com/paperless-ngx/paperless-ngx/pull/7048))
### All App Changes
<details>
<summary>5 changes</summary>
- Fix: always update document modified property on bulk edit operations [@shamoon](https://github.com/shamoon) ([#7079](https://github.com/paperless-ngx/paperless-ngx/pull/7079))
- Fix: correct frontend retrieval of trash delay setting [@shamoon](https://github.com/shamoon) ([#7067](https://github.com/paperless-ngx/paperless-ngx/pull/7067))
- Fix: index fresh document data after update archive file [@shamoon](https://github.com/shamoon) ([#7057](https://github.com/paperless-ngx/paperless-ngx/pull/7057))
- Fix: Safari browser PDF viewer not loading in 2.10.x [@shamoon](https://github.com/shamoon) ([#7056](https://github.com/paperless-ngx/paperless-ngx/pull/7056))
- Fix: Prefer the exporter metadata JSON file over the version JSON file [@stumpylog](https://github.com/stumpylog) ([#7048](https://github.com/paperless-ngx/paperless-ngx/pull/7048))
</details>
## paperless-ngx 2.10.1
### Bug Fixes
- Fix: dont require admin perms to view trash on frontend @shamoon ([#7028](https://github.com/paperless-ngx/paperless-ngx/pull/7028))
## paperless-ngx 2.10.0
### Features
- Feature: documents trash aka soft delete [@shamoon](https://github.com/shamoon) ([#6944](https://github.com/paperless-ngx/paperless-ngx/pull/6944))
- Enhancement: better boolean custom field display [@shamoon](https://github.com/shamoon) ([#7001](https://github.com/paperless-ngx/paperless-ngx/pull/7001))
- Feature: Allow encrypting sensitive fields in export [@stumpylog](https://github.com/stumpylog) ([#6927](https://github.com/paperless-ngx/paperless-ngx/pull/6927))
- Enhancement: allow consumption of odg files [@daniel-boehme](https://github.com/daniel-boehme) ([#6940](https://github.com/paperless-ngx/paperless-ngx/pull/6940))
### Bug Fixes
- Fix: Document history could include extra fields [@stumpylog](https://github.com/stumpylog) ([#6989](https://github.com/paperless-ngx/paperless-ngx/pull/6989))
- Fix: use local pdf worker js [@shamoon](https://github.com/shamoon) ([#6990](https://github.com/paperless-ngx/paperless-ngx/pull/6990))
- Fix: Revert masking the content field from auditlog [@tribut](https://github.com/tribut) ([#6981](https://github.com/paperless-ngx/paperless-ngx/pull/6981))
- Fix: respect model permissions for tasks API endpoint [@shamoon](https://github.com/shamoon) ([#6958](https://github.com/paperless-ngx/paperless-ngx/pull/6958))
- Fix: Make the logging of an email message to be something useful [@stumpylog](https://github.com/stumpylog) ([#6901](https://github.com/paperless-ngx/paperless-ngx/pull/6901))
### Documentation
- Documentation: Corrections and clarifications for Python support [@stumpylog](https://github.com/stumpylog) ([#6995](https://github.com/paperless-ngx/paperless-ngx/pull/6995))
### Maintenance
- Chore(deps): Bump stumpylog/image-cleaner-action from 0.6.0 to 0.7.0 in the actions group [@dependabot](https://github.com/dependabot) ([#6968](https://github.com/paperless-ngx/paperless-ngx/pull/6968))
- Chore: Configures dependabot to ignore djangorestframework [@stumpylog](https://github.com/stumpylog) ([#6967](https://github.com/paperless-ngx/paperless-ngx/pull/6967))
### Dependencies
<details>
<summary>10 changes</summary>
- Chore(deps): Bump pipenv from 2023.12.1 to 2024.0.1 [@stumpylog](https://github.com/stumpylog) ([#7019](https://github.com/paperless-ngx/paperless-ngx/pull/7019))
- Chore(deps): Bump the small-changes group with 2 updates [@dependabot](https://github.com/dependabot) ([#7013](https://github.com/paperless-ngx/paperless-ngx/pull/7013))
- Chore(deps-dev): Bump the development group with 2 updates [@dependabot](https://github.com/dependabot) ([#7012](https://github.com/paperless-ngx/paperless-ngx/pull/7012))
- Chore(deps-dev): Bump ws from 8.15.1 to 8.17.1 in /src-ui [@dependabot](https://github.com/dependabot) ([#7015](https://github.com/paperless-ngx/paperless-ngx/pull/7015))
- Chore(deps): Bump urllib3 from 2.2.1 to 2.2.2 [@dependabot](https://github.com/dependabot) ([#7014](https://github.com/paperless-ngx/paperless-ngx/pull/7014))
- Chore: update packages used by mail parser html template [@shamoon](https://github.com/shamoon) ([#6970](https://github.com/paperless-ngx/paperless-ngx/pull/6970))
- Chore(deps): Bump stumpylog/image-cleaner-action from 0.6.0 to 0.7.0 in the actions group [@dependabot](https://github.com/dependabot) ([#6968](https://github.com/paperless-ngx/paperless-ngx/pull/6968))
- Chore(deps-dev): Bump the development group with 3 updates [@dependabot](https://github.com/dependabot) ([#6953](https://github.com/paperless-ngx/paperless-ngx/pull/6953))
- Chore: Updates to latest Trixie version of Ghostscript 10.03.1 [@stumpylog](https://github.com/stumpylog) ([#6956](https://github.com/paperless-ngx/paperless-ngx/pull/6956))
- Chore(deps): Bump tornado from 6.4 to 6.4.1 [@dependabot](https://github.com/dependabot) ([#6930](https://github.com/paperless-ngx/paperless-ngx/pull/6930))
</details>
### All App Changes
<details>
<summary>17 changes</summary>
- Chore(deps): Bump the small-changes group with 2 updates [@dependabot](https://github.com/dependabot) ([#7013](https://github.com/paperless-ngx/paperless-ngx/pull/7013))
- Chore(deps-dev): Bump the development group with 2 updates [@dependabot](https://github.com/dependabot) ([#7012](https://github.com/paperless-ngx/paperless-ngx/pull/7012))
- Chore(deps-dev): Bump ws from 8.15.1 to 8.17.1 in /src-ui [@dependabot](https://github.com/dependabot) ([#7015](https://github.com/paperless-ngx/paperless-ngx/pull/7015))
- Feature: documents trash aka soft delete [@shamoon](https://github.com/shamoon) ([#6944](https://github.com/paperless-ngx/paperless-ngx/pull/6944))
- Enhancement: better boolean custom field display [@shamoon](https://github.com/shamoon) ([#7001](https://github.com/paperless-ngx/paperless-ngx/pull/7001))
- Fix: default order of documents gets lost in QuerySet pipeline [@madduck](https://github.com/madduck) ([#6982](https://github.com/paperless-ngx/paperless-ngx/pull/6982))
- Fix: Document history could include extra fields [@stumpylog](https://github.com/stumpylog) ([#6989](https://github.com/paperless-ngx/paperless-ngx/pull/6989))
- Fix: use local pdf worker js [@shamoon](https://github.com/shamoon) ([#6990](https://github.com/paperless-ngx/paperless-ngx/pull/6990))
- Fix: Revert masking the content field from auditlog [@tribut](https://github.com/tribut) ([#6981](https://github.com/paperless-ngx/paperless-ngx/pull/6981))
- Chore: update packages used by mail parser html template [@shamoon](https://github.com/shamoon) ([#6970](https://github.com/paperless-ngx/paperless-ngx/pull/6970))
- Chore(deps-dev): Bump the development group with 3 updates [@dependabot](https://github.com/dependabot) ([#6953](https://github.com/paperless-ngx/paperless-ngx/pull/6953))
- Fix: respect model permissions for tasks API endpoint [@shamoon](https://github.com/shamoon) ([#6958](https://github.com/paperless-ngx/paperless-ngx/pull/6958))
- Feature: Allow encrypting sensitive fields in export [@stumpylog](https://github.com/stumpylog) ([#6927](https://github.com/paperless-ngx/paperless-ngx/pull/6927))
- Enhancement: allow consumption of odg files [@daniel-boehme](https://github.com/daniel-boehme) ([#6940](https://github.com/paperless-ngx/paperless-ngx/pull/6940))
- Enhancement: use note model permissions for notes [@shamoon](https://github.com/shamoon) ([#6913](https://github.com/paperless-ngx/paperless-ngx/pull/6913))
- Chore: Resolves test issues with Python 3.12 [@stumpylog](https://github.com/stumpylog) ([#6902](https://github.com/paperless-ngx/paperless-ngx/pull/6902))
- Fix: Make the logging of an email message to be something useful [@stumpylog](https://github.com/stumpylog) ([#6901](https://github.com/paperless-ngx/paperless-ngx/pull/6901))
</details>
## paperless-ngx 2.9.0
### Features

View File

@@ -594,7 +594,15 @@ system. See the corresponding
#### [`PAPERLESS_DISABLE_REGULAR_LOGIN=<bool>`](#PAPERLESS_DISABLE_REGULAR_LOGIN) {#PAPERLESS_DISABLE_REGULAR_LOGIN}
: Disables the regular frontend username / password login, i.e. once you have setup SSO. Note that this setting does not disable the Django admin login. To prevent logins directly to Django, consider blocking `/admin/` in your [web server or reverse proxy configuration](https://github.com/paperless-ngx/paperless-ngx/wiki/Using-a-Reverse-Proxy-with-Paperless-ngx).
: Disables the regular frontend username / password login, i.e. once you have setup SSO. Note that this setting does not disable the Django admin login nor logging in with local credentials via the API. To prevent access to the Django admin, consider blocking `/admin/` in your [web server or reverse proxy configuration](https://github.com/paperless-ngx/paperless-ngx/wiki/Using-a-Reverse-Proxy-with-Paperless-ngx).
You can optionally also automatically redirect users to the SSO login with [PAPERLESS_REDIRECT_LOGIN_TO_SSO](#PAPERLESS_REDIRECT_LOGIN_TO_SSO)
Defaults to False
#### [`PAPERLESS_REDIRECT_LOGIN_TO_SSO=<bool>`](#PAPERLESS_REDIRECT_LOGIN_TO_SSO) {#PAPERLESS_REDIRECT_LOGIN_TO_SSO}
: When this setting is enabled users will automatically be redirected (using javascript) to the first SSO provider login. You may still want to disable the frontend login form for clarity.
Defaults to False
@@ -1366,7 +1374,7 @@ processing. This only has an effect if
## Trash
#### [`EMPTY_TRASH_DELAY=<num>`](#EMPTY_TRASH_DELAY) {#EMPTY_TRASH_DELAY}
#### [`PAPERLESS_EMPTY_TRASH_DELAY=<num>`](#PAPERLESS_EMPTY_TRASH_DELAY) {#PAPERLESS_EMPTY_TRASH_DELAY}
: Sets how long in days documents remain in the 'trash' before they are permanently deleted.

View File

@@ -540,8 +540,7 @@ are released, dependency support is confirmed, etc.
15. Optional: If using the NLTK machine learning processing (see
[`PAPERLESS_ENABLE_NLTK`](configuration.md#PAPERLESS_ENABLE_NLTK) for details),
download the NLTK data for the Snowball
Stemmer, Stopwords and Punkt tokenizer to your
`PAPERLESS_DATA_DIR/nltk`. Refer to the [NLTK
Stemmer, Stopwords and Punkt tokenizer to `/usr/share/nltk_data`. Refer to the [NLTK
instructions](https://www.nltk.org/data.html) for details on how to
download the data.

View File

@@ -237,9 +237,13 @@ Settings > Users & Groups, assuming the user has access. If a user is designated
as a member of a group those permissions will be inherited and this is reflected in the UI. Explicit
permissions can be granted to limit access to certain parts of the UI (and corresponding API endpoints).
!!! note
!!! tip
Superusers can access all parts of the front and backend application as well as any and all objects.
By default, new users are not granted any permissions, except those inherited from any group(s) of which they are a member.
#### Superusers
Superusers can access all parts of the front and backend application as well as any and all objects.
#### Admin Status
@@ -248,29 +252,29 @@ as well as accessing the Django backend.
#### Detailed Explanation of Global Permissions {#global-permissions}
Global permissions define what areas of the app and API endpoints the user can access. For example, they
Global permissions define what areas of the app and API endpoints users can access. For example, they
determine if a user can create, edit, delete or view _any_ documents, but individual documents themselves
still have "object-level" permissions.
| Type | Details |
| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| AppConfig | _Change_ or higher permissions grants access to the "Application Configuration" area. |
| Correspondent | Grants global permissions to add, edit, delete or view Correspondents. |
| CustomField | Grants global permissions to add, edit, delete or view Custom Fields. |
| Document | Grants global permissions to add, edit, delete or view Documents. |
| DocumentType | Grants global permissions to add, edit, delete or view Document Types. |
| Group | Grants global permissions to add, edit, delete or view Groups. |
| MailAccount | Grants global permissions to add, edit, delete or view Mail Accounts. |
| MailRule | Grants global permissions to add, edit, delete or view Mail Rules. |
| Note | Grants global permissions to add, edit, delete or view Notes. |
| PaperlessTask | Grants global permissions to view or dismiss (_Change_) File Tasks. |
| SavedView | Grants global permissions to add, edit, delete or view Saved Views. |
| ShareLink | Grants global permissions to add, delete or view Share Links. |
| StoragePath | Grants global permissions to add, edit, delete or view Storage Paths. |
| Tag | Grants global permissions to add, edit, delete or view Tags. |
| UISettings | Grants global permissions to add, edit, delete or view the UI settings that are used by the web app.<br/>Users expected to access the web UI should usually be granted at least _View_ permissions. |
| User | Grants global permissions to add, edit, delete or view Users. |
| Workflow | Grants global permissions to add, edit, delete or view Workflows.<br/>Note that Workflows are global, in other words all users who can access workflows have access to the same set of them. |
| Type | Details |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| AppConfig | _Change_ or higher permissions grants access to the "Application Configuration" area. |
| Correspondent | Add, edit, delete or view Correspondents. |
| CustomField | Add, edit, delete or view Custom Fields. |
| Document | Add, edit, delete or view Documents. |
| DocumentType | Add, edit, delete or view Document Types. |
| Group | Add, edit, delete or view Groups. |
| MailAccount | Add, edit, delete or view Mail Accounts. |
| MailRule | Add, edit, delete or view Mail Rules. |
| Note | Add, edit, delete or view Notes. |
| PaperlessTask | View or dismiss (_Change_) File Tasks. |
| SavedView | Add, edit, delete or view Saved Views. |
| ShareLink | Add, delete or view Share Links. |
| StoragePath | Add, edit, delete or view Storage Paths. |
| Tag | Add, edit, delete or view Tags. |
| UISettings | Add, edit, delete or view the UI settings that are used by the web app.<br/>:warning: **Users that will access the web UI must be granted at least _View_ permissions.** |
| User | Add, edit, delete or view Users. |
| Workflow | Add, edit, delete or view Workflows.<br/>Note that Workflows are global, in other words all users who can access workflows have access to the same set of them. |
#### Detailed Explanation of Object Permissions {#object-permissions}
@@ -445,6 +449,7 @@ The following custom field types are supported:
- `Number`: float number e.g. 12.3456
- `Monetary`: [ISO 4217 currency code](https://en.wikipedia.org/wiki/ISO_4217#List_of_ISO_4217_currency_codes) and a number with exactly two decimals, e.g. USD12.30
- `Document Link`: reference(s) to other document(s) displayed as links, automatically creates a symmetrical link in reverse
- `Select`: a pre-defined list of strings from which the user can choose
## Share Links
@@ -481,7 +486,7 @@ as "System".
## Document Trash
When you first delete a document it is moved to the 'trash' until either it is explicitly deleted or it is automatically removed after a set amount of time has passed.
You can set how long documents remain in the trash before being automatically deleted with [`EMPTY_TRASH_DELAY`](configuration.md#EMPTY_TRASH_DELAY), which defaults
You can set how long documents remain in the trash before being automatically deleted with [`PAPERLESS_EMPTY_TRASH_DELAY`](configuration.md#PAPERLESS_EMPTY_TRASH_DELAY), which defaults
to 30 days. Until the file is actually deleted (e.g. the trash is emptied), all files and database content remains intact and can be restored at any point up until that time.
Additionally you may configure a directory where deleted files are moved to when they the trash is emptied with [`PAPERLESS_EMPTY_TRASH_DIR`](configuration.md#PAPERLESS_EMPTY_TRASH_DIR).

View File

@@ -49,6 +49,9 @@ markdown_extensions:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format
- pymdownx.emoji:
emoji_index: !!python/name:material.extensions.emoji.twemoji
emoji_generator: !!python/name:material.extensions.emoji.to_svg
strict: true
nav:
- index.md

View File

@@ -14,6 +14,7 @@ following additional information about it:
* Thumbnail Path: ${DOCUMENT_THUMBNAIL_PATH}
* Download URL: ${DOCUMENT_DOWNLOAD_URL}
* Thumbnail URL: ${DOCUMENT_THUMBNAIL_URL}
* Owner Name: ${DOCUMENT_OWNER}
* Correspondent: ${DOCUMENT_CORRESPONDENT}
* Tags: ${DOCUMENT_TAGS}

View File

@@ -77,7 +77,6 @@
"scripts": [],
"allowedCommonJsDependencies": [
"ng2-pdf-viewer",
"filesize",
"file-saver"
],
"vendorChunk": true,

View File

@@ -9,7 +9,7 @@ test('dashboard inbox link', async ({ page }) => {
await page.routeFromHAR(REQUESTS_HAR1, { notFound: 'fallback' })
await page.goto('/dashboard')
await page.getByRole('link', { name: 'Documents in inbox' }).click()
await expect(page).toHaveURL(/tags__id__all=9/)
await expect(page).toHaveURL(/tags__id__in=9/)
await expect(page.locator('pngx-document-list')).toHaveText(/8 documents/)
})

View File

@@ -236,7 +236,7 @@
"content": {
"size": -1,
"mimeType": "application/json",
"text": "{\"documents_total\":61,\"documents_inbox\":8,\"inbox_tag\":9,\"document_file_type_counts\":[{\"mime_type\":\"application/pdf\",\"mime_type_count\":57},{\"mime_type\":\"text/plain\",\"mime_type_count\":3},{\"mime_type\":\"text/csv\",\"mime_type_count\":1}],\"character_count\":2407053}"
"text": "{\"documents_total\":61,\"documents_inbox\":8,\"inbox_tags\":[9],\"document_file_type_counts\":[{\"mime_type\":\"application/pdf\",\"mime_type_count\":57},{\"mime_type\":\"text/plain\",\"mime_type_count\":3},{\"mime_type\":\"text/csv\",\"mime_type_count\":1}],\"character_count\":2407053}"
},
"headersSize": -1,
"bodySize": -1,
@@ -250,7 +250,7 @@
"time": 0.609,
"request": {
"method": "GET",
"url": "http://localhost:8000/api/documents/?page=1&page_size=10&ordering=-created&truncate_content=true&tags__id__all=9",
"url": "http://localhost:8000/api/documents/?page=1&page_size=10&ordering=-created&truncate_content=true&tags__id__in=9",
"httpVersion": "HTTP/1.1",
"cookies": [],
"headers": [
@@ -284,7 +284,7 @@
"value": "true"
},
{
"name": "tags__id__all",
"name": "tags__id__in",
"value": "9"
}
],
@@ -468,7 +468,7 @@
"time": 0.951,
"request": {
"method": "GET",
"url": "http://localhost:8000/api/documents/?page=1&page_size=50&ordering=-created&truncate_content=true&tags__id__all=9",
"url": "http://localhost:8000/api/documents/?page=1&page_size=50&ordering=-created&truncate_content=true&tags__id__in=9",
"httpVersion": "HTTP/1.1",
"cookies": [],
"headers": [
@@ -502,7 +502,7 @@
"value": "true"
},
{
"name": "tags__id__all",
"name": "tags__id__in",
"value": "9"
}
],

View File

@@ -236,7 +236,7 @@
"content": {
"size": -1,
"mimeType": "application/json",
"text": "{\"documents_total\":61,\"documents_inbox\":8,\"inbox_tag\":9,\"document_file_type_counts\":[{\"mime_type\":\"application/pdf\",\"mime_type_count\":57},{\"mime_type\":\"text/plain\",\"mime_type_count\":3},{\"mime_type\":\"text/csv\",\"mime_type_count\":1}],\"character_count\":2407053}"
"text": "{\"documents_total\":61,\"documents_inbox\":8,\"inbox_tags\":[9],\"document_file_type_counts\":[{\"mime_type\":\"application/pdf\",\"mime_type_count\":57},{\"mime_type\":\"text/plain\",\"mime_type_count\":3},{\"mime_type\":\"text/csv\",\"mime_type_count\":1}],\"character_count\":2407053}"
},
"headersSize": -1,
"bodySize": -1,
@@ -250,7 +250,7 @@
"time": 0.622,
"request": {
"method": "GET",
"url": "http://localhost:8000/api/documents/?page=1&page_size=10&ordering=-created&truncate_content=true&tags__id__all=9",
"url": "http://localhost:8000/api/documents/?page=1&page_size=10&ordering=-created&truncate_content=true&tags__id__in=9",
"httpVersion": "HTTP/1.1",
"cookies": [],
"headers": [
@@ -284,7 +284,7 @@
"value": "true"
},
{
"name": "tags__id__all",
"name": "tags__id__in",
"value": "9"
}
],

View File

@@ -236,7 +236,7 @@
"content": {
"size": -1,
"mimeType": "application/json",
"text": "{\"documents_total\":61,\"documents_inbox\":8,\"inbox_tag\":9,\"document_file_type_counts\":[{\"mime_type\":\"application/pdf\",\"mime_type_count\":57},{\"mime_type\":\"text/plain\",\"mime_type_count\":3},{\"mime_type\":\"text/csv\",\"mime_type_count\":1}],\"character_count\":2407053}"
"text": "{\"documents_total\":61,\"documents_inbox\":8,\"inbox_tags\":[9],\"document_file_type_counts\":[{\"mime_type\":\"application/pdf\",\"mime_type_count\":57},{\"mime_type\":\"text/plain\",\"mime_type_count\":3},{\"mime_type\":\"text/csv\",\"mime_type_count\":1}],\"character_count\":2407053}"
},
"headersSize": -1,
"bodySize": -1,

View File

@@ -236,7 +236,7 @@
"content": {
"size": -1,
"mimeType": "application/json",
"text": "{\"documents_total\":61,\"documents_inbox\":8,\"inbox_tag\":9,\"document_file_type_counts\":[{\"mime_type\":\"application/pdf\",\"mime_type_count\":57},{\"mime_type\":\"text/plain\",\"mime_type_count\":3},{\"mime_type\":\"text/csv\",\"mime_type_count\":1}],\"character_count\":2407053}"
"text": "{\"documents_total\":61,\"documents_inbox\":8,\"inbox_tags\":[9],\"document_file_type_counts\":[{\"mime_type\":\"application/pdf\",\"mime_type_count\":57},{\"mime_type\":\"text/plain\",\"mime_type_count\":3},{\"mime_type\":\"text/csv\",\"mime_type_count\":1}],\"character_count\":2407053}"
},
"headersSize": -1,
"bodySize": -1,

View File

@@ -84,13 +84,8 @@ test('date filtering', async ({ page }) => {
await page.getByRole('button', { name: 'Dates' }).click()
await page.getByRole('menuitem', { name: 'Last 3 months' }).first().click()
await expect(page.locator('pngx-document-list')).toHaveText(/one document/i)
await page.getByRole('button', { name: 'Dates Clear selected' }).click()
await page.getByRole('button', { name: 'Dates' }).click()
await page
.getByRole('menuitem', { name: 'After mm/dd/yyyy' })
.getByRole('button')
.first()
.click()
await page.getByRole('menuitem', { name: 'Last 3 months' }).first().click()
await page.getByLabel('Datesselected').getByRole('button').first().click()
await page.getByRole('combobox', { name: 'Select month' }).selectOption('12')
await page.getByRole('combobox', { name: 'Select year' }).selectOption('2022')
await page.getByText('11', { exact: true }).click()

File diff suppressed because it is too large Load Diff

6937
src-ui/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -11,17 +11,17 @@
},
"private": true,
"dependencies": {
"@angular/cdk": "^17.3.10",
"@angular/common": "~17.3.9",
"@angular/compiler": "~17.3.9",
"@angular/core": "~17.3.9",
"@angular/forms": "~17.3.9",
"@angular/localize": "~17.3.9",
"@angular/platform-browser": "~17.3.9",
"@angular/platform-browser-dynamic": "~17.3.9",
"@angular/router": "~17.3.9",
"@ng-bootstrap/ng-bootstrap": "^16.0.0",
"@ng-select/ng-select": "^12.0.7",
"@angular/cdk": "^18.1.3",
"@angular/common": "~18.1.3",
"@angular/compiler": "~18.1.3",
"@angular/core": "~18.1.3",
"@angular/forms": "~18.1.3",
"@angular/localize": "~18.1.3",
"@angular/platform-browser": "~18.1.3",
"@angular/platform-browser-dynamic": "~18.1.3",
"@angular/router": "~18.1.3",
"@ng-bootstrap/ng-bootstrap": "^17.0.0",
"@ng-select/ng-select": "^13.5.0",
"@ngneat/dirty-check-forms": "^3.0.3",
"@popperjs/core": "^2.11.8",
"bootstrap": "^5.3.3",
@@ -30,35 +30,37 @@
"ng2-pdf-viewer": "^10.2.2",
"ngx-bootstrap-icons": "^1.9.3",
"ngx-color": "^9.0.0",
"ngx-cookie-service": "^17.1.0",
"ngx-cookie-service": "^18.0.0",
"ngx-file-drop": "^16.0.0",
"ngx-filesize": "^3.0.3",
"ngx-ui-tour-ng-bootstrap": "^14.0.3",
"ngx-ui-tour-ng-bootstrap": "^15.0.0",
"rxjs": "^7.8.1",
"tslib": "^2.6.2",
"uuid": "^9.0.1",
"zone.js": "^0.14.4"
"uuid": "^10.0.0",
"zone.js": "^0.14.8"
},
"devDependencies": {
"@angular-builders/jest": "17.0.3",
"@angular-devkit/build-angular": "~17.3.7",
"@angular-eslint/builder": "17.4.1",
"@angular-eslint/eslint-plugin": "17.4.1",
"@angular-eslint/eslint-plugin-template": "17.4.1",
"@angular-eslint/schematics": "17.4.1",
"@angular-eslint/template-parser": "17.4.1",
"@angular/cli": "~17.3.7",
"@angular/compiler-cli": "~17.3.2",
"@playwright/test": "^1.42.1",
"@angular-builders/jest": "^18.0.0",
"@angular-devkit/build-angular": "^18.1.3",
"@angular-devkit/core": "^18.1.3",
"@angular-devkit/schematics": "^18.1.3",
"@angular-eslint/builder": "18.2.0",
"@angular-eslint/eslint-plugin": "18.2.0",
"@angular-eslint/eslint-plugin-template": "18.2.0",
"@angular-eslint/schematics": "18.2.0",
"@angular-eslint/template-parser": "18.2.0",
"@angular/cli": "~18.1.3",
"@angular/compiler-cli": "~18.1.3",
"@playwright/test": "^1.45.3",
"@types/jest": "^29.5.12",
"@types/node": "^20.12.2",
"@typescript-eslint/eslint-plugin": "^7.4.0",
"@typescript-eslint/parser": "^7.4.0",
"@types/node": "^22.0.2",
"@typescript-eslint/eslint-plugin": "^8.0.0",
"@typescript-eslint/parser": "^8.0.0",
"@typescript-eslint/utils": "^8.0.0",
"concurrently": "^8.2.2",
"eslint": "^8.57.0",
"eslint": "^9.8.0",
"jest": "29.7.0",
"jest-environment-jsdom": "^29.7.0",
"jest-preset-angular": "^14.1.0",
"jest-preset-angular": "^14.2.2",
"jest-websocket-mock": "^2.5.0",
"patch-package": "^8.0.0",
"ts-node": "~10.9.1",

View File

@@ -150,7 +150,10 @@ export const routes: Routes = [
component: TrashComponent,
canActivate: [PermissionsGuard],
data: {
requireAdmin: true,
requiredPermission: {
action: PermissionAction.Delete,
type: PermissionType.Document,
},
},
},
// redirect old paths

View File

@@ -1,4 +1,4 @@
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import {
ComponentFixture,
TestBed,
@@ -24,6 +24,7 @@ import { NgbModalModule } from '@ng-bootstrap/ng-bootstrap'
import { HotKeyService } from './services/hot-key.service'
import { PermissionsGuard } from './guards/permissions.guard'
import { DirtySavedViewGuard } from './guards/dirty-saved-view.guard'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
describe('AppComponent', () => {
let component: AppComponent
@@ -39,14 +40,18 @@ describe('AppComponent', () => {
beforeEach(async () => {
TestBed.configureTestingModule({
declarations: [AppComponent, ToastsComponent, FileDropComponent],
providers: [PermissionsGuard, DirtySavedViewGuard],
imports: [
HttpClientTestingModule,
TourNgBootstrapModule,
RouterModule.forRoot(routes),
NgxFileDropModule,
NgbModalModule,
],
providers: [
PermissionsGuard,
DirtySavedViewGuard,
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
}).compileComponents()
tourService = TestBed.inject(TourService)

View File

@@ -7,7 +7,11 @@ import {
NgbDateParserFormatter,
NgbModule,
} from '@ng-bootstrap/ng-bootstrap'
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'
import {
HTTP_INTERCEPTORS,
provideHttpClient,
withInterceptorsFromDi,
} from '@angular/common/http'
import { DocumentListComponent } from './components/document-list/document-list.component'
import { DocumentDetailComponent } from './components/document-detail/document-detail.component'
import { DashboardComponent } from './components/dashboard/dashboard.component'
@@ -115,7 +119,6 @@ import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
import { ConfirmButtonComponent } from './components/common/confirm-button/confirm-button.component'
import { MonetaryComponent } from './components/common/input/monetary/monetary.component'
import { SystemStatusDialogComponent } from './components/common/system-status-dialog/system-status-dialog.component'
import { NgxFilesizeModule } from 'ngx-filesize'
import { RotateConfirmDialogComponent } from './components/common/confirm-dialog/rotate-confirm-dialog/rotate-confirm-dialog.component'
import { MergeConfirmDialogComponent } from './components/common/confirm-dialog/merge-confirm-dialog/merge-confirm-dialog.component'
import { SplitConfirmDialogComponent } from './components/common/confirm-dialog/split-confirm-dialog/split-confirm-dialog.component'
@@ -500,11 +503,11 @@ function initializeApp(settings: SettingsService) {
DeletePagesConfirmDialogComponent,
TrashComponent,
],
bootstrap: [AppComponent],
imports: [
BrowserModule,
AppRoutingModule,
NgbModule,
HttpClientModule,
FormsModule,
ReactiveFormsModule,
PdfViewerModule,
@@ -514,7 +517,6 @@ function initializeApp(settings: SettingsService) {
TourNgBootstrapModule,
DragDropModule,
NgxBootstrapIconsModule.pick(icons),
NgxFilesizeModule,
],
providers: [
{
@@ -543,7 +545,7 @@ function initializeApp(settings: SettingsService) {
DirtyDocGuard,
DirtySavedViewGuard,
UsernamePipe,
provideHttpClient(withInterceptorsFromDi()),
],
bootstrap: [AppComponent],
})
export class AppModule {}

View File

@@ -5,7 +5,7 @@ import { ConfigService } from 'src/app/services/config.service'
import { ToastService } from 'src/app/services/toast.service'
import { of, throwError } from 'rxjs'
import { OutputTypeConfig } from 'src/app/data/paperless-config'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import { BrowserModule } from '@angular/platform-browser'
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'
import { NgSelectModule } from '@ng-select/ng-select'
@@ -18,6 +18,7 @@ import { SelectComponent } from '../../common/input/select/select.component'
import { FileComponent } from '../../common/input/file/file.component'
import { SettingsService } from 'src/app/services/settings.service'
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
describe('ConfigComponent', () => {
let component: ConfigComponent
@@ -38,7 +39,6 @@ describe('ConfigComponent', () => {
PageHeaderComponent,
],
imports: [
HttpClientTestingModule,
BrowserModule,
NgbModule,
NgSelectModule,
@@ -46,6 +46,10 @@ describe('ConfigComponent', () => {
ReactiveFormsModule,
NgxBootstrapIconsModule.pick(allIcons),
],
providers: [
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
}).compileComponents()
configService = TestBed.inject(ConfigService)

View File

@@ -8,10 +8,11 @@ import { LogService } from 'src/app/services/rest/log.service'
import { PageHeaderComponent } from '../../common/page-header/page-header.component'
import { LogsComponent } from './logs.component'
import { of, throwError } from 'rxjs'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import { NgbModule, NgbNavLink } from '@ng-bootstrap/ng-bootstrap'
import { BrowserModule, By } from '@angular/platform-browser'
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
const paperless_logs = [
'[2023-05-29 03:05:01,224] [DEBUG] [paperless.tasks] Training data unchanged.',
@@ -37,13 +38,15 @@ describe('LogsComponent', () => {
beforeEach(async () => {
TestBed.configureTestingModule({
declarations: [LogsComponent, PageHeaderComponent],
providers: [],
imports: [
HttpClientTestingModule,
BrowserModule,
NgbModule,
NgxBootstrapIconsModule.pick(allIcons),
],
providers: [
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
}).compileComponents()
logService = TestBed.inject(LogService)

View File

@@ -348,7 +348,7 @@
@for (view of savedViews; track view) {
<li class="list-group-item py-3">
<div [formGroupName]="view.id" class="row">
<div [formGroupName]="view.id">
<div class="row">
<div class="col">
<pngx-input-text title="Name" formControlName="name"></pngx-input-text>

View File

@@ -1,5 +1,5 @@
import { ViewportScroller, DatePipe } from '@angular/common'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import { ComponentFixture, TestBed } from '@angular/core/testing'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { By } from '@angular/platform-browser'
@@ -50,6 +50,7 @@ import {
} from 'src/app/data/system-status'
import { DragDropSelectComponent } from '../../common/input/drag-drop-select/drag-drop-select.component'
import { DragDropModule } from '@angular/cdk/drag-drop'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
const savedViews = [
{ id: 1, name: 'view1', show_in_sidebar: true, show_on_dashboard: true },
@@ -100,10 +101,8 @@ describe('SettingsComponent', () => {
ConfirmButtonComponent,
DragDropSelectComponent,
],
providers: [CustomDatePipe, DatePipe, PermissionsGuard],
imports: [
NgbModule,
HttpClientTestingModule,
RouterTestingModule.withRoutes(routes),
FormsModule,
ReactiveFormsModule,
@@ -113,6 +112,13 @@ describe('SettingsComponent', () => {
NgbModalModule,
DragDropModule,
],
providers: [
CustomDatePipe,
DatePipe,
PermissionsGuard,
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
}).compileComponents()
router = TestBed.inject(Router)

View File

@@ -1,7 +1,7 @@
import { DatePipe } from '@angular/common'
import {
HttpTestingController,
HttpClientTestingModule,
provideHttpClientTesting,
} from '@angular/common/http/testing'
import { ComponentFixture, TestBed } from '@angular/core/testing'
import { By } from '@angular/platform-browser'
@@ -30,6 +30,7 @@ import { TasksComponent } from './tasks.component'
import { PermissionsGuard } from 'src/app/guards/permissions.guard'
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
import { FormsModule } from '@angular/forms'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
const tasks: PaperlessTask[] = [
{
@@ -125,6 +126,12 @@ describe('TasksComponent', () => {
CustomDatePipe,
ConfirmDialogComponent,
],
imports: [
NgbModule,
RouterTestingModule.withRoutes(routes),
NgxBootstrapIconsModule.pick(allIcons),
FormsModule,
],
providers: [
{
provide: PermissionsService,
@@ -135,13 +142,8 @@ describe('TasksComponent', () => {
CustomDatePipe,
DatePipe,
PermissionsGuard,
],
imports: [
NgbModule,
HttpClientTestingModule,
RouterTestingModule.withRoutes(routes),
NgxBootstrapIconsModule.pick(allIcons),
FormsModule,
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
}).compileComponents()

View File

@@ -11,9 +11,11 @@ import {
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { TrashService } from 'src/app/services/trash.service'
import { of } from 'rxjs'
import { of, throwError } from 'rxjs'
import { ConfirmDialogComponent } from '../../common/confirm-dialog/confirm-dialog.component'
import { By } from '@angular/platform-browser'
import { SafeHtmlPipe } from 'src/app/pipes/safehtml.pipe'
import { ToastService } from 'src/app/services/toast.service'
const documentsInTrash = [
{
@@ -35,6 +37,7 @@ describe('TrashComponent', () => {
let fixture: ComponentFixture<TrashComponent>
let trashService: TrashService
let modalService: NgbModal
let toastService: ToastService
beforeEach(async () => {
await TestBed.configureTestingModule({
@@ -42,6 +45,7 @@ describe('TrashComponent', () => {
TrashComponent,
PageHeaderComponent,
ConfirmDialogComponent,
SafeHtmlPipe,
],
imports: [
HttpClientTestingModule,
@@ -56,6 +60,7 @@ describe('TrashComponent', () => {
fixture = TestBed.createComponent(TrashComponent)
trashService = TestBed.inject(TrashService)
modalService = TestBed.inject(NgbModal)
toastService = TestBed.inject(ToastService)
component = fixture.componentInstance
fixture.detectChanges()
})
@@ -74,12 +79,20 @@ describe('TrashComponent', () => {
expect(component.documentsInTrash).toEqual(documentsInTrash)
})
it('should support delete document', () => {
it('should support delete document, show error if needed', () => {
const trashSpy = jest.spyOn(trashService, 'emptyTrash')
let modal
modalService.activeInstances.subscribe((instances) => {
modal = instances[0]
})
const toastErrorSpy = jest.spyOn(toastService, 'showError')
// fail first
trashSpy.mockReturnValue(throwError(() => 'Error'))
component.delete(documentsInTrash[0])
modal.componentInstance.confirmClicked.next()
expect(toastErrorSpy).toHaveBeenCalled()
trashSpy.mockReturnValue(of('OK'))
component.delete(documentsInTrash[0])
expect(modal).toBeDefined()
@@ -87,12 +100,20 @@ describe('TrashComponent', () => {
expect(trashSpy).toHaveBeenCalled()
})
it('should support empty trash', () => {
it('should support empty trash, show error if needed', () => {
const trashSpy = jest.spyOn(trashService, 'emptyTrash')
let modal
modalService.activeInstances.subscribe((instances) => {
modal = instances[instances.length - 1]
})
const toastErrorSpy = jest.spyOn(toastService, 'showError')
// fail first
trashSpy.mockReturnValue(throwError(() => 'Error'))
component.emptyTrash()
modal.componentInstance.confirmClicked.next()
expect(toastErrorSpy).toHaveBeenCalled()
trashSpy.mockReturnValue(of('OK'))
component.emptyTrash()
expect(modal).toBeDefined()
@@ -104,18 +125,34 @@ describe('TrashComponent', () => {
expect(trashSpy).toHaveBeenCalledWith([1, 2])
})
it('should support restore document', () => {
it('should support restore document, show error if needed', () => {
const restoreSpy = jest.spyOn(trashService, 'restoreDocuments')
const reloadSpy = jest.spyOn(component, 'reload')
const toastErrorSpy = jest.spyOn(toastService, 'showError')
// fail first
restoreSpy.mockReturnValue(throwError(() => 'Error'))
component.restore(documentsInTrash[0])
expect(toastErrorSpy).toHaveBeenCalled()
expect(reloadSpy).not.toHaveBeenCalled()
restoreSpy.mockReturnValue(of('OK'))
component.restore(documentsInTrash[0])
expect(restoreSpy).toHaveBeenCalledWith([documentsInTrash[0].id])
expect(reloadSpy).toHaveBeenCalled()
})
it('should support restore all documents', () => {
it('should support restore all documents, show error if needed', () => {
const restoreSpy = jest.spyOn(trashService, 'restoreDocuments')
const reloadSpy = jest.spyOn(component, 'reload')
const toastErrorSpy = jest.spyOn(toastService, 'showError')
// fail first
restoreSpy.mockReturnValue(throwError(() => 'Error'))
component.restoreAll()
expect(toastErrorSpy).toHaveBeenCalled()
expect(reloadSpy).not.toHaveBeenCalled()
restoreSpy.mockReturnValue(of('OK'))
component.restoreAll()
expect(restoreSpy).toHaveBeenCalled()

View File

@@ -59,10 +59,16 @@ export class TrashComponent implements OnDestroy {
.pipe(takeUntil(this.unsubscribeNotifier))
.subscribe(() => {
modal.componentInstance.buttonsEnabled = false
this.trashService.emptyTrash([document.id]).subscribe(() => {
this.toastService.showInfo($localize`Document deleted`)
modal.close()
this.reload()
this.trashService.emptyTrash([document.id]).subscribe({
next: () => {
this.toastService.showInfo($localize`Document deleted`)
modal.close()
this.reload()
},
error: (err) => {
this.toastService.showError($localize`Error deleting document`, err)
modal.close()
},
})
})
}
@@ -83,29 +89,51 @@ export class TrashComponent implements OnDestroy {
.subscribe(() => {
this.trashService
.emptyTrash(documents ? Array.from(documents) : null)
.subscribe(() => {
this.toastService.showInfo($localize`Document(s) deleted`)
this.allToggled = false
modal.close()
this.reload()
.subscribe({
next: () => {
this.toastService.showInfo($localize`Document(s) deleted`)
this.allToggled = false
modal.close()
this.reload()
},
error: (err) => {
this.toastService.showError(
$localize`Error deleting document(s)`,
err
)
modal.close()
},
})
})
}
restore(document: Document) {
this.trashService.restoreDocuments([document.id]).subscribe(() => {
this.toastService.showInfo($localize`Document restored`)
this.reload()
this.trashService.restoreDocuments([document.id]).subscribe({
next: () => {
this.toastService.showInfo($localize`Document restored`)
this.reload()
},
error: (err) => {
this.toastService.showError($localize`Error restoring document`, err)
},
})
}
restoreAll(documents: Set<number> = null) {
this.trashService
.restoreDocuments(documents ? Array.from(documents) : null)
.subscribe(() => {
this.toastService.showInfo($localize`Document(s) restored`)
this.allToggled = false
this.reload()
.subscribe({
next: () => {
this.toastService.showInfo($localize`Document(s) restored`)
this.allToggled = false
this.reload()
},
error: (err) => {
this.toastService.showError(
$localize`Error restoring document(s)`,
err
)
},
})
}

View File

@@ -1,5 +1,5 @@
import { DatePipe } from '@angular/common'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import {
ComponentFixture,
TestBed,
@@ -44,6 +44,7 @@ import { UsersAndGroupsComponent } from './users-groups.component'
import { User } from 'src/app/data/user'
import { Group } from 'src/app/data/group'
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
const users = [
{ id: 1, username: 'user1', is_superuser: false },
@@ -84,10 +85,8 @@ describe('UsersAndGroupsComponent', () => {
PermissionsGroupComponent,
IfOwnerDirective,
],
providers: [CustomDatePipe, DatePipe, PermissionsGuard],
imports: [
NgbModule,
HttpClientTestingModule,
RouterTestingModule.withRoutes(routes),
FormsModule,
ReactiveFormsModule,
@@ -95,6 +94,13 @@ describe('UsersAndGroupsComponent', () => {
NgSelectModule,
NgxBootstrapIconsModule.pick(allIcons),
],
providers: [
CustomDatePipe,
DatePipe,
PermissionsGuard,
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
}).compileComponents()
fixture = TestBed.createComponent(UsersAndGroupsComponent)
settingsService = TestBed.inject(SettingsService)

View File

@@ -214,6 +214,13 @@
<i-bs class="me-1" name="envelope"></i-bs><span>&nbsp;<ng-container i18n>Mail</ng-container></span>
</a>
</li>
<li class="nav-item app-link" *pngxIfPermissions="{ action: PermissionAction.Delete, type: PermissionType.Document }">
<a class="nav-link" routerLink="trash" routerLinkActive="active" (click)="closeMenu()" ngbPopover="Trash"
i18n-ngbPopover [disablePopover]="!slimSidebarEnabled" placement="end" container="body"
triggers="mouseenter:mouseleave" popoverClass="popover-slim">
<i-bs class="me-1" name="trash"></i-bs><span>&nbsp;<ng-container i18n>Trash</ng-container></span>
</a>
</li>
</ul>
</div>
@@ -267,13 +274,6 @@
</a>
</li>
}
<li class="nav-item app-link" *pngxIfPermissions="{ action: PermissionAction.Delete, type: PermissionType.Document }">
<a class="nav-link" routerLink="trash" routerLinkActive="active" (click)="closeMenu()" ngbPopover="Trash"
i18n-ngbPopover [disablePopover]="!slimSidebarEnabled" placement="end" container="body"
triggers="mouseenter:mouseleave" popoverClass="popover-slim">
<i-bs class="me-1" name="trash"></i-bs><span>&nbsp;<ng-container i18n>Trash</ng-container></span>
</a>
</li>
<li class="nav-item mt-2" tourAnchor="tour.outro">
<a class="px-3 py-2 text-muted small d-flex align-items-center flex-wrap text-decoration-none"
target="_blank" rel="noopener noreferrer" href="https://docs.paperless-ngx.com" ngbPopover="Documentation"

View File

@@ -1,6 +1,6 @@
import {
HttpClientTestingModule,
HttpTestingController,
provideHttpClientTesting,
} from '@angular/common/http/testing'
import { AppFrameComponent } from './app-frame.component'
import {
@@ -37,6 +37,7 @@ import { SavedView } from 'src/app/data/saved-view'
import { ProfileEditDialogComponent } from '../common/profile-edit-dialog/profile-edit-dialog.component'
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
import { GlobalSearchComponent } from './global-search/global-search.component'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
const saved_views = [
{
@@ -100,7 +101,6 @@ describe('AppFrameComponent', () => {
GlobalSearchComponent,
],
imports: [
HttpClientTestingModule,
BrowserModule,
RouterTestingModule.withRoutes(routes),
NgbModule,
@@ -150,6 +150,8 @@ describe('AppFrameComponent', () => {
},
},
PermissionsGuard,
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
}).compileComponents()

View File

@@ -17,7 +17,7 @@ import {
import { CorrespondentEditDialogComponent } from '../../common/edit-dialog/correspondent-edit-dialog/correspondent-edit-dialog.component'
import { UserEditDialogComponent } from '../../common/edit-dialog/user-edit-dialog/user-edit-dialog.component'
import { DocumentListViewService } from 'src/app/services/document-list-view.service'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import {
FILTER_FULLTEXT_QUERY,
@@ -40,6 +40,7 @@ import { DataType } from 'src/app/data/datatype'
import { queryParamsFromFilterRules } from 'src/app/utils/query-params'
import { SettingsService } from 'src/app/services/settings.service'
import { GlobalSearchType, SETTINGS_KEYS } from 'src/app/data/ui-settings'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
const searchResults = {
total: 11,
@@ -139,13 +140,16 @@ describe('GlobalSearchComponent', () => {
await TestBed.configureTestingModule({
declarations: [GlobalSearchComponent],
imports: [
HttpClientTestingModule,
NgbModalModule,
NgbDropdownModule,
FormsModule,
ReactiveFormsModule,
NgxBootstrapIconsModule.pick(allIcons),
],
providers: [
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
}).compileComponents()
searchService = TestBed.inject(SearchService)

View File

@@ -1,11 +1,12 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'
import { DeletePagesConfirmDialogComponent } from './delete-pages-confirm-dialog.component'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
import { SafeHtmlPipe } from 'src/app/pipes/safehtml.pipe'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { PdfViewerComponent } from 'ng2-pdf-viewer'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
describe('DeletePagesConfirmDialogComponent', () => {
let component: DeletePagesConfirmDialogComponent
@@ -14,13 +15,17 @@ describe('DeletePagesConfirmDialogComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [DeletePagesConfirmDialogComponent, PdfViewerComponent],
providers: [NgbActiveModal, SafeHtmlPipe],
imports: [
HttpClientTestingModule,
NgxBootstrapIconsModule.pick(allIcons),
FormsModule,
ReactiveFormsModule,
],
providers: [
NgbActiveModal,
SafeHtmlPipe,
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
}).compileComponents()
fixture = TestBed.createComponent(DeletePagesConfirmDialogComponent)
component = fixture.componentInstance

View File

@@ -1,11 +1,12 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
import { MergeConfirmDialogComponent } from './merge-confirm-dialog.component'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
import { of } from 'rxjs'
import { DocumentService } from 'src/app/services/rest/document.service'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
describe('MergeConfirmDialogComponent', () => {
let component: MergeConfirmDialogComponent
@@ -15,13 +16,16 @@ describe('MergeConfirmDialogComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [MergeConfirmDialogComponent],
providers: [NgbActiveModal],
imports: [
HttpClientTestingModule,
NgxBootstrapIconsModule.pick(allIcons),
ReactiveFormsModule,
FormsModule,
],
providers: [
NgbActiveModal,
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
}).compileComponents()
fixture = TestBed.createComponent(MergeConfirmDialogComponent)

View File

@@ -2,8 +2,9 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'
import { RotateConfirmDialogComponent } from './rotate-confirm-dialog.component'
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
import { SafeHtmlPipe } from 'src/app/pipes/safehtml.pipe'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
describe('RotateConfirmDialogComponent', () => {
let component: RotateConfirmDialogComponent
@@ -12,10 +13,12 @@ describe('RotateConfirmDialogComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [RotateConfirmDialogComponent, SafeHtmlPipe],
providers: [NgbActiveModal, SafeHtmlPipe],
imports: [
HttpClientTestingModule,
NgxBootstrapIconsModule.pick(allIcons),
imports: [NgxBootstrapIconsModule.pick(allIcons)],
providers: [
NgbActiveModal,
SafeHtmlPipe,
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
}).compileComponents()

View File

@@ -23,7 +23,7 @@
</div>
<div class="col-4">
<div class="d-grid">
<button class="btn btn-sm btn-primary" (click)="addSplit()" [disabled]="page === totalPages">
<button class="btn btn-sm btn-primary" (click)="addSplit()" [disabled]="!canSplit">
<i-bs name="plus-circle"></i-bs>&nbsp;
<span i18n>Add Split</span>
</button>

View File

@@ -1,13 +1,14 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'
import { SplitConfirmDialogComponent } from './split-confirm-dialog.component'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import { ReactiveFormsModule, FormsModule } from '@angular/forms'
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
import { DocumentService } from 'src/app/services/rest/document.service'
import { PdfViewerModule } from 'ng2-pdf-viewer'
import { of } from 'rxjs'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
describe('SplitConfirmDialogComponent', () => {
let component: SplitConfirmDialogComponent
@@ -17,14 +18,17 @@ describe('SplitConfirmDialogComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [SplitConfirmDialogComponent],
providers: [NgbActiveModal],
imports: [
HttpClientTestingModule,
NgxBootstrapIconsModule.pick(allIcons),
ReactiveFormsModule,
FormsModule,
PdfViewerModule,
],
providers: [
NgbActiveModal,
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
}).compileComponents()
fixture = TestBed.createComponent(SplitConfirmDialogComponent)
@@ -88,4 +92,16 @@ describe('SplitConfirmDialogComponent', () => {
component.pdfPreviewLoaded({ numPages: 5 } as any)
expect(component.totalPages).toEqual(5)
})
it('should correctly disable split button', () => {
component.totalPages = 5
component.page = 1
expect(component.canSplit).toBeTruthy()
component.page = 5
expect(component.canSplit).toBeFalsy()
component.page = 4
expect(component.canSplit).toBeTruthy()
component['pages'] = new Set([1, 2, 3, 4])
expect(component.canSplit).toBeFalsy()
})
})

View File

@@ -42,6 +42,14 @@ export class SplitConfirmDialogComponent
public totalPages: number
public deleteOriginal: boolean = false
public get canSplit(): boolean {
return (
this.page < this.totalPages &&
this.pages.size < this.totalPages - 1 &&
!this.pages.has(this.page)
)
}
public get pdfSrc(): string {
return this.documentService.getPreviewUrl(this.documentID)
}

View File

@@ -30,6 +30,9 @@
<input type="checkbox" id="{{field.name}}" name="{{field.name}}" [checked]="value" value="" class="form-check-input ms-2 mt-0 pe-none">
</div>
}
@case (CustomFieldDataType.Select) {
<span [ngbTooltip]="nameTooltip">{{getSelectValue(field, value)}}</span>
}
@default {
<span [ngbTooltip]="nameTooltip">{{value}}</span>
}

View File

@@ -4,13 +4,28 @@ import { CustomField, CustomFieldDataType } from 'src/app/data/custom-field'
import { DocumentService } from 'src/app/services/rest/document.service'
import { CustomFieldDisplayComponent } from './custom-field-display.component'
import { DisplayField, Document } from 'src/app/data/document'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
const customFields: CustomField[] = [
{ id: 1, name: 'Field 1', data_type: CustomFieldDataType.String },
{ id: 2, name: 'Field 2', data_type: CustomFieldDataType.Monetary },
{ id: 3, name: 'Field 3', data_type: CustomFieldDataType.DocumentLink },
{
id: 4,
name: 'Field 4',
data_type: CustomFieldDataType.Select,
extra_data: {
select_options: ['Option 1', 'Option 2', 'Option 3'],
},
},
{
id: 5,
name: 'Field 5',
data_type: CustomFieldDataType.Monetary,
extra_data: { default_currency: 'JPY' },
},
]
const document: Document = {
id: 1,
@@ -31,8 +46,12 @@ describe('CustomFieldDisplayComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [CustomFieldDisplayComponent],
providers: [DocumentService],
imports: [HttpClientTestingModule],
imports: [],
providers: [
DocumentService,
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
}).compileComponents()
})
@@ -98,4 +117,20 @@ describe('CustomFieldDisplayComponent', () => {
expect(component.currency).toEqual('EUR')
expect(component.value).toEqual(100)
})
it('should respect explicit default currency', () => {
component['defaultCurrencyCode'] = 'EUR' // mock default locale injection
component.fieldId = 5
component.document = {
id: 1,
title: 'Doc 1',
custom_fields: [{ field: 5, document: 1, created: null, value: '100' }],
}
expect(component.currency).toEqual('JPY')
expect(component.value).toEqual(100)
})
it('should show select value', () => {
expect(component.getSelectValue(customFields[3], 2)).toEqual('Option 3')
})
})

View File

@@ -90,7 +90,9 @@ export class CustomFieldDisplayComponent implements OnInit, OnDestroy {
)?.value
if (this.value && this.field.data_type === CustomFieldDataType.Monetary) {
this.currency =
this.value.match(/([A-Z]{3})/)?.[0] ?? this.defaultCurrencyCode
this.value.match(/([A-Z]{3})/)?.[0] ??
this.field.extra_data?.default_currency ??
this.defaultCurrencyCode
this.value = parseFloat(this.value.replace(this.currency, ''))
} else if (
this.value?.length &&
@@ -115,6 +117,10 @@ export class CustomFieldDisplayComponent implements OnInit, OnDestroy {
return this.docLinkDocuments?.find((d) => d.id === docId)?.title
}
public getSelectValue(field: CustomField, index: number): string {
return field.extra_data.select_options[index]
}
ngOnDestroy(): void {
this.unsubscribeNotifier.next(true)
this.unsubscribeNotifier.complete()

View File

@@ -5,7 +5,7 @@ import {
tick,
} from '@angular/core/testing'
import { CustomFieldsDropdownComponent } from './custom-fields-dropdown.component'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import { ToastService } from 'src/app/services/toast.service'
import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service'
import { of } from 'rxjs'
@@ -22,6 +22,7 @@ import {
import { CustomFieldEditDialogComponent } from '../edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component'
import { By } from '@angular/platform-browser'
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
const fields: CustomField[] = [
{
@@ -47,7 +48,6 @@ describe('CustomFieldsDropdownComponent', () => {
TestBed.configureTestingModule({
declarations: [CustomFieldsDropdownComponent, SelectComponent],
imports: [
HttpClientTestingModule,
NgSelectModule,
FormsModule,
ReactiveFormsModule,
@@ -55,6 +55,10 @@ describe('CustomFieldsDropdownComponent', () => {
NgbDropdownModule,
NgxBootstrapIconsModule.pick(allIcons),
],
providers: [
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
})
customFieldService = TestBed.inject(CustomFieldsService)
toastService = TestBed.inject(ToastService)

View File

@@ -10,7 +10,7 @@ import {
DateSelection,
RelativeDate,
} from './dates-dropdown.component'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'
import { SettingsService } from 'src/app/services/settings.service'
import { ClearableBadgeComponent } from '../clearable-badge/clearable-badge.component'
@@ -18,6 +18,7 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { CustomDatePipe } from 'src/app/pipes/custom-date.pipe'
import { DatePipe } from '@angular/common'
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
describe('DatesDropdownComponent', () => {
let component: DatesDropdownComponent
@@ -31,14 +32,19 @@ describe('DatesDropdownComponent', () => {
ClearableBadgeComponent,
CustomDatePipe,
],
providers: [SettingsService, CustomDatePipe, DatePipe],
imports: [
HttpClientTestingModule,
NgbModule,
FormsModule,
ReactiveFormsModule,
NgxBootstrapIconsModule.pick(allIcons),
],
providers: [
SettingsService,
CustomDatePipe,
DatePipe,
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
}).compileComponents()
settingsService = TestBed.inject(SettingsService)

View File

@@ -1,4 +1,4 @@
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import { ComponentFixture, TestBed } from '@angular/core/testing'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { NgbActiveModal, NgbModule } from '@ng-bootstrap/ng-bootstrap'
@@ -11,6 +11,7 @@ import { SelectComponent } from '../../input/select/select.component'
import { TextComponent } from '../../input/text/text.component'
import { EditDialogMode } from '../edit-dialog.component'
import { CorrespondentEditDialogComponent } from './correspondent-edit-dialog.component'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
describe('CorrespondentEditDialogComponent', () => {
let component: CorrespondentEditDialogComponent
@@ -27,13 +28,11 @@ describe('CorrespondentEditDialogComponent', () => {
TextComponent,
PermissionsFormComponent,
],
providers: [NgbActiveModal],
imports: [
HttpClientTestingModule,
FormsModule,
ReactiveFormsModule,
NgSelectModule,
NgbModule,
imports: [FormsModule, ReactiveFormsModule, NgSelectModule, NgbModule],
providers: [
NgbActiveModal,
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
}).compileComponents()

View File

@@ -13,6 +13,28 @@
@if (typeFieldDisabled) {
<small class="d-block mt-n2" i18n>Data type cannot be changed after a field is created</small>
}
<div [formGroup]="objectForm.controls.extra_data">
@switch (objectForm.get('data_type').value) {
@case (CustomFieldDataType.Select) {
<button type="button" class="btn btn-sm btn-primary my-2" (click)="addSelectOption()">
<span i18n>Add option</span>&nbsp;<i-bs name="plus-circle"></i-bs>
</button>
<div formArrayName="select_options">
@for (option of objectForm.controls.extra_data.controls.select_options.controls; track option; let i = $index) {
<div class="input-group input-group-sm my-2">
<input #selectOption type="text" class="form-control" [formControl]="option" autocomplete="off">
<button type="button" class="btn btn-outline-danger" (click)="removeSelectOption(i)" i18n>Delete</button>
</div>
}
</div>
}
@case (CustomFieldDataType.Monetary) {
<div class="my-3">
<pngx-input-text i18n-title title="Default Currency" hint="3-character currency code" i18n-hint formControlName="default_currency" placeholder="Use locale" i18n-placeholder autocomplete="off"></pngx-input-text>
</div>
}
}
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-secondary" (click)="cancel()" i18n [disabled]="networkActive">Cancel</button>

View File

@@ -1,7 +1,7 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'
import { CustomFieldEditDialogComponent } from './custom-field-edit-dialog.component'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { NgbActiveModal, NgbModule } from '@ng-bootstrap/ng-bootstrap'
import { NgSelectModule } from '@ng-select/ng-select'
@@ -12,6 +12,10 @@ import { SettingsService } from 'src/app/services/settings.service'
import { SelectComponent } from '../../input/select/select.component'
import { TextComponent } from '../../input/text/text.component'
import { EditDialogMode } from '../edit-dialog.component'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
import { CustomFieldDataType } from 'src/app/data/custom-field'
import { ElementRef, QueryList } from '@angular/core'
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
describe('CustomFieldEditDialogComponent', () => {
let component: CustomFieldEditDialogComponent
@@ -28,13 +32,17 @@ describe('CustomFieldEditDialogComponent', () => {
TextComponent,
SafeHtmlPipe,
],
providers: [NgbActiveModal],
imports: [
HttpClientTestingModule,
FormsModule,
ReactiveFormsModule,
NgSelectModule,
NgbModule,
NgxBootstrapIconsModule.pick(allIcons),
],
providers: [
NgbActiveModal,
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
}).compileComponents()
@@ -64,4 +72,55 @@ describe('CustomFieldEditDialogComponent', () => {
component.ngOnInit()
expect(component.objectForm.get('data_type').disabled).toBeTruthy()
})
it('should initialize select options on edit', () => {
component.dialogMode = EditDialogMode.EDIT
component.object = {
id: 1,
name: 'Field 1',
data_type: CustomFieldDataType.Select,
extra_data: {
select_options: ['Option 1', 'Option 2', 'Option 3'],
},
}
fixture.detectChanges()
component.ngOnInit()
expect(
component.objectForm.get('extra_data').get('select_options').value.length
).toBe(3)
})
it('should support add / remove select options', () => {
component.dialogMode = EditDialogMode.CREATE
fixture.detectChanges()
component.ngOnInit()
expect(
component.objectForm.get('extra_data').get('select_options').value.length
).toBe(1)
component.addSelectOption()
expect(
component.objectForm.get('extra_data').get('select_options').value.length
).toBe(2)
component.addSelectOption()
expect(
component.objectForm.get('extra_data').get('select_options').value.length
).toBe(3)
component.removeSelectOption(0)
expect(
component.objectForm.get('extra_data').get('select_options').value.length
).toBe(2)
})
it('should focus on last select option input', () => {
const selectOptionInputs = component[
'selectOptionInputs'
] as QueryList<ElementRef>
component.dialogMode = EditDialogMode.CREATE
component.objectForm.get('data_type').setValue(CustomFieldDataType.Select)
component.ngOnInit()
component.ngAfterViewInit()
component.addSelectOption()
fixture.detectChanges()
expect(document.activeElement).toBe(selectOptionInputs.last.nativeElement)
})
})

View File

@@ -1,11 +1,24 @@
import { Component, OnInit } from '@angular/core'
import { FormGroup, FormControl } from '@angular/forms'
import {
AfterViewInit,
Component,
ElementRef,
OnDestroy,
OnInit,
QueryList,
ViewChildren,
} from '@angular/core'
import { FormGroup, FormControl, FormArray } from '@angular/forms'
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
import { DATA_TYPE_LABELS, CustomField } from 'src/app/data/custom-field'
import {
DATA_TYPE_LABELS,
CustomField,
CustomFieldDataType,
} from 'src/app/data/custom-field'
import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service'
import { UserService } from 'src/app/services/rest/user.service'
import { SettingsService } from 'src/app/services/settings.service'
import { EditDialogComponent, EditDialogMode } from '../edit-dialog.component'
import { Subject, takeUntil } from 'rxjs'
@Component({
selector: 'pngx-custom-field-edit-dialog',
@@ -14,8 +27,20 @@ import { EditDialogComponent, EditDialogMode } from '../edit-dialog.component'
})
export class CustomFieldEditDialogComponent
extends EditDialogComponent<CustomField>
implements OnInit
implements OnInit, AfterViewInit, OnDestroy
{
CustomFieldDataType = CustomFieldDataType
@ViewChildren('selectOption')
private selectOptionInputs: QueryList<ElementRef>
private unsubscribeNotifier: Subject<any> = new Subject()
private get selectOptions(): FormArray {
return (this.objectForm.controls.extra_data as FormGroup).controls
.select_options as FormArray
}
constructor(
service: CustomFieldsService,
activeModal: NgbActiveModal,
@@ -30,6 +55,25 @@ export class CustomFieldEditDialogComponent
if (this.typeFieldDisabled) {
this.objectForm.get('data_type').disable()
}
if (this.object?.data_type === CustomFieldDataType.Select) {
this.selectOptions.clear()
this.object.extra_data.select_options.forEach((option) =>
this.selectOptions.push(new FormControl(option))
)
}
}
ngAfterViewInit(): void {
this.selectOptionInputs.changes
.pipe(takeUntil(this.unsubscribeNotifier))
.subscribe(() => {
this.selectOptionInputs.last.nativeElement.focus()
})
}
ngOnDestroy(): void {
this.unsubscribeNotifier.next(true)
this.unsubscribeNotifier.complete()
}
getCreateTitle() {
@@ -44,6 +88,10 @@ export class CustomFieldEditDialogComponent
return new FormGroup({
name: new FormControl(null),
data_type: new FormControl(null),
extra_data: new FormGroup({
select_options: new FormArray([new FormControl(null)]),
default_currency: new FormControl(null),
}),
})
}
@@ -54,4 +102,12 @@ export class CustomFieldEditDialogComponent
get typeFieldDisabled(): boolean {
return this.dialogMode === EditDialogMode.EDIT
}
public addSelectOption() {
this.selectOptions.push(new FormControl(''))
}
public removeSelectOption(index: number) {
this.selectOptions.removeAt(index)
}
}

View File

@@ -10,7 +10,7 @@
<div class="modal-body">
<div class="col">
<pngx-input-text i18n-title title="Name" formControlName="name" [error]="error?.name"></pngx-input-text>
<pngx-input-text i18n-title title="Name" formControlName="name" [error]="error?.name" autocomplete="off"></pngx-input-text>
<pngx-input-select i18n-title title="Matching algorithm" [items]="getMatchingAlgorithms()" formControlName="matching_algorithm"></pngx-input-select>
@if (patternRequired) {
<pngx-input-text i18n-title title="Matching pattern" formControlName="match" [error]="error?.match"></pngx-input-text>

View File

@@ -1,4 +1,4 @@
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import { ComponentFixture, TestBed } from '@angular/core/testing'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { NgbActiveModal, NgbModule } from '@ng-bootstrap/ng-bootstrap'
@@ -11,6 +11,7 @@ import { SelectComponent } from '../../input/select/select.component'
import { TextComponent } from '../../input/text/text.component'
import { EditDialogMode } from '../edit-dialog.component'
import { DocumentTypeEditDialogComponent } from './document-type-edit-dialog.component'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
describe('DocumentTypeEditDialogComponent', () => {
let component: DocumentTypeEditDialogComponent
@@ -27,13 +28,11 @@ describe('DocumentTypeEditDialogComponent', () => {
TextComponent,
PermissionsFormComponent,
],
providers: [NgbActiveModal],
imports: [
HttpClientTestingModule,
FormsModule,
ReactiveFormsModule,
NgSelectModule,
NgbModule,
imports: [FormsModule, ReactiveFormsModule, NgSelectModule, NgbModule],
providers: [
NgbActiveModal,
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
}).compileComponents()

View File

@@ -1,6 +1,6 @@
import {
HttpTestingController,
HttpClientTestingModule,
provideHttpClientTesting,
} from '@angular/common/http/testing'
import { Component } from '@angular/core'
import {
@@ -30,6 +30,7 @@ import { UserService } from 'src/app/services/rest/user.service'
import { SettingsService } from 'src/app/services/settings.service'
import { environment } from 'src/environments/environment'
import { EditDialogComponent, EditDialogMode } from './edit-dialog.component'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
@Component({
template: `
@@ -96,6 +97,7 @@ describe('EditDialogComponent', () => {
beforeEach(async () => {
TestBed.configureTestingModule({
declarations: [TestComponent],
imports: [FormsModule, ReactiveFormsModule],
providers: [
NgbActiveModal,
{
@@ -114,8 +116,9 @@ describe('EditDialogComponent', () => {
},
SettingsService,
TagService,
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
imports: [HttpClientTestingModule, FormsModule, ReactiveFormsModule],
}).compileComponents()
tagService = TestBed.inject(TagService)

View File

@@ -1,4 +1,4 @@
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import { ComponentFixture, TestBed } from '@angular/core/testing'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { NgbActiveModal, NgbModule } from '@ng-bootstrap/ng-bootstrap'
@@ -12,6 +12,8 @@ import { TextComponent } from '../../input/text/text.component'
import { PermissionsSelectComponent } from '../../permissions-select/permissions-select.component'
import { EditDialogMode } from '../edit-dialog.component'
import { GroupEditDialogComponent } from './group-edit-dialog.component'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
describe('GroupEditDialogComponent', () => {
let component: GroupEditDialogComponent
@@ -29,13 +31,17 @@ describe('GroupEditDialogComponent', () => {
PermissionsFormComponent,
PermissionsSelectComponent,
],
providers: [NgbActiveModal],
imports: [
HttpClientTestingModule,
FormsModule,
ReactiveFormsModule,
NgSelectModule,
NgbModule,
NgxBootstrapIconsModule.pick(allIcons),
],
providers: [
NgbActiveModal,
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
}).compileComponents()

View File

@@ -1,6 +1,6 @@
import {
HttpTestingController,
HttpClientTestingModule,
provideHttpClientTesting,
} from '@angular/common/http/testing'
import {
ComponentFixture,
@@ -23,6 +23,7 @@ import { SelectComponent } from '../../input/select/select.component'
import { TextComponent } from '../../input/text/text.component'
import { EditDialogMode } from '../edit-dialog.component'
import { MailAccountEditDialogComponent } from './mail-account-edit-dialog.component'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
describe('MailAccountEditDialogComponent', () => {
let component: MailAccountEditDialogComponent
@@ -42,13 +43,11 @@ describe('MailAccountEditDialogComponent', () => {
PermissionsFormComponent,
PasswordComponent,
],
providers: [NgbActiveModal],
imports: [
HttpClientTestingModule,
FormsModule,
ReactiveFormsModule,
NgSelectModule,
NgbModule,
imports: [FormsModule, ReactiveFormsModule, NgSelectModule, NgbModule],
providers: [
NgbActiveModal,
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
}).compileComponents()

View File

@@ -1,4 +1,4 @@
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import { ComponentFixture, TestBed } from '@angular/core/testing'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { NgbActiveModal, NgbModule } from '@ng-bootstrap/ng-bootstrap'
@@ -23,6 +23,7 @@ import { TagsComponent } from '../../input/tags/tags.component'
import { TextComponent } from '../../input/text/text.component'
import { EditDialogMode } from '../edit-dialog.component'
import { MailRuleEditDialogComponent } from './mail-rule-edit-dialog.component'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
describe('MailRuleEditDialogComponent', () => {
let component: MailRuleEditDialogComponent
@@ -43,6 +44,7 @@ describe('MailRuleEditDialogComponent', () => {
SafeHtmlPipe,
CheckComponent,
],
imports: [FormsModule, ReactiveFormsModule, NgSelectModule, NgbModule],
providers: [
NgbActiveModal,
{
@@ -63,13 +65,8 @@ describe('MailRuleEditDialogComponent', () => {
listAll: () => of([]),
},
},
],
imports: [
HttpClientTestingModule,
FormsModule,
ReactiveFormsModule,
NgSelectModule,
NgbModule,
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
}).compileComponents()

View File

@@ -1,4 +1,4 @@
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import { ComponentFixture, TestBed } from '@angular/core/testing'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { NgbActiveModal, NgbModule } from '@ng-bootstrap/ng-bootstrap'
@@ -12,6 +12,7 @@ import { SelectComponent } from '../../input/select/select.component'
import { TextComponent } from '../../input/text/text.component'
import { EditDialogMode } from '../edit-dialog.component'
import { StoragePathEditDialogComponent } from './storage-path-edit-dialog.component'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
describe('StoragePathEditDialogComponent', () => {
let component: StoragePathEditDialogComponent
@@ -29,13 +30,11 @@ describe('StoragePathEditDialogComponent', () => {
PermissionsFormComponent,
SafeHtmlPipe,
],
providers: [NgbActiveModal],
imports: [
HttpClientTestingModule,
FormsModule,
ReactiveFormsModule,
NgSelectModule,
NgbModule,
imports: [FormsModule, ReactiveFormsModule, NgSelectModule, NgbModule],
providers: [
NgbActiveModal,
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
}).compileComponents()

View File

@@ -1,4 +1,4 @@
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import { ComponentFixture, TestBed } from '@angular/core/testing'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { NgbActiveModal, NgbModule } from '@ng-bootstrap/ng-bootstrap'
@@ -14,6 +14,7 @@ import { TextComponent } from '../../input/text/text.component'
import { EditDialogMode } from '../edit-dialog.component'
import { TagEditDialogComponent } from './tag-edit-dialog.component'
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
describe('TagEditDialogComponent', () => {
let component: TagEditDialogComponent
@@ -32,15 +33,19 @@ describe('TagEditDialogComponent', () => {
ColorComponent,
CheckComponent,
],
providers: [NgbActiveModal, SettingsService],
imports: [
HttpClientTestingModule,
FormsModule,
ReactiveFormsModule,
NgSelectModule,
NgbModule,
NgxBootstrapIconsModule.pick(allIcons),
],
providers: [
NgbActiveModal,
SettingsService,
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
}).compileComponents()
fixture = TestBed.createComponent(TagEditDialogComponent)

View File

@@ -1,4 +1,4 @@
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import { ComponentFixture, TestBed } from '@angular/core/testing'
import {
FormsModule,
@@ -19,6 +19,8 @@ import { TextComponent } from '../../input/text/text.component'
import { PermissionsSelectComponent } from '../../permissions-select/permissions-select.component'
import { EditDialogMode } from '../edit-dialog.component'
import { UserEditDialogComponent } from './user-edit-dialog.component'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
describe('UserEditDialogComponent', () => {
let component: UserEditDialogComponent
@@ -37,6 +39,13 @@ describe('UserEditDialogComponent', () => {
PermissionsFormComponent,
PermissionsSelectComponent,
],
imports: [
FormsModule,
ReactiveFormsModule,
NgSelectModule,
NgbModule,
NgxBootstrapIconsModule.pick(allIcons),
],
providers: [
NgbActiveModal,
{
@@ -54,13 +63,8 @@ describe('UserEditDialogComponent', () => {
},
},
SettingsService,
],
imports: [
HttpClientTestingModule,
FormsModule,
ReactiveFormsModule,
NgSelectModule,
NgbModule,
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
}).compileComponents()

View File

@@ -140,7 +140,7 @@
</div>
@if (formGroup.get('type').value === WorkflowTriggerType.DocumentAdded || formGroup.get('type').value === WorkflowTriggerType.DocumentUpdated) {
<div class="col-md-6">
<pngx-input-tags [allowCreate]="false" i18n-title title="Has tags" formControlName="filter_has_tags"></pngx-input-tags>
<pngx-input-tags [allowCreate]="false" i18n-title title="Has any of tags" formControlName="filter_has_tags"></pngx-input-tags>
<pngx-input-select i18n-title title="Has correspondent" [items]="correspondents" [allowNull]="true" formControlName="filter_has_correspondent"></pngx-input-select>
<pngx-input-select i18n-title title="Has document type" [items]="documentTypes" [allowNull]="true" formControlName="filter_has_document_type"></pngx-input-select>
</div>

View File

@@ -1,4 +1,4 @@
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import { ComponentFixture, TestBed } from '@angular/core/testing'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { NgbActiveModal, NgbModule } from '@ng-bootstrap/ng-bootstrap'
@@ -39,6 +39,7 @@ import {
} from 'src/app/data/workflow-action'
import { MATCHING_ALGORITHMS, MATCH_AUTO } from 'src/app/data/matching-model'
import { ConfirmButtonComponent } from '../../confirm-button/confirm-button.component'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
const workflow: Workflow = {
name: 'Workflow 1',
@@ -88,6 +89,7 @@ describe('WorkflowEditDialogComponent', () => {
SafeHtmlPipe,
ConfirmButtonComponent,
],
imports: [FormsModule, ReactiveFormsModule, NgSelectModule, NgbModule],
providers: [
NgbActiveModal,
{
@@ -150,13 +152,8 @@ describe('WorkflowEditDialogComponent', () => {
}),
},
},
],
imports: [
HttpClientTestingModule,
FormsModule,
ReactiveFormsModule,
NgSelectModule,
NgbModule,
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
}).compileComponents()

View File

@@ -5,7 +5,7 @@ import {
ReactiveFormsModule,
} from '@angular/forms'
import { DateComponent } from './date.component'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import {
NgbDateParserFormatter,
NgbDatepickerModule,
@@ -13,6 +13,7 @@ import {
import { RouterTestingModule } from '@angular/router/testing'
import { LocalizedDateParserFormatter } from 'src/app/utils/ngb-date-parser-formatter'
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
describe('DateComponent', () => {
let component: DateComponent
@@ -22,19 +23,20 @@ describe('DateComponent', () => {
beforeEach(async () => {
TestBed.configureTestingModule({
declarations: [DateComponent],
imports: [
FormsModule,
ReactiveFormsModule,
NgbDatepickerModule,
RouterTestingModule,
NgxBootstrapIconsModule.pick(allIcons),
],
providers: [
{
provide: NgbDateParserFormatter,
useClass: LocalizedDateParserFormatter,
},
],
imports: [
FormsModule,
ReactiveFormsModule,
HttpClientTestingModule,
NgbDatepickerModule,
RouterTestingModule,
NgxBootstrapIconsModule.pick(allIcons),
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
}).compileComponents()

View File

@@ -1,4 +1,4 @@
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import { ComponentFixture, TestBed } from '@angular/core/testing'
import {
FormsModule,
@@ -10,6 +10,7 @@ import { of, throwError } from 'rxjs'
import { DocumentService } from 'src/app/services/rest/document.service'
import { DocumentLinkComponent } from './document-link.component'
import { FILTER_TITLE } from 'src/app/data/filter-rule-type'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
const documents = [
{
@@ -38,11 +39,10 @@ describe('DocumentLinkComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [DocumentLinkComponent],
imports: [
HttpClientTestingModule,
NgSelectModule,
FormsModule,
ReactiveFormsModule,
imports: [NgSelectModule, FormsModule, ReactiveFormsModule],
providers: [
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
})
documentService = TestBed.inject(DocumentService)

View File

@@ -13,10 +13,10 @@
}
</div>
</div>
<div class="d-flex flex-row mt-2 align-items-center bg-light p-2">
<div class="d-flex flex-row gap-2 w-100 mh-1" style="min-height: 1em;"
<div class="mt-2 align-items-center bg-light p-2">
<div class="d-flex flex-wrap flex-row gap-2 w-100"
cdkDropList #unselectedList="cdkDropList"
cdkDropListOrientation="horizontal"
cdkDropListOrientation="mixed"
(cdkDropListDropped)="drop($event)"
[cdkDropListConnectedTo]="[selectedList]">
@for (item of unselectedItems; track item.id) {

View File

@@ -1,7 +1,3 @@
.badge {
cursor: move;
}
.d-flex {
overflow-x: scroll;
}

View File

@@ -1,8 +1,9 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'
import { FileComponent } from './file.component'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
describe('FileComponent', () => {
let component: FileComponent
@@ -11,7 +12,11 @@ describe('FileComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [FileComponent],
imports: [FormsModule, ReactiveFormsModule, HttpClientTestingModule],
imports: [FormsModule, ReactiveFormsModule],
providers: [
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
}).compileComponents()
fixture = TestBed.createComponent(FileComponent)

View File

@@ -4,9 +4,10 @@ import {
NG_VALUE_ACCESSOR,
ReactiveFormsModule,
} from '@angular/forms'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import { CurrencyPipe } from '@angular/common'
import { MonetaryComponent } from './monetary.component'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
describe('MonetaryComponent', () => {
let component: MonetaryComponent
@@ -15,8 +16,12 @@ describe('MonetaryComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [MonetaryComponent],
providers: [CurrencyPipe],
imports: [FormsModule, ReactiveFormsModule, HttpClientTestingModule],
imports: [FormsModule, ReactiveFormsModule],
providers: [
CurrencyPipe,
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
}).compileComponents()
fixture = TestBed.createComponent(MonetaryComponent)
@@ -47,6 +52,11 @@ describe('MonetaryComponent', () => {
expect(component.defaultCurrencyCode).toEqual('BRL')
})
it('should support setting a default currency code', () => {
component.defaultCurrency = 'EUR'
expect(component.defaultCurrencyCode).toEqual('EUR')
})
it('should parse monetary value correctly', () => {
expect(component['parseMonetaryValue']('123.4')).toEqual('123.4')
expect(component['parseMonetaryValue']('123.4', true)).toEqual('123.40')

View File

@@ -1,4 +1,4 @@
import { Component, forwardRef, Inject, LOCALE_ID } from '@angular/core'
import { Component, forwardRef, Inject, Input, LOCALE_ID } from '@angular/core'
import { NG_VALUE_ACCESSOR } from '@angular/forms'
import { AbstractInputComponent } from '../abstract-input'
import { getLocaleCurrencyCode } from '@angular/common'
@@ -29,11 +29,16 @@ export class MonetaryComponent extends AbstractInputComponent<string> {
defaultCurrencyCode: string
@Input()
set defaultCurrency(currency: string) {
if (currency) this.defaultCurrencyCode = currency
}
constructor(@Inject(LOCALE_ID) currentLocale: string) {
super()
this.currency = this.defaultCurrencyCode =
getLocaleCurrencyCode(currentLocale)
this.defaultCurrency ?? getLocaleCurrencyCode(currentLocale)
}
writeValue(newValue: any): void {

View File

@@ -6,8 +6,9 @@ import {
} from '@angular/forms'
import { NumberComponent } from './number.component'
import { DocumentService } from 'src/app/services/rest/document.service'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import { of } from 'rxjs'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
describe('NumberComponent', () => {
let component: NumberComponent
@@ -18,8 +19,12 @@ describe('NumberComponent', () => {
beforeEach(async () => {
TestBed.configureTestingModule({
declarations: [NumberComponent],
providers: [DocumentService],
imports: [FormsModule, ReactiveFormsModule, HttpClientTestingModule],
imports: [FormsModule, ReactiveFormsModule],
providers: [
DocumentService,
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
}).compileComponents()
fixture = TestBed.createComponent(NumberComponent)

View File

@@ -9,8 +9,9 @@ import { SelectComponent } from '../../select/select.component'
import { NgbAccordionModule } from '@ng-bootstrap/ng-bootstrap'
import { PermissionsGroupComponent } from '../permissions-group/permissions-group.component'
import { PermissionsUserComponent } from '../permissions-user/permissions-user.component'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import { NgSelectModule } from '@ng-select/ng-select'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
describe('PermissionsFormComponent', () => {
let component: PermissionsFormComponent
@@ -24,14 +25,16 @@ describe('PermissionsFormComponent', () => {
PermissionsGroupComponent,
PermissionsUserComponent,
],
providers: [],
imports: [
FormsModule,
ReactiveFormsModule,
NgbAccordionModule,
HttpClientTestingModule,
NgSelectModule,
],
providers: [
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
}).compileComponents()
fixture = TestBed.createComponent(PermissionsFormComponent)

View File

@@ -5,10 +5,11 @@ import {
ReactiveFormsModule,
} from '@angular/forms'
import { PermissionsGroupComponent } from './permissions-group.component'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import { NgSelectModule } from '@ng-select/ng-select'
import { GroupService } from 'src/app/services/rest/group.service'
import { of } from 'rxjs'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
describe('PermissionsGroupComponent', () => {
let component: PermissionsGroupComponent
@@ -19,12 +20,11 @@ describe('PermissionsGroupComponent', () => {
beforeEach(async () => {
TestBed.configureTestingModule({
declarations: [PermissionsGroupComponent],
providers: [GroupService],
imports: [
FormsModule,
ReactiveFormsModule,
HttpClientTestingModule,
NgSelectModule,
imports: [FormsModule, ReactiveFormsModule, NgSelectModule],
providers: [
GroupService,
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
}).compileComponents()

View File

@@ -5,11 +5,12 @@ import {
ReactiveFormsModule,
} from '@angular/forms'
import { PermissionsUserComponent } from './permissions-user.component'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import { NgSelectModule } from '@ng-select/ng-select'
import { GroupService } from 'src/app/services/rest/group.service'
import { of } from 'rxjs'
import { UserService } from 'src/app/services/rest/user.service'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
describe('PermissionsUserComponent', () => {
let component: PermissionsUserComponent
@@ -20,12 +21,11 @@ describe('PermissionsUserComponent', () => {
beforeEach(async () => {
TestBed.configureTestingModule({
declarations: [PermissionsUserComponent],
providers: [UserService],
imports: [
FormsModule,
ReactiveFormsModule,
HttpClientTestingModule,
NgSelectModule,
imports: [FormsModule, ReactiveFormsModule, NgSelectModule],
providers: [
UserService,
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
}).compileComponents()

View File

@@ -132,4 +132,12 @@ describe('SelectComponent', () => {
const expectedTitle = `Filter documents with this ${component.title}`
expect(component.filterButtonTitle).toEqual(expectedTitle)
})
it('should support setting items as a plain array', () => {
component.itemsArray = ['foo', 'bar']
expect(component.items).toEqual([
{ id: 0, name: 'foo' },
{ id: 1, name: 'bar' },
])
})
})

View File

@@ -34,6 +34,11 @@ export class SelectComponent extends AbstractInputComponent<number> {
if (items && this.value) this.checkForPrivateItems(this.value)
}
@Input()
set itemsArray(items: any[]) {
this._items = items.map((item, index) => ({ id: index, name: item }))
}
writeValue(newValue: any): void {
if (newValue && this._items) {
this.checkForPrivateItems(newValue)

View File

@@ -32,7 +32,7 @@
</div>
</ng-template>
</ng-select>
@if (allowCreate) {
@if (allowCreate && !hideAddButton) {
<button class="btn btn-outline-secondary" type="button" (click)="createTag()" [disabled]="disabled">
<i-bs width="1.2em" height="1.2em" name="plus"></i-bs>
</button>
@@ -49,7 +49,7 @@
@if (getSuggestions().length > 0) {
<small class="position-absolute top-100">
<span i18n>Suggestions:</span>&nbsp;
@for (tag of getSuggestions(); track tag) {
@for (tag of getSuggestions(); track tag.id) {
<a (click)="addTag(tag.id)" [routerLink]="[]">{{tag?.name}}</a>&nbsp;
}
</small>

View File

@@ -12,7 +12,7 @@ import {
} from 'src/app/data/matching-model'
import { NgSelectModule } from '@ng-select/ng-select'
import { RouterTestingModule } from '@angular/router/testing'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import { of } from 'rxjs'
import { TagService } from 'src/app/services/rest/tag.service'
import {
@@ -31,6 +31,7 @@ import { PermissionsFormComponent } from '../permissions/permissions-form/permis
import { SelectComponent } from '../select/select.component'
import { SettingsService } from 'src/app/services/settings.service'
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
const tags: Tag[] = [
{
@@ -74,6 +75,16 @@ describe('TagsComponent', () => {
ColorComponent,
CheckComponent,
],
imports: [
FormsModule,
ReactiveFormsModule,
NgSelectModule,
RouterTestingModule,
NgbModalModule,
NgbAccordionModule,
NgbPopoverModule,
NgxBootstrapIconsModule.pick(allIcons),
],
providers: [
{
provide: TagService,
@@ -90,17 +101,8 @@ describe('TagsComponent', () => {
}),
},
},
],
imports: [
FormsModule,
ReactiveFormsModule,
NgSelectModule,
RouterTestingModule,
HttpClientTestingModule,
NgbModalModule,
NgbAccordionModule,
NgbPopoverModule,
NgxBootstrapIconsModule.pick(allIcons),
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
}).compileComponents()

View File

@@ -74,6 +74,9 @@ export class TagsComponent implements OnInit, ControlValueAccessor {
@Input()
allowCreate: boolean = true
@Input()
hideAddButton: boolean = false
@Input()
showFilter: boolean = false

View File

@@ -11,7 +11,7 @@
}
</div>
<div class="position-relative" [class.col-md-9]="horizontal">
<input #inputField type="text" class="form-control" [class.is-invalid]="error" [id]="inputId" [(ngModel)]="value" (change)="onChange(value)" [disabled]="disabled" [autocomplete]="autocomplete">
<input #inputField type="text" class="form-control" [class.is-invalid]="error" [id]="inputId" [(ngModel)]="value" (change)="onChange(value)" [disabled]="disabled" [autocomplete]="autocomplete" [placeholder]="placeholder">
@if (hint) {
<small class="form-text text-muted" [innerHTML]="hint | safeHtml"></small>
}

View File

@@ -18,6 +18,9 @@ export class TextComponent extends AbstractInputComponent<string> {
@Input()
autocomplete: string
@Input()
placeholder: string = ''
constructor() {
super()
}

View File

@@ -2,9 +2,10 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'
import { LogoComponent } from './logo.component'
import { By } from '@angular/platform-browser'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import { SettingsService } from 'src/app/services/settings.service'
import { SETTINGS_KEYS } from 'src/app/data/ui-settings'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
describe('LogoComponent', () => {
let component: LogoComponent
@@ -14,7 +15,11 @@ describe('LogoComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [LogoComponent],
imports: [HttpClientTestingModule],
imports: [],
providers: [
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
],
})
settingsService = TestBed.inject(SettingsService)
fixture = TestBed.createComponent(LogoComponent)

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