mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-07-16 17:25:11 -05:00
Compare commits
61 Commits
d960aa2699
...
3c75deed80
Author | SHA1 | Date | |
---|---|---|---|
![]() |
3c75deed80 | ||
![]() |
d05343c927 | ||
![]() |
e7972b7eaf | ||
![]() |
75a091cc0d | ||
![]() |
dca74803fd | ||
![]() |
3cf3d868d0 | ||
![]() |
bf4fc6604a | ||
![]() |
e8c1eb86fa | ||
![]() |
c3dad3cf69 | ||
![]() |
811bd66088 | ||
![]() |
feb320cae9 | ||
![]() |
9178af5fb2 | ||
![]() |
850444c2fc | ||
![]() |
90baba2cec | ||
![]() |
9889c59d3d | ||
![]() |
3d2a3ede71 | ||
![]() |
bc019fab96 | ||
![]() |
1cd21d0f38 | ||
![]() |
f940ed0b7b | ||
![]() |
3180ccf4cb | ||
![]() |
43abb0541b | ||
![]() |
a3a405354f | ||
![]() |
09e98d600e | ||
![]() |
01a39b9bb4 | ||
![]() |
3b0b40f071 | ||
![]() |
6dce83865f | ||
![]() |
18252a19d7 | ||
![]() |
733a9674d6 | ||
![]() |
f3b6e15321 | ||
![]() |
6591d5da63 | ||
![]() |
c974dc9400 | ||
![]() |
1671d49d44 | ||
![]() |
6b248ef140 | ||
![]() |
735681d294 | ||
![]() |
a9085c65c5 | ||
![]() |
e312425b1c | ||
![]() |
13fe064f6e | ||
![]() |
958f98d7e5 | ||
![]() |
dfad3c4d8e | ||
![]() |
37267f3f04 | ||
![]() |
b34538d991 | ||
![]() |
fc97bd1315 | ||
![]() |
dbf3721ec2 | ||
![]() |
59afbe09b1 | ||
![]() |
bfeaa1b119 | ||
![]() |
e1c3124698 | ||
![]() |
f2e22e103b | ||
![]() |
dda94f013e | ||
![]() |
caf00e7ead | ||
![]() |
f214440d2e | ||
![]() |
240c9ac511 | ||
![]() |
a2c9bc346a | ||
![]() |
b1cbb1c73a | ||
![]() |
434b1e3245 | ||
![]() |
497fdcaf4e | ||
![]() |
52b95f2b62 | ||
![]() |
83391af866 | ||
![]() |
0a1786f39b | ||
![]() |
3b069ac034 | ||
![]() |
07882b918b | ||
![]() |
cc5ba71f06 |
@ -20,7 +20,6 @@
|
|||||||
#
|
#
|
||||||
# This file is intended only to be used through VSCOde devcontainers. See README.md
|
# This file is intended only to be used through VSCOde devcontainers. See README.md
|
||||||
# in the folder .devcontainer.
|
# in the folder .devcontainer.
|
||||||
|
|
||||||
services:
|
services:
|
||||||
broker:
|
broker:
|
||||||
image: docker.io/library/redis:7
|
image: docker.io/library/redis:7
|
||||||
|
55
.github/DISCUSSION_TEMPLATE/support.yml
vendored
Normal file
55
.github/DISCUSSION_TEMPLATE/support.yml
vendored
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
title: "[Support] "
|
||||||
|
body:
|
||||||
|
- type: textarea
|
||||||
|
id: description
|
||||||
|
attributes:
|
||||||
|
label: What's your question or issue?
|
||||||
|
description: Provide a clear and concise description of what you're trying to do, and what's going wrong.
|
||||||
|
placeholder: |
|
||||||
|
I'm trying to...
|
||||||
|
|
||||||
|
[Include screenshots if helpful]
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: steps
|
||||||
|
attributes:
|
||||||
|
label: What have you tried?
|
||||||
|
description: Describe any steps you've already taken to troubleshoot or solve the issue.
|
||||||
|
placeholder: |
|
||||||
|
- I checked the logs and saw...
|
||||||
|
- I followed the install guide and tried...
|
||||||
|
- type: input
|
||||||
|
id: version
|
||||||
|
attributes:
|
||||||
|
label: Paperless-ngx version
|
||||||
|
placeholder: e.g. 1.14.0
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: host-os
|
||||||
|
attributes:
|
||||||
|
label: Host OS
|
||||||
|
description: Include architecture if relevant.
|
||||||
|
placeholder: e.g. Ubuntu 22.04 / Raspberry Pi arm64
|
||||||
|
- type: dropdown
|
||||||
|
id: install-method
|
||||||
|
attributes:
|
||||||
|
label: Installation method
|
||||||
|
options:
|
||||||
|
- Docker - official image
|
||||||
|
- Docker - linuxserver.io image
|
||||||
|
- Bare metal
|
||||||
|
- Other (please describe above)
|
||||||
|
- type: textarea
|
||||||
|
id: system-status
|
||||||
|
attributes:
|
||||||
|
label: System status
|
||||||
|
description: If available, copy & paste the system status output from Settings > System Status > Copy
|
||||||
|
render: json
|
||||||
|
- type: textarea
|
||||||
|
id: logs
|
||||||
|
attributes:
|
||||||
|
label: Relevant logs or output
|
||||||
|
description: If you have logs, errors that might help, paste it here.
|
||||||
|
render: bash
|
1
.github/dependabot.yml
vendored
1
.github/dependabot.yml
vendored
@ -1,6 +1,5 @@
|
|||||||
# Please see the documentation for all configuration options:
|
# Please see the documentation for all configuration options:
|
||||||
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||||
|
|
||||||
version: 2
|
version: 2
|
||||||
# Required for uv support for now
|
# Required for uv support for now
|
||||||
enable-beta-ecosystems: true
|
enable-beta-ecosystems: true
|
||||||
|
1
.github/workflows/cleanup-tags.yml
vendored
1
.github/workflows/cleanup-tags.yml
vendored
@ -4,7 +4,6 @@
|
|||||||
# Requires a PAT with the correct scope set in the secrets.
|
# Requires a PAT with the correct scope set in the secrets.
|
||||||
#
|
#
|
||||||
# This workflow will not trigger runs on forked repos.
|
# This workflow will not trigger runs on forked repos.
|
||||||
|
|
||||||
name: Cleanup Image Tags
|
name: Cleanup Image Tags
|
||||||
on:
|
on:
|
||||||
delete:
|
delete:
|
||||||
|
2
.github/workflows/translate-strings.yml
vendored
2
.github/workflows/translate-strings.yml
vendored
@ -61,7 +61,7 @@ jobs:
|
|||||||
cd src-ui
|
cd src-ui
|
||||||
pnpm run ng extract-i18n
|
pnpm run ng extract-i18n
|
||||||
- name: Commit changes
|
- name: Commit changes
|
||||||
uses: stefanzweifel/git-auto-commit-action@v5
|
uses: stefanzweifel/git-auto-commit-action@v6
|
||||||
with:
|
with:
|
||||||
file_pattern: 'src-ui/messages.xlf src/locale/en_US/LC_MESSAGES/django.po'
|
file_pattern: 'src-ui/messages.xlf src/locale/en_US/LC_MESSAGES/django.po'
|
||||||
commit_message: "Auto translate strings"
|
commit_message: "Auto translate strings"
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
# This file configures pre-commit hooks.
|
# This file configures pre-commit hooks.
|
||||||
# See https://pre-commit.com/ for general information
|
# See https://pre-commit.com/ for general information
|
||||||
# See https://pre-commit.com/hooks.html for a listing of possible hooks
|
# See https://pre-commit.com/hooks.html for a listing of possible hooks
|
||||||
|
|
||||||
repos:
|
repos:
|
||||||
# General hooks
|
# General hooks
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
@ -29,7 +28,7 @@ repos:
|
|||||||
- id: check-case-conflict
|
- id: check-case-conflict
|
||||||
- id: detect-private-key
|
- id: detect-private-key
|
||||||
- repo: https://github.com/codespell-project/codespell
|
- repo: https://github.com/codespell-project/codespell
|
||||||
rev: v2.4.0
|
rev: v2.4.1
|
||||||
hooks:
|
hooks:
|
||||||
- id: codespell
|
- id: codespell
|
||||||
exclude: "(^src-ui/src/locale/)|(^src-ui/pnpm-lock.yaml)|(^src-ui/e2e/)|(^src/paperless_mail/tests/samples/)"
|
exclude: "(^src-ui/src/locale/)|(^src-ui/pnpm-lock.yaml)|(^src-ui/e2e/)|(^src/paperless_mail/tests/samples/)"
|
||||||
@ -38,7 +37,7 @@ repos:
|
|||||||
- json
|
- json
|
||||||
# See https://github.com/prettier/prettier/issues/15742 for the fork reason
|
# See https://github.com/prettier/prettier/issues/15742 for the fork reason
|
||||||
- repo: https://github.com/rbubley/mirrors-prettier
|
- repo: https://github.com/rbubley/mirrors-prettier
|
||||||
rev: 'v3.3.3'
|
rev: 'v3.6.2'
|
||||||
hooks:
|
hooks:
|
||||||
- id: prettier
|
- id: prettier
|
||||||
types_or:
|
types_or:
|
||||||
@ -50,17 +49,17 @@ repos:
|
|||||||
- 'prettier-plugin-organize-imports@4.1.0'
|
- 'prettier-plugin-organize-imports@4.1.0'
|
||||||
# Python hooks
|
# Python hooks
|
||||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||||
rev: v0.9.9
|
rev: v0.12.2
|
||||||
hooks:
|
hooks:
|
||||||
- id: ruff
|
- id: ruff
|
||||||
- id: ruff-format
|
- id: ruff-format
|
||||||
- repo: https://github.com/tox-dev/pyproject-fmt
|
- repo: https://github.com/tox-dev/pyproject-fmt
|
||||||
rev: "v2.5.1"
|
rev: "v2.6.0"
|
||||||
hooks:
|
hooks:
|
||||||
- id: pyproject-fmt
|
- id: pyproject-fmt
|
||||||
# Dockerfile hooks
|
# Dockerfile hooks
|
||||||
- repo: https://github.com/AleksaC/hadolint-py
|
- repo: https://github.com/AleksaC/hadolint-py
|
||||||
rev: v2.12.0.3
|
rev: v2.12.1b3
|
||||||
hooks:
|
hooks:
|
||||||
- id: hadolint
|
- id: hadolint
|
||||||
# Shell script hooks
|
# Shell script hooks
|
||||||
@ -77,7 +76,7 @@ repos:
|
|||||||
hooks:
|
hooks:
|
||||||
- id: shellcheck
|
- id: shellcheck
|
||||||
- repo: https://github.com/google/yamlfmt
|
- repo: https://github.com/google/yamlfmt
|
||||||
rev: v0.14.0
|
rev: v0.17.2
|
||||||
hooks:
|
hooks:
|
||||||
- id: yamlfmt
|
- id: yamlfmt
|
||||||
exclude: "^src-ui/pnpm-lock.yaml"
|
exclude: "^src-ui/pnpm-lock.yaml"
|
||||||
|
@ -21,7 +21,7 @@ ARG PNGX_TAG_VERSION=
|
|||||||
RUN set -eux && \
|
RUN set -eux && \
|
||||||
case "${PNGX_TAG_VERSION}" in \
|
case "${PNGX_TAG_VERSION}" in \
|
||||||
dev|beta|fix*|feature*) \
|
dev|beta|fix*|feature*) \
|
||||||
sed -i -E "s/version: '([0-9\.]+)'/version: '\1 #${PNGX_TAG_VERSION}'/g" /src/src-ui/src/environments/environment.prod.ts \
|
sed -i -E "s/tag: '([a-z\.]+)'/tag: '${PNGX_TAG_VERSION}'/g" /src/src-ui/src/environments/environment.prod.ts \
|
||||||
;; \
|
;; \
|
||||||
esac
|
esac
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ RUN set -eux \
|
|||||||
# Purpose: Installs s6-overlay and rootfs
|
# Purpose: Installs s6-overlay and rootfs
|
||||||
# Comments:
|
# Comments:
|
||||||
# - Don't leave anything extra in here either
|
# - Don't leave anything extra in here either
|
||||||
FROM ghcr.io/astral-sh/uv:0.7.9-python3.12-bookworm-slim AS s6-overlay-base
|
FROM ghcr.io/astral-sh/uv:0.7.19-python3.12-bookworm-slim AS s6-overlay-base
|
||||||
|
|
||||||
WORKDIR /usr/src/s6
|
WORKDIR /usr/src/s6
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
# and Tika containers for a more end to end test of the Tika related functionality
|
# and Tika containers for a more end to end test of the Tika related functionality
|
||||||
# Can be used locally or by the CI to start the necessary containers with the
|
# Can be used locally or by the CI to start the necessary containers with the
|
||||||
# correct networking for the tests
|
# correct networking for the tests
|
||||||
|
|
||||||
services:
|
services:
|
||||||
gotenberg:
|
gotenberg:
|
||||||
image: docker.io/gotenberg/gotenberg:8.20
|
image: docker.io/gotenberg/gotenberg:8.20
|
||||||
|
@ -25,11 +25,9 @@
|
|||||||
# and '.env' into a folder.
|
# and '.env' into a folder.
|
||||||
# - Run 'docker compose pull'.
|
# - Run 'docker compose pull'.
|
||||||
# - Run 'docker compose up -d'.
|
# - Run 'docker compose up -d'.
|
||||||
|
|
||||||
#
|
#
|
||||||
# For more extensive installation and update instructions, refer to the
|
# For more extensive installation and update instructions, refer to the
|
||||||
# documentation.
|
# documentation.
|
||||||
|
|
||||||
services:
|
services:
|
||||||
broker:
|
broker:
|
||||||
image: docker.io/library/redis:8
|
image: docker.io/library/redis:8
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
#
|
#
|
||||||
# For more extensive installation and update instructions, refer to the
|
# For more extensive installation and update instructions, refer to the
|
||||||
# documentation.
|
# documentation.
|
||||||
|
|
||||||
services:
|
services:
|
||||||
broker:
|
broker:
|
||||||
image: docker.io/library/redis:8
|
image: docker.io/library/redis:8
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
#
|
#
|
||||||
# For more extensive installation and update instructions, refer to the
|
# For more extensive installation and update instructions, refer to the
|
||||||
# documentation.
|
# documentation.
|
||||||
|
|
||||||
services:
|
services:
|
||||||
broker:
|
broker:
|
||||||
image: docker.io/library/redis:8
|
image: docker.io/library/redis:8
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
#
|
#
|
||||||
# For more extensive installation and update instructions, refer to the
|
# For more extensive installation and update instructions, refer to the
|
||||||
# documentation.
|
# documentation.
|
||||||
|
|
||||||
services:
|
services:
|
||||||
broker:
|
broker:
|
||||||
image: docker.io/library/redis:8
|
image: docker.io/library/redis:8
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
#
|
#
|
||||||
# For more extensive installation and update instructions, refer to the
|
# For more extensive installation and update instructions, refer to the
|
||||||
# documentation.
|
# documentation.
|
||||||
|
|
||||||
services:
|
services:
|
||||||
broker:
|
broker:
|
||||||
image: docker.io/library/redis:8
|
image: docker.io/library/redis:8
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
#
|
#
|
||||||
# For more extensive installation and update instructions, refer to the
|
# For more extensive installation and update instructions, refer to the
|
||||||
# documentation.
|
# documentation.
|
||||||
|
|
||||||
services:
|
services:
|
||||||
broker:
|
broker:
|
||||||
image: docker.io/library/redis:8
|
image: docker.io/library/redis:8
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
#
|
#
|
||||||
# For more extensive installation and update instructions, refer to the
|
# For more extensive installation and update instructions, refer to the
|
||||||
# documentation.
|
# documentation.
|
||||||
|
|
||||||
services:
|
services:
|
||||||
broker:
|
broker:
|
||||||
image: docker.io/library/redis:8
|
image: docker.io/library/redis:8
|
||||||
|
@ -13,8 +13,8 @@ echo $(date +%s) > /var/run/s6/container_environment/PAPERLESS_START_TIME_S
|
|||||||
# Check if we're starting as a non-root user
|
# Check if we're starting as a non-root user
|
||||||
if [ "$(id --user)" != "0" ]; then
|
if [ "$(id --user)" != "0" ]; then
|
||||||
printf "true" > /var/run/s6/container_environment/USER_IS_NON_ROOT
|
printf "true" > /var/run/s6/container_environment/USER_IS_NON_ROOT
|
||||||
echo "${log_prefix} paperless-ngx docker container running under a user ($(id --user):$(id --group))"
|
echo "${log_prefix} paperless-ngx docker container running under a user ($(id --user):$(id --group))"
|
||||||
else
|
else
|
||||||
printf "/usr/src/paperless" > /var/run/s6/container_environment/HOME
|
printf "/usr/src/paperless" > /var/run/s6/container_environment/HOME
|
||||||
echo "${log_prefix} paperless-ngx docker container starting init as root"
|
echo "${log_prefix} paperless-ngx docker container starting init as root"
|
||||||
fi
|
fi
|
||||||
|
@ -457,6 +457,22 @@ of the index and usually makes queries faster and also ensures that the
|
|||||||
autocompletion works properly. This command is regularly invoked by the
|
autocompletion works properly. This command is regularly invoked by the
|
||||||
task scheduler.
|
task scheduler.
|
||||||
|
|
||||||
|
### Clearing the database read cache
|
||||||
|
|
||||||
|
If the database read cache is enabled, **you must run this command** after making any changes to the database outside the application context.
|
||||||
|
This includes operations such as restoring a database backup or executing SQL statements like UPDATE, INSERT, DELETE, ALTER, CREATE, or DROP.
|
||||||
|
|
||||||
|
Failing to invalidate the cache after such modifications can lead to stale data being served from the cache, and **may cause data corruption** or inconsistent behavior in the application.
|
||||||
|
|
||||||
|
Use the following management command to clear the cache:
|
||||||
|
|
||||||
|
```
|
||||||
|
invalidate_cachalot
|
||||||
|
```
|
||||||
|
|
||||||
|
!!! info
|
||||||
|
The database read cache is based on Django-Cachalot. You can refer to their [documentation](https://django-cachalot.readthedocs.io/en/latest/quickstart.html#manage-py-command).
|
||||||
|
|
||||||
### Managing filenames {#renamer}
|
### Managing filenames {#renamer}
|
||||||
|
|
||||||
If you use paperless' feature to
|
If you use paperless' feature to
|
||||||
|
@ -1,5 +1,64 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## paperless-ngx 2.17.1
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- Fix: correct PAPERLESS_EMPTY_TRASH_DIR to Path [@shamoon](https://github.com/shamoon) ([#10227](https://github.com/paperless-ngx/paperless-ngx/pull/10227))
|
||||||
|
|
||||||
|
### All App Changes
|
||||||
|
|
||||||
|
- Fix: correct PAPERLESS_EMPTY_TRASH_DIR to Path [@shamoon](https://github.com/shamoon) ([#10227](https://github.com/paperless-ngx/paperless-ngx/pull/10227))
|
||||||
|
|
||||||
|
## paperless-ngx 2.17.0
|
||||||
|
|
||||||
|
### Breaking Changes
|
||||||
|
|
||||||
|
- Fix: restore expected pre-2.16 scheduled workflow offset behavior [@shamoon](https://github.com/shamoon) ([#10218](https://github.com/paperless-ngx/paperless-ngx/pull/10218))
|
||||||
|
|
||||||
|
### Features / Enhancements
|
||||||
|
|
||||||
|
- QoL: log version at startup, show backend vs frontend mismatch in system status [@shamoon](https://github.com/shamoon) ([#10214](https://github.com/paperless-ngx/paperless-ngx/pull/10214))
|
||||||
|
- Feature: add Persian translation [@shamoon](https://github.com/shamoon) ([#10183](https://github.com/paperless-ngx/paperless-ngx/pull/10183))
|
||||||
|
- Enhancement: support import of zipped export [@kaerbr](https://github.com/kaerbr) ([#10073](https://github.com/paperless-ngx/paperless-ngx/pull/10073))
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- Fix: more api fixes [@shamoon](https://github.com/shamoon) ([#10204](https://github.com/paperless-ngx/paperless-ngx/pull/10204))
|
||||||
|
- Fix: restore expected pre-2.16 scheduled workflow offset behavior [@shamoon](https://github.com/shamoon) ([#10218](https://github.com/paperless-ngx/paperless-ngx/pull/10218))
|
||||||
|
- Fix: fix some API crashes [@shamoon](https://github.com/shamoon) ([#10196](https://github.com/paperless-ngx/paperless-ngx/pull/10196))
|
||||||
|
- Fix: remove duplicate base path in websocket urls [@robertmx](https://github.com/robertmx) ([#10194](https://github.com/paperless-ngx/paperless-ngx/pull/10194))
|
||||||
|
- Fix: use hard delete for custom fields with workflow removal [@shamoon](https://github.com/shamoon) ([#10191](https://github.com/paperless-ngx/paperless-ngx/pull/10191))
|
||||||
|
- Fix: fix mail account test api schema [@shamoon](https://github.com/shamoon) ([#10164](https://github.com/paperless-ngx/paperless-ngx/pull/10164))
|
||||||
|
- Fix: correct api schema for mail_account process [@shamoon](https://github.com/shamoon) ([#10157](https://github.com/paperless-ngx/paperless-ngx/pull/10157))
|
||||||
|
- Fix: correct api schema for next_asn [@shamoon](https://github.com/shamoon) ([#10151](https://github.com/paperless-ngx/paperless-ngx/pull/10151))
|
||||||
|
- Fix: fix email and notes endpoints api spec [@shamoon](https://github.com/shamoon) ([#10148](https://github.com/paperless-ngx/paperless-ngx/pull/10148))
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
|
||||||
|
- Chore: bump angular/common to 19.12.14 [@shamoon](https://github.com/shamoon) ([#10212](https://github.com/paperless-ngx/paperless-ngx/pull/10212))
|
||||||
|
|
||||||
|
### All App Changes
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>14 changes</summary>
|
||||||
|
|
||||||
|
- QoL: log version at startup, show backend vs frontend mismatch in system status [@shamoon](https://github.com/shamoon) ([#10214](https://github.com/paperless-ngx/paperless-ngx/pull/10214))
|
||||||
|
- Fix: more api fixes [@shamoon](https://github.com/shamoon) ([#10204](https://github.com/paperless-ngx/paperless-ngx/pull/10204))
|
||||||
|
- Fix: restore expected pre-2.16 scheduled workflow offset behavior [@shamoon](https://github.com/shamoon) ([#10218](https://github.com/paperless-ngx/paperless-ngx/pull/10218))
|
||||||
|
- Chore: switch from os.path to pathlib.Path [@gothicVI](https://github.com/gothicVI) ([#9933](https://github.com/paperless-ngx/paperless-ngx/pull/9933))
|
||||||
|
- Chore: bump angular/common to 19.12.14 [@shamoon](https://github.com/shamoon) ([#10212](https://github.com/paperless-ngx/paperless-ngx/pull/10212))
|
||||||
|
- Fix: fix some API crashes [@shamoon](https://github.com/shamoon) ([#10196](https://github.com/paperless-ngx/paperless-ngx/pull/10196))
|
||||||
|
- Fix: remove duplicate base path in websocket urls [@robertmx](https://github.com/robertmx) ([#10194](https://github.com/paperless-ngx/paperless-ngx/pull/10194))
|
||||||
|
- Fix: use hard delete for custom fields with workflow removal [@shamoon](https://github.com/shamoon) ([#10191](https://github.com/paperless-ngx/paperless-ngx/pull/10191))
|
||||||
|
- Feature: add Persian translation [@shamoon](https://github.com/shamoon) ([#10183](https://github.com/paperless-ngx/paperless-ngx/pull/10183))
|
||||||
|
- Enhancement: support import of zipped export [@kaerbr](https://github.com/kaerbr) ([#10073](https://github.com/paperless-ngx/paperless-ngx/pull/10073))
|
||||||
|
- Fix: fix mail account test api schema [@shamoon](https://github.com/shamoon) ([#10164](https://github.com/paperless-ngx/paperless-ngx/pull/10164))
|
||||||
|
- Fix: correct api schema for mail_account process [@shamoon](https://github.com/shamoon) ([#10157](https://github.com/paperless-ngx/paperless-ngx/pull/10157))
|
||||||
|
- Fix: correct api schema for next_asn [@shamoon](https://github.com/shamoon) ([#10151](https://github.com/paperless-ngx/paperless-ngx/pull/10151))
|
||||||
|
- Fix: fix email and notes endpoints api spec [@shamoon](https://github.com/shamoon) ([#10148](https://github.com/paperless-ngx/paperless-ngx/pull/10148))
|
||||||
|
</details>
|
||||||
|
|
||||||
## paperless-ngx 2.16.3
|
## paperless-ngx 2.16.3
|
||||||
|
|
||||||
### Features / Enhancements
|
### Features / Enhancements
|
||||||
@ -5948,7 +6007,6 @@ primarily.
|
|||||||
a very good job at ocr'ing a document with the default
|
a very good job at ocr'ing a document with the default
|
||||||
language. Certain language specifics such as umlauts may not get
|
language. Certain language specifics such as umlauts may not get
|
||||||
picked up properly.
|
picked up properly.
|
||||||
- `PAPERLESS_DEBUG` defaults to `false`.
|
|
||||||
- The presence of `PAPERLESS_DBHOST` now determines whether to use
|
- The presence of `PAPERLESS_DBHOST` now determines whether to use
|
||||||
PostgreSQL or SQLite.
|
PostgreSQL or SQLite.
|
||||||
- `PAPERLESS_OCR_THREADS` is gone and replaced with
|
- `PAPERLESS_OCR_THREADS` is gone and replaced with
|
||||||
|
@ -159,6 +159,41 @@ Available options are `postgresql` and `mariadb`.
|
|||||||
|
|
||||||
Defaults to unset, which uses Django’s built-in defaults.
|
Defaults to unset, which uses Django’s built-in defaults.
|
||||||
|
|
||||||
|
#### [`PAPERLESS_DB_READ_CACHE_ENABLED=<bool>`](#PAPERLESS_DB_READ_CACHE_ENABLED) {#PAPERLESS_DB_READ_CACHE_ENABLED}
|
||||||
|
|
||||||
|
: Caches the database read query results into Redis. This can significantly improve application response times by caching database queries, at the cost of slightly increased memory usage.
|
||||||
|
|
||||||
|
Defaults to `false`.
|
||||||
|
|
||||||
|
!!! danger
|
||||||
|
|
||||||
|
**Do not modify the database outside the application while it is running.**
|
||||||
|
This includes actions such as restoring a backup, upgrading the database, or performing manual inserts. All external modifications must be done **only when the application is stopped**.
|
||||||
|
After making any such changes, you **must invalidate the DB read cache** using the `invalidate_cachalot` management command.
|
||||||
|
|
||||||
|
#### [`PAPERLESS_READ_CACHE_TTL=<int>`](#PAPERLESS_READ_CACHE_TTL) {#PAPERLESS_READ_CACHE_TTL}
|
||||||
|
|
||||||
|
: Specifies how long (in seconds) read data should be cached.
|
||||||
|
|
||||||
|
Allowed values are between `1` (one second) and `31536000` (one year). Defaults to `3600` (one hour).
|
||||||
|
|
||||||
|
!!! warning
|
||||||
|
|
||||||
|
A high TTL increases memory usage over time. Memory may be used until end of TTL, even if the cache is invalidated with the `invalidate_cachalot` command.
|
||||||
|
|
||||||
|
In case of an out-of-memory (OOM) situation, Redis may stop accepting new data — including cache entries, scheduled tasks, and documents to consume.
|
||||||
|
If your system has limited RAM, consider configuring a dedicated Redis instance for the read cache, with a memory limit and the eviction policy set to `allkeys-lru`.
|
||||||
|
For more details, refer to the [Redis eviction policy documentation](https://redis.io/docs/latest/develop/reference/eviction/), and see the `PAPERLESS_READ_CACHE_REDIS_URL` setting to specify a separate Redis broker.
|
||||||
|
|
||||||
|
#### [`PAPERLESS_READ_CACHE_REDIS_URL=<url>`](#PAPERLESS_READ_CACHE_REDIS_URL) {#PAPERLESS_READ_CACHE_REDIS_URL}
|
||||||
|
|
||||||
|
: Defines the Redis instance used for the read cache.
|
||||||
|
|
||||||
|
Defaults to `None`.
|
||||||
|
|
||||||
|
!!! Note
|
||||||
|
If this value is not set, the same Redis instance used for scheduled tasks will be used for caching as well.
|
||||||
|
|
||||||
## Optional Services
|
## Optional Services
|
||||||
|
|
||||||
### Tika {#tika}
|
### Tika {#tika}
|
||||||
@ -968,6 +1003,22 @@ still perform some basic text pre-processing before matching.
|
|||||||
|
|
||||||
Defaults to 1.
|
Defaults to 1.
|
||||||
|
|
||||||
|
#### [`PAPERLESS_DATE_PARSER_LANGUAGES=<lang>`](#PAPERLESS_DATE_PARSER_LANGUAGES) {#PAPERLESS_DATE_PARSER_LANGUAGES}
|
||||||
|
|
||||||
|
Specifies which language Paperless should use when parsing dates from documents.
|
||||||
|
|
||||||
|
This should be a language code supported by the dateparser library,
|
||||||
|
for example: "en", or a combination such as "en+de".
|
||||||
|
Locales are also supported (e.g., "en-AU").
|
||||||
|
Multiple languages can be combined using "+", for example: "en+de" or "en-AU+de".
|
||||||
|
For valid values, refer to the list of supported languages and locales in the [dateparser documentation](https://dateparser.readthedocs.io/en/latest/supported_locales.html).
|
||||||
|
|
||||||
|
Set this to match the languages in which most of your documents are written.
|
||||||
|
If not set, Paperless will attempt to infer the language(s) from the OCR configuration (`PAPERLESS_OCR_LANGUAGE`).
|
||||||
|
|
||||||
|
!!! note
|
||||||
|
This format differs from the `PAPERLESS_OCR_LANGUAGE` setting, which uses ISO 639-2 codes (3 letters, e.g., "eng+deu" for Tesseract OCR).
|
||||||
|
|
||||||
#### [`PAPERLESS_EMAIL_TASK_CRON=<cron expression>`](#PAPERLESS_EMAIL_TASK_CRON) {#PAPERLESS_EMAIL_TASK_CRON}
|
#### [`PAPERLESS_EMAIL_TASK_CRON=<cron expression>`](#PAPERLESS_EMAIL_TASK_CRON) {#PAPERLESS_EMAIL_TASK_CRON}
|
||||||
|
|
||||||
: Configures the scheduled email fetching frequency. The value
|
: Configures the scheduled email fetching frequency. The value
|
||||||
|
@ -408,7 +408,7 @@ Currently, there are three events that correspond to workflow trigger 'types':
|
|||||||
tags, doc type, or correspondent.
|
tags, doc type, or correspondent.
|
||||||
4. **Scheduled**: a scheduled trigger that can be used to run workflows at a specific time. The date used can be either the document
|
4. **Scheduled**: a scheduled trigger that can be used to run workflows at a specific time. The date used can be either the document
|
||||||
added, created, updated date or you can specify a (date) custom field. You can also specify a day offset from the date (positive
|
added, created, updated date or you can specify a (date) custom field. You can also specify a day offset from the date (positive
|
||||||
offsets will trigger before the date, negative offsets will trigger after).
|
offsets will trigger after the date, negative offsets will trigger before).
|
||||||
|
|
||||||
The following flow diagram illustrates the three document trigger types:
|
The following flow diagram illustrates the three document trigger types:
|
||||||
|
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
# Have a look at the docs for documentation.
|
# Have a look at the docs for documentation.
|
||||||
# https://docs.paperless-ngx.com/configuration/
|
# https://docs.paperless-ngx.com/configuration/
|
||||||
|
|
||||||
# Debug. Only enable this for development.
|
|
||||||
|
|
||||||
#PAPERLESS_DEBUG=false
|
|
||||||
|
|
||||||
# Required services
|
# Required services
|
||||||
|
|
||||||
#PAPERLESS_REDIS=redis://localhost:6379
|
#PAPERLESS_REDIS=redis://localhost:6379
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "paperless-ngx"
|
name = "paperless-ngx"
|
||||||
version = "2.16.3"
|
version = "2.17.1"
|
||||||
description = "A community-supported supercharged version of paperless: scan, index and archive all your physical documents"
|
description = "A community-supported supercharged version of paperless: scan, index and archive all your physical documents"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.10"
|
requires-python = ">=3.10"
|
||||||
@ -27,6 +27,7 @@ dependencies = [
|
|||||||
"django~=5.1.7",
|
"django~=5.1.7",
|
||||||
"django-allauth[socialaccount,mfa]~=65.4.0",
|
"django-allauth[socialaccount,mfa]~=65.4.0",
|
||||||
"django-auditlog~=3.1.2",
|
"django-auditlog~=3.1.2",
|
||||||
|
"django-cachalot~=2.8.0",
|
||||||
"django-celery-results~=2.6.0",
|
"django-celery-results~=2.6.0",
|
||||||
"django-compression-middleware~=0.5.0",
|
"django-compression-middleware~=0.5.0",
|
||||||
"django-cors-headers~=4.7.0",
|
"django-cors-headers~=4.7.0",
|
||||||
@ -44,13 +45,13 @@ dependencies = [
|
|||||||
"flower~=2.0.1",
|
"flower~=2.0.1",
|
||||||
"gotenberg-client~=0.10.0",
|
"gotenberg-client~=0.10.0",
|
||||||
"httpx-oauth~=0.16",
|
"httpx-oauth~=0.16",
|
||||||
"imap-tools~=1.10.0",
|
"imap-tools~=1.11.0",
|
||||||
"inotifyrecursive~=0.3",
|
"inotifyrecursive~=0.3",
|
||||||
"jinja2~=3.1.5",
|
"jinja2~=3.1.5",
|
||||||
"langdetect~=1.0.9",
|
"langdetect~=1.0.9",
|
||||||
"nltk~=3.9.1",
|
"nltk~=3.9.1",
|
||||||
"ocrmypdf~=16.10.0",
|
"ocrmypdf~=16.10.0",
|
||||||
"pathvalidate~=3.2.3",
|
"pathvalidate~=3.3.1",
|
||||||
"pdf2image~=1.17.0",
|
"pdf2image~=1.17.0",
|
||||||
"python-dateutil~=2.9.0",
|
"python-dateutil~=2.9.0",
|
||||||
"python-dotenv~=1.1.0",
|
"python-dotenv~=1.1.0",
|
||||||
@ -60,7 +61,7 @@ dependencies = [
|
|||||||
"pyzbar~=0.1.9",
|
"pyzbar~=0.1.9",
|
||||||
"rapidfuzz~=3.13.0",
|
"rapidfuzz~=3.13.0",
|
||||||
"redis[hiredis]~=5.2.1",
|
"redis[hiredis]~=5.2.1",
|
||||||
"scikit-learn~=1.6.1",
|
"scikit-learn~=1.7.0",
|
||||||
"setproctitle~=1.3.4",
|
"setproctitle~=1.3.4",
|
||||||
"tika-client~=0.9.0",
|
"tika-client~=0.9.0",
|
||||||
"tqdm~=4.67.1",
|
"tqdm~=4.67.1",
|
||||||
@ -74,12 +75,12 @@ optional-dependencies.mariadb = [
|
|||||||
"mysqlclient~=2.2.7",
|
"mysqlclient~=2.2.7",
|
||||||
]
|
]
|
||||||
optional-dependencies.postgres = [
|
optional-dependencies.postgres = [
|
||||||
"psycopg[c]==3.2.5",
|
"psycopg[c]==3.2.9",
|
||||||
# Direct dependency for proper resolution of the pre-built wheels
|
# Direct dependency for proper resolution of the pre-built wheels
|
||||||
"psycopg-c==3.2.5",
|
"psycopg-c==3.2.9",
|
||||||
]
|
]
|
||||||
optional-dependencies.webserver = [
|
optional-dependencies.webserver = [
|
||||||
"granian[uvloop]~=2.3.2",
|
"granian[uvloop]~=2.4.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[dependency-groups]
|
[dependency-groups]
|
||||||
@ -113,7 +114,7 @@ testing = [
|
|||||||
lint = [
|
lint = [
|
||||||
"pre-commit~=4.1.0",
|
"pre-commit~=4.1.0",
|
||||||
"pre-commit-uv~=4.1.3",
|
"pre-commit-uv~=4.1.3",
|
||||||
"ruff~=0.9.9",
|
"ruff~=0.12.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
typing = [
|
typing = [
|
||||||
@ -173,6 +174,7 @@ lint.extend-select = [
|
|||||||
]
|
]
|
||||||
lint.ignore = [
|
lint.ignore = [
|
||||||
"DJ001",
|
"DJ001",
|
||||||
|
"PLC0415",
|
||||||
"RUF012",
|
"RUF012",
|
||||||
"SIM105",
|
"SIM105",
|
||||||
]
|
]
|
||||||
@ -222,22 +224,9 @@ lint.per-file-ignores."src/documents/parsers.py" = [
|
|||||||
lint.per-file-ignores."src/documents/signals/handlers.py" = [
|
lint.per-file-ignores."src/documents/signals/handlers.py" = [
|
||||||
"PTH",
|
"PTH",
|
||||||
] # TODO Enable & remove
|
] # TODO Enable & remove
|
||||||
lint.per-file-ignores."src/documents/views.py" = [
|
|
||||||
"PTH",
|
|
||||||
] # TODO Enable & remove
|
|
||||||
lint.per-file-ignores."src/paperless/checks.py" = [
|
|
||||||
"PTH",
|
|
||||||
] # TODO Enable & remove
|
|
||||||
lint.per-file-ignores."src/paperless/settings.py" = [
|
|
||||||
"PTH",
|
|
||||||
] # TODO Enable & remove
|
|
||||||
lint.per-file-ignores."src/paperless_mail/mail.py" = [
|
|
||||||
"PTH",
|
|
||||||
] # TODO Enable & remove
|
|
||||||
lint.per-file-ignores."src/paperless_tesseract/tests/test_parser.py" = [
|
lint.per-file-ignores."src/paperless_tesseract/tests/test_parser.py" = [
|
||||||
"PTH",
|
|
||||||
"RUF001",
|
"RUF001",
|
||||||
] # TODO PTH Enable & remove
|
]
|
||||||
lint.isort.force-single-line = true
|
lint.isort.force-single-line = true
|
||||||
|
|
||||||
[tool.pytest.ini_options]
|
[tool.pytest.ini_options]
|
||||||
@ -251,6 +240,7 @@ testpaths = [
|
|||||||
"src/paperless_mail/tests/",
|
"src/paperless_mail/tests/",
|
||||||
"src/paperless_tesseract/tests/",
|
"src/paperless_tesseract/tests/",
|
||||||
"src/paperless_tika/tests",
|
"src/paperless_tika/tests",
|
||||||
|
"src/paperless_remote/tests/",
|
||||||
]
|
]
|
||||||
addopts = [
|
addopts = [
|
||||||
"--pythonwarnings=all",
|
"--pythonwarnings=all",
|
||||||
@ -314,8 +304,8 @@ environments = [
|
|||||||
[tool.uv.sources]
|
[tool.uv.sources]
|
||||||
# Markers are chosen to select these almost exclusively when building the Docker image
|
# Markers are chosen to select these almost exclusively when building the Docker image
|
||||||
psycopg-c = [
|
psycopg-c = [
|
||||||
{ url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.5/psycopg_c-3.2.5-cp312-cp312-linux_x86_64.whl", marker = "sys_platform == 'linux' and platform_machine == 'x86_64' and python_version == '3.12'" },
|
{ url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.9/psycopg_c-3.2.9-cp312-cp312-linux_x86_64.whl", marker = "sys_platform == 'linux' and platform_machine == 'x86_64' and python_version == '3.12'" },
|
||||||
{ url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.5/psycopg_c-3.2.5-cp312-cp312-linux_aarch64.whl", marker = "sys_platform == 'linux' and platform_machine == 'aarch64' and python_version == '3.12'" },
|
{ url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.9/psycopg_c-3.2.9-cp312-cp312-linux_aarch64.whl", marker = "sys_platform == 'linux' and platform_machine == 'aarch64' and python_version == '3.12'" },
|
||||||
]
|
]
|
||||||
zxing-cpp = [
|
zxing-cpp = [
|
||||||
{ url = "https://github.com/paperless-ngx/builder/releases/download/zxing-2.3.0/zxing_cpp-2.3.0-cp312-cp312-linux_x86_64.whl", marker = "sys_platform == 'linux' and platform_machine == 'x86_64' and python_version == '3.12'" },
|
{ url = "https://github.com/paperless-ngx/builder/releases/download/zxing-2.3.0/zxing_cpp-2.3.0-cp312-cp312-linux_x86_64.whl", marker = "sys_platform == 'linux' and platform_machine == 'x86_64' and python_version == '3.12'" },
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
"sv-SE": "src/locale/messages.sv_SE.xlf",
|
"sv-SE": "src/locale/messages.sv_SE.xlf",
|
||||||
"tr-TR": "src/locale/messages.tr_TR.xlf",
|
"tr-TR": "src/locale/messages.tr_TR.xlf",
|
||||||
"uk-UA": "src/locale/messages.uk_UA.xlf",
|
"uk-UA": "src/locale/messages.uk_UA.xlf",
|
||||||
|
"vi-VN": "src/locale/messages.vi_VN.xlf",
|
||||||
"zh-CN": "src/locale/messages.zh_CN.xlf",
|
"zh-CN": "src/locale/messages.zh_CN.xlf",
|
||||||
"zh-TW": "src/locale/messages.zh_TW.xlf"
|
"zh-TW": "src/locale/messages.zh_TW.xlf"
|
||||||
}
|
}
|
||||||
@ -60,10 +61,12 @@
|
|||||||
"path": "./extra-webpack.config.ts"
|
"path": "./extra-webpack.config.ts"
|
||||||
},
|
},
|
||||||
"outputPath": "dist/paperless-ui",
|
"outputPath": "dist/paperless-ui",
|
||||||
|
"main": "src/main.ts",
|
||||||
"outputHashing": "none",
|
"outputHashing": "none",
|
||||||
"index": "src/index.html",
|
"index": "src/index.html",
|
||||||
"main": "src/main.ts",
|
"polyfills": [
|
||||||
"polyfills": "src/polyfills.ts",
|
"src/polyfills.ts"
|
||||||
|
],
|
||||||
"tsConfig": "tsconfig.app.json",
|
"tsConfig": "tsconfig.app.json",
|
||||||
"localize": true,
|
"localize": true,
|
||||||
"assets": [
|
"assets": [
|
||||||
@ -86,12 +89,15 @@
|
|||||||
"file-saver",
|
"file-saver",
|
||||||
"utif"
|
"utif"
|
||||||
],
|
],
|
||||||
"vendorChunk": true,
|
|
||||||
"extractLicenses": false,
|
"extractLicenses": false,
|
||||||
"buildOptimizer": false,
|
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"optimization": false,
|
"optimization": false,
|
||||||
"namedChunks": true
|
"namedChunks": true,
|
||||||
|
"stylePreprocessorOptions": {
|
||||||
|
"includePaths": [
|
||||||
|
"."
|
||||||
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"configurations": {
|
"configurations": {
|
||||||
"production": {
|
"production": {
|
||||||
@ -107,8 +113,6 @@
|
|||||||
"sourceMap": false,
|
"sourceMap": false,
|
||||||
"namedChunks": false,
|
"namedChunks": false,
|
||||||
"extractLicenses": true,
|
"extractLicenses": true,
|
||||||
"vendorChunk": false,
|
|
||||||
"buildOptimizer": true,
|
|
||||||
"budgets": [
|
"budgets": [
|
||||||
{
|
{
|
||||||
"type": "initial",
|
"type": "initial",
|
||||||
@ -188,6 +192,30 @@
|
|||||||
},
|
},
|
||||||
"@angular-eslint/schematics:library": {
|
"@angular-eslint/schematics:library": {
|
||||||
"setParserOptionsProject": true
|
"setParserOptionsProject": true
|
||||||
|
},
|
||||||
|
"@schematics/angular:component": {
|
||||||
|
"type": "component"
|
||||||
|
},
|
||||||
|
"@schematics/angular:directive": {
|
||||||
|
"type": "directive"
|
||||||
|
},
|
||||||
|
"@schematics/angular:service": {
|
||||||
|
"type": "service"
|
||||||
|
},
|
||||||
|
"@schematics/angular:guard": {
|
||||||
|
"typeSeparator": "."
|
||||||
|
},
|
||||||
|
"@schematics/angular:interceptor": {
|
||||||
|
"typeSeparator": "."
|
||||||
|
},
|
||||||
|
"@schematics/angular:module": {
|
||||||
|
"typeSeparator": "."
|
||||||
|
},
|
||||||
|
"@schematics/angular:pipe": {
|
||||||
|
"typeSeparator": "."
|
||||||
|
},
|
||||||
|
"@schematics/angular:resolver": {
|
||||||
|
"typeSeparator": "."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "paperless-ngx-ui",
|
"name": "paperless-ngx-ui",
|
||||||
"version": "2.16.3",
|
"version": "2.17.1",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"preinstall": "npx only-allow pnpm",
|
"preinstall": "npx only-allow pnpm",
|
||||||
"ng": "ng",
|
"ng": "ng",
|
||||||
@ -11,28 +11,28 @@
|
|||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/cdk": "^19.2.14",
|
"@angular/cdk": "^20.0.4",
|
||||||
"@angular/common": "~19.2.14",
|
"@angular/common": "~20.0.6",
|
||||||
"@angular/compiler": "~19.2.14",
|
"@angular/compiler": "~20.0.6",
|
||||||
"@angular/core": "~19.2.14",
|
"@angular/core": "~20.0.6",
|
||||||
"@angular/forms": "~19.2.14",
|
"@angular/forms": "~20.0.6",
|
||||||
"@angular/localize": "~19.2.14",
|
"@angular/localize": "~20.0.6",
|
||||||
"@angular/platform-browser": "~19.2.14",
|
"@angular/platform-browser": "~20.0.6",
|
||||||
"@angular/platform-browser-dynamic": "~19.2.14",
|
"@angular/platform-browser-dynamic": "~20.0.6",
|
||||||
"@angular/router": "~19.2.14",
|
"@angular/router": "~20.0.6",
|
||||||
"@ng-bootstrap/ng-bootstrap": "^18.0.0",
|
"@ng-bootstrap/ng-bootstrap": "^19.0.1",
|
||||||
"@ng-select/ng-select": "^14.9.0",
|
"@ng-select/ng-select": "^15.1.3",
|
||||||
"@ngneat/dirty-check-forms": "^3.0.3",
|
"@ngneat/dirty-check-forms": "^3.0.3",
|
||||||
"@popperjs/core": "^2.11.8",
|
"@popperjs/core": "^2.11.8",
|
||||||
"bootstrap": "^5.3.6",
|
"bootstrap": "^5.3.7",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"mime-names": "^1.0.0",
|
"mime-names": "^1.0.0",
|
||||||
"ng2-pdf-viewer": "^10.4.0",
|
"ng2-pdf-viewer": "^10.4.0",
|
||||||
"ngx-bootstrap-icons": "^1.9.3",
|
"ngx-bootstrap-icons": "^1.9.3",
|
||||||
"ngx-color": "^10.0.0",
|
"ngx-color": "^10.0.0",
|
||||||
"ngx-cookie-service": "^19.1.2",
|
"ngx-cookie-service": "^20.0.1",
|
||||||
"ngx-device-detector": "^9.0.0",
|
"ngx-device-detector": "^10.0.2",
|
||||||
"ngx-ui-tour-ng-bootstrap": "^16.0.0",
|
"ngx-ui-tour-ng-bootstrap": "^17.0.0",
|
||||||
"rxjs": "^7.8.2",
|
"rxjs": "^7.8.2",
|
||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"utif": "^3.1.0",
|
"utif": "^3.1.0",
|
||||||
@ -40,26 +40,26 @@
|
|||||||
"zone.js": "^0.15.1"
|
"zone.js": "^0.15.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@angular-builders/custom-webpack": "^19.0.1",
|
"@angular-builders/custom-webpack": "^20.0.0",
|
||||||
"@angular-builders/jest": "^19.0.1",
|
"@angular-builders/jest": "^20.0.0",
|
||||||
"@angular-devkit/build-angular": "^19.2.14",
|
"@angular-devkit/core": "^20.0.4",
|
||||||
"@angular-devkit/core": "^19.2.14",
|
"@angular-devkit/schematics": "^20.0.4",
|
||||||
"@angular-devkit/schematics": "^19.2.14",
|
"@angular-eslint/builder": "20.1.1",
|
||||||
"@angular-eslint/builder": "19.7.0",
|
"@angular-eslint/eslint-plugin": "20.1.1",
|
||||||
"@angular-eslint/eslint-plugin": "19.7.0",
|
"@angular-eslint/eslint-plugin-template": "20.1.1",
|
||||||
"@angular-eslint/eslint-plugin-template": "19.7.0",
|
"@angular-eslint/schematics": "20.1.1",
|
||||||
"@angular-eslint/schematics": "19.7.0",
|
"@angular-eslint/template-parser": "20.1.1",
|
||||||
"@angular-eslint/template-parser": "19.7.0",
|
"@angular/build": "^20.0.4",
|
||||||
"@angular/cli": "~19.2.14",
|
"@angular/cli": "~20.0.4",
|
||||||
"@angular/compiler-cli": "~19.2.14",
|
"@angular/compiler-cli": "~20.0.6",
|
||||||
"@codecov/webpack-plugin": "^1.9.1",
|
"@codecov/webpack-plugin": "^1.9.1",
|
||||||
"@playwright/test": "^1.51.1",
|
"@playwright/test": "^1.53.2",
|
||||||
"@types/jest": "^29.5.14",
|
"@types/jest": "^29.5.14",
|
||||||
"@types/node": "^22.15.29",
|
"@types/node": "^24.0.10",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.33.0",
|
"@typescript-eslint/eslint-plugin": "^8.35.1",
|
||||||
"@typescript-eslint/parser": "^8.33.0",
|
"@typescript-eslint/parser": "^8.35.1",
|
||||||
"@typescript-eslint/utils": "^8.33.0",
|
"@typescript-eslint/utils": "^8.35.1",
|
||||||
"eslint": "^9.28.0",
|
"eslint": "^9.30.1",
|
||||||
"jest": "29.7.0",
|
"jest": "29.7.0",
|
||||||
"jest-environment-jsdom": "^29.7.0",
|
"jest-environment-jsdom": "^29.7.0",
|
||||||
"jest-junit": "^16.0.0",
|
"jest-junit": "^16.0.0",
|
||||||
@ -67,7 +67,8 @@
|
|||||||
"jest-websocket-mock": "^2.5.0",
|
"jest-websocket-mock": "^2.5.0",
|
||||||
"prettier-plugin-organize-imports": "^4.1.0",
|
"prettier-plugin-organize-imports": "^4.1.0",
|
||||||
"ts-node": "~10.9.1",
|
"ts-node": "~10.9.1",
|
||||||
"typescript": "^5.5.4"
|
"typescript": "^5.8.3",
|
||||||
|
"webpack": "^5.99.9"
|
||||||
},
|
},
|
||||||
"pnpm": {
|
"pnpm": {
|
||||||
"onlyBuiltDependencies": [
|
"onlyBuiltDependencies": [
|
||||||
@ -77,6 +78,5 @@
|
|||||||
"lmdb",
|
"lmdb",
|
||||||
"msgpackr-extract"
|
"msgpackr-extract"
|
||||||
]
|
]
|
||||||
},
|
}
|
||||||
"typings": "./src/typings.d.ts"
|
|
||||||
}
|
}
|
||||||
|
4074
src-ui/pnpm-lock.yaml
generated
4074
src-ui/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -40,6 +40,7 @@ import localeSr from '@angular/common/locales/sr'
|
|||||||
import localeSv from '@angular/common/locales/sv'
|
import localeSv from '@angular/common/locales/sv'
|
||||||
import localeTr from '@angular/common/locales/tr'
|
import localeTr from '@angular/common/locales/tr'
|
||||||
import localeUk from '@angular/common/locales/uk'
|
import localeUk from '@angular/common/locales/uk'
|
||||||
|
import localeVi from '@angular/common/locales/vi'
|
||||||
import localeZh from '@angular/common/locales/zh'
|
import localeZh from '@angular/common/locales/zh'
|
||||||
import localeZhHant from '@angular/common/locales/zh-Hant'
|
import localeZhHant from '@angular/common/locales/zh-Hant'
|
||||||
|
|
||||||
@ -75,6 +76,7 @@ registerLocaleData(localeSr)
|
|||||||
registerLocaleData(localeSv)
|
registerLocaleData(localeSv)
|
||||||
registerLocaleData(localeTr)
|
registerLocaleData(localeTr)
|
||||||
registerLocaleData(localeUk)
|
registerLocaleData(localeUk)
|
||||||
|
registerLocaleData(localeVi)
|
||||||
registerLocaleData(localeZh)
|
registerLocaleData(localeZh)
|
||||||
registerLocaleData(localeZhHant)
|
registerLocaleData(localeZhHant)
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, OnDestroy, OnInit, Renderer2 } from '@angular/core'
|
import { Component, inject, OnDestroy, OnInit, Renderer2 } from '@angular/core'
|
||||||
import { Router, RouterOutlet } from '@angular/router'
|
import { Router, RouterOutlet } from '@angular/router'
|
||||||
import { TourNgBootstrapModule, TourService } from 'ngx-ui-tour-ng-bootstrap'
|
import { TourNgBootstrapModule, TourService } from 'ngx-ui-tour-ng-bootstrap'
|
||||||
import { first, Subscription } from 'rxjs'
|
import { first, Subscription } from 'rxjs'
|
||||||
@ -29,22 +29,22 @@ import { WebsocketStatusService } from './services/websocket-status.service'
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class AppComponent implements OnInit, OnDestroy {
|
export class AppComponent implements OnInit, OnDestroy {
|
||||||
|
private settings = inject(SettingsService)
|
||||||
|
private websocketStatusService = inject(WebsocketStatusService)
|
||||||
|
private toastService = inject(ToastService)
|
||||||
|
private router = inject(Router)
|
||||||
|
private tasksService = inject(TasksService)
|
||||||
|
tourService = inject(TourService)
|
||||||
|
private renderer = inject(Renderer2)
|
||||||
|
private permissionsService = inject(PermissionsService)
|
||||||
|
private hotKeyService = inject(HotKeyService)
|
||||||
|
private componentRouterService = inject(ComponentRouterService)
|
||||||
|
|
||||||
newDocumentSubscription: Subscription
|
newDocumentSubscription: Subscription
|
||||||
successSubscription: Subscription
|
successSubscription: Subscription
|
||||||
failedSubscription: Subscription
|
failedSubscription: Subscription
|
||||||
|
|
||||||
constructor(
|
constructor() {
|
||||||
private settings: SettingsService,
|
|
||||||
private websocketStatusService: WebsocketStatusService,
|
|
||||||
private toastService: ToastService,
|
|
||||||
private router: Router,
|
|
||||||
private tasksService: TasksService,
|
|
||||||
public tourService: TourService,
|
|
||||||
private renderer: Renderer2,
|
|
||||||
private permissionsService: PermissionsService,
|
|
||||||
private hotKeyService: HotKeyService,
|
|
||||||
private componentRouterService: ComponentRouterService
|
|
||||||
) {
|
|
||||||
let anyWindow = window as any
|
let anyWindow = window as any
|
||||||
anyWindow.pdfWorkerSrc = 'assets/js/pdf.worker.min.mjs'
|
anyWindow.pdfWorkerSrc = 'assets/js/pdf.worker.min.mjs'
|
||||||
this.settings.updateAppearanceSettings()
|
this.settings.updateAppearanceSettings()
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { AsyncPipe } from '@angular/common'
|
import { AsyncPipe } from '@angular/common'
|
||||||
import { Component, OnDestroy, OnInit } from '@angular/core'
|
import { Component, OnDestroy, OnInit, inject } from '@angular/core'
|
||||||
import {
|
import {
|
||||||
AbstractControl,
|
AbstractControl,
|
||||||
FormControl,
|
FormControl,
|
||||||
@ -57,6 +57,10 @@ export class ConfigComponent
|
|||||||
extends LoadingComponentWithPermissions
|
extends LoadingComponentWithPermissions
|
||||||
implements OnInit, OnDestroy, DirtyComponent
|
implements OnInit, OnDestroy, DirtyComponent
|
||||||
{
|
{
|
||||||
|
private configService = inject(ConfigService)
|
||||||
|
private toastService = inject(ToastService)
|
||||||
|
private settingsService = inject(SettingsService)
|
||||||
|
|
||||||
public readonly ConfigOptionType = ConfigOptionType
|
public readonly ConfigOptionType = ConfigOptionType
|
||||||
|
|
||||||
// generated dynamically
|
// generated dynamically
|
||||||
@ -77,11 +81,7 @@ export class ConfigComponent
|
|||||||
storeSub: Subscription
|
storeSub: Subscription
|
||||||
isDirty$: Observable<boolean>
|
isDirty$: Observable<boolean>
|
||||||
|
|
||||||
constructor(
|
constructor() {
|
||||||
private configService: ConfigService,
|
|
||||||
private toastService: ToastService,
|
|
||||||
private settingsService: SettingsService
|
|
||||||
) {
|
|
||||||
super()
|
super()
|
||||||
this.configForm.addControl('id', new FormControl())
|
this.configForm.addControl('id', new FormControl())
|
||||||
PaperlessConfigOptions.forEach((option) => {
|
PaperlessConfigOptions.forEach((option) => {
|
||||||
|
@ -5,6 +5,7 @@ import {
|
|||||||
OnDestroy,
|
OnDestroy,
|
||||||
OnInit,
|
OnInit,
|
||||||
ViewChild,
|
ViewChild,
|
||||||
|
inject,
|
||||||
} from '@angular/core'
|
} from '@angular/core'
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
|
||||||
import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap'
|
||||||
@ -28,12 +29,8 @@ export class LogsComponent
|
|||||||
extends LoadingComponentWithPermissions
|
extends LoadingComponentWithPermissions
|
||||||
implements OnInit, OnDestroy
|
implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
constructor(
|
private logService = inject(LogService)
|
||||||
private logService: LogService,
|
private changedetectorRef = inject(ChangeDetectorRef)
|
||||||
private changedetectorRef: ChangeDetectorRef
|
|
||||||
) {
|
|
||||||
super()
|
|
||||||
}
|
|
||||||
|
|
||||||
public logs: string[] = []
|
public logs: string[] = []
|
||||||
|
|
||||||
|
@ -2,10 +2,10 @@ import { AsyncPipe, ViewportScroller } from '@angular/common'
|
|||||||
import {
|
import {
|
||||||
AfterViewInit,
|
AfterViewInit,
|
||||||
Component,
|
Component,
|
||||||
Inject,
|
|
||||||
LOCALE_ID,
|
LOCALE_ID,
|
||||||
OnDestroy,
|
OnDestroy,
|
||||||
OnInit,
|
OnInit,
|
||||||
|
inject,
|
||||||
} from '@angular/core'
|
} from '@angular/core'
|
||||||
import {
|
import {
|
||||||
FormControl,
|
FormControl,
|
||||||
@ -104,6 +104,20 @@ export class SettingsComponent
|
|||||||
extends ComponentWithPermissions
|
extends ComponentWithPermissions
|
||||||
implements OnInit, AfterViewInit, OnDestroy, DirtyComponent
|
implements OnInit, AfterViewInit, OnDestroy, DirtyComponent
|
||||||
{
|
{
|
||||||
|
private documentListViewService = inject(DocumentListViewService)
|
||||||
|
private toastService = inject(ToastService)
|
||||||
|
private settings = inject(SettingsService)
|
||||||
|
currentLocale = inject(LOCALE_ID)
|
||||||
|
private viewportScroller = inject(ViewportScroller)
|
||||||
|
private activatedRoute = inject(ActivatedRoute)
|
||||||
|
readonly tourService = inject(TourService)
|
||||||
|
private usersService = inject(UserService)
|
||||||
|
private groupsService = inject(GroupService)
|
||||||
|
private router = inject(Router)
|
||||||
|
permissionsService = inject(PermissionsService)
|
||||||
|
private modalService = inject(NgbModal)
|
||||||
|
private systemStatusService = inject(SystemStatusService)
|
||||||
|
|
||||||
activeNavID: number
|
activeNavID: number
|
||||||
|
|
||||||
settingsForm = new FormGroup({
|
settingsForm = new FormGroup({
|
||||||
@ -179,21 +193,7 @@ export class SettingsComponent
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(
|
constructor() {
|
||||||
private documentListViewService: DocumentListViewService,
|
|
||||||
private toastService: ToastService,
|
|
||||||
private settings: SettingsService,
|
|
||||||
@Inject(LOCALE_ID) public currentLocale: string,
|
|
||||||
private viewportScroller: ViewportScroller,
|
|
||||||
private activatedRoute: ActivatedRoute,
|
|
||||||
public readonly tourService: TourService,
|
|
||||||
private usersService: UserService,
|
|
||||||
private groupsService: GroupService,
|
|
||||||
private router: Router,
|
|
||||||
public permissionsService: PermissionsService,
|
|
||||||
private modalService: NgbModal,
|
|
||||||
private systemStatusService: SystemStatusService
|
|
||||||
) {
|
|
||||||
super()
|
super()
|
||||||
this.settings.settingsSaved.subscribe(() => {
|
this.settings.settingsSaved.subscribe(() => {
|
||||||
if (!this.savePending) this.initialize()
|
if (!this.savePending) this.initialize()
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { NgTemplateOutlet, SlicePipe } from '@angular/common'
|
import { NgTemplateOutlet, SlicePipe } from '@angular/common'
|
||||||
import { Component, OnDestroy, OnInit } from '@angular/core'
|
import { Component, inject, OnDestroy, OnInit } from '@angular/core'
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
|
||||||
import { Router } from '@angular/router'
|
import { Router } from '@angular/router'
|
||||||
import {
|
import {
|
||||||
@ -69,6 +69,10 @@ export class TasksComponent
|
|||||||
extends LoadingComponentWithPermissions
|
extends LoadingComponentWithPermissions
|
||||||
implements OnInit, OnDestroy
|
implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
|
tasksService = inject(TasksService)
|
||||||
|
private modalService = inject(NgbModal)
|
||||||
|
private readonly router = inject(Router)
|
||||||
|
|
||||||
public activeTab: TaskTab
|
public activeTab: TaskTab
|
||||||
public selectedTasks: Set<number> = new Set()
|
public selectedTasks: Set<number> = new Set()
|
||||||
public togggleAll: boolean = false
|
public togggleAll: boolean = false
|
||||||
@ -105,14 +109,6 @@ export class TasksComponent
|
|||||||
: $localize`Dismiss all`
|
: $localize`Dismiss all`
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(
|
|
||||||
public tasksService: TasksService,
|
|
||||||
private modalService: NgbModal,
|
|
||||||
private readonly router: Router
|
|
||||||
) {
|
|
||||||
super()
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.tasksService.reload()
|
this.tasksService.reload()
|
||||||
timer(5000, 5000)
|
timer(5000, 5000)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, OnDestroy } from '@angular/core'
|
import { Component, OnDestroy, inject } from '@angular/core'
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
|
||||||
import { Router } from '@angular/router'
|
import { Router } from '@angular/router'
|
||||||
import {
|
import {
|
||||||
@ -36,19 +36,19 @@ export class TrashComponent
|
|||||||
extends LoadingComponentWithPermissions
|
extends LoadingComponentWithPermissions
|
||||||
implements OnDestroy
|
implements OnDestroy
|
||||||
{
|
{
|
||||||
|
private trashService = inject(TrashService)
|
||||||
|
private toastService = inject(ToastService)
|
||||||
|
private modalService = inject(NgbModal)
|
||||||
|
private settingsService = inject(SettingsService)
|
||||||
|
private router = inject(Router)
|
||||||
|
|
||||||
public documentsInTrash: Document[] = []
|
public documentsInTrash: Document[] = []
|
||||||
public selectedDocuments: Set<number> = new Set()
|
public selectedDocuments: Set<number> = new Set()
|
||||||
public allToggled: boolean = false
|
public allToggled: boolean = false
|
||||||
public page: number = 1
|
public page: number = 1
|
||||||
public totalDocuments: number
|
public totalDocuments: number
|
||||||
|
|
||||||
constructor(
|
constructor() {
|
||||||
private trashService: TrashService,
|
|
||||||
private toastService: ToastService,
|
|
||||||
private modalService: NgbModal,
|
|
||||||
private settingsService: SettingsService,
|
|
||||||
private router: Router
|
|
||||||
) {
|
|
||||||
super()
|
super()
|
||||||
this.reload()
|
this.reload()
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, OnDestroy, OnInit } from '@angular/core'
|
import { Component, OnDestroy, OnInit, inject } from '@angular/core'
|
||||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
||||||
import { Subject, first, takeUntil } from 'rxjs'
|
import { Subject, first, takeUntil } from 'rxjs'
|
||||||
@ -31,22 +31,18 @@ export class UsersAndGroupsComponent
|
|||||||
extends ComponentWithPermissions
|
extends ComponentWithPermissions
|
||||||
implements OnInit, OnDestroy
|
implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
|
private usersService = inject(UserService)
|
||||||
|
private groupsService = inject(GroupService)
|
||||||
|
private toastService = inject(ToastService)
|
||||||
|
private modalService = inject(NgbModal)
|
||||||
|
permissionsService = inject(PermissionsService)
|
||||||
|
private settings = inject(SettingsService)
|
||||||
|
|
||||||
users: User[]
|
users: User[]
|
||||||
groups: Group[]
|
groups: Group[]
|
||||||
|
|
||||||
unsubscribeNotifier: Subject<any> = new Subject()
|
unsubscribeNotifier: Subject<any> = new Subject()
|
||||||
|
|
||||||
constructor(
|
|
||||||
private usersService: UserService,
|
|
||||||
private groupsService: GroupService,
|
|
||||||
private toastService: ToastService,
|
|
||||||
private modalService: NgbModal,
|
|
||||||
public permissionsService: PermissionsService,
|
|
||||||
private settings: SettingsService
|
|
||||||
) {
|
|
||||||
super()
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.usersService
|
this.usersService
|
||||||
.listAll(null, null, { full_perms: true })
|
.listAll(null, null, { full_perms: true })
|
||||||
|
@ -6,7 +6,7 @@ import {
|
|||||||
moveItemInArray,
|
moveItemInArray,
|
||||||
} from '@angular/cdk/drag-drop'
|
} from '@angular/cdk/drag-drop'
|
||||||
import { NgClass } from '@angular/common'
|
import { NgClass } from '@angular/common'
|
||||||
import { Component, HostListener, OnInit } from '@angular/core'
|
import { Component, HostListener, inject, OnInit } from '@angular/core'
|
||||||
import { ActivatedRoute, Router, RouterModule } from '@angular/router'
|
import { ActivatedRoute, Router, RouterModule } from '@angular/router'
|
||||||
import {
|
import {
|
||||||
NgbCollapseModule,
|
NgbCollapseModule,
|
||||||
@ -74,27 +74,27 @@ export class AppFrameComponent
|
|||||||
extends ComponentWithPermissions
|
extends ComponentWithPermissions
|
||||||
implements OnInit, ComponentCanDeactivate
|
implements OnInit, ComponentCanDeactivate
|
||||||
{
|
{
|
||||||
versionString = `${environment.appTitle} ${environment.version}`
|
router = inject(Router)
|
||||||
|
private activatedRoute = inject(ActivatedRoute)
|
||||||
|
private openDocumentsService = inject(OpenDocumentsService)
|
||||||
|
savedViewService = inject(SavedViewService)
|
||||||
|
private remoteVersionService = inject(RemoteVersionService)
|
||||||
|
settingsService = inject(SettingsService)
|
||||||
|
tasksService = inject(TasksService)
|
||||||
|
private readonly toastService = inject(ToastService)
|
||||||
|
private modalService = inject(NgbModal)
|
||||||
|
permissionsService = inject(PermissionsService)
|
||||||
|
private djangoMessagesService = inject(DjangoMessagesService)
|
||||||
|
|
||||||
appRemoteVersion: AppRemoteVersion
|
appRemoteVersion: AppRemoteVersion
|
||||||
|
|
||||||
isMenuCollapsed: boolean = true
|
isMenuCollapsed: boolean = true
|
||||||
|
|
||||||
slimSidebarAnimating: boolean = false
|
slimSidebarAnimating: boolean = false
|
||||||
|
|
||||||
constructor(
|
constructor() {
|
||||||
public router: Router,
|
|
||||||
private activatedRoute: ActivatedRoute,
|
|
||||||
private openDocumentsService: OpenDocumentsService,
|
|
||||||
public savedViewService: SavedViewService,
|
|
||||||
private remoteVersionService: RemoteVersionService,
|
|
||||||
public settingsService: SettingsService,
|
|
||||||
public tasksService: TasksService,
|
|
||||||
private readonly toastService: ToastService,
|
|
||||||
private modalService: NgbModal,
|
|
||||||
public permissionsService: PermissionsService,
|
|
||||||
private djangoMessagesService: DjangoMessagesService
|
|
||||||
) {
|
|
||||||
super()
|
super()
|
||||||
|
const permissionsService = this.permissionsService
|
||||||
|
|
||||||
if (
|
if (
|
||||||
permissionsService.currentUserCan(
|
permissionsService.currentUserCan(
|
||||||
@ -142,6 +142,10 @@ export class AppFrameComponent
|
|||||||
}, 200) // slightly longer than css animation for slim sidebar
|
}, 200) // slightly longer than css animation for slim sidebar
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get versionString(): string {
|
||||||
|
return `${environment.appTitle} v${this.settingsService.get(SETTINGS_KEYS.VERSION)}${environment.production ? '' : ` #${environment.tag}`}`
|
||||||
|
}
|
||||||
|
|
||||||
get customAppTitle(): string {
|
get customAppTitle(): string {
|
||||||
return this.settingsService.get(SETTINGS_KEYS.APP_TITLE)
|
return this.settingsService.get(SETTINGS_KEYS.APP_TITLE)
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import {
|
|||||||
QueryList,
|
QueryList,
|
||||||
ViewChild,
|
ViewChild,
|
||||||
ViewChildren,
|
ViewChildren,
|
||||||
|
inject,
|
||||||
} from '@angular/core'
|
} from '@angular/core'
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
|
||||||
import { Router } from '@angular/router'
|
import { Router } from '@angular/router'
|
||||||
@ -69,6 +70,17 @@ import { WorkflowEditDialogComponent } from '../../common/edit-dialog/workflow-e
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class GlobalSearchComponent implements OnInit {
|
export class GlobalSearchComponent implements OnInit {
|
||||||
|
searchService = inject(SearchService)
|
||||||
|
private router = inject(Router)
|
||||||
|
private modalService = inject(NgbModal)
|
||||||
|
private documentService = inject(DocumentService)
|
||||||
|
private documentListViewService = inject(DocumentListViewService)
|
||||||
|
private permissionsService = inject(PermissionsService)
|
||||||
|
private toastService = inject(ToastService)
|
||||||
|
private hotkeyService = inject(HotKeyService)
|
||||||
|
private settingsService = inject(SettingsService)
|
||||||
|
private locationStrategy = inject(LocationStrategy)
|
||||||
|
|
||||||
public DataType = DataType
|
public DataType = DataType
|
||||||
public query: string
|
public query: string
|
||||||
public queryDebounce: Subject<string>
|
public queryDebounce: Subject<string>
|
||||||
@ -90,18 +102,7 @@ export class GlobalSearchComponent implements OnInit {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(
|
constructor() {
|
||||||
public searchService: SearchService,
|
|
||||||
private router: Router,
|
|
||||||
private modalService: NgbModal,
|
|
||||||
private documentService: DocumentService,
|
|
||||||
private documentListViewService: DocumentListViewService,
|
|
||||||
private permissionsService: PermissionsService,
|
|
||||||
private toastService: ToastService,
|
|
||||||
private hotkeyService: HotKeyService,
|
|
||||||
private settingsService: SettingsService,
|
|
||||||
private locationStrategy: LocationStrategy
|
|
||||||
) {
|
|
||||||
this.queryDebounce = new Subject<string>()
|
this.queryDebounce = new Subject<string>()
|
||||||
|
|
||||||
this.queryDebounce
|
this.queryDebounce
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, OnDestroy, OnInit } from '@angular/core'
|
import { Component, OnDestroy, OnInit, inject } from '@angular/core'
|
||||||
import {
|
import {
|
||||||
NgbDropdownModule,
|
NgbDropdownModule,
|
||||||
NgbProgressbarModule,
|
NgbProgressbarModule,
|
||||||
@ -20,7 +20,7 @@ import { ToastComponent } from '../../common/toast/toast.component'
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class ToastsDropdownComponent implements OnInit, OnDestroy {
|
export class ToastsDropdownComponent implements OnInit, OnDestroy {
|
||||||
constructor(public toastService: ToastService) {}
|
toastService = inject(ToastService)
|
||||||
|
|
||||||
private subscription: Subscription
|
private subscription: Subscription
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { DecimalPipe } from '@angular/common'
|
import { DecimalPipe } from '@angular/common'
|
||||||
import { Component, EventEmitter, Input, Output } from '@angular/core'
|
import { Component, EventEmitter, Input, Output, inject } from '@angular/core'
|
||||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { Subject } from 'rxjs'
|
import { Subject } from 'rxjs'
|
||||||
import { SafeHtmlPipe } from 'src/app/pipes/safehtml.pipe'
|
import { SafeHtmlPipe } from 'src/app/pipes/safehtml.pipe'
|
||||||
@ -12,9 +12,7 @@ import { LoadingComponentWithPermissions } from '../../loading-component/loading
|
|||||||
imports: [DecimalPipe, SafeHtmlPipe],
|
imports: [DecimalPipe, SafeHtmlPipe],
|
||||||
})
|
})
|
||||||
export class ConfirmDialogComponent extends LoadingComponentWithPermissions {
|
export class ConfirmDialogComponent extends LoadingComponentWithPermissions {
|
||||||
constructor(public activeModal: NgbActiveModal) {
|
activeModal = inject(NgbActiveModal)
|
||||||
super()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
public confirmClicked = new EventEmitter()
|
public confirmClicked = new EventEmitter()
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { Component, TemplateRef, ViewChild } from '@angular/core'
|
import { Component, TemplateRef, ViewChild, inject } from '@angular/core'
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
|
||||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
|
||||||
import {
|
import {
|
||||||
PDFDocumentProxy,
|
PDFDocumentProxy,
|
||||||
PdfViewerComponent,
|
PdfViewerComponent,
|
||||||
@ -17,6 +16,8 @@ import { ConfirmDialogComponent } from '../confirm-dialog.component'
|
|||||||
imports: [PdfViewerModule, FormsModule, ReactiveFormsModule, SafeHtmlPipe],
|
imports: [PdfViewerModule, FormsModule, ReactiveFormsModule, SafeHtmlPipe],
|
||||||
})
|
})
|
||||||
export class DeletePagesConfirmDialogComponent extends ConfirmDialogComponent {
|
export class DeletePagesConfirmDialogComponent extends ConfirmDialogComponent {
|
||||||
|
private documentService = inject(DocumentService)
|
||||||
|
|
||||||
public documentID: number
|
public documentID: number
|
||||||
public pages: number[] = []
|
public pages: number[] = []
|
||||||
public currentPage: number = 1
|
public currentPage: number = 1
|
||||||
@ -34,11 +35,8 @@ export class DeletePagesConfirmDialogComponent extends ConfirmDialogComponent {
|
|||||||
return this.documentService.getPreviewUrl(this.documentID)
|
return this.documentService.getPreviewUrl(this.documentID)
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(
|
constructor() {
|
||||||
activeModal: NgbActiveModal,
|
super()
|
||||||
private documentService: DocumentService
|
|
||||||
) {
|
|
||||||
super(activeModal)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public pdfPreviewLoaded(pdf: PDFDocumentProxy) {
|
public pdfPreviewLoaded(pdf: PDFDocumentProxy) {
|
||||||
|
@ -3,9 +3,8 @@ import {
|
|||||||
DragDropModule,
|
DragDropModule,
|
||||||
moveItemInArray,
|
moveItemInArray,
|
||||||
} from '@angular/cdk/drag-drop'
|
} from '@angular/cdk/drag-drop'
|
||||||
import { Component, OnInit } from '@angular/core'
|
import { Component, OnInit, inject } from '@angular/core'
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
|
||||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
|
||||||
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
||||||
import { takeUntil } from 'rxjs'
|
import { takeUntil } from 'rxjs'
|
||||||
import { Document } from 'src/app/data/document'
|
import { Document } from 'src/app/data/document'
|
||||||
@ -28,6 +27,9 @@ export class MergeConfirmDialogComponent
|
|||||||
extends ConfirmDialogComponent
|
extends ConfirmDialogComponent
|
||||||
implements OnInit
|
implements OnInit
|
||||||
{
|
{
|
||||||
|
private documentService = inject(DocumentService)
|
||||||
|
private permissionService = inject(PermissionsService)
|
||||||
|
|
||||||
public documentIDs: number[] = []
|
public documentIDs: number[] = []
|
||||||
public archiveFallback: boolean = false
|
public archiveFallback: boolean = false
|
||||||
public deleteOriginals: boolean = false
|
public deleteOriginals: boolean = false
|
||||||
@ -38,12 +40,8 @@ export class MergeConfirmDialogComponent
|
|||||||
|
|
||||||
public metadataDocumentID: number = -1
|
public metadataDocumentID: number = -1
|
||||||
|
|
||||||
constructor(
|
constructor() {
|
||||||
activeModal: NgbActiveModal,
|
super()
|
||||||
private documentService: DocumentService,
|
|
||||||
private permissionService: PermissionsService
|
|
||||||
) {
|
|
||||||
super(activeModal)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { NgStyle } from '@angular/common'
|
import { NgStyle } from '@angular/common'
|
||||||
import { Component } from '@angular/core'
|
import { Component, inject } from '@angular/core'
|
||||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
|
||||||
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
||||||
import { SafeHtmlPipe } from 'src/app/pipes/safehtml.pipe'
|
import { SafeHtmlPipe } from 'src/app/pipes/safehtml.pipe'
|
||||||
import { DocumentService } from 'src/app/services/rest/document.service'
|
import { DocumentService } from 'src/app/services/rest/document.service'
|
||||||
@ -13,6 +12,8 @@ import { ConfirmDialogComponent } from '../confirm-dialog.component'
|
|||||||
imports: [NgStyle, NgxBootstrapIconsModule, SafeHtmlPipe],
|
imports: [NgStyle, NgxBootstrapIconsModule, SafeHtmlPipe],
|
||||||
})
|
})
|
||||||
export class RotateConfirmDialogComponent extends ConfirmDialogComponent {
|
export class RotateConfirmDialogComponent extends ConfirmDialogComponent {
|
||||||
|
documentService = inject(DocumentService)
|
||||||
|
|
||||||
public documentID: number
|
public documentID: number
|
||||||
public showPDFNote: boolean = true
|
public showPDFNote: boolean = true
|
||||||
|
|
||||||
@ -25,11 +26,8 @@ export class RotateConfirmDialogComponent extends ConfirmDialogComponent {
|
|||||||
return degrees
|
return degrees
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(
|
constructor() {
|
||||||
activeModal: NgbActiveModal,
|
super()
|
||||||
public documentService: DocumentService
|
|
||||||
) {
|
|
||||||
super(activeModal)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rotate(clockwise: boolean = true) {
|
rotate(clockwise: boolean = true) {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { Component, OnInit } from '@angular/core'
|
import { Component, OnInit, inject } from '@angular/core'
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
|
||||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
|
||||||
import { PDFDocumentProxy, PdfViewerModule } from 'ng2-pdf-viewer'
|
import { PDFDocumentProxy, PdfViewerModule } from 'ng2-pdf-viewer'
|
||||||
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
||||||
import { Document } from 'src/app/data/document'
|
import { Document } from 'src/app/data/document'
|
||||||
@ -23,6 +22,9 @@ export class SplitConfirmDialogComponent
|
|||||||
extends ConfirmDialogComponent
|
extends ConfirmDialogComponent
|
||||||
implements OnInit
|
implements OnInit
|
||||||
{
|
{
|
||||||
|
private documentService = inject(DocumentService)
|
||||||
|
private permissionService = inject(PermissionsService)
|
||||||
|
|
||||||
public get pagesString(): string {
|
public get pagesString(): string {
|
||||||
let pagesStr = ''
|
let pagesStr = ''
|
||||||
|
|
||||||
@ -62,12 +64,8 @@ export class SplitConfirmDialogComponent
|
|||||||
return this.documentService.getPreviewUrl(this.documentID)
|
return this.documentService.getPreviewUrl(this.documentID)
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(
|
constructor() {
|
||||||
activeModal: NgbActiveModal,
|
super()
|
||||||
private documentService: DocumentService,
|
|
||||||
private permissionService: PermissionsService
|
|
||||||
) {
|
|
||||||
super(activeModal)
|
|
||||||
this.confirmButtonEnabled = this.pages.size > 0
|
this.confirmButtonEnabled = this.pages.size > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { CurrencyPipe, getLocaleCurrencyCode } from '@angular/common'
|
import { CurrencyPipe, getLocaleCurrencyCode } from '@angular/common'
|
||||||
import { Component, Inject, Input, LOCALE_ID, OnInit } from '@angular/core'
|
import { Component, Input, LOCALE_ID, OnInit, inject } from '@angular/core'
|
||||||
import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { takeUntil } from 'rxjs'
|
import { takeUntil } from 'rxjs'
|
||||||
import { CustomField, CustomFieldDataType } from 'src/app/data/custom-field'
|
import { CustomField, CustomFieldDataType } from 'src/app/data/custom-field'
|
||||||
@ -20,6 +20,9 @@ export class CustomFieldDisplayComponent
|
|||||||
extends LoadingComponentWithPermissions
|
extends LoadingComponentWithPermissions
|
||||||
implements OnInit
|
implements OnInit
|
||||||
{
|
{
|
||||||
|
private customFieldService = inject(CustomFieldsService)
|
||||||
|
private documentService = inject(DocumentService)
|
||||||
|
|
||||||
CustomFieldDataType = CustomFieldDataType
|
CustomFieldDataType = CustomFieldDataType
|
||||||
|
|
||||||
private _document: Document
|
private _document: Document
|
||||||
@ -63,11 +66,9 @@ export class CustomFieldDisplayComponent
|
|||||||
|
|
||||||
private defaultCurrencyCode: any
|
private defaultCurrencyCode: any
|
||||||
|
|
||||||
constructor(
|
constructor() {
|
||||||
private customFieldService: CustomFieldsService,
|
const currentLocale = inject(LOCALE_ID)
|
||||||
private documentService: DocumentService,
|
|
||||||
@Inject(LOCALE_ID) currentLocale: string
|
|
||||||
) {
|
|
||||||
super()
|
super()
|
||||||
this.defaultCurrencyCode = getLocaleCurrencyCode(currentLocale)
|
this.defaultCurrencyCode = getLocaleCurrencyCode(currentLocale)
|
||||||
this.customFieldService.listAll().subscribe((r) => {
|
this.customFieldService.listAll().subscribe((r) => {
|
||||||
|
@ -7,6 +7,7 @@ import {
|
|||||||
QueryList,
|
QueryList,
|
||||||
ViewChild,
|
ViewChild,
|
||||||
ViewChildren,
|
ViewChildren,
|
||||||
|
inject,
|
||||||
} from '@angular/core'
|
} from '@angular/core'
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
|
||||||
import { NgbDropdownModule, NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbDropdownModule, NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||||
@ -37,6 +38,11 @@ import { CustomFieldEditDialogComponent } from '../edit-dialog/custom-field-edit
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class CustomFieldsDropdownComponent extends LoadingComponentWithPermissions {
|
export class CustomFieldsDropdownComponent extends LoadingComponentWithPermissions {
|
||||||
|
private customFieldsService = inject(CustomFieldsService)
|
||||||
|
private modalService = inject(NgbModal)
|
||||||
|
private toastService = inject(ToastService)
|
||||||
|
private permissionsService = inject(PermissionsService)
|
||||||
|
|
||||||
public popperOptions = pngxPopperOptions
|
public popperOptions = pngxPopperOptions
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
@ -78,12 +84,7 @@ export class CustomFieldsDropdownComponent extends LoadingComponentWithPermissio
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(
|
constructor() {
|
||||||
private customFieldsService: CustomFieldsService,
|
|
||||||
private modalService: NgbModal,
|
|
||||||
private toastService: ToastService,
|
|
||||||
private permissionsService: PermissionsService
|
|
||||||
) {
|
|
||||||
super()
|
super()
|
||||||
this.getFields()
|
this.getFields()
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ import { NgTemplateOutlet } from '@angular/common'
|
|||||||
import {
|
import {
|
||||||
Component,
|
Component,
|
||||||
EventEmitter,
|
EventEmitter,
|
||||||
|
inject,
|
||||||
Input,
|
Input,
|
||||||
Output,
|
Output,
|
||||||
QueryList,
|
QueryList,
|
||||||
@ -178,6 +179,8 @@ export class CustomFieldQueriesModel {
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class CustomFieldsQueryDropdownComponent extends LoadingComponentWithPermissions {
|
export class CustomFieldsQueryDropdownComponent extends LoadingComponentWithPermissions {
|
||||||
|
protected customFieldsService = inject(CustomFieldsService)
|
||||||
|
|
||||||
public CustomFieldQueryComponentType = CustomFieldQueryElementType
|
public CustomFieldQueryComponentType = CustomFieldQueryElementType
|
||||||
public CustomFieldQueryOperator = CustomFieldQueryOperator
|
public CustomFieldQueryOperator = CustomFieldQueryOperator
|
||||||
public CustomFieldDataType = CustomFieldDataType
|
public CustomFieldDataType = CustomFieldDataType
|
||||||
@ -245,7 +248,7 @@ export class CustomFieldsQueryDropdownComponent extends LoadingComponentWithPerm
|
|||||||
|
|
||||||
public readonly today: string = new Date().toISOString().split('T')[0]
|
public readonly today: string = new Date().toISOString().split('T')[0]
|
||||||
|
|
||||||
constructor(protected customFieldsService: CustomFieldsService) {
|
constructor() {
|
||||||
super()
|
super()
|
||||||
this.selectionModel = new CustomFieldQueriesModel()
|
this.selectionModel = new CustomFieldQueriesModel()
|
||||||
this.getFields()
|
this.getFields()
|
||||||
|
@ -6,6 +6,7 @@ import {
|
|||||||
OnDestroy,
|
OnDestroy,
|
||||||
OnInit,
|
OnInit,
|
||||||
Output,
|
Output,
|
||||||
|
inject,
|
||||||
} from '@angular/core'
|
} from '@angular/core'
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
|
||||||
import {
|
import {
|
||||||
@ -63,7 +64,9 @@ export enum RelativeDate {
|
|||||||
export class DatesDropdownComponent implements OnInit, OnDestroy {
|
export class DatesDropdownComponent implements OnInit, OnDestroy {
|
||||||
public popperOptions = pngxPopperOptions
|
public popperOptions = pngxPopperOptions
|
||||||
|
|
||||||
constructor(settings: SettingsService) {
|
constructor() {
|
||||||
|
const settings = inject(SettingsService)
|
||||||
|
|
||||||
this.datePlaceHolder = settings.getLocalizedDateInputFormat()
|
this.datePlaceHolder = settings.getLocalizedDateInputFormat()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,8 +13,6 @@
|
|||||||
<pngx-input-select i18n-title title="Matching algorithm" [items]="getMatchingAlgorithms()" formControlName="matching_algorithm"></pngx-input-select>
|
<pngx-input-select i18n-title title="Matching algorithm" [items]="getMatchingAlgorithms()" formControlName="matching_algorithm"></pngx-input-select>
|
||||||
@if (patternRequired) {
|
@if (patternRequired) {
|
||||||
<pngx-input-text i18n-title title="Matching pattern" formControlName="match" [error]="error?.match"></pngx-input-text>
|
<pngx-input-text i18n-title title="Matching pattern" formControlName="match" [error]="error?.match"></pngx-input-text>
|
||||||
}
|
|
||||||
@if (patternRequired) {
|
|
||||||
<pngx-input-check i18n-title title="Case insensitive" formControlName="is_insensitive" novalidate></pngx-input-check>
|
<pngx-input-check i18n-title title="Case insensitive" formControlName="is_insensitive" novalidate></pngx-input-check>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import { Component } from '@angular/core'
|
import { Component, inject } from '@angular/core'
|
||||||
import {
|
import {
|
||||||
FormControl,
|
FormControl,
|
||||||
FormGroup,
|
FormGroup,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
} from '@angular/forms'
|
} from '@angular/forms'
|
||||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
|
||||||
import { EditDialogComponent } from 'src/app/components/common/edit-dialog/edit-dialog.component'
|
import { EditDialogComponent } from 'src/app/components/common/edit-dialog/edit-dialog.component'
|
||||||
import { Correspondent } from 'src/app/data/correspondent'
|
import { Correspondent } from 'src/app/data/correspondent'
|
||||||
import { DEFAULT_MATCHING_ALGORITHM } from 'src/app/data/matching-model'
|
import { DEFAULT_MATCHING_ALGORITHM } from 'src/app/data/matching-model'
|
||||||
@ -13,6 +12,7 @@ import { IfOwnerDirective } from 'src/app/directives/if-owner.directive'
|
|||||||
import { CorrespondentService } from 'src/app/services/rest/correspondent.service'
|
import { CorrespondentService } from 'src/app/services/rest/correspondent.service'
|
||||||
import { UserService } from 'src/app/services/rest/user.service'
|
import { UserService } from 'src/app/services/rest/user.service'
|
||||||
import { SettingsService } from 'src/app/services/settings.service'
|
import { SettingsService } from 'src/app/services/settings.service'
|
||||||
|
import { CheckComponent } from '../../input/check/check.component'
|
||||||
import { PermissionsFormComponent } from '../../input/permissions/permissions-form/permissions-form.component'
|
import { PermissionsFormComponent } from '../../input/permissions/permissions-form/permissions-form.component'
|
||||||
import { SelectComponent } from '../../input/select/select.component'
|
import { SelectComponent } from '../../input/select/select.component'
|
||||||
import { TextComponent } from '../../input/text/text.component'
|
import { TextComponent } from '../../input/text/text.component'
|
||||||
@ -22,6 +22,7 @@ import { TextComponent } from '../../input/text/text.component'
|
|||||||
templateUrl: './correspondent-edit-dialog.component.html',
|
templateUrl: './correspondent-edit-dialog.component.html',
|
||||||
styleUrls: ['./correspondent-edit-dialog.component.scss'],
|
styleUrls: ['./correspondent-edit-dialog.component.scss'],
|
||||||
imports: [
|
imports: [
|
||||||
|
CheckComponent,
|
||||||
SelectComponent,
|
SelectComponent,
|
||||||
PermissionsFormComponent,
|
PermissionsFormComponent,
|
||||||
TextComponent,
|
TextComponent,
|
||||||
@ -31,13 +32,11 @@ import { TextComponent } from '../../input/text/text.component'
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class CorrespondentEditDialogComponent extends EditDialogComponent<Correspondent> {
|
export class CorrespondentEditDialogComponent extends EditDialogComponent<Correspondent> {
|
||||||
constructor(
|
constructor() {
|
||||||
service: CorrespondentService,
|
super()
|
||||||
activeModal: NgbActiveModal,
|
this.service = inject(CorrespondentService)
|
||||||
userService: UserService,
|
this.userService = inject(UserService)
|
||||||
settingsService: SettingsService
|
this.settingsService = inject(SettingsService)
|
||||||
) {
|
|
||||||
super(service, activeModal, userService, settingsService)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getCreateTitle() {
|
getCreateTitle() {
|
||||||
|
@ -5,6 +5,7 @@ import {
|
|||||||
OnInit,
|
OnInit,
|
||||||
QueryList,
|
QueryList,
|
||||||
ViewChildren,
|
ViewChildren,
|
||||||
|
inject,
|
||||||
} from '@angular/core'
|
} from '@angular/core'
|
||||||
import {
|
import {
|
||||||
FormArray,
|
FormArray,
|
||||||
@ -13,7 +14,6 @@ import {
|
|||||||
FormsModule,
|
FormsModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
} from '@angular/forms'
|
} from '@angular/forms'
|
||||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
|
||||||
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
||||||
import { takeUntil } from 'rxjs'
|
import { takeUntil } from 'rxjs'
|
||||||
import {
|
import {
|
||||||
@ -54,13 +54,11 @@ export class CustomFieldEditDialogComponent
|
|||||||
.select_options as FormArray
|
.select_options as FormArray
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(
|
constructor() {
|
||||||
service: CustomFieldsService,
|
super()
|
||||||
activeModal: NgbActiveModal,
|
this.service = inject(CustomFieldsService)
|
||||||
userService: UserService,
|
this.userService = inject(UserService)
|
||||||
settingsService: SettingsService
|
this.settingsService = inject(SettingsService)
|
||||||
) {
|
|
||||||
super(service, activeModal, userService, settingsService)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
@ -14,8 +14,6 @@
|
|||||||
<pngx-input-select i18n-title title="Matching algorithm" [items]="getMatchingAlgorithms()" formControlName="matching_algorithm"></pngx-input-select>
|
<pngx-input-select i18n-title title="Matching algorithm" [items]="getMatchingAlgorithms()" formControlName="matching_algorithm"></pngx-input-select>
|
||||||
@if (patternRequired) {
|
@if (patternRequired) {
|
||||||
<pngx-input-text i18n-title title="Matching pattern" formControlName="match" [error]="error?.match"></pngx-input-text>
|
<pngx-input-text i18n-title title="Matching pattern" formControlName="match" [error]="error?.match"></pngx-input-text>
|
||||||
}
|
|
||||||
@if (patternRequired) {
|
|
||||||
<pngx-input-check i18n-title title="Case insensitive" formControlName="is_insensitive"></pngx-input-check>
|
<pngx-input-check i18n-title title="Case insensitive" formControlName="is_insensitive"></pngx-input-check>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import { Component } from '@angular/core'
|
import { Component, inject } from '@angular/core'
|
||||||
import {
|
import {
|
||||||
FormControl,
|
FormControl,
|
||||||
FormGroup,
|
FormGroup,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
} from '@angular/forms'
|
} from '@angular/forms'
|
||||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
|
||||||
import { EditDialogComponent } from 'src/app/components/common/edit-dialog/edit-dialog.component'
|
import { EditDialogComponent } from 'src/app/components/common/edit-dialog/edit-dialog.component'
|
||||||
import { DocumentType } from 'src/app/data/document-type'
|
import { DocumentType } from 'src/app/data/document-type'
|
||||||
import { DEFAULT_MATCHING_ALGORITHM } from 'src/app/data/matching-model'
|
import { DEFAULT_MATCHING_ALGORITHM } from 'src/app/data/matching-model'
|
||||||
@ -13,6 +12,7 @@ import { IfOwnerDirective } from 'src/app/directives/if-owner.directive'
|
|||||||
import { DocumentTypeService } from 'src/app/services/rest/document-type.service'
|
import { DocumentTypeService } from 'src/app/services/rest/document-type.service'
|
||||||
import { UserService } from 'src/app/services/rest/user.service'
|
import { UserService } from 'src/app/services/rest/user.service'
|
||||||
import { SettingsService } from 'src/app/services/settings.service'
|
import { SettingsService } from 'src/app/services/settings.service'
|
||||||
|
import { CheckComponent } from '../../input/check/check.component'
|
||||||
import { PermissionsFormComponent } from '../../input/permissions/permissions-form/permissions-form.component'
|
import { PermissionsFormComponent } from '../../input/permissions/permissions-form/permissions-form.component'
|
||||||
import { SelectComponent } from '../../input/select/select.component'
|
import { SelectComponent } from '../../input/select/select.component'
|
||||||
import { TextComponent } from '../../input/text/text.component'
|
import { TextComponent } from '../../input/text/text.component'
|
||||||
@ -22,6 +22,7 @@ import { TextComponent } from '../../input/text/text.component'
|
|||||||
templateUrl: './document-type-edit-dialog.component.html',
|
templateUrl: './document-type-edit-dialog.component.html',
|
||||||
styleUrls: ['./document-type-edit-dialog.component.scss'],
|
styleUrls: ['./document-type-edit-dialog.component.scss'],
|
||||||
imports: [
|
imports: [
|
||||||
|
CheckComponent,
|
||||||
SelectComponent,
|
SelectComponent,
|
||||||
PermissionsFormComponent,
|
PermissionsFormComponent,
|
||||||
TextComponent,
|
TextComponent,
|
||||||
@ -31,13 +32,11 @@ import { TextComponent } from '../../input/text/text.component'
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class DocumentTypeEditDialogComponent extends EditDialogComponent<DocumentType> {
|
export class DocumentTypeEditDialogComponent extends EditDialogComponent<DocumentType> {
|
||||||
constructor(
|
constructor() {
|
||||||
service: DocumentTypeService,
|
super()
|
||||||
activeModal: NgbActiveModal,
|
this.service = inject(DocumentTypeService)
|
||||||
userService: UserService,
|
this.userService = inject(UserService)
|
||||||
settingsService: SettingsService
|
this.settingsService = inject(SettingsService)
|
||||||
) {
|
|
||||||
super(service, activeModal, userService, settingsService)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getCreateTitle() {
|
getCreateTitle() {
|
||||||
|
@ -41,13 +41,9 @@ import { EditDialogComponent, EditDialogMode } from './edit-dialog.component'
|
|||||||
imports: [FormsModule, ReactiveFormsModule],
|
imports: [FormsModule, ReactiveFormsModule],
|
||||||
})
|
})
|
||||||
class TestComponent extends EditDialogComponent<Tag> {
|
class TestComponent extends EditDialogComponent<Tag> {
|
||||||
constructor(
|
constructor() {
|
||||||
service: TagService,
|
super()
|
||||||
activeModal: NgbActiveModal,
|
this.service = TestBed.inject(TagService)
|
||||||
userService: UserService,
|
|
||||||
settingsService: SettingsService
|
|
||||||
) {
|
|
||||||
super(service, activeModal, userService, settingsService)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getForm(): FormGroup<any> {
|
getForm(): FormGroup<any> {
|
||||||
|
@ -1,4 +1,11 @@
|
|||||||
import { Directive, EventEmitter, Input, OnInit, Output } from '@angular/core'
|
import {
|
||||||
|
Directive,
|
||||||
|
EventEmitter,
|
||||||
|
Input,
|
||||||
|
OnInit,
|
||||||
|
Output,
|
||||||
|
inject,
|
||||||
|
} from '@angular/core'
|
||||||
import { FormGroup } from '@angular/forms'
|
import { FormGroup } from '@angular/forms'
|
||||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { Observable } from 'rxjs'
|
import { Observable } from 'rxjs'
|
||||||
@ -29,14 +36,12 @@ export abstract class EditDialogComponent<
|
|||||||
extends LoadingComponentWithPermissions
|
extends LoadingComponentWithPermissions
|
||||||
implements OnInit
|
implements OnInit
|
||||||
{
|
{
|
||||||
constructor(
|
protected service = inject<AbstractPaperlessService<T>>(
|
||||||
protected service: AbstractPaperlessService<T>,
|
AbstractPaperlessService
|
||||||
private activeModal: NgbActiveModal,
|
)
|
||||||
private userService: UserService,
|
protected activeModal = inject(NgbActiveModal)
|
||||||
protected settingsService: SettingsService
|
protected userService = inject(UserService)
|
||||||
) {
|
protected settingsService = inject(SettingsService)
|
||||||
super()
|
|
||||||
}
|
|
||||||
|
|
||||||
users: User[]
|
users: User[]
|
||||||
|
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import { Component } from '@angular/core'
|
import { Component, inject } from '@angular/core'
|
||||||
import {
|
import {
|
||||||
FormControl,
|
FormControl,
|
||||||
FormGroup,
|
FormGroup,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
} from '@angular/forms'
|
} from '@angular/forms'
|
||||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
|
||||||
import { EditDialogComponent } from 'src/app/components/common/edit-dialog/edit-dialog.component'
|
import { EditDialogComponent } from 'src/app/components/common/edit-dialog/edit-dialog.component'
|
||||||
import { Group } from 'src/app/data/group'
|
import { Group } from 'src/app/data/group'
|
||||||
import { GroupService } from 'src/app/services/rest/group.service'
|
import { GroupService } from 'src/app/services/rest/group.service'
|
||||||
@ -26,13 +25,11 @@ import { PermissionsSelectComponent } from '../../permissions-select/permissions
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class GroupEditDialogComponent extends EditDialogComponent<Group> {
|
export class GroupEditDialogComponent extends EditDialogComponent<Group> {
|
||||||
constructor(
|
constructor() {
|
||||||
service: GroupService,
|
super()
|
||||||
activeModal: NgbActiveModal,
|
this.service = inject(GroupService)
|
||||||
userService: UserService,
|
this.userService = inject(UserService)
|
||||||
settingsService: SettingsService
|
this.settingsService = inject(SettingsService)
|
||||||
) {
|
|
||||||
super(service, activeModal, userService, settingsService)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getCreateTitle() {
|
getCreateTitle() {
|
||||||
@ -46,7 +43,7 @@ export class GroupEditDialogComponent extends EditDialogComponent<Group> {
|
|||||||
getForm(): FormGroup {
|
getForm(): FormGroup {
|
||||||
return new FormGroup({
|
return new FormGroup({
|
||||||
name: new FormControl(''),
|
name: new FormControl(''),
|
||||||
permissions: new FormControl(null),
|
permissions: new FormControl([]),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,11 @@
|
|||||||
import { Component, ViewChild } from '@angular/core'
|
import { Component, ViewChild, inject } from '@angular/core'
|
||||||
import {
|
import {
|
||||||
FormControl,
|
FormControl,
|
||||||
FormGroup,
|
FormGroup,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
} from '@angular/forms'
|
} from '@angular/forms'
|
||||||
import {
|
import { NgbAlert, NgbAlertModule } from '@ng-bootstrap/ng-bootstrap'
|
||||||
NgbActiveModal,
|
|
||||||
NgbAlert,
|
|
||||||
NgbAlertModule,
|
|
||||||
} from '@ng-bootstrap/ng-bootstrap'
|
|
||||||
import { EditDialogComponent } from 'src/app/components/common/edit-dialog/edit-dialog.component'
|
import { EditDialogComponent } from 'src/app/components/common/edit-dialog/edit-dialog.component'
|
||||||
import { IMAPSecurity, MailAccount } from 'src/app/data/mail-account'
|
import { IMAPSecurity, MailAccount } from 'src/app/data/mail-account'
|
||||||
import { MailAccountService } from 'src/app/services/rest/mail-account.service'
|
import { MailAccountService } from 'src/app/services/rest/mail-account.service'
|
||||||
@ -47,13 +43,11 @@ export class MailAccountEditDialogComponent extends EditDialogComponent<MailAcco
|
|||||||
|
|
||||||
@ViewChild('testResultAlert', { static: false }) testResultAlert: NgbAlert
|
@ViewChild('testResultAlert', { static: false }) testResultAlert: NgbAlert
|
||||||
|
|
||||||
constructor(
|
constructor() {
|
||||||
service: MailAccountService,
|
super()
|
||||||
activeModal: NgbActiveModal,
|
this.service = inject(MailAccountService)
|
||||||
userService: UserService,
|
this.userService = inject(UserService)
|
||||||
settingsService: SettingsService
|
this.settingsService = inject(SettingsService)
|
||||||
) {
|
|
||||||
super(service, activeModal, userService, settingsService)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getCreateTitle() {
|
getCreateTitle() {
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import { Component } from '@angular/core'
|
import { Component, inject } from '@angular/core'
|
||||||
import {
|
import {
|
||||||
FormControl,
|
FormControl,
|
||||||
FormGroup,
|
FormGroup,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
} from '@angular/forms'
|
} from '@angular/forms'
|
||||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
|
||||||
import { first } from 'rxjs'
|
import { first } from 'rxjs'
|
||||||
import { EditDialogComponent } from 'src/app/components/common/edit-dialog/edit-dialog.component'
|
import { EditDialogComponent } from 'src/app/components/common/edit-dialog/edit-dialog.component'
|
||||||
import { Correspondent } from 'src/app/data/correspondent'
|
import { Correspondent } from 'src/app/data/correspondent'
|
||||||
@ -155,32 +154,34 @@ const METADATA_CORRESPONDENT_OPTIONS = [
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class MailRuleEditDialogComponent extends EditDialogComponent<MailRule> {
|
export class MailRuleEditDialogComponent extends EditDialogComponent<MailRule> {
|
||||||
|
private accountService: MailAccountService
|
||||||
|
private correspondentService: CorrespondentService
|
||||||
|
private documentTypeService: DocumentTypeService
|
||||||
|
|
||||||
accounts: MailAccount[]
|
accounts: MailAccount[]
|
||||||
correspondents: Correspondent[]
|
correspondents: Correspondent[]
|
||||||
documentTypes: DocumentType[]
|
documentTypes: DocumentType[]
|
||||||
|
|
||||||
constructor(
|
constructor() {
|
||||||
service: MailRuleService,
|
super()
|
||||||
activeModal: NgbActiveModal,
|
this.service = inject(MailRuleService)
|
||||||
accountService: MailAccountService,
|
this.accountService = inject(MailAccountService)
|
||||||
correspondentService: CorrespondentService,
|
this.correspondentService = inject(CorrespondentService)
|
||||||
documentTypeService: DocumentTypeService,
|
this.documentTypeService = inject(DocumentTypeService)
|
||||||
userService: UserService,
|
this.userService = inject(UserService)
|
||||||
settingsService: SettingsService
|
this.settingsService = inject(SettingsService)
|
||||||
) {
|
|
||||||
super(service, activeModal, userService, settingsService)
|
|
||||||
|
|
||||||
accountService
|
this.accountService
|
||||||
.listAll()
|
.listAll()
|
||||||
.pipe(first())
|
.pipe(first())
|
||||||
.subscribe((result) => (this.accounts = result.results))
|
.subscribe((result) => (this.accounts = result.results))
|
||||||
|
|
||||||
correspondentService
|
this.correspondentService
|
||||||
.listAll()
|
.listAll()
|
||||||
.pipe(first())
|
.pipe(first())
|
||||||
.subscribe((result) => (this.correspondents = result.results))
|
.subscribe((result) => (this.correspondents = result.results))
|
||||||
|
|
||||||
documentTypeService
|
this.documentTypeService
|
||||||
.listAll()
|
.listAll()
|
||||||
.pipe(first())
|
.pipe(first())
|
||||||
.subscribe((result) => (this.documentTypes = result.results))
|
.subscribe((result) => (this.documentTypes = result.results))
|
||||||
|
@ -64,8 +64,6 @@
|
|||||||
<pngx-input-select i18n-title title="Matching algorithm" [items]="getMatchingAlgorithms()" formControlName="matching_algorithm"></pngx-input-select>
|
<pngx-input-select i18n-title title="Matching algorithm" [items]="getMatchingAlgorithms()" formControlName="matching_algorithm"></pngx-input-select>
|
||||||
@if (patternRequired) {
|
@if (patternRequired) {
|
||||||
<pngx-input-text i18n-title title="Matching pattern" formControlName="match" [error]="error?.match"></pngx-input-text>
|
<pngx-input-text i18n-title title="Matching pattern" formControlName="match" [error]="error?.match"></pngx-input-text>
|
||||||
}
|
|
||||||
@if (patternRequired) {
|
|
||||||
<pngx-input-check i18n-title title="Case insensitive" formControlName="is_insensitive"></pngx-input-check>
|
<pngx-input-check i18n-title title="Case insensitive" formControlName="is_insensitive"></pngx-input-check>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { AsyncPipe, NgTemplateOutlet } from '@angular/common'
|
import { AsyncPipe, NgTemplateOutlet } from '@angular/common'
|
||||||
import { Component, OnDestroy } from '@angular/core'
|
import { Component, OnDestroy, inject } from '@angular/core'
|
||||||
import {
|
import {
|
||||||
FormControl,
|
FormControl,
|
||||||
FormGroup,
|
FormGroup,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
} from '@angular/forms'
|
} from '@angular/forms'
|
||||||
import { NgbAccordionModule, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbAccordionModule } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { NgSelectComponent } from '@ng-select/ng-select'
|
import { NgSelectComponent } from '@ng-select/ng-select'
|
||||||
import {
|
import {
|
||||||
Observable,
|
Observable,
|
||||||
@ -60,6 +60,8 @@ export class StoragePathEditDialogComponent
|
|||||||
extends EditDialogComponent<StoragePath>
|
extends EditDialogComponent<StoragePath>
|
||||||
implements OnDestroy
|
implements OnDestroy
|
||||||
{
|
{
|
||||||
|
private documentsService = inject(DocumentService)
|
||||||
|
|
||||||
public documentsInput$ = new Subject<string>()
|
public documentsInput$ = new Subject<string>()
|
||||||
public foundDocuments$: Observable<Document[]>
|
public foundDocuments$: Observable<Document[]>
|
||||||
private testDocument: Document
|
private testDocument: Document
|
||||||
@ -68,14 +70,11 @@ export class StoragePathEditDialogComponent
|
|||||||
public loading = false
|
public loading = false
|
||||||
public testLoading = false
|
public testLoading = false
|
||||||
|
|
||||||
constructor(
|
constructor() {
|
||||||
service: StoragePathService,
|
super()
|
||||||
activeModal: NgbActiveModal,
|
this.service = inject(StoragePathService)
|
||||||
userService: UserService,
|
this.userService = inject(UserService)
|
||||||
settingsService: SettingsService,
|
this.settingsService = inject(SettingsService)
|
||||||
private documentsService: DocumentService
|
|
||||||
) {
|
|
||||||
super(service, activeModal, userService, settingsService)
|
|
||||||
this.initPathObservables()
|
this.initPathObservables()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,8 +16,6 @@
|
|||||||
<pngx-input-select i18n-title title="Matching algorithm" [items]="getMatchingAlgorithms()" formControlName="matching_algorithm"></pngx-input-select>
|
<pngx-input-select i18n-title title="Matching algorithm" [items]="getMatchingAlgorithms()" formControlName="matching_algorithm"></pngx-input-select>
|
||||||
@if (patternRequired) {
|
@if (patternRequired) {
|
||||||
<pngx-input-text i18n-title title="Matching pattern" formControlName="match" [error]="error?.match"></pngx-input-text>
|
<pngx-input-text i18n-title title="Matching pattern" formControlName="match" [error]="error?.match"></pngx-input-text>
|
||||||
}
|
|
||||||
@if (patternRequired) {
|
|
||||||
<pngx-input-check i18n-title title="Case insensitive" formControlName="is_insensitive"></pngx-input-check>
|
<pngx-input-check i18n-title title="Case insensitive" formControlName="is_insensitive"></pngx-input-check>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import { Component } from '@angular/core'
|
import { Component, inject } from '@angular/core'
|
||||||
import {
|
import {
|
||||||
FormControl,
|
FormControl,
|
||||||
FormGroup,
|
FormGroup,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
} from '@angular/forms'
|
} from '@angular/forms'
|
||||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
|
||||||
import { EditDialogComponent } from 'src/app/components/common/edit-dialog/edit-dialog.component'
|
import { EditDialogComponent } from 'src/app/components/common/edit-dialog/edit-dialog.component'
|
||||||
import { DEFAULT_MATCHING_ALGORITHM } from 'src/app/data/matching-model'
|
import { DEFAULT_MATCHING_ALGORITHM } from 'src/app/data/matching-model'
|
||||||
import { Tag } from 'src/app/data/tag'
|
import { Tag } from 'src/app/data/tag'
|
||||||
@ -36,13 +35,11 @@ import { TextComponent } from '../../input/text/text.component'
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class TagEditDialogComponent extends EditDialogComponent<Tag> {
|
export class TagEditDialogComponent extends EditDialogComponent<Tag> {
|
||||||
constructor(
|
constructor() {
|
||||||
service: TagService,
|
super()
|
||||||
activeModal: NgbActiveModal,
|
this.service = inject(TagService)
|
||||||
userService: UserService,
|
this.userService = inject(UserService)
|
||||||
settingsService: SettingsService
|
this.settingsService = inject(SettingsService)
|
||||||
) {
|
|
||||||
super(service, activeModal, userService, settingsService)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getCreateTitle() {
|
getCreateTitle() {
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import { Component, OnInit } from '@angular/core'
|
import { Component, OnInit, inject } from '@angular/core'
|
||||||
import {
|
import {
|
||||||
FormControl,
|
FormControl,
|
||||||
FormGroup,
|
FormGroup,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
} from '@angular/forms'
|
} from '@angular/forms'
|
||||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
|
||||||
import { first } from 'rxjs'
|
import { first } from 'rxjs'
|
||||||
import { EditDialogComponent } from 'src/app/components/common/edit-dialog/edit-dialog.component'
|
import { EditDialogComponent } from 'src/app/components/common/edit-dialog/edit-dialog.component'
|
||||||
import { Group } from 'src/app/data/group'
|
import { Group } from 'src/app/data/group'
|
||||||
@ -37,21 +36,21 @@ export class UserEditDialogComponent
|
|||||||
extends EditDialogComponent<User>
|
extends EditDialogComponent<User>
|
||||||
implements OnInit
|
implements OnInit
|
||||||
{
|
{
|
||||||
|
private toastService = inject(ToastService)
|
||||||
|
private permissionsService = inject(PermissionsService)
|
||||||
|
private groupsService: GroupService
|
||||||
|
|
||||||
groups: Group[]
|
groups: Group[]
|
||||||
passwordIsSet: boolean = false
|
passwordIsSet: boolean = false
|
||||||
public totpLoading: boolean = false
|
public totpLoading: boolean = false
|
||||||
|
|
||||||
constructor(
|
constructor() {
|
||||||
service: UserService,
|
super()
|
||||||
activeModal: NgbActiveModal,
|
this.service = inject(UserService)
|
||||||
groupsService: GroupService,
|
this.groupsService = inject(GroupService)
|
||||||
settingsService: SettingsService,
|
this.settingsService = inject(SettingsService)
|
||||||
private toastService: ToastService,
|
|
||||||
private permissionsService: PermissionsService
|
|
||||||
) {
|
|
||||||
super(service, activeModal, service, settingsService)
|
|
||||||
|
|
||||||
groupsService
|
this.groupsService
|
||||||
.listAll()
|
.listAll()
|
||||||
.pipe(first())
|
.pipe(first())
|
||||||
.subscribe((result) => (this.groups = result.results))
|
.subscribe((result) => (this.groups = result.results))
|
||||||
|
@ -129,7 +129,7 @@
|
|||||||
formControlName="schedule_offset_days"
|
formControlName="schedule_offset_days"
|
||||||
[showAdd]="false"
|
[showAdd]="false"
|
||||||
[error]="error?.schedule_offset_days"
|
[error]="error?.schedule_offset_days"
|
||||||
hint="Positive values will trigger the workflow before the date, negative values after."
|
hint="Positive values will trigger after the date, negative values before."
|
||||||
i18n-hint
|
i18n-hint
|
||||||
></pngx-input-number>
|
></pngx-input-number>
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,7 +4,7 @@ import {
|
|||||||
moveItemInArray,
|
moveItemInArray,
|
||||||
} from '@angular/cdk/drag-drop'
|
} from '@angular/cdk/drag-drop'
|
||||||
import { NgTemplateOutlet } from '@angular/common'
|
import { NgTemplateOutlet } from '@angular/common'
|
||||||
import { Component, OnInit } from '@angular/core'
|
import { Component, OnInit, inject } from '@angular/core'
|
||||||
import {
|
import {
|
||||||
FormArray,
|
FormArray,
|
||||||
FormControl,
|
FormControl,
|
||||||
@ -12,7 +12,7 @@ import {
|
|||||||
FormsModule,
|
FormsModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
} from '@angular/forms'
|
} from '@angular/forms'
|
||||||
import { NgbAccordionModule, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbAccordionModule } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
||||||
import { first } from 'rxjs'
|
import { first } from 'rxjs'
|
||||||
import { Correspondent } from 'src/app/data/correspondent'
|
import { Correspondent } from 'src/app/data/correspondent'
|
||||||
@ -171,6 +171,12 @@ export class WorkflowEditDialogComponent
|
|||||||
public WorkflowTriggerType = WorkflowTriggerType
|
public WorkflowTriggerType = WorkflowTriggerType
|
||||||
public WorkflowActionType = WorkflowActionType
|
public WorkflowActionType = WorkflowActionType
|
||||||
|
|
||||||
|
private correspondentService: CorrespondentService
|
||||||
|
private documentTypeService: DocumentTypeService
|
||||||
|
private storagePathService: StoragePathService
|
||||||
|
private mailRuleService: MailRuleService
|
||||||
|
private customFieldsService: CustomFieldsService
|
||||||
|
|
||||||
templates: Workflow[]
|
templates: Workflow[]
|
||||||
correspondents: Correspondent[]
|
correspondents: Correspondent[]
|
||||||
documentTypes: DocumentType[]
|
documentTypes: DocumentType[]
|
||||||
@ -183,40 +189,38 @@ export class WorkflowEditDialogComponent
|
|||||||
|
|
||||||
private allowedActionTypes = []
|
private allowedActionTypes = []
|
||||||
|
|
||||||
constructor(
|
constructor() {
|
||||||
service: WorkflowService,
|
super()
|
||||||
activeModal: NgbActiveModal,
|
this.service = inject(WorkflowService)
|
||||||
correspondentService: CorrespondentService,
|
this.correspondentService = inject(CorrespondentService)
|
||||||
documentTypeService: DocumentTypeService,
|
this.documentTypeService = inject(DocumentTypeService)
|
||||||
storagePathService: StoragePathService,
|
this.storagePathService = inject(StoragePathService)
|
||||||
mailRuleService: MailRuleService,
|
this.mailRuleService = inject(MailRuleService)
|
||||||
userService: UserService,
|
this.userService = inject(UserService)
|
||||||
settingsService: SettingsService,
|
this.settingsService = inject(SettingsService)
|
||||||
customFieldsService: CustomFieldsService
|
this.customFieldsService = inject(CustomFieldsService)
|
||||||
) {
|
|
||||||
super(service, activeModal, userService, settingsService)
|
|
||||||
|
|
||||||
correspondentService
|
this.correspondentService
|
||||||
.listAll()
|
.listAll()
|
||||||
.pipe(first())
|
.pipe(first())
|
||||||
.subscribe((result) => (this.correspondents = result.results))
|
.subscribe((result) => (this.correspondents = result.results))
|
||||||
|
|
||||||
documentTypeService
|
this.documentTypeService
|
||||||
.listAll()
|
.listAll()
|
||||||
.pipe(first())
|
.pipe(first())
|
||||||
.subscribe((result) => (this.documentTypes = result.results))
|
.subscribe((result) => (this.documentTypes = result.results))
|
||||||
|
|
||||||
storagePathService
|
this.storagePathService
|
||||||
.listAll()
|
.listAll()
|
||||||
.pipe(first())
|
.pipe(first())
|
||||||
.subscribe((result) => (this.storagePaths = result.results))
|
.subscribe((result) => (this.storagePaths = result.results))
|
||||||
|
|
||||||
mailRuleService
|
this.mailRuleService
|
||||||
.listAll()
|
.listAll()
|
||||||
.pipe(first())
|
.pipe(first())
|
||||||
.subscribe((result) => (this.mailRules = result.results))
|
.subscribe((result) => (this.mailRules = result.results))
|
||||||
|
|
||||||
customFieldsService
|
this.customFieldsService
|
||||||
.listAll()
|
.listAll()
|
||||||
.pipe(first())
|
.pipe(first())
|
||||||
.subscribe((result) => {
|
.subscribe((result) => {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, Input } from '@angular/core'
|
import { Component, Input, inject } from '@angular/core'
|
||||||
import { FormsModule } from '@angular/forms'
|
import { FormsModule } from '@angular/forms'
|
||||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
||||||
@ -13,6 +13,10 @@ import { LoadingComponentWithPermissions } from '../../loading-component/loading
|
|||||||
imports: [FormsModule, NgxBootstrapIconsModule],
|
imports: [FormsModule, NgxBootstrapIconsModule],
|
||||||
})
|
})
|
||||||
export class EmailDocumentDialogComponent extends LoadingComponentWithPermissions {
|
export class EmailDocumentDialogComponent extends LoadingComponentWithPermissions {
|
||||||
|
private activeModal = inject(NgbActiveModal)
|
||||||
|
private documentService = inject(DocumentService)
|
||||||
|
private toastService = inject(ToastService)
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
title = $localize`Email Document`
|
title = $localize`Email Document`
|
||||||
|
|
||||||
@ -37,11 +41,7 @@ export class EmailDocumentDialogComponent extends LoadingComponentWithPermission
|
|||||||
public emailSubject: string = ''
|
public emailSubject: string = ''
|
||||||
public emailMessage: string = ''
|
public emailMessage: string = ''
|
||||||
|
|
||||||
constructor(
|
constructor() {
|
||||||
private activeModal: NgbActiveModal,
|
|
||||||
private documentService: DocumentService,
|
|
||||||
private toastService: ToastService
|
|
||||||
) {
|
|
||||||
super()
|
super()
|
||||||
this.loading = false
|
this.loading = false
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import {
|
|||||||
OnInit,
|
OnInit,
|
||||||
Output,
|
Output,
|
||||||
ViewChild,
|
ViewChild,
|
||||||
|
inject,
|
||||||
} from '@angular/core'
|
} from '@angular/core'
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
|
||||||
import { NgbDropdown, NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbDropdown, NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'
|
||||||
@ -434,6 +435,9 @@ export class FilterableDropdownComponent
|
|||||||
extends LoadingComponentWithPermissions
|
extends LoadingComponentWithPermissions
|
||||||
implements OnInit
|
implements OnInit
|
||||||
{
|
{
|
||||||
|
private filterPipe = inject(FilterPipe)
|
||||||
|
private hotkeyService = inject(HotKeyService)
|
||||||
|
|
||||||
@ViewChild('listFilterTextInput') listFilterTextInput: ElementRef
|
@ViewChild('listFilterTextInput') listFilterTextInput: ElementRef
|
||||||
@ViewChild('dropdown') dropdown: NgbDropdown
|
@ViewChild('dropdown') dropdown: NgbDropdown
|
||||||
@ViewChild('buttonItems') buttonItems: ElementRef
|
@ViewChild('buttonItems') buttonItems: ElementRef
|
||||||
@ -536,10 +540,7 @@ export class FilterableDropdownComponent
|
|||||||
|
|
||||||
private keyboardIndex: number
|
private keyboardIndex: number
|
||||||
|
|
||||||
constructor(
|
constructor() {
|
||||||
private filterPipe: FilterPipe,
|
|
||||||
private hotkeyService: HotKeyService
|
|
||||||
) {
|
|
||||||
super()
|
super()
|
||||||
this.selectionModelChange.subscribe((updatedModel) => {
|
this.selectionModelChange.subscribe((updatedModel) => {
|
||||||
this.modelIsDirty = updatedModel.isDirty()
|
this.modelIsDirty = updatedModel.isDirty()
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component } from '@angular/core'
|
import { Component, inject } from '@angular/core'
|
||||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
||||||
|
|
||||||
const SYMBOLS = {
|
const SYMBOLS = {
|
||||||
@ -19,11 +19,11 @@ const SYMBOLS = {
|
|||||||
styleUrl: './hotkey-dialog.component.scss',
|
styleUrl: './hotkey-dialog.component.scss',
|
||||||
})
|
})
|
||||||
export class HotkeyDialogComponent {
|
export class HotkeyDialogComponent {
|
||||||
|
activeModal = inject(NgbActiveModal)
|
||||||
|
|
||||||
public title: string = $localize`Keyboard shortcuts`
|
public title: string = $localize`Keyboard shortcuts`
|
||||||
public hotkeys: Map<string, string> = new Map()
|
public hotkeys: Map<string, string> = new Map()
|
||||||
|
|
||||||
constructor(public activeModal: NgbActiveModal) {}
|
|
||||||
|
|
||||||
public close(): void {
|
public close(): void {
|
||||||
this.activeModal.close()
|
this.activeModal.close()
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ import {
|
|||||||
Component,
|
Component,
|
||||||
EventEmitter,
|
EventEmitter,
|
||||||
forwardRef,
|
forwardRef,
|
||||||
|
inject,
|
||||||
Input,
|
Input,
|
||||||
Output,
|
Output,
|
||||||
} from '@angular/core'
|
} from '@angular/core'
|
||||||
@ -55,7 +56,9 @@ import { UrlComponent } from '../url/url.component'
|
|||||||
export class CustomFieldsValuesComponent extends AbstractInputComponent<Object> {
|
export class CustomFieldsValuesComponent extends AbstractInputComponent<Object> {
|
||||||
public CustomFieldDataType = CustomFieldDataType
|
public CustomFieldDataType = CustomFieldDataType
|
||||||
|
|
||||||
constructor(customFieldsService: CustomFieldsService) {
|
constructor() {
|
||||||
|
const customFieldsService = inject(CustomFieldsService)
|
||||||
|
|
||||||
super()
|
super()
|
||||||
customFieldsService.listAll().subscribe((items) => {
|
customFieldsService.listAll().subscribe((items) => {
|
||||||
this.fields = items.results
|
this.fields = items.results
|
||||||
|
@ -2,6 +2,7 @@ import {
|
|||||||
Component,
|
Component,
|
||||||
EventEmitter,
|
EventEmitter,
|
||||||
forwardRef,
|
forwardRef,
|
||||||
|
inject,
|
||||||
Input,
|
Input,
|
||||||
OnInit,
|
OnInit,
|
||||||
Output,
|
Output,
|
||||||
@ -45,13 +46,9 @@ export class DateComponent
|
|||||||
extends AbstractInputComponent<string>
|
extends AbstractInputComponent<string>
|
||||||
implements OnInit
|
implements OnInit
|
||||||
{
|
{
|
||||||
constructor(
|
private settings = inject(SettingsService)
|
||||||
private settings: SettingsService,
|
private ngbDateParserFormatter = inject(NgbDateParserFormatter)
|
||||||
private ngbDateParserFormatter: NgbDateParserFormatter,
|
private isoDateAdapter = inject<NgbDateAdapter<string>>(NgbDateAdapter)
|
||||||
private isoDateAdapter: NgbDateAdapter<string>
|
|
||||||
) {
|
|
||||||
super()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
suggestions: string[]
|
suggestions: string[]
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
import { AsyncPipe, NgTemplateOutlet } from '@angular/common'
|
import { AsyncPipe, NgTemplateOutlet } from '@angular/common'
|
||||||
import { Component, forwardRef, Input, OnDestroy, OnInit } from '@angular/core'
|
import {
|
||||||
|
Component,
|
||||||
|
forwardRef,
|
||||||
|
inject,
|
||||||
|
Input,
|
||||||
|
OnDestroy,
|
||||||
|
OnInit,
|
||||||
|
} from '@angular/core'
|
||||||
import {
|
import {
|
||||||
FormsModule,
|
FormsModule,
|
||||||
NG_VALUE_ACCESSOR,
|
NG_VALUE_ACCESSOR,
|
||||||
@ -52,6 +59,8 @@ export class DocumentLinkComponent
|
|||||||
extends AbstractInputComponent<any[]>
|
extends AbstractInputComponent<any[]>
|
||||||
implements OnInit, OnDestroy
|
implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
|
private documentsService = inject(DocumentService)
|
||||||
|
|
||||||
documentsInput$ = new Subject<string>()
|
documentsInput$ = new Subject<string>()
|
||||||
foundDocuments$: Observable<Document[]>
|
foundDocuments$: Observable<Document[]>
|
||||||
loading = false
|
loading = false
|
||||||
@ -75,10 +84,6 @@ export class DocumentLinkComponent
|
|||||||
return this.selectedDocuments.map((d) => d.id)
|
return this.selectedDocuments.map((d) => d.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(private documentsService: DocumentService) {
|
|
||||||
super()
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.loadDocs()
|
this.loadDocs()
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
|
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
|
||||||
import { provideHttpClientTesting } from '@angular/common/http/testing'
|
import { provideHttpClientTesting } from '@angular/common/http/testing'
|
||||||
|
import { LOCALE_ID } from '@angular/core'
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing'
|
import { ComponentFixture, TestBed } from '@angular/core/testing'
|
||||||
import { NG_VALUE_ACCESSOR } from '@angular/forms'
|
import { NG_VALUE_ACCESSOR } from '@angular/forms'
|
||||||
import { MonetaryComponent } from './monetary.component'
|
import { MonetaryComponent } from './monetary.component'
|
||||||
@ -41,8 +42,6 @@ describe('MonetaryComponent', () => {
|
|||||||
|
|
||||||
it('should set the default currency code based on LOCALE_ID', () => {
|
it('should set the default currency code based on LOCALE_ID', () => {
|
||||||
expect(component.defaultCurrencyCode).toEqual('USD') // default
|
expect(component.defaultCurrencyCode).toEqual('USD') // default
|
||||||
component = new MonetaryComponent('pt-BR')
|
|
||||||
expect(component.defaultCurrencyCode).toEqual('BRL')
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support setting a default currency code', () => {
|
it('should support setting a default currency code', () => {
|
||||||
@ -87,3 +86,28 @@ describe('MonetaryComponent', () => {
|
|||||||
expect(component.value).toEqual('USD0.00')
|
expect(component.value).toEqual('USD0.00')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('MonetaryComponent (Alternate Locale)', () => {
|
||||||
|
let component: MonetaryComponent
|
||||||
|
let fixture: ComponentFixture<MonetaryComponent>
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [MonetaryComponent],
|
||||||
|
providers: [
|
||||||
|
{ provide: LOCALE_ID, useValue: 'pt-BR' }, // Brazilian Portuguese
|
||||||
|
provideHttpClient(withInterceptorsFromDi()),
|
||||||
|
provideHttpClientTesting(),
|
||||||
|
],
|
||||||
|
}).compileComponents()
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(MonetaryComponent)
|
||||||
|
fixture.debugElement.injector.get(NG_VALUE_ACCESSOR)
|
||||||
|
component = fixture.componentInstance
|
||||||
|
fixture.detectChanges()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should set the default currency code based on LOCALE_ID', () => {
|
||||||
|
expect(component.defaultCurrencyCode).toEqual('BRL')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { CurrencyPipe, getLocaleCurrencyCode } from '@angular/common'
|
import { CurrencyPipe, getLocaleCurrencyCode } from '@angular/common'
|
||||||
import { Component, forwardRef, Inject, Input, LOCALE_ID } from '@angular/core'
|
import { Component, forwardRef, inject, Input, LOCALE_ID } from '@angular/core'
|
||||||
import {
|
import {
|
||||||
FormsModule,
|
FormsModule,
|
||||||
NG_VALUE_ACCESSOR,
|
NG_VALUE_ACCESSOR,
|
||||||
@ -27,6 +27,8 @@ import { AbstractInputComponent } from '../abstract-input'
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class MonetaryComponent extends AbstractInputComponent<string> {
|
export class MonetaryComponent extends AbstractInputComponent<string> {
|
||||||
|
currentLocale = inject(LOCALE_ID)
|
||||||
|
|
||||||
public currency: string = ''
|
public currency: string = ''
|
||||||
|
|
||||||
public _monetaryValue: string = ''
|
public _monetaryValue: string = ''
|
||||||
@ -45,11 +47,10 @@ export class MonetaryComponent extends AbstractInputComponent<string> {
|
|||||||
if (currency) this.defaultCurrencyCode = currency
|
if (currency) this.defaultCurrencyCode = currency
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(@Inject(LOCALE_ID) currentLocale: string) {
|
constructor() {
|
||||||
super()
|
super()
|
||||||
|
|
||||||
this.currency = this.defaultCurrencyCode =
|
this.currency = this.defaultCurrencyCode =
|
||||||
this.defaultCurrency ?? getLocaleCurrencyCode(currentLocale)
|
this.defaultCurrency ?? getLocaleCurrencyCode(this.currentLocale)
|
||||||
}
|
}
|
||||||
|
|
||||||
writeValue(newValue: any): void {
|
writeValue(newValue: any): void {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, forwardRef, Input } from '@angular/core'
|
import { Component, forwardRef, inject, Input } from '@angular/core'
|
||||||
import {
|
import {
|
||||||
FormsModule,
|
FormsModule,
|
||||||
NG_VALUE_ACCESSOR,
|
NG_VALUE_ACCESSOR,
|
||||||
@ -22,16 +22,14 @@ import { AbstractInputComponent } from '../abstract-input'
|
|||||||
imports: [FormsModule, ReactiveFormsModule, NgxBootstrapIconsModule],
|
imports: [FormsModule, ReactiveFormsModule, NgxBootstrapIconsModule],
|
||||||
})
|
})
|
||||||
export class NumberComponent extends AbstractInputComponent<number> {
|
export class NumberComponent extends AbstractInputComponent<number> {
|
||||||
|
private documentService = inject(DocumentService)
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
showAdd: boolean = true
|
showAdd: boolean = true
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
step: number = 1
|
step: number = 1
|
||||||
|
|
||||||
constructor(private documentService: DocumentService) {
|
|
||||||
super()
|
|
||||||
}
|
|
||||||
|
|
||||||
nextAsn() {
|
nextAsn() {
|
||||||
if (this.value) {
|
if (this.value) {
|
||||||
return
|
return
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, forwardRef } from '@angular/core'
|
import { Component, forwardRef, inject } from '@angular/core'
|
||||||
import {
|
import {
|
||||||
FormsModule,
|
FormsModule,
|
||||||
NG_VALUE_ACCESSOR,
|
NG_VALUE_ACCESSOR,
|
||||||
@ -26,7 +26,9 @@ import { AbstractInputComponent } from '../../abstract-input'
|
|||||||
export class PermissionsGroupComponent extends AbstractInputComponent<Group> {
|
export class PermissionsGroupComponent extends AbstractInputComponent<Group> {
|
||||||
groups: Group[]
|
groups: Group[]
|
||||||
|
|
||||||
constructor(groupService: GroupService) {
|
constructor() {
|
||||||
|
const groupService = inject(GroupService)
|
||||||
|
|
||||||
super()
|
super()
|
||||||
groupService
|
groupService
|
||||||
.listAll()
|
.listAll()
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, forwardRef } from '@angular/core'
|
import { Component, forwardRef, inject } from '@angular/core'
|
||||||
import {
|
import {
|
||||||
FormsModule,
|
FormsModule,
|
||||||
NG_VALUE_ACCESSOR,
|
NG_VALUE_ACCESSOR,
|
||||||
@ -8,7 +8,6 @@ import { NgSelectComponent } from '@ng-select/ng-select'
|
|||||||
import { first } from 'rxjs/operators'
|
import { first } from 'rxjs/operators'
|
||||||
import { User } from 'src/app/data/user'
|
import { User } from 'src/app/data/user'
|
||||||
import { UserService } from 'src/app/services/rest/user.service'
|
import { UserService } from 'src/app/services/rest/user.service'
|
||||||
import { SettingsService } from 'src/app/services/settings.service'
|
|
||||||
import { AbstractInputComponent } from '../../abstract-input'
|
import { AbstractInputComponent } from '../../abstract-input'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -27,7 +26,9 @@ import { AbstractInputComponent } from '../../abstract-input'
|
|||||||
export class PermissionsUserComponent extends AbstractInputComponent<User[]> {
|
export class PermissionsUserComponent extends AbstractInputComponent<User[]> {
|
||||||
users: User[]
|
users: User[]
|
||||||
|
|
||||||
constructor(userService: UserService, settings: SettingsService) {
|
constructor() {
|
||||||
|
const userService = inject(UserService)
|
||||||
|
|
||||||
super()
|
super()
|
||||||
userService
|
userService
|
||||||
.listAll()
|
.listAll()
|
||||||
|
@ -2,6 +2,7 @@ import {
|
|||||||
Component,
|
Component,
|
||||||
EventEmitter,
|
EventEmitter,
|
||||||
forwardRef,
|
forwardRef,
|
||||||
|
inject,
|
||||||
Input,
|
Input,
|
||||||
OnInit,
|
OnInit,
|
||||||
Output,
|
Output,
|
||||||
@ -45,10 +46,10 @@ import { TagComponent } from '../../tag/tag.component'
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class TagsComponent implements OnInit, ControlValueAccessor {
|
export class TagsComponent implements OnInit, ControlValueAccessor {
|
||||||
constructor(
|
private tagService = inject(TagService)
|
||||||
private tagService: TagService,
|
private modalService = inject(NgbModal)
|
||||||
private modalService: NgbModal
|
|
||||||
) {
|
constructor() {
|
||||||
this.createTagRef = this.createTag.bind(this)
|
this.createTagRef = this.createTag.bind(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, Input } from '@angular/core'
|
import { Component, Input, inject } from '@angular/core'
|
||||||
import { SETTINGS_KEYS } from 'src/app/data/ui-settings'
|
import { SETTINGS_KEYS } from 'src/app/data/ui-settings'
|
||||||
import { SettingsService } from 'src/app/services/settings.service'
|
import { SettingsService } from 'src/app/services/settings.service'
|
||||||
import { environment } from 'src/environments/environment'
|
import { environment } from 'src/environments/environment'
|
||||||
@ -9,6 +9,8 @@ import { environment } from 'src/environments/environment'
|
|||||||
styleUrls: ['./logo.component.scss'],
|
styleUrls: ['./logo.component.scss'],
|
||||||
})
|
})
|
||||||
export class LogoComponent {
|
export class LogoComponent {
|
||||||
|
private settingsService = inject(SettingsService)
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
extra_classes: string
|
extra_classes: string
|
||||||
|
|
||||||
@ -24,8 +26,6 @@ export class LogoComponent {
|
|||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(private settingsService: SettingsService) {}
|
|
||||||
|
|
||||||
getClasses() {
|
getClasses() {
|
||||||
return ['logo'].concat(this.extra_classes).join(' ')
|
return ['logo'].concat(this.extra_classes).join(' ')
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, Input } from '@angular/core'
|
import { Component, Input, inject } from '@angular/core'
|
||||||
import { Title } from '@angular/platform-browser'
|
import { Title } from '@angular/platform-browser'
|
||||||
import { NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
||||||
@ -12,7 +12,7 @@ import { environment } from 'src/environments/environment'
|
|||||||
imports: [NgbPopoverModule, NgxBootstrapIconsModule, TourNgBootstrapModule],
|
imports: [NgbPopoverModule, NgxBootstrapIconsModule, TourNgBootstrapModule],
|
||||||
})
|
})
|
||||||
export class PageHeaderComponent {
|
export class PageHeaderComponent {
|
||||||
constructor(private titleService: Title) {}
|
private titleService = inject(Title)
|
||||||
|
|
||||||
_title = ''
|
_title = ''
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, EventEmitter, Input, Output } from '@angular/core'
|
import { Component, EventEmitter, Input, Output, inject } from '@angular/core'
|
||||||
import {
|
import {
|
||||||
FormControl,
|
FormControl,
|
||||||
FormGroup,
|
FormGroup,
|
||||||
@ -24,13 +24,13 @@ import { SwitchComponent } from '../input/switch/switch.component'
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class PermissionsDialogComponent {
|
export class PermissionsDialogComponent {
|
||||||
|
activeModal = inject(NgbActiveModal)
|
||||||
|
private userService = inject(UserService)
|
||||||
|
|
||||||
users: User[]
|
users: User[]
|
||||||
private o: ObjectWithPermissions = undefined
|
private o: ObjectWithPermissions = undefined
|
||||||
|
|
||||||
constructor(
|
constructor() {
|
||||||
public activeModal: NgbActiveModal,
|
|
||||||
private userService: UserService
|
|
||||||
) {
|
|
||||||
this.userService.listAll().subscribe((r) => (this.users = r.results))
|
this.userService.listAll().subscribe((r) => (this.users = r.results))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { NgClass } from '@angular/common'
|
import { NgClass } from '@angular/common'
|
||||||
import { Component, EventEmitter, Input, Output } from '@angular/core'
|
import { Component, EventEmitter, Input, Output, inject } from '@angular/core'
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
|
||||||
import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { NgSelectComponent } from '@ng-select/ng-select'
|
import { NgSelectComponent } from '@ng-select/ng-select'
|
||||||
@ -58,6 +58,9 @@ export enum OwnerFilterType {
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class PermissionsFilterDropdownComponent extends ComponentWithPermissions {
|
export class PermissionsFilterDropdownComponent extends ComponentWithPermissions {
|
||||||
|
permissionsService = inject(PermissionsService)
|
||||||
|
private settingsService = inject(SettingsService)
|
||||||
|
|
||||||
public OwnerFilterType = OwnerFilterType
|
public OwnerFilterType = OwnerFilterType
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
@ -83,12 +86,12 @@ export class PermissionsFilterDropdownComponent extends ComponentWithPermissions
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(
|
constructor() {
|
||||||
public permissionsService: PermissionsService,
|
const userService = inject(UserService)
|
||||||
userService: UserService,
|
|
||||||
private settingsService: SettingsService
|
|
||||||
) {
|
|
||||||
super()
|
super()
|
||||||
|
const permissionsService = this.permissionsService
|
||||||
|
|
||||||
if (
|
if (
|
||||||
permissionsService.currentUserCan(
|
permissionsService.currentUserCan(
|
||||||
PermissionAction.View,
|
PermissionAction.View,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { KeyValuePipe } from '@angular/common'
|
import { KeyValuePipe } from '@angular/common'
|
||||||
import { Component, forwardRef, Input, OnInit } from '@angular/core'
|
import { Component, forwardRef, inject, Input, OnInit } from '@angular/core'
|
||||||
import {
|
import {
|
||||||
AbstractControl,
|
AbstractControl,
|
||||||
ControlValueAccessor,
|
ControlValueAccessor,
|
||||||
@ -43,6 +43,9 @@ export class PermissionsSelectComponent
|
|||||||
extends ComponentWithPermissions
|
extends ComponentWithPermissions
|
||||||
implements OnInit, ControlValueAccessor
|
implements OnInit, ControlValueAccessor
|
||||||
{
|
{
|
||||||
|
private readonly permissionsService = inject(PermissionsService)
|
||||||
|
private readonly settingsService = inject(SettingsService)
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
title: string = 'Permissions'
|
title: string = 'Permissions'
|
||||||
|
|
||||||
@ -76,10 +79,7 @@ export class PermissionsSelectComponent
|
|||||||
|
|
||||||
public allowedTypes = Object.keys(PermissionType)
|
public allowedTypes = Object.keys(PermissionType)
|
||||||
|
|
||||||
constructor(
|
constructor() {
|
||||||
private readonly permissionsService: PermissionsService,
|
|
||||||
private readonly settingsService: SettingsService
|
|
||||||
) {
|
|
||||||
super()
|
super()
|
||||||
if (!this.settingsService.get(SETTINGS_KEYS.AUDITLOG_ENABLED)) {
|
if (!this.settingsService.get(SETTINGS_KEYS.AUDITLOG_ENABLED)) {
|
||||||
this.allowedTypes.splice(this.allowedTypes.indexOf('History'), 1)
|
this.allowedTypes.splice(this.allowedTypes.indexOf('History'), 1)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { HttpClient } from '@angular/common/http'
|
import { HttpClient } from '@angular/common/http'
|
||||||
import { Component, Input, OnDestroy, ViewChild } from '@angular/core'
|
import { Component, inject, Input, OnDestroy, ViewChild } from '@angular/core'
|
||||||
import { NgbPopover, NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbPopover, NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { PdfViewerComponent, PdfViewerModule } from 'ng2-pdf-viewer'
|
import { PdfViewerComponent, PdfViewerModule } from 'ng2-pdf-viewer'
|
||||||
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
||||||
@ -24,6 +24,10 @@ import { SettingsService } from 'src/app/services/settings.service'
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class PreviewPopupComponent implements OnDestroy {
|
export class PreviewPopupComponent implements OnDestroy {
|
||||||
|
private settingsService = inject(SettingsService)
|
||||||
|
private documentService = inject(DocumentService)
|
||||||
|
private http = inject(HttpClient)
|
||||||
|
|
||||||
private _document: Document
|
private _document: Document
|
||||||
@Input()
|
@Input()
|
||||||
set document(document: Document) {
|
set document(document: Document) {
|
||||||
@ -82,12 +86,6 @@ export class PreviewPopupComponent implements OnDestroy {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(
|
|
||||||
private settingsService: SettingsService,
|
|
||||||
private documentService: DocumentService,
|
|
||||||
private http: HttpClient
|
|
||||||
) {}
|
|
||||||
|
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
this.unsubscribeNotifier.next(this)
|
this.unsubscribeNotifier.next(this)
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Clipboard } from '@angular/cdk/clipboard'
|
import { Clipboard } from '@angular/cdk/clipboard'
|
||||||
import { Component, OnInit } from '@angular/core'
|
import { Component, OnInit, inject } from '@angular/core'
|
||||||
import {
|
import {
|
||||||
FormControl,
|
FormControl,
|
||||||
FormGroup,
|
FormGroup,
|
||||||
@ -46,6 +46,11 @@ export class ProfileEditDialogComponent
|
|||||||
extends LoadingComponentWithPermissions
|
extends LoadingComponentWithPermissions
|
||||||
implements OnInit
|
implements OnInit
|
||||||
{
|
{
|
||||||
|
private profileService = inject(ProfileService)
|
||||||
|
activeModal = inject(NgbActiveModal)
|
||||||
|
private toastService = inject(ToastService)
|
||||||
|
private clipboard = inject(Clipboard)
|
||||||
|
|
||||||
public networkActive: boolean = false
|
public networkActive: boolean = false
|
||||||
public error: any
|
public error: any
|
||||||
|
|
||||||
@ -83,15 +88,6 @@ export class ProfileEditDialogComponent
|
|||||||
public socialAccounts: SocialAccount[] = []
|
public socialAccounts: SocialAccount[] = []
|
||||||
public socialAccountProviders: SocialAccountProvider[] = []
|
public socialAccountProviders: SocialAccountProvider[] = []
|
||||||
|
|
||||||
constructor(
|
|
||||||
private profileService: ProfileService,
|
|
||||||
public activeModal: NgbActiveModal,
|
|
||||||
private toastService: ToastService,
|
|
||||||
private clipboard: Clipboard
|
|
||||||
) {
|
|
||||||
super()
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.networkActive = true
|
this.networkActive = true
|
||||||
this.profileService
|
this.profileService
|
||||||
|
@ -10,6 +10,7 @@ import {
|
|||||||
fakeAsync,
|
fakeAsync,
|
||||||
tick,
|
tick,
|
||||||
} from '@angular/core/testing'
|
} from '@angular/core/testing'
|
||||||
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
|
||||||
import { By } from '@angular/platform-browser'
|
import { By } from '@angular/platform-browser'
|
||||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
|
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
|
||||||
@ -33,6 +34,8 @@ describe('ShareLinksDialogComponent', () => {
|
|||||||
imports: [
|
imports: [
|
||||||
ShareLinksDialogComponent,
|
ShareLinksDialogComponent,
|
||||||
NgxBootstrapIconsModule.pick(allIcons),
|
NgxBootstrapIconsModule.pick(allIcons),
|
||||||
|
FormsModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
provideHttpClient(withInterceptorsFromDi()),
|
provideHttpClient(withInterceptorsFromDi()),
|
||||||
@ -223,16 +226,18 @@ describe('ShareLinksDialogComponent', () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should disable archive switch & option if no archive available', () => {
|
it('should disable archive switch & option if no archive available', (done) => {
|
||||||
component.hasArchiveVersion = false
|
component.hasArchiveVersion = false
|
||||||
component.ngOnInit()
|
component.ngOnInit()
|
||||||
fixture.detectChanges()
|
fixture.detectChanges()
|
||||||
expect(component.useArchiveVersion).toBeFalsy()
|
expect(component.useArchiveVersion).toBeFalsy()
|
||||||
expect(
|
setTimeout(() => {
|
||||||
fixture.debugElement.query(By.css("input[type='checkbox']")).attributes[
|
// some stupid change detection issue
|
||||||
'ng-reflect-is-disabled'
|
const inputEl = fixture.debugElement.query(By.css('#versionSwitch'))
|
||||||
]
|
.nativeElement as HTMLInputElement
|
||||||
).toBeTruthy()
|
expect(inputEl.disabled).toBeTruthy()
|
||||||
|
done()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support close', () => {
|
it('should support close', () => {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Clipboard } from '@angular/cdk/clipboard'
|
import { Clipboard } from '@angular/cdk/clipboard'
|
||||||
import { Component, Input, OnInit } from '@angular/core'
|
import { Component, Input, OnInit, inject } from '@angular/core'
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
|
||||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
||||||
@ -16,6 +16,11 @@ import { environment } from 'src/environments/environment'
|
|||||||
imports: [FormsModule, ReactiveFormsModule, NgxBootstrapIconsModule],
|
imports: [FormsModule, ReactiveFormsModule, NgxBootstrapIconsModule],
|
||||||
})
|
})
|
||||||
export class ShareLinksDialogComponent implements OnInit {
|
export class ShareLinksDialogComponent implements OnInit {
|
||||||
|
private activeModal = inject(NgbActiveModal)
|
||||||
|
private shareLinkService = inject(ShareLinkService)
|
||||||
|
private toastService = inject(ToastService)
|
||||||
|
private clipboard = inject(Clipboard)
|
||||||
|
|
||||||
EXPIRATION_OPTIONS = [
|
EXPIRATION_OPTIONS = [
|
||||||
{ label: $localize`1 day`, value: 1 },
|
{ label: $localize`1 day`, value: 1 },
|
||||||
{ label: $localize`7 days`, value: 7 },
|
{ label: $localize`7 days`, value: 7 },
|
||||||
@ -58,13 +63,6 @@ export class ShareLinksDialogComponent implements OnInit {
|
|||||||
|
|
||||||
useArchiveVersion: boolean = true
|
useArchiveVersion: boolean = true
|
||||||
|
|
||||||
constructor(
|
|
||||||
private activeModal: NgbActiveModal,
|
|
||||||
private shareLinkService: ShareLinkService,
|
|
||||||
private toastService: ToastService,
|
|
||||||
private clipboard: Clipboard
|
|
||||||
) {}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
if (this._documentId !== undefined) this.refresh()
|
if (this._documentId !== undefined) this.refresh()
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,18 @@
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<dl class="card-text">
|
<dl class="card-text">
|
||||||
<dt i18n>Paperless-ngx Version</dt>
|
<dt i18n>Paperless-ngx Version</dt>
|
||||||
<dd>{{status.pngx_version}}</dd>
|
<dd>
|
||||||
|
{{status.pngx_version}}
|
||||||
|
@if (versionMismatch) {
|
||||||
|
<button class="btn btn-sm d-inline align-items-center btn-dark text-uppercase small" [ngbPopover]="versionPopover" triggers="click mouseenter:mouseleave">
|
||||||
|
<i-bs name="exclamation-triangle-fill" class="text-danger lh-1"></i-bs>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
<ng-template #versionPopover>
|
||||||
|
Frontend version: {{frontendVersion}}<br>
|
||||||
|
Backend version: {{status.pngx_version}}
|
||||||
|
</ng-template>
|
||||||
|
</dd>
|
||||||
<dt i18n>Install Type</dt>
|
<dt i18n>Install Type</dt>
|
||||||
<dd>{{status.install_type}}</dd>
|
<dd>{{status.install_type}}</dd>
|
||||||
<dt i18n>Server OS</dt>
|
<dt i18n>Server OS</dt>
|
||||||
|
@ -1,3 +1,18 @@
|
|||||||
|
// Mock production environment for testing
|
||||||
|
jest.mock('src/environments/environment', () => ({
|
||||||
|
environment: {
|
||||||
|
production: true,
|
||||||
|
apiBaseUrl: 'http://localhost:8000/api/',
|
||||||
|
apiVersion: '9',
|
||||||
|
appTitle: 'Paperless-ngx',
|
||||||
|
tag: 'prod',
|
||||||
|
version: '2.4.3',
|
||||||
|
webSocketHost: 'localhost:8000',
|
||||||
|
webSocketProtocol: 'ws:',
|
||||||
|
webSocketBaseUrl: '/ws/',
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
|
||||||
import { Clipboard } from '@angular/cdk/clipboard'
|
import { Clipboard } from '@angular/cdk/clipboard'
|
||||||
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
|
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
|
||||||
import { provideHttpClientTesting } from '@angular/common/http/testing'
|
import { provideHttpClientTesting } from '@angular/common/http/testing'
|
||||||
@ -142,4 +157,15 @@ describe('SystemStatusDialogComponent', () => {
|
|||||||
`Task ${PaperlessTaskName.IndexOptimize} started`
|
`Task ${PaperlessTaskName.IndexOptimize} started`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('shoduld handle version mismatch', () => {
|
||||||
|
component.frontendVersion = '2.4.2'
|
||||||
|
component.ngOnInit()
|
||||||
|
expect(component.versionMismatch).toBeTruthy()
|
||||||
|
expect(component.status.pngx_version).toContain('(frontend: 2.4.2)')
|
||||||
|
component.frontendVersion = '2.4.3'
|
||||||
|
component.status.pngx_version = '2.4.3'
|
||||||
|
component.ngOnInit()
|
||||||
|
expect(component.versionMismatch).toBeFalsy()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Clipboard, ClipboardModule } from '@angular/cdk/clipboard'
|
import { Clipboard, ClipboardModule } from '@angular/cdk/clipboard'
|
||||||
import { Component } from '@angular/core'
|
import { Component, OnInit, inject } from '@angular/core'
|
||||||
import {
|
import {
|
||||||
NgbActiveModal,
|
NgbActiveModal,
|
||||||
NgbModalModule,
|
NgbModalModule,
|
||||||
@ -18,6 +18,7 @@ import { PermissionsService } from 'src/app/services/permissions.service'
|
|||||||
import { SystemStatusService } from 'src/app/services/system-status.service'
|
import { SystemStatusService } from 'src/app/services/system-status.service'
|
||||||
import { TasksService } from 'src/app/services/tasks.service'
|
import { TasksService } from 'src/app/services/tasks.service'
|
||||||
import { ToastService } from 'src/app/services/toast.service'
|
import { ToastService } from 'src/app/services/toast.service'
|
||||||
|
import { environment } from 'src/environments/environment'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'pngx-system-status-dialog',
|
selector: 'pngx-system-status-dialog',
|
||||||
@ -33,10 +34,19 @@ import { ToastService } from 'src/app/services/toast.service'
|
|||||||
NgxBootstrapIconsModule,
|
NgxBootstrapIconsModule,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class SystemStatusDialogComponent {
|
export class SystemStatusDialogComponent implements OnInit {
|
||||||
|
activeModal = inject(NgbActiveModal)
|
||||||
|
private clipboard = inject(Clipboard)
|
||||||
|
private systemStatusService = inject(SystemStatusService)
|
||||||
|
private tasksService = inject(TasksService)
|
||||||
|
private toastService = inject(ToastService)
|
||||||
|
private permissionsService = inject(PermissionsService)
|
||||||
|
|
||||||
public SystemStatusItemStatus = SystemStatusItemStatus
|
public SystemStatusItemStatus = SystemStatusItemStatus
|
||||||
public PaperlessTaskName = PaperlessTaskName
|
public PaperlessTaskName = PaperlessTaskName
|
||||||
public status: SystemStatus
|
public status: SystemStatus
|
||||||
|
public frontendVersion: string = environment.version
|
||||||
|
public versionMismatch: boolean = false
|
||||||
|
|
||||||
public copied: boolean = false
|
public copied: boolean = false
|
||||||
|
|
||||||
@ -46,14 +56,16 @@ export class SystemStatusDialogComponent {
|
|||||||
return this.permissionsService.isSuperUser()
|
return this.permissionsService.isSuperUser()
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(
|
public ngOnInit() {
|
||||||
public activeModal: NgbActiveModal,
|
this.versionMismatch =
|
||||||
private clipboard: Clipboard,
|
environment.production &&
|
||||||
private systemStatusService: SystemStatusService,
|
this.status.pngx_version &&
|
||||||
private tasksService: TasksService,
|
this.frontendVersion &&
|
||||||
private toastService: ToastService,
|
this.status.pngx_version !== this.frontendVersion
|
||||||
private permissionsService: PermissionsService
|
if (this.versionMismatch) {
|
||||||
) {}
|
this.status.pngx_version = `${this.status.pngx_version} (frontend: ${this.frontendVersion})`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public close() {
|
public close() {
|
||||||
this.activeModal.close()
|
this.activeModal.close()
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, Input } from '@angular/core'
|
import { Component, inject, Input } from '@angular/core'
|
||||||
import { Tag } from 'src/app/data/tag'
|
import { Tag } from 'src/app/data/tag'
|
||||||
import {
|
import {
|
||||||
PermissionAction,
|
PermissionAction,
|
||||||
@ -13,14 +13,12 @@ import { TagService } from 'src/app/services/rest/tag.service'
|
|||||||
styleUrls: ['./tag.component.scss'],
|
styleUrls: ['./tag.component.scss'],
|
||||||
})
|
})
|
||||||
export class TagComponent {
|
export class TagComponent {
|
||||||
|
private permissionsService = inject(PermissionsService)
|
||||||
|
private tagService = inject(TagService)
|
||||||
|
|
||||||
private _tag: Tag
|
private _tag: Tag
|
||||||
private _tagID: number
|
private _tagID: number
|
||||||
|
|
||||||
constructor(
|
|
||||||
private permissionsService: PermissionsService,
|
|
||||||
private tagService: TagService
|
|
||||||
) {}
|
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
public set tag(tag: Tag) {
|
public set tag(tag: Tag) {
|
||||||
this._tag = tag
|
this._tag = tag
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Clipboard } from '@angular/cdk/clipboard'
|
import { Clipboard } from '@angular/cdk/clipboard'
|
||||||
import { DecimalPipe } from '@angular/common'
|
import { DecimalPipe } from '@angular/common'
|
||||||
import { Component, EventEmitter, Input, Output } from '@angular/core'
|
import { Component, EventEmitter, Input, Output, inject } from '@angular/core'
|
||||||
import {
|
import {
|
||||||
NgbProgressbarModule,
|
NgbProgressbarModule,
|
||||||
NgbToastModule,
|
NgbToastModule,
|
||||||
@ -21,6 +21,8 @@ import { Toast } from 'src/app/services/toast.service'
|
|||||||
styleUrl: './toast.component.scss',
|
styleUrl: './toast.component.scss',
|
||||||
})
|
})
|
||||||
export class ToastComponent {
|
export class ToastComponent {
|
||||||
|
private clipboard = inject(Clipboard)
|
||||||
|
|
||||||
@Input() toast: Toast
|
@Input() toast: Toast
|
||||||
|
|
||||||
@Input() autohide: boolean = true
|
@Input() autohide: boolean = true
|
||||||
@ -31,8 +33,6 @@ export class ToastComponent {
|
|||||||
|
|
||||||
public copied: boolean = false
|
public copied: boolean = false
|
||||||
|
|
||||||
constructor(private clipboard: Clipboard) {}
|
|
||||||
|
|
||||||
onShown(toast: Toast) {
|
onShown(toast: Toast) {
|
||||||
if (!this.autohide) return
|
if (!this.autohide) return
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, OnDestroy, OnInit } from '@angular/core'
|
import { Component, OnDestroy, OnInit, inject } from '@angular/core'
|
||||||
import {
|
import {
|
||||||
NgbAccordionModule,
|
NgbAccordionModule,
|
||||||
NgbProgressbarModule,
|
NgbProgressbarModule,
|
||||||
@ -20,7 +20,7 @@ import { ToastComponent } from '../toast/toast.component'
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class ToastsComponent implements OnInit, OnDestroy {
|
export class ToastsComponent implements OnInit, OnDestroy {
|
||||||
constructor(public toastService: ToastService) {}
|
toastService = inject(ToastService)
|
||||||
|
|
||||||
private subscription: Subscription
|
private subscription: Subscription
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import {
|
|||||||
DragDropModule,
|
DragDropModule,
|
||||||
moveItemInArray,
|
moveItemInArray,
|
||||||
} from '@angular/cdk/drag-drop'
|
} from '@angular/cdk/drag-drop'
|
||||||
import { Component } from '@angular/core'
|
import { Component, inject } from '@angular/core'
|
||||||
import { RouterModule } from '@angular/router'
|
import { RouterModule } from '@angular/router'
|
||||||
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
||||||
import { TourNgBootstrapModule, TourService } from 'ngx-ui-tour-ng-bootstrap'
|
import { TourNgBootstrapModule, TourService } from 'ngx-ui-tour-ng-bootstrap'
|
||||||
@ -42,13 +42,13 @@ import { WelcomeWidgetComponent } from './widgets/welcome-widget/welcome-widget.
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class DashboardComponent extends ComponentWithPermissions {
|
export class DashboardComponent extends ComponentWithPermissions {
|
||||||
|
settingsService = inject(SettingsService)
|
||||||
|
savedViewService = inject(SavedViewService)
|
||||||
|
private tourService = inject(TourService)
|
||||||
|
private toastService = inject(ToastService)
|
||||||
|
|
||||||
public dashboardViews: SavedView[] = []
|
public dashboardViews: SavedView[] = []
|
||||||
constructor(
|
constructor() {
|
||||||
public settingsService: SettingsService,
|
|
||||||
public savedViewService: SavedViewService,
|
|
||||||
private tourService: TourService,
|
|
||||||
private toastService: ToastService
|
|
||||||
) {
|
|
||||||
super()
|
super()
|
||||||
|
|
||||||
this.savedViewService.listAll().subscribe(() => {
|
this.savedViewService.listAll().subscribe(() => {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { AsyncPipe, NgClass, NgStyle } from '@angular/common'
|
import { AsyncPipe, NgClass, NgStyle } from '@angular/common'
|
||||||
import {
|
import {
|
||||||
Component,
|
Component,
|
||||||
|
inject,
|
||||||
Input,
|
Input,
|
||||||
OnDestroy,
|
OnDestroy,
|
||||||
OnInit,
|
OnInit,
|
||||||
@ -84,26 +85,22 @@ export class SavedViewWidgetComponent
|
|||||||
extends LoadingComponentWithPermissions
|
extends LoadingComponentWithPermissions
|
||||||
implements OnInit, OnDestroy
|
implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
|
private documentService = inject(DocumentService)
|
||||||
|
private router = inject(Router)
|
||||||
|
private list = inject(DocumentListViewService)
|
||||||
|
private websocketStatusService = inject(WebsocketStatusService)
|
||||||
|
openDocumentsService = inject(OpenDocumentsService)
|
||||||
|
documentListViewService = inject(DocumentListViewService)
|
||||||
|
permissionsService = inject(PermissionsService)
|
||||||
|
private settingsService = inject(SettingsService)
|
||||||
|
private customFieldService = inject(CustomFieldsService)
|
||||||
|
|
||||||
public DisplayMode = DisplayMode
|
public DisplayMode = DisplayMode
|
||||||
public DisplayField = DisplayField
|
public DisplayField = DisplayField
|
||||||
public CustomFieldDataType = CustomFieldDataType
|
public CustomFieldDataType = CustomFieldDataType
|
||||||
|
|
||||||
private customFields: CustomField[] = []
|
private customFields: CustomField[] = []
|
||||||
|
|
||||||
constructor(
|
|
||||||
private documentService: DocumentService,
|
|
||||||
private router: Router,
|
|
||||||
private list: DocumentListViewService,
|
|
||||||
private websocketStatusService: WebsocketStatusService,
|
|
||||||
public openDocumentsService: OpenDocumentsService,
|
|
||||||
public documentListViewService: DocumentListViewService,
|
|
||||||
public permissionsService: PermissionsService,
|
|
||||||
private settingsService: SettingsService,
|
|
||||||
private customFieldService: CustomFieldsService
|
|
||||||
) {
|
|
||||||
super()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
savedView: SavedView
|
savedView: SavedView
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { DecimalPipe } from '@angular/common'
|
import { DecimalPipe } from '@angular/common'
|
||||||
import { HttpClient } from '@angular/common/http'
|
import { HttpClient } from '@angular/common/http'
|
||||||
import { Component, OnDestroy, OnInit } from '@angular/core'
|
import { Component, inject, OnDestroy, OnInit } from '@angular/core'
|
||||||
import { RouterModule } from '@angular/router'
|
import { RouterModule } from '@angular/router'
|
||||||
import { NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import * as mimeTypeNames from 'mime-names'
|
import * as mimeTypeNames from 'mime-names'
|
||||||
@ -51,15 +51,11 @@ export class StatisticsWidgetComponent
|
|||||||
extends ComponentWithPermissions
|
extends ComponentWithPermissions
|
||||||
implements OnInit, OnDestroy
|
implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
loading: boolean = false
|
private http = inject(HttpClient)
|
||||||
|
private websocketConnectionService = inject(WebsocketStatusService)
|
||||||
|
private documentListViewService = inject(DocumentListViewService)
|
||||||
|
|
||||||
constructor(
|
loading: boolean = false
|
||||||
private http: HttpClient,
|
|
||||||
private websocketConnectionService: WebsocketStatusService,
|
|
||||||
private documentListViewService: DocumentListViewService
|
|
||||||
) {
|
|
||||||
super()
|
|
||||||
}
|
|
||||||
|
|
||||||
statistics: Statistics = {}
|
statistics: Statistics = {}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { NgClass, NgTemplateOutlet } from '@angular/common'
|
import { NgClass, NgTemplateOutlet } from '@angular/common'
|
||||||
import { Component, QueryList, ViewChildren } from '@angular/core'
|
import { Component, QueryList, ViewChildren, inject } from '@angular/core'
|
||||||
import { RouterModule } from '@angular/router'
|
import { RouterModule } from '@angular/router'
|
||||||
import {
|
import {
|
||||||
NgbAlert,
|
NgbAlert,
|
||||||
@ -37,15 +37,11 @@ import { WidgetFrameComponent } from '../widget-frame/widget-frame.component'
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class UploadFileWidgetComponent extends ComponentWithPermissions {
|
export class UploadFileWidgetComponent extends ComponentWithPermissions {
|
||||||
@ViewChildren(NgbAlert) alerts: QueryList<NgbAlert>
|
private websocketStatusService = inject(WebsocketStatusService)
|
||||||
|
private uploadDocumentsService = inject(UploadDocumentsService)
|
||||||
|
settingsService = inject(SettingsService)
|
||||||
|
|
||||||
constructor(
|
@ViewChildren(NgbAlert) alerts: QueryList<NgbAlert>
|
||||||
private websocketStatusService: WebsocketStatusService,
|
|
||||||
private uploadDocumentsService: UploadDocumentsService,
|
|
||||||
public settingsService: SettingsService
|
|
||||||
) {
|
|
||||||
super()
|
|
||||||
}
|
|
||||||
|
|
||||||
getStatus() {
|
getStatus() {
|
||||||
return this.websocketStatusService.getConsumerStatus()
|
return this.websocketStatusService.getConsumerStatus()
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, EventEmitter, Output } from '@angular/core'
|
import { Component, EventEmitter, Output, inject } from '@angular/core'
|
||||||
import { NgbAlertModule } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbAlertModule } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { TourService } from 'ngx-ui-tour-ng-bootstrap'
|
import { TourService } from 'ngx-ui-tour-ng-bootstrap'
|
||||||
|
|
||||||
@ -9,7 +9,7 @@ import { TourService } from 'ngx-ui-tour-ng-bootstrap'
|
|||||||
imports: [NgbAlertModule],
|
imports: [NgbAlertModule],
|
||||||
})
|
})
|
||||||
export class WelcomeWidgetComponent {
|
export class WelcomeWidgetComponent {
|
||||||
constructor(public readonly tourService: TourService) {}
|
readonly tourService = inject(TourService)
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
dismiss: EventEmitter<boolean> = new EventEmitter()
|
dismiss: EventEmitter<boolean> = new EventEmitter()
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, OnInit } from '@angular/core'
|
import { Component, OnInit, inject } from '@angular/core'
|
||||||
import { ActivatedRoute, Router } from '@angular/router'
|
import { ActivatedRoute, Router } from '@angular/router'
|
||||||
import { FILTER_ASN } from '../../data/filter-rule-type'
|
import { FILTER_ASN } from '../../data/filter-rule-type'
|
||||||
import { DocumentService } from '../../services/rest/document.service'
|
import { DocumentService } from '../../services/rest/document.service'
|
||||||
@ -9,12 +9,11 @@ import { DocumentService } from '../../services/rest/document.service'
|
|||||||
styleUrls: ['./document-asn.component.scss'],
|
styleUrls: ['./document-asn.component.scss'],
|
||||||
})
|
})
|
||||||
export class DocumentAsnComponent implements OnInit {
|
export class DocumentAsnComponent implements OnInit {
|
||||||
|
private documentsService = inject(DocumentService)
|
||||||
|
private route = inject(ActivatedRoute)
|
||||||
|
private router = inject(Router)
|
||||||
|
|
||||||
asn: string
|
asn: string
|
||||||
constructor(
|
|
||||||
private documentsService: DocumentService,
|
|
||||||
private route: ActivatedRoute,
|
|
||||||
private router: Router
|
|
||||||
) {}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.route.paramMap.subscribe((paramMap) => {
|
this.route.paramMap.subscribe((paramMap) => {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { AsyncPipe, NgTemplateOutlet } from '@angular/common'
|
import { AsyncPipe, NgTemplateOutlet } from '@angular/common'
|
||||||
import { HttpClient, HttpResponse } from '@angular/common/http'
|
import { HttpClient, HttpResponse } from '@angular/common/http'
|
||||||
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'
|
import { Component, inject, OnDestroy, OnInit, ViewChild } from '@angular/core'
|
||||||
import {
|
import {
|
||||||
FormArray,
|
FormArray,
|
||||||
FormControl,
|
FormControl,
|
||||||
@ -176,6 +176,26 @@ export class DocumentDetailComponent
|
|||||||
extends ComponentWithPermissions
|
extends ComponentWithPermissions
|
||||||
implements OnInit, OnDestroy, DirtyComponent
|
implements OnInit, OnDestroy, DirtyComponent
|
||||||
{
|
{
|
||||||
|
private documentsService = inject(DocumentService)
|
||||||
|
private route = inject(ActivatedRoute)
|
||||||
|
private correspondentService = inject(CorrespondentService)
|
||||||
|
private documentTypeService = inject(DocumentTypeService)
|
||||||
|
private router = inject(Router)
|
||||||
|
private modalService = inject(NgbModal)
|
||||||
|
private openDocumentService = inject(OpenDocumentsService)
|
||||||
|
private documentListViewService = inject(DocumentListViewService)
|
||||||
|
private documentTitlePipe = inject(DocumentTitlePipe)
|
||||||
|
private toastService = inject(ToastService)
|
||||||
|
private settings = inject(SettingsService)
|
||||||
|
private storagePathService = inject(StoragePathService)
|
||||||
|
private permissionsService = inject(PermissionsService)
|
||||||
|
private userService = inject(UserService)
|
||||||
|
private customFieldsService = inject(CustomFieldsService)
|
||||||
|
private http = inject(HttpClient)
|
||||||
|
private hotKeyService = inject(HotKeyService)
|
||||||
|
private componentRouterService = inject(ComponentRouterService)
|
||||||
|
private deviceDetectorService = inject(DeviceDetectorService)
|
||||||
|
|
||||||
@ViewChild('inputTitle')
|
@ViewChild('inputTitle')
|
||||||
titleInput: TextComponent
|
titleInput: TextComponent
|
||||||
|
|
||||||
@ -259,30 +279,6 @@ export class DocumentDetailComponent
|
|||||||
DocumentDetailNavIDs = DocumentDetailNavIDs
|
DocumentDetailNavIDs = DocumentDetailNavIDs
|
||||||
activeNavID: number
|
activeNavID: number
|
||||||
|
|
||||||
constructor(
|
|
||||||
private documentsService: DocumentService,
|
|
||||||
private route: ActivatedRoute,
|
|
||||||
private correspondentService: CorrespondentService,
|
|
||||||
private documentTypeService: DocumentTypeService,
|
|
||||||
private router: Router,
|
|
||||||
private modalService: NgbModal,
|
|
||||||
private openDocumentService: OpenDocumentsService,
|
|
||||||
private documentListViewService: DocumentListViewService,
|
|
||||||
private documentTitlePipe: DocumentTitlePipe,
|
|
||||||
private toastService: ToastService,
|
|
||||||
private settings: SettingsService,
|
|
||||||
private storagePathService: StoragePathService,
|
|
||||||
private permissionsService: PermissionsService,
|
|
||||||
private userService: UserService,
|
|
||||||
private customFieldsService: CustomFieldsService,
|
|
||||||
private http: HttpClient,
|
|
||||||
private hotKeyService: HotKeyService,
|
|
||||||
private componentRouterService: ComponentRouterService,
|
|
||||||
private deviceDetectorService: DeviceDetectorService
|
|
||||||
) {
|
|
||||||
super()
|
|
||||||
}
|
|
||||||
|
|
||||||
titleKeyUp(event) {
|
titleKeyUp(event) {
|
||||||
this.titleSubject.next(event.target?.value)
|
this.titleSubject.next(event.target?.value)
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { AsyncPipe, KeyValuePipe, TitleCasePipe } from '@angular/common'
|
import { AsyncPipe, KeyValuePipe, TitleCasePipe } from '@angular/common'
|
||||||
import { Component, Input, OnInit } from '@angular/core'
|
import { Component, Input, OnInit, inject } from '@angular/core'
|
||||||
import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
||||||
import { Observable, first, map, of } from 'rxjs'
|
import { Observable, first, map, of } from 'rxjs'
|
||||||
@ -26,6 +26,12 @@ import { UserService } from 'src/app/services/rest/user.service'
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class DocumentHistoryComponent implements OnInit {
|
export class DocumentHistoryComponent implements OnInit {
|
||||||
|
private documentService = inject(DocumentService)
|
||||||
|
private correspondentService = inject(CorrespondentService)
|
||||||
|
private storagePathService = inject(StoragePathService)
|
||||||
|
private documentTypeService = inject(DocumentTypeService)
|
||||||
|
private userService = inject(UserService)
|
||||||
|
|
||||||
public AuditLogAction = AuditLogAction
|
public AuditLogAction = AuditLogAction
|
||||||
|
|
||||||
private _documentId: number
|
private _documentId: number
|
||||||
@ -38,14 +44,6 @@ export class DocumentHistoryComponent implements OnInit {
|
|||||||
public loading: boolean = true
|
public loading: boolean = true
|
||||||
public entries: AuditLogEntry[] = []
|
public entries: AuditLogEntry[] = []
|
||||||
|
|
||||||
constructor(
|
|
||||||
private documentService: DocumentService,
|
|
||||||
private correspondentService: CorrespondentService,
|
|
||||||
private storagePathService: StoragePathService,
|
|
||||||
private documentTypeService: DocumentTypeService,
|
|
||||||
private userService: UserService
|
|
||||||
) {}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
if (this._documentId) {
|
if (this._documentId) {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, Input, OnDestroy, OnInit } from '@angular/core'
|
import { Component, inject, Input, OnDestroy, OnInit } from '@angular/core'
|
||||||
import {
|
import {
|
||||||
FormControl,
|
FormControl,
|
||||||
FormGroup,
|
FormGroup,
|
||||||
@ -71,6 +71,19 @@ export class BulkEditorComponent
|
|||||||
extends ComponentWithPermissions
|
extends ComponentWithPermissions
|
||||||
implements OnInit, OnDestroy
|
implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
|
private documentTypeService = inject(DocumentTypeService)
|
||||||
|
private tagService = inject(TagService)
|
||||||
|
private correspondentService = inject(CorrespondentService)
|
||||||
|
list = inject(DocumentListViewService)
|
||||||
|
private documentService = inject(DocumentService)
|
||||||
|
private modalService = inject(NgbModal)
|
||||||
|
private openDocumentService = inject(OpenDocumentsService)
|
||||||
|
private settings = inject(SettingsService)
|
||||||
|
private toastService = inject(ToastService)
|
||||||
|
private storagePathService = inject(StoragePathService)
|
||||||
|
private customFieldService = inject(CustomFieldsService)
|
||||||
|
private permissionService = inject(PermissionsService)
|
||||||
|
|
||||||
tagSelectionModel = new FilterableDropdownSelectionModel(true)
|
tagSelectionModel = new FilterableDropdownSelectionModel(true)
|
||||||
correspondentSelectionModel = new FilterableDropdownSelectionModel()
|
correspondentSelectionModel = new FilterableDropdownSelectionModel()
|
||||||
documentTypeSelectionModel = new FilterableDropdownSelectionModel()
|
documentTypeSelectionModel = new FilterableDropdownSelectionModel()
|
||||||
@ -94,23 +107,6 @@ export class BulkEditorComponent
|
|||||||
@Input()
|
@Input()
|
||||||
public disabled: boolean = false
|
public disabled: boolean = false
|
||||||
|
|
||||||
constructor(
|
|
||||||
private documentTypeService: DocumentTypeService,
|
|
||||||
private tagService: TagService,
|
|
||||||
private correspondentService: CorrespondentService,
|
|
||||||
public list: DocumentListViewService,
|
|
||||||
private documentService: DocumentService,
|
|
||||||
private modalService: NgbModal,
|
|
||||||
private openDocumentService: OpenDocumentsService,
|
|
||||||
private settings: SettingsService,
|
|
||||||
private toastService: ToastService,
|
|
||||||
private storagePathService: StoragePathService,
|
|
||||||
private customFieldService: CustomFieldsService,
|
|
||||||
private permissionService: PermissionsService
|
|
||||||
) {
|
|
||||||
super()
|
|
||||||
}
|
|
||||||
|
|
||||||
applyOnClose: boolean = this.settings.get(
|
applyOnClose: boolean = this.settings.get(
|
||||||
SETTINGS_KEYS.BULK_EDIT_APPLY_ON_CLOSE
|
SETTINGS_KEYS.BULK_EDIT_APPLY_ON_CLOSE
|
||||||
)
|
)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, EventEmitter, Output } from '@angular/core'
|
import { Component, EventEmitter, Output, inject } from '@angular/core'
|
||||||
import {
|
import {
|
||||||
FormControl,
|
FormControl,
|
||||||
FormGroup,
|
FormGroup,
|
||||||
@ -38,6 +38,9 @@ import { DocumentService } from 'src/app/services/rest/document.service'
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class CustomFieldsBulkEditDialogComponent {
|
export class CustomFieldsBulkEditDialogComponent {
|
||||||
|
private activeModal = inject(NgbActiveModal)
|
||||||
|
private documentService = inject(DocumentService)
|
||||||
|
|
||||||
CustomFieldDataType = CustomFieldDataType
|
CustomFieldDataType = CustomFieldDataType
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
@ -73,11 +76,6 @@ export class CustomFieldsBulkEditDialogComponent {
|
|||||||
|
|
||||||
public documents: number[] = []
|
public documents: number[] = []
|
||||||
|
|
||||||
constructor(
|
|
||||||
private activeModal: NgbActiveModal,
|
|
||||||
private documentService: DocumentService
|
|
||||||
) {}
|
|
||||||
|
|
||||||
initForm() {
|
initForm() {
|
||||||
Object.keys(this.form.controls).forEach((key) => {
|
Object.keys(this.form.controls).forEach((key) => {
|
||||||
if (!this._fieldsToAddIds.includes(parseInt(key))) {
|
if (!this._fieldsToAddIds.includes(parseInt(key))) {
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user