mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-09-06 21:13:43 -05:00
Compare commits
1 Commits
e1b9434645
...
feature-pr
Author | SHA1 | Date | |
---|---|---|---|
![]() |
4070cd0e1b |
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -16,7 +16,7 @@ on:
|
|||||||
env:
|
env:
|
||||||
# This is the version of pipenv all the steps will use
|
# This is the version of pipenv all the steps will use
|
||||||
# If changing this, change Dockerfile
|
# If changing this, change Dockerfile
|
||||||
DEFAULT_PIP_ENV_VERSION: "2024.4.1"
|
DEFAULT_PIP_ENV_VERSION: "2024.4.0"
|
||||||
# This is the default version of Python to use in most steps which aren't specific
|
# This is the default version of Python to use in most steps which aren't specific
|
||||||
DEFAULT_PYTHON_VERSION: "3.11"
|
DEFAULT_PYTHON_VERSION: "3.11"
|
||||||
|
|
||||||
|
@@ -29,7 +29,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.3.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: codespell
|
- id: codespell
|
||||||
exclude: "(^src-ui/src/locale/)|(^src-ui/e2e/)|(^src/paperless_mail/tests/samples/)"
|
exclude: "(^src-ui/src/locale/)|(^src-ui/e2e/)|(^src/paperless_mail/tests/samples/)"
|
||||||
|
10
Dockerfile
10
Dockerfile
@@ -39,7 +39,7 @@ COPY Pipfile* ./
|
|||||||
|
|
||||||
RUN set -eux \
|
RUN set -eux \
|
||||||
&& echo "Installing pipenv" \
|
&& echo "Installing pipenv" \
|
||||||
&& python3 -m pip install --no-cache-dir --upgrade pipenv==2024.4.1 \
|
&& python3 -m pip install --no-cache-dir --upgrade pipenv==2024.4.0 \
|
||||||
&& echo "Generating requirement.txt" \
|
&& echo "Generating requirement.txt" \
|
||||||
&& pipenv requirements > requirements.txt
|
&& pipenv requirements > requirements.txt
|
||||||
|
|
||||||
@@ -233,11 +233,11 @@ RUN --mount=type=cache,target=/root/.cache/pip/,id=pip-cache \
|
|||||||
&& python3 -m pip install --no-cache-dir --upgrade wheel \
|
&& python3 -m pip install --no-cache-dir --upgrade wheel \
|
||||||
&& echo "Installing Python requirements" \
|
&& echo "Installing Python requirements" \
|
||||||
&& curl --fail --silent --show-error --location \
|
&& curl --fail --silent --show-error --location \
|
||||||
--output psycopg_c-3.2.4-cp312-cp312-linux_x86_64.whl \
|
--output psycopg_c-3.2.3-cp312-cp312-linux_x86_64.whl \
|
||||||
https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.4/psycopg_c-3.2.4-cp312-cp312-linux_x86_64.whl \
|
https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.3/psycopg_c-3.2.3-cp312-cp312-linux_x86_64.whl \
|
||||||
&& curl --fail --silent --show-error --location \
|
&& curl --fail --silent --show-error --location \
|
||||||
--output psycopg_c-3.2.4-cp312-cp312-linux_aarch64.whl \
|
--output psycopg_c-3.2.3-cp312-cp312-linux_aarch64.whl \
|
||||||
https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.4/psycopg_c-3.2.4-cp312-cp312-linux_aarch64.whl \
|
https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.3/psycopg_c-3.2.3-cp312-cp312-linux_aarch64.whl \
|
||||||
&& python3 -m pip install --default-timeout=1000 --find-links . --requirement requirements.txt \
|
&& python3 -m pip install --default-timeout=1000 --find-links . --requirement requirements.txt \
|
||||||
&& echo "Installing NLTK data" \
|
&& echo "Installing NLTK data" \
|
||||||
&& python3 -W ignore::RuntimeWarning -m nltk.downloader -d "/usr/share/nltk_data" snowball_data \
|
&& python3 -W ignore::RuntimeWarning -m nltk.downloader -d "/usr/share/nltk_data" snowball_data \
|
||||||
|
2362
Pipfile.lock
generated
2362
Pipfile.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -81,8 +81,7 @@
|
|||||||
"scripts": [],
|
"scripts": [],
|
||||||
"allowedCommonJsDependencies": [
|
"allowedCommonJsDependencies": [
|
||||||
"ng2-pdf-viewer",
|
"ng2-pdf-viewer",
|
||||||
"file-saver",
|
"file-saver"
|
||||||
"utif"
|
|
||||||
],
|
],
|
||||||
"vendorChunk": true,
|
"vendorChunk": true,
|
||||||
"extractLicenses": false,
|
"extractLicenses": false,
|
||||||
|
@@ -324,7 +324,7 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/document-list.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-list/document-list.component.ts</context>
|
||||||
<context context-type="linenumber">193</context>
|
<context context-type="linenumber">187</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/manage/custom-fields/custom-fields.component.html</context>
|
<context context-type="sourcefile">src/app/components/manage/custom-fields/custom-fields.component.html</context>
|
||||||
@@ -523,7 +523,7 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
||||||
<context context-type="linenumber">123</context>
|
<context context-type="linenumber">124</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="3823219296477075982" datatype="html">
|
<trans-unit id="3823219296477075982" datatype="html">
|
||||||
@@ -589,7 +589,7 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
||||||
<context context-type="linenumber">183</context>
|
<context context-type="linenumber">184</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
|
||||||
@@ -723,11 +723,11 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
||||||
<context context-type="linenumber">110</context>
|
<context context-type="linenumber">111</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
||||||
<context context-type="linenumber">126</context>
|
<context context-type="linenumber">127</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/system-status-dialog/system-status-dialog.component.html</context>
|
<context context-type="sourcefile">src/app/components/common/system-status-dialog/system-status-dialog.component.html</context>
|
||||||
@@ -1128,11 +1128,11 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">58</context>
|
<context context-type="linenumber">63</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">95</context>
|
<context context-type="linenumber">100</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="293524471897878391" datatype="html">
|
<trans-unit id="293524471897878391" datatype="html">
|
||||||
@@ -1445,7 +1445,7 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
||||||
<context context-type="linenumber">182</context>
|
<context context-type="linenumber">183</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.html</context>
|
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.html</context>
|
||||||
@@ -1712,11 +1712,11 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">34</context>
|
<context context-type="linenumber">39</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">92</context>
|
<context context-type="linenumber">97</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="5968132631442328843" datatype="html">
|
<trans-unit id="5968132631442328843" datatype="html">
|
||||||
@@ -2232,7 +2232,7 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||||
<context context-type="linenumber">924</context>
|
<context context-type="linenumber">922</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="7266264608936522311" datatype="html">
|
<trans-unit id="7266264608936522311" datatype="html">
|
||||||
@@ -2509,19 +2509,19 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||||
<context context-type="linenumber">948</context>
|
<context context-type="linenumber">946</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||||
<context context-type="linenumber">1255</context>
|
<context context-type="linenumber">1253</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||||
<context context-type="linenumber">1294</context>
|
<context context-type="linenumber">1292</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||||
<context context-type="linenumber">1335</context>
|
<context context-type="linenumber">1333</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
|
||||||
@@ -2738,7 +2738,7 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">42</context>
|
<context context-type="linenumber">47</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="4369111787961525769" datatype="html">
|
<trans-unit id="4369111787961525769" datatype="html">
|
||||||
@@ -2950,7 +2950,7 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
|
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
|
||||||
<context context-type="linenumber">103</context>
|
<context context-type="linenumber">80</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
|
||||||
@@ -3115,7 +3115,7 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||||
<context context-type="linenumber">901</context>
|
<context context-type="linenumber">899</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
|
||||||
@@ -3439,11 +3439,11 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">38</context>
|
<context context-type="linenumber">43</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">93</context>
|
<context context-type="linenumber">98</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="4873149362496451858" datatype="html">
|
<trans-unit id="4873149362496451858" datatype="html">
|
||||||
@@ -4310,11 +4310,11 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
||||||
<context context-type="linenumber">103</context>
|
<context context-type="linenumber">104</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
||||||
<context context-type="linenumber">137</context>
|
<context context-type="linenumber">138</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="8418597938335066730" datatype="html">
|
<trans-unit id="8418597938335066730" datatype="html">
|
||||||
@@ -4329,43 +4329,43 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
||||||
<context context-type="linenumber">168</context>
|
<context context-type="linenumber">169</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
||||||
<context context-type="linenumber">170</context>
|
<context context-type="linenumber">171</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="1436831433675346331" datatype="html">
|
<trans-unit id="1436831433675346331" datatype="html">
|
||||||
<source>Create new user account</source>
|
<source>Create new user account</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.ts</context>
|
<context context-type="sourcefile">src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.ts</context>
|
||||||
<context context-type="linenumber">71</context>
|
<context context-type="linenumber">66</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="2887331217965896363" datatype="html">
|
<trans-unit id="2887331217965896363" datatype="html">
|
||||||
<source>Edit user account</source>
|
<source>Edit user account</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.ts</context>
|
<context context-type="sourcefile">src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.ts</context>
|
||||||
<context context-type="linenumber">75</context>
|
<context context-type="linenumber">70</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="5872286584705575476" datatype="html">
|
<trans-unit id="5872286584705575476" datatype="html">
|
||||||
<source>Totp deactivated</source>
|
<source>Totp deactivated</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.ts</context>
|
<context context-type="sourcefile">src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.ts</context>
|
||||||
<context context-type="linenumber">131</context>
|
<context context-type="linenumber">126</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="6439190193788239059" datatype="html">
|
<trans-unit id="6439190193788239059" datatype="html">
|
||||||
<source>Totp deactivation failed</source>
|
<source>Totp deactivation failed</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.ts</context>
|
<context context-type="sourcefile">src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.ts</context>
|
||||||
<context context-type="linenumber">134</context>
|
<context context-type="linenumber">129</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.ts</context>
|
<context context-type="sourcefile">src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.ts</context>
|
||||||
<context context-type="linenumber">139</context>
|
<context context-type="linenumber">134</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="8419515490539218007" datatype="html">
|
<trans-unit id="8419515490539218007" datatype="html">
|
||||||
@@ -4775,42 +4775,35 @@
|
|||||||
<source>Use parameters for webhook body</source>
|
<source>Use parameters for webhook body</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
|
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
|
||||||
<context context-type="linenumber">342</context>
|
<context context-type="linenumber">341</context>
|
||||||
</context-group>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="4078214298308732810" datatype="html">
|
|
||||||
<source>Send webhook payload as JSON</source>
|
|
||||||
<context-group purpose="location">
|
|
||||||
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
|
|
||||||
<context context-type="linenumber">343</context>
|
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="6806149889743731985" datatype="html">
|
<trans-unit id="6806149889743731985" datatype="html">
|
||||||
<source>Webhook params</source>
|
<source>Webhook params</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
|
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
|
||||||
<context context-type="linenumber">346</context>
|
<context context-type="linenumber">343</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="7089924379374330" datatype="html">
|
<trans-unit id="7089924379374330" datatype="html">
|
||||||
<source>Webhook body</source>
|
<source>Webhook body</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
|
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
|
||||||
<context context-type="linenumber">348</context>
|
<context context-type="linenumber">345</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="3829826512656746316" datatype="html">
|
<trans-unit id="3829826512656746316" datatype="html">
|
||||||
<source>Webhook headers</source>
|
<source>Webhook headers</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
|
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
|
||||||
<context context-type="linenumber">350</context>
|
<context context-type="linenumber">347</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="2114525789021600887" datatype="html">
|
<trans-unit id="2114525789021600887" datatype="html">
|
||||||
<source>Include document</source>
|
<source>Include document</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
|
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
|
||||||
<context context-type="linenumber">351</context>
|
<context context-type="linenumber">348</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="4626030417479279989" datatype="html">
|
<trans-unit id="4626030417479279989" datatype="html">
|
||||||
@@ -4842,7 +4835,7 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">94</context>
|
<context context-type="linenumber">99</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="8686921715946540725" datatype="html">
|
<trans-unit id="8686921715946540725" datatype="html">
|
||||||
@@ -4974,7 +4967,7 @@
|
|||||||
<source>Not assigned</source>
|
<source>Not assigned</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts</context>
|
<context context-type="sourcefile">src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts</context>
|
||||||
<context context-type="linenumber">380</context>
|
<context context-type="linenumber">390</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<note priority="1" from="description">Filter drop down element to filter for documents with no correspondent/type/tag assigned</note>
|
<note priority="1" from="description">Filter drop down element to filter for documents with no correspondent/type/tag assigned</note>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
@@ -4982,7 +4975,7 @@
|
|||||||
<source>Open <x id="PH" equiv-text="this.title"/> filter</source>
|
<source>Open <x id="PH" equiv-text="this.title"/> filter</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts</context>
|
<context context-type="sourcefile">src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts</context>
|
||||||
<context context-type="linenumber">501</context>
|
<context context-type="linenumber">511</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="7005745151564974365" datatype="html">
|
<trans-unit id="7005745151564974365" datatype="html">
|
||||||
@@ -5188,8 +5181,8 @@
|
|||||||
<context context-type="linenumber">13</context>
|
<context context-type="linenumber">13</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/pipes/object-name.pipe.ts</context>
|
<context context-type="sourcefile">src/app/components/document-list/document-card-small/document-card-small.component.ts</context>
|
||||||
<context context-type="linenumber">43</context>
|
<context context-type="linenumber">118</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="2504502765849142619" datatype="html">
|
<trans-unit id="2504502765849142619" datatype="html">
|
||||||
@@ -5394,7 +5387,7 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
||||||
<context context-type="linenumber">155</context>
|
<context context-type="linenumber">156</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/share-links-dropdown/share-links-dropdown.component.html</context>
|
<context context-type="sourcefile">src/app/components/common/share-links-dropdown/share-links-dropdown.component.html</context>
|
||||||
@@ -5432,11 +5425,11 @@
|
|||||||
<source>Copied!</source>
|
<source>Copied!</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
||||||
<context context-type="linenumber">54</context>
|
<context context-type="linenumber">55</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
||||||
<context context-type="linenumber">162</context>
|
<context context-type="linenumber">163</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/share-links-dropdown/share-links-dropdown.component.html</context>
|
<context context-type="sourcefile">src/app/components/common/share-links-dropdown/share-links-dropdown.component.html</context>
|
||||||
@@ -5447,91 +5440,91 @@
|
|||||||
<source>Warning: changing the token cannot be undone</source>
|
<source>Warning: changing the token cannot be undone</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
||||||
<context context-type="linenumber">56</context>
|
<context context-type="linenumber">57</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="8935717557476105185" datatype="html">
|
<trans-unit id="8935717557476105185" datatype="html">
|
||||||
<source>Connected social accounts</source>
|
<source>Connected social accounts</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
||||||
<context context-type="linenumber">62</context>
|
<context context-type="linenumber">63</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="8383227756109993898" datatype="html">
|
<trans-unit id="8383227756109993898" datatype="html">
|
||||||
<source>Set a password before disconnecting social account.</source>
|
<source>Set a password before disconnecting social account.</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
||||||
<context context-type="linenumber">66</context>
|
<context context-type="linenumber">67</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="2907016025519254862" datatype="html">
|
<trans-unit id="2907016025519254862" datatype="html">
|
||||||
<source>Disconnect</source>
|
<source>Disconnect</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
||||||
<context context-type="linenumber">72</context>
|
<context context-type="linenumber">73</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="5322995394400578831" datatype="html">
|
<trans-unit id="5322995394400578831" datatype="html">
|
||||||
<source>Disconnect <x id="INTERPOLATION" equiv-text="{{ account.name }}"/> social account</source>
|
<source>Disconnect <x id="INTERPOLATION" equiv-text="{{ account.name }}"/> social account</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
||||||
<context context-type="linenumber">74</context>
|
<context context-type="linenumber">75</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="649824314893051979" datatype="html">
|
<trans-unit id="649824314893051979" datatype="html">
|
||||||
<source>Warning: disconnecting social accounts cannot be undone</source>
|
<source>Warning: disconnecting social accounts cannot be undone</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
||||||
<context context-type="linenumber">84</context>
|
<context context-type="linenumber">85</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="1375396510511350122" datatype="html">
|
<trans-unit id="1375396510511350122" datatype="html">
|
||||||
<source>Connect new social account</source>
|
<source>Connect new social account</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
||||||
<context context-type="linenumber">89</context>
|
<context context-type="linenumber">90</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="4187671210825254690" datatype="html">
|
<trans-unit id="4187671210825254690" datatype="html">
|
||||||
<source>Scan the QR code with your authenticator app and then enter the code below</source>
|
<source>Scan the QR code with your authenticator app and then enter the code below</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
||||||
<context context-type="linenumber">114</context>
|
<context context-type="linenumber">115</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="5867169599865838267" datatype="html">
|
<trans-unit id="5867169599865838267" datatype="html">
|
||||||
<source>Authenticator secret</source>
|
<source>Authenticator secret</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
||||||
<context context-type="linenumber">117</context>
|
<context context-type="linenumber">118</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="5331198279926709145" datatype="html">
|
<trans-unit id="5331198279926709145" datatype="html">
|
||||||
<source>You can store this secret and use it to reinstall your authenticator app at a later time.</source>
|
<source>You can store this secret and use it to reinstall your authenticator app at a later time.</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
||||||
<context context-type="linenumber">118</context>
|
<context context-type="linenumber">119</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="8186013988289067040" datatype="html">
|
<trans-unit id="8186013988289067040" datatype="html">
|
||||||
<source>Code</source>
|
<source>Code</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
||||||
<context context-type="linenumber">121</context>
|
<context context-type="linenumber">122</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="3176701652604668614" datatype="html">
|
<trans-unit id="3176701652604668614" datatype="html">
|
||||||
<source>Recovery codes will not be shown again, make sure to save them.</source>
|
<source>Recovery codes will not be shown again, make sure to save them.</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
||||||
<context context-type="linenumber">140</context>
|
<context context-type="linenumber">141</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="2722512118372958038" datatype="html">
|
<trans-unit id="2722512118372958038" datatype="html">
|
||||||
<source>Copy codes</source>
|
<source>Copy codes</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
<context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html</context>
|
||||||
<context context-type="linenumber">158</context>
|
<context context-type="linenumber">159</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="6141884091799403188" datatype="html">
|
<trans-unit id="6141884091799403188" datatype="html">
|
||||||
@@ -5961,40 +5954,11 @@
|
|||||||
<context context-type="linenumber">345</context>
|
<context context-type="linenumber">345</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="883965278435032344" datatype="html">
|
|
||||||
<source>Filter by owner</source>
|
|
||||||
<context-group purpose="location">
|
|
||||||
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
|
|
||||||
<context context-type="linenumber">73</context>
|
|
||||||
</context-group>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="2807800733729323332" datatype="html">
|
|
||||||
<source>Yes</source>
|
|
||||||
<context-group purpose="location">
|
|
||||||
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
|
|
||||||
<context context-type="linenumber">83</context>
|
|
||||||
</context-group>
|
|
||||||
<context-group purpose="location">
|
|
||||||
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
|
|
||||||
<context context-type="linenumber">366</context>
|
|
||||||
</context-group>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="3542042671420335679" datatype="html">
|
|
||||||
<source>No</source>
|
|
||||||
<context-group purpose="location">
|
|
||||||
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
|
|
||||||
<context context-type="linenumber">83</context>
|
|
||||||
</context-group>
|
|
||||||
<context-group purpose="location">
|
|
||||||
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
|
|
||||||
<context context-type="linenumber">366</context>
|
|
||||||
</context-group>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="872092479747931526" datatype="html">
|
<trans-unit id="872092479747931526" datatype="html">
|
||||||
<source>No documents</source>
|
<source>No documents</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
|
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
|
||||||
<context context-type="linenumber">148</context>
|
<context context-type="linenumber">125</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="1069523139277190436" datatype="html">
|
<trans-unit id="1069523139277190436" datatype="html">
|
||||||
@@ -6241,7 +6205,7 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||||
<context context-type="linenumber">1312</context>
|
<context context-type="linenumber">1310</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/guards/dirty-saved-view.guard.ts</context>
|
<context context-type="sourcefile">src/app/guards/dirty-saved-view.guard.ts</context>
|
||||||
@@ -6278,11 +6242,11 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">30</context>
|
<context context-type="linenumber">35</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">90</context>
|
<context context-type="linenumber">95</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="1379170675585571971" datatype="html">
|
<trans-unit id="1379170675585571971" datatype="html">
|
||||||
@@ -6319,11 +6283,11 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">46</context>
|
<context context-type="linenumber">51</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">89</context>
|
<context context-type="linenumber">94</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="5066119607229701477" datatype="html">
|
<trans-unit id="5066119607229701477" datatype="html">
|
||||||
@@ -6346,11 +6310,11 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">50</context>
|
<context context-type="linenumber">55</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">91</context>
|
<context context-type="linenumber">96</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="2091353339965748767" datatype="html">
|
<trans-unit id="2091353339965748767" datatype="html">
|
||||||
@@ -6373,7 +6337,7 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">54</context>
|
<context context-type="linenumber">59</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="5607669932062416162" datatype="html">
|
<trans-unit id="5607669932062416162" datatype="html">
|
||||||
@@ -6631,21 +6595,21 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||||
<context context-type="linenumber">874</context>
|
<context context-type="linenumber">872</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="8410796510716511826" datatype="html">
|
<trans-unit id="8410796510716511826" datatype="html">
|
||||||
<source>Do you really want to move the document "<x id="PH" equiv-text="this.document.title"/>" to the trash?</source>
|
<source>Do you really want to move the document "<x id="PH" equiv-text="this.document.title"/>" to the trash?</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||||
<context context-type="linenumber">902</context>
|
<context context-type="linenumber">900</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="282586936710748252" datatype="html">
|
<trans-unit id="282586936710748252" datatype="html">
|
||||||
<source>Documents can be restored prior to permanent deletion.</source>
|
<source>Documents can be restored prior to permanent deletion.</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||||
<context context-type="linenumber">903</context>
|
<context context-type="linenumber">901</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
|
||||||
@@ -6656,7 +6620,7 @@
|
|||||||
<source>Move to trash</source>
|
<source>Move to trash</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||||
<context context-type="linenumber">905</context>
|
<context context-type="linenumber">903</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
|
||||||
@@ -6667,7 +6631,7 @@
|
|||||||
<source>Reprocess confirm</source>
|
<source>Reprocess confirm</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||||
<context context-type="linenumber">944</context>
|
<context context-type="linenumber">942</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
|
||||||
@@ -6678,70 +6642,70 @@
|
|||||||
<source>This operation will permanently recreate the archive file for this document.</source>
|
<source>This operation will permanently recreate the archive file for this document.</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||||
<context context-type="linenumber">945</context>
|
<context context-type="linenumber">943</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="302054111564709516" datatype="html">
|
<trans-unit id="302054111564709516" datatype="html">
|
||||||
<source>The archive file will be re-generated with the current settings.</source>
|
<source>The archive file will be re-generated with the current settings.</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||||
<context context-type="linenumber">946</context>
|
<context context-type="linenumber">944</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="1192507664585066165" datatype="html">
|
<trans-unit id="1192507664585066165" datatype="html">
|
||||||
<source>Reprocess operation will begin in the background. Close and re-open or reload this document after the operation has completed to see new content.</source>
|
<source>Reprocess operation will begin in the background. Close and re-open or reload this document after the operation has completed to see new content.</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||||
<context context-type="linenumber">956</context>
|
<context context-type="linenumber">954</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="4409560272830824468" datatype="html">
|
<trans-unit id="4409560272830824468" datatype="html">
|
||||||
<source>Error executing operation</source>
|
<source>Error executing operation</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||||
<context context-type="linenumber">967</context>
|
<context context-type="linenumber">965</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="4458954481601077369" datatype="html">
|
<trans-unit id="4458954481601077369" datatype="html">
|
||||||
<source>Page Fit</source>
|
<source>Page Fit</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||||
<context context-type="linenumber">1040</context>
|
<context context-type="linenumber">1038</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="1217563727923422413" datatype="html">
|
<trans-unit id="1217563727923422413" datatype="html">
|
||||||
<source>Split confirm</source>
|
<source>Split confirm</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||||
<context context-type="linenumber">1253</context>
|
<context context-type="linenumber">1251</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="2805304563009985503" datatype="html">
|
<trans-unit id="2805304563009985503" datatype="html">
|
||||||
<source>This operation will split the selected document(s) into new documents.</source>
|
<source>This operation will split the selected document(s) into new documents.</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||||
<context context-type="linenumber">1254</context>
|
<context context-type="linenumber">1252</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="4158171846914923744" datatype="html">
|
<trans-unit id="4158171846914923744" datatype="html">
|
||||||
<source>Split operation will begin in the background.</source>
|
<source>Split operation will begin in the background.</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||||
<context context-type="linenumber">1270</context>
|
<context context-type="linenumber">1268</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="3235014591864339926" datatype="html">
|
<trans-unit id="3235014591864339926" datatype="html">
|
||||||
<source>Error executing split operation</source>
|
<source>Error executing split operation</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||||
<context context-type="linenumber">1279</context>
|
<context context-type="linenumber">1277</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="6555329262222566158" datatype="html">
|
<trans-unit id="6555329262222566158" datatype="html">
|
||||||
<source>Rotate confirm</source>
|
<source>Rotate confirm</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||||
<context context-type="linenumber">1292</context>
|
<context context-type="linenumber">1290</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
|
||||||
@@ -6752,60 +6716,60 @@
|
|||||||
<source>This operation will permanently rotate the original version of the current document.</source>
|
<source>This operation will permanently rotate the original version of the current document.</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||||
<context context-type="linenumber">1293</context>
|
<context context-type="linenumber">1291</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="4069543875319587651" datatype="html">
|
<trans-unit id="4069543875319587651" datatype="html">
|
||||||
<source>Rotation will begin in the background. Close and re-open the document after the operation has completed to see the changes.</source>
|
<source>Rotation will begin in the background. Close and re-open the document after the operation has completed to see the changes.</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||||
<context context-type="linenumber">1309</context>
|
<context context-type="linenumber">1307</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="2962674215361798818" datatype="html">
|
<trans-unit id="2962674215361798818" datatype="html">
|
||||||
<source>Error executing rotate operation</source>
|
<source>Error executing rotate operation</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||||
<context context-type="linenumber">1321</context>
|
<context context-type="linenumber">1319</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="3539261415918606512" datatype="html">
|
<trans-unit id="3539261415918606512" datatype="html">
|
||||||
<source>Delete pages confirm</source>
|
<source>Delete pages confirm</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||||
<context context-type="linenumber">1333</context>
|
<context context-type="linenumber">1331</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="5854352498125813866" datatype="html">
|
<trans-unit id="5854352498125813866" datatype="html">
|
||||||
<source>This operation will permanently delete the selected pages from the original document.</source>
|
<source>This operation will permanently delete the selected pages from the original document.</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||||
<context context-type="linenumber">1334</context>
|
<context context-type="linenumber">1332</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="8617528702531167646" datatype="html">
|
<trans-unit id="8617528702531167646" datatype="html">
|
||||||
<source>Delete pages operation will begin in the background. Close and re-open or reload this document after the operation has completed to see the changes.</source>
|
<source>Delete pages operation will begin in the background. Close and re-open or reload this document after the operation has completed to see the changes.</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||||
<context context-type="linenumber">1349</context>
|
<context context-type="linenumber">1347</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="1249139200486584973" datatype="html">
|
<trans-unit id="1249139200486584973" datatype="html">
|
||||||
<source>Error executing delete pages operation</source>
|
<source>Error executing delete pages operation</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||||
<context context-type="linenumber">1358</context>
|
<context context-type="linenumber">1356</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="6085793215710522488" datatype="html">
|
<trans-unit id="6085793215710522488" datatype="html">
|
||||||
<source>An error occurred loading tiff: <x id="PH" equiv-text="err.toString()"/></source>
|
<source>An error occurred loading tiff: <x id="PH" equiv-text="err.toString()"/></source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||||
<context context-type="linenumber">1398</context>
|
<context context-type="linenumber">1396</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||||
<context context-type="linenumber">1402</context>
|
<context context-type="linenumber">1400</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="4958946940233632319" datatype="html">
|
<trans-unit id="4958946940233632319" datatype="html">
|
||||||
@@ -7305,11 +7269,11 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">66</context>
|
<context context-type="linenumber">71</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/pipes/username.pipe.ts</context>
|
<context context-type="sourcefile">src/app/pipes/username.pipe.ts</context>
|
||||||
<context context-type="linenumber">37</context>
|
<context context-type="linenumber">33</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="2332107018974972998" datatype="html">
|
<trans-unit id="2332107018974972998" datatype="html">
|
||||||
@@ -7373,7 +7337,7 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/document-list.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-list/document-list.component.ts</context>
|
||||||
<context context-type="linenumber">310</context>
|
<context context-type="linenumber">304</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="1494518490116523821" datatype="html">
|
<trans-unit id="1494518490116523821" datatype="html">
|
||||||
@@ -7384,7 +7348,7 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/document-list.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-list/document-list.component.ts</context>
|
||||||
<context context-type="linenumber">303</context>
|
<context context-type="linenumber">297</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="8461842260159597706" datatype="html">
|
<trans-unit id="8461842260159597706" datatype="html">
|
||||||
@@ -7491,11 +7455,11 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">70</context>
|
<context context-type="linenumber">75</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">88</context>
|
<context context-type="linenumber">93</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="6954625430271090777" datatype="html">
|
<trans-unit id="6954625430271090777" datatype="html">
|
||||||
@@ -7527,11 +7491,11 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">62</context>
|
<context context-type="linenumber">67</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">96</context>
|
<context context-type="linenumber">101</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="3557446856808034218" datatype="html">
|
<trans-unit id="3557446856808034218" datatype="html">
|
||||||
@@ -7584,11 +7548,11 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">74</context>
|
<context context-type="linenumber">79</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">97</context>
|
<context context-type="linenumber">102</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/paperless-config.ts</context>
|
<context context-type="sourcefile">src/app/data/paperless-config.ts</context>
|
||||||
@@ -7623,46 +7587,60 @@
|
|||||||
<context context-type="linenumber">307</context>
|
<context context-type="linenumber">307</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="2807800733729323332" datatype="html">
|
||||||
|
<source>Yes</source>
|
||||||
|
<context-group purpose="location">
|
||||||
|
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
|
||||||
|
<context context-type="linenumber">366</context>
|
||||||
|
</context-group>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="3542042671420335679" datatype="html">
|
||||||
|
<source>No</source>
|
||||||
|
<context-group purpose="location">
|
||||||
|
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
|
||||||
|
<context context-type="linenumber">366</context>
|
||||||
|
</context-group>
|
||||||
|
</trans-unit>
|
||||||
<trans-unit id="4512084577073831437" datatype="html">
|
<trans-unit id="4512084577073831437" datatype="html">
|
||||||
<source>Reset filters / selection</source>
|
<source>Reset filters / selection</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/document-list.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-list/document-list.component.ts</context>
|
||||||
<context context-type="linenumber">291</context>
|
<context context-type="linenumber">285</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="4135055128446167640" datatype="html">
|
<trans-unit id="4135055128446167640" datatype="html">
|
||||||
<source>Open first [selected] document</source>
|
<source>Open first [selected] document</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/document-list.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-list/document-list.component.ts</context>
|
||||||
<context context-type="linenumber">319</context>
|
<context context-type="linenumber">313</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="3629960544875360046" datatype="html">
|
<trans-unit id="3629960544875360046" datatype="html">
|
||||||
<source>Previous page</source>
|
<source>Previous page</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/document-list.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-list/document-list.component.ts</context>
|
||||||
<context context-type="linenumber">335</context>
|
<context context-type="linenumber">329</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="3337301694210287595" datatype="html">
|
<trans-unit id="3337301694210287595" datatype="html">
|
||||||
<source>Next page</source>
|
<source>Next page</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/document-list.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-list/document-list.component.ts</context>
|
||||||
<context context-type="linenumber">347</context>
|
<context context-type="linenumber">341</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="2155249406916744630" datatype="html">
|
<trans-unit id="2155249406916744630" datatype="html">
|
||||||
<source>View "<x id="PH" equiv-text="this.list.activeSavedViewTitle"/>" saved successfully.</source>
|
<source>View "<x id="PH" equiv-text="this.list.activeSavedViewTitle"/>" saved successfully.</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/document-list.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-list/document-list.component.ts</context>
|
||||||
<context context-type="linenumber">379</context>
|
<context context-type="linenumber">373</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="6837554170707123455" datatype="html">
|
<trans-unit id="6837554170707123455" datatype="html">
|
||||||
<source>View "<x id="PH" equiv-text="savedView.name"/>" created successfully.</source>
|
<source>View "<x id="PH" equiv-text="savedView.name"/>" created successfully.</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/document-list.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-list/document-list.component.ts</context>
|
||||||
<context context-type="linenumber">422</context>
|
<context context-type="linenumber">416</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="739880801667335279" datatype="html">
|
<trans-unit id="739880801667335279" datatype="html">
|
||||||
@@ -8829,7 +8807,7 @@
|
|||||||
<source>Search score</source>
|
<source>Search score</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">103</context>
|
<context context-type="linenumber">108</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<note priority="1" from="description">Score is a value returned by the full text search engine and specifies how well a result matches the given query</note>
|
<note priority="1" from="description">Score is a value returned by the full text search engine and specifies how well a result matches the given query</note>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
@@ -49,7 +49,7 @@ const CONSUMPTION_SCOPE_OPTIONS = [
|
|||||||
name: $localize`Only process attachments`,
|
name: $localize`Only process attachments`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: MailRuleConsumptionScope.EmailOnly,
|
id: MailRuleConsumptionScope.Email_Only,
|
||||||
name: $localize`Process message as .eml`,
|
name: $localize`Process message as .eml`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
|
|
||||||
import { provideHttpClientTesting } from '@angular/common/http/testing'
|
|
||||||
import {
|
import {
|
||||||
ComponentFixture,
|
ComponentFixture,
|
||||||
TestBed,
|
TestBed,
|
||||||
@@ -53,11 +51,7 @@ describe('FilterableDropdownComponent & FilterableDropdownSelectionModel', () =>
|
|||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
providers: [
|
providers: [FilterPipe],
|
||||||
FilterPipe,
|
|
||||||
provideHttpClient(withInterceptorsFromDi()),
|
|
||||||
provideHttpClientTesting(),
|
|
||||||
],
|
|
||||||
imports: [NgxBootstrapIconsModule.pick(allIcons)],
|
imports: [NgxBootstrapIconsModule.pick(allIcons)],
|
||||||
}).compileComponents()
|
}).compileComponents()
|
||||||
|
|
||||||
@@ -496,6 +490,37 @@ describe('FilterableDropdownComponent & FilterableDropdownSelectionModel', () =>
|
|||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('selection model should sort items by state and document counts, if set', () => {
|
||||||
|
component.items = items.concat([{ id: 4, name: 'Item D' }])
|
||||||
|
component.selectionModel = selectionModel
|
||||||
|
component.documentCounts = [
|
||||||
|
{ id: 1, document_count: 0 }, // Tag1
|
||||||
|
{ id: 2, document_count: 1 }, // Tag2
|
||||||
|
{ id: 4, document_count: 2 },
|
||||||
|
]
|
||||||
|
component.selectionModel.apply()
|
||||||
|
expect(selectionModel.items).toEqual([
|
||||||
|
nullItem,
|
||||||
|
{ id: 4, name: 'Item D' },
|
||||||
|
items[1], // Tag2
|
||||||
|
items[0], // Tag1
|
||||||
|
])
|
||||||
|
|
||||||
|
selectionModel.toggle(items[1].id)
|
||||||
|
component.documentCounts = [
|
||||||
|
{ id: 1, document_count: 0 },
|
||||||
|
{ id: 2, document_count: 1 },
|
||||||
|
{ id: 4, document_count: 0 },
|
||||||
|
]
|
||||||
|
selectionModel.apply()
|
||||||
|
expect(selectionModel.items).toEqual([
|
||||||
|
nullItem,
|
||||||
|
items[1], // Tag2
|
||||||
|
{ id: 4, name: 'Item D' },
|
||||||
|
items[0], // Tag1
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
it('should set support create, keep open model and call createRef method', fakeAsync(() => {
|
it('should set support create, keep open model and call createRef method', fakeAsync(() => {
|
||||||
component.items = items
|
component.items = items
|
||||||
component.icon = 'tag-fill'
|
component.icon = 'tag-fill'
|
||||||
|
@@ -81,6 +81,16 @@ export class FilterableDropdownSelectionModel {
|
|||||||
this.getNonTemporary(b.id) == ToggleableItemState.NotSelected
|
this.getNonTemporary(b.id) == ToggleableItemState.NotSelected
|
||||||
) {
|
) {
|
||||||
return -1
|
return -1
|
||||||
|
} else if (
|
||||||
|
this._documentCounts.length &&
|
||||||
|
this.getDocumentCount(a.id) > this.getDocumentCount(b.id)
|
||||||
|
) {
|
||||||
|
return -1
|
||||||
|
} else if (
|
||||||
|
this._documentCounts.length &&
|
||||||
|
this.getDocumentCount(a.id) < this.getDocumentCount(b.id)
|
||||||
|
) {
|
||||||
|
return 1
|
||||||
} else {
|
} else {
|
||||||
return a.name.localeCompare(b.name)
|
return a.name.localeCompare(b.name)
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
|
|
||||||
import { provideHttpClientTesting } from '@angular/common/http/testing'
|
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing'
|
import { ComponentFixture, TestBed } from '@angular/core/testing'
|
||||||
import { Tag } from 'src/app/data/tag'
|
import { Tag } from 'src/app/data/tag'
|
||||||
import { TagComponent } from '../../tag/tag.component'
|
import { TagComponent } from '../../tag/tag.component'
|
||||||
@@ -14,10 +12,7 @@ describe('ToggleableDropdownButtonComponent', () => {
|
|||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
providers: [
|
providers: [],
|
||||||
provideHttpClient(withInterceptorsFromDi()),
|
|
||||||
provideHttpClientTesting(),
|
|
||||||
],
|
|
||||||
imports: [ToggleableDropdownButtonComponent, TagComponent],
|
imports: [ToggleableDropdownButtonComponent, TagComponent],
|
||||||
}).compileComponents()
|
}).compileComponents()
|
||||||
|
|
||||||
|
@@ -1,10 +1,14 @@
|
|||||||
<a [href]="link ?? previewUrl" class="{{linkClasses}}" [target]="linkTarget" [title]="linkTitle"
|
@if (!previewOnly) {
|
||||||
[ngbPopover]="previewContent" [popoverTitle]="document.title | documentTitle" container="body"
|
<a [href]="link ?? previewUrl" class="{{linkClasses}}" [target]="linkTarget" [title]="linkTitle"
|
||||||
autoClose="true" [popoverClass]="popoverClass" (mouseenter)="mouseEnterPreview()" (mouseleave)="mouseLeavePreview()" #popover="ngbPopover">
|
[ngbPopover]="previewContent" [popoverTitle]="document.title | documentTitle" container="body"
|
||||||
<ng-content></ng-content>
|
autoClose="true" [popoverClass]="popoverClass" (mouseenter)="mouseEnterPreview()" (mouseleave)="mouseLeavePreview()" #popover="ngbPopover">
|
||||||
</a>
|
<ng-content></ng-content>
|
||||||
|
</a>
|
||||||
|
} @else {
|
||||||
|
<ng-container [ngTemplateOutlet]="previewContent" [ngTemplateOutletContext]="{ $implicit: document }"></ng-container>
|
||||||
|
}
|
||||||
<ng-template #previewContent>
|
<ng-template #previewContent>
|
||||||
<div class="preview-popup-container" (mouseenter)="mouseEnterPreview()" (mouseleave)="mouseLeavePreview(); close()">
|
<div class="preview-popup-container" [class.full-size]="previewOnly" (mouseenter)="mouseEnterPreview()" (mouseleave)="mouseLeavePreview(); close()">
|
||||||
@if (error) {
|
@if (error) {
|
||||||
<div class="w-100 h-100 position-relative">
|
<div class="w-100 h-100 position-relative">
|
||||||
<p class="fst-italic position-absolute top-50 start-50 translate-middle" i18n>Error loading preview</p>
|
<p class="fst-italic position-absolute top-50 start-50 translate-middle" i18n>Error loading preview</p>
|
||||||
@@ -28,8 +32,7 @@
|
|||||||
[original-size]="false"
|
[original-size]="false"
|
||||||
[show-borders]="false"
|
[show-borders]="false"
|
||||||
[show-all]="true"
|
[show-all]="true"
|
||||||
(text-layer-rendered)="onPageRendered()"
|
(error)="onError($event)">
|
||||||
(error)="onError($event)" #pdfViewer>
|
|
||||||
</pdf-viewer>
|
</pdf-viewer>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,6 +4,16 @@
|
|||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.preview-popup-container.full-size {
|
||||||
|
width: 100% !important;
|
||||||
|
height: 100% !important;
|
||||||
|
|
||||||
|
> * {
|
||||||
|
width: 100% !important;
|
||||||
|
height: 100% !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
::ng-deep .popover.popover-preview {
|
::ng-deep .popover.popover-preview {
|
||||||
max-width: 32rem;
|
max-width: 32rem;
|
||||||
}
|
}
|
||||||
|
@@ -158,24 +158,4 @@ describe('PreviewPopupComponent', () => {
|
|||||||
jest.advanceTimersByTime(1)
|
jest.advanceTimersByTime(1)
|
||||||
expect(component.popover.isOpen()).toBeFalsy()
|
expect(component.popover.isOpen()).toBeFalsy()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should dispatch find event on viewer loaded if searchQuery set', () => {
|
|
||||||
documentService.searchQuery = 'test'
|
|
||||||
settingsService.set(SETTINGS_KEYS.USE_NATIVE_PDF_VIEWER, false)
|
|
||||||
component.popover.open()
|
|
||||||
jest.advanceTimersByTime(1000)
|
|
||||||
fixture.detectChanges()
|
|
||||||
// normally setup by pdf-viewer
|
|
||||||
jest.replaceProperty(component.pdfViewer, 'eventBus', {
|
|
||||||
dispatch: jest.fn(),
|
|
||||||
} as any)
|
|
||||||
const dispatchSpy = jest.spyOn(component.pdfViewer.eventBus, 'dispatch')
|
|
||||||
component.onPageRendered()
|
|
||||||
expect(dispatchSpy).toHaveBeenCalledWith('find', {
|
|
||||||
query: 'test',
|
|
||||||
caseSensitive: false,
|
|
||||||
highlightAll: true,
|
|
||||||
phraseSearch: true,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
|
import { NgTemplateOutlet } from '@angular/common'
|
||||||
import { HttpClient } from '@angular/common/http'
|
import { HttpClient } from '@angular/common/http'
|
||||||
import { Component, Input, OnDestroy, ViewChild } from '@angular/core'
|
import { Component, 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 { PdfViewerModule } from 'ng2-pdf-viewer'
|
||||||
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
||||||
import { first, Subject, takeUntil } from 'rxjs'
|
import { first, Subject, takeUntil } from 'rxjs'
|
||||||
import { Document } from 'src/app/data/document'
|
import { Document } from 'src/app/data/document'
|
||||||
@@ -17,6 +18,7 @@ import { SettingsService } from 'src/app/services/settings.service'
|
|||||||
styleUrls: ['./preview-popup.component.scss'],
|
styleUrls: ['./preview-popup.component.scss'],
|
||||||
imports: [
|
imports: [
|
||||||
NgbPopoverModule,
|
NgbPopoverModule,
|
||||||
|
NgTemplateOutlet,
|
||||||
DocumentTitlePipe,
|
DocumentTitlePipe,
|
||||||
PdfViewerModule,
|
PdfViewerModule,
|
||||||
SafeUrlPipe,
|
SafeUrlPipe,
|
||||||
@@ -47,6 +49,9 @@ export class PreviewPopupComponent implements OnDestroy {
|
|||||||
@Input()
|
@Input()
|
||||||
linkTitle: string = $localize`Open preview`
|
linkTitle: string = $localize`Open preview`
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
previewOnly: boolean = false
|
||||||
|
|
||||||
unsubscribeNotifier: Subject<any> = new Subject()
|
unsubscribeNotifier: Subject<any> = new Subject()
|
||||||
|
|
||||||
error = false
|
error = false
|
||||||
@@ -57,8 +62,6 @@ export class PreviewPopupComponent implements OnDestroy {
|
|||||||
|
|
||||||
@ViewChild('popover') popover: NgbPopover
|
@ViewChild('popover') popover: NgbPopover
|
||||||
|
|
||||||
@ViewChild('pdfViewer') pdfViewer: PdfViewerComponent
|
|
||||||
|
|
||||||
mouseOnPreview: boolean = false
|
mouseOnPreview: boolean = false
|
||||||
|
|
||||||
popoverClass: string = 'shadow popover-preview'
|
popoverClass: string = 'shadow popover-preview'
|
||||||
@@ -93,6 +96,8 @@ export class PreviewPopupComponent implements OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
|
this.error = false
|
||||||
|
this.requiresPassword = false
|
||||||
if (this.document.mime_type?.includes('text')) {
|
if (this.document.mime_type?.includes('text')) {
|
||||||
this.http
|
this.http
|
||||||
.get(this.previewURL, { responseType: 'text' })
|
.get(this.previewURL, { responseType: 'text' })
|
||||||
@@ -116,23 +121,12 @@ export class PreviewPopupComponent implements OnDestroy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onPageRendered() {
|
|
||||||
// Only triggered by the pngx pdf viewer
|
|
||||||
if (this.documentService.searchQuery) {
|
|
||||||
this.pdfViewer.eventBus.dispatch('find', {
|
|
||||||
query: this.documentService.searchQuery,
|
|
||||||
caseSensitive: false,
|
|
||||||
highlightAll: true,
|
|
||||||
phraseSearch: true,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get previewUrl() {
|
get previewUrl() {
|
||||||
return this.documentService.getPreviewUrl(this.document.id)
|
return this.documentService.getPreviewUrl(this.document.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
mouseEnterPreview() {
|
mouseEnterPreview() {
|
||||||
|
if (this.previewOnly) return
|
||||||
this.mouseOnPreview = true
|
this.mouseOnPreview = true
|
||||||
if (!this.popover.isOpen()) {
|
if (!this.popover.isOpen()) {
|
||||||
// we're going to open but hide to pre-load content during hover delay
|
// we're going to open but hide to pre-load content during hover delay
|
||||||
@@ -150,10 +144,12 @@ export class PreviewPopupComponent implements OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mouseLeavePreview() {
|
mouseLeavePreview() {
|
||||||
|
if (this.previewOnly) return
|
||||||
this.mouseOnPreview = false
|
this.mouseOnPreview = false
|
||||||
}
|
}
|
||||||
|
|
||||||
public close(immediate: boolean = false) {
|
public close(immediate: boolean = false) {
|
||||||
|
if (this.previewOnly) return
|
||||||
setTimeout(
|
setTimeout(
|
||||||
() => {
|
() => {
|
||||||
if (!this.mouseOnPreview) this.popover.close()
|
if (!this.mouseOnPreview) this.popover.close()
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
@if (tag) {
|
@if (tag !== undefined) {
|
||||||
@if (!clickable) {
|
@if (!clickable) {
|
||||||
<span class="badge" [style.background]="tag.color" [style.color]="tag.text_color">{{tag.name}}</span>
|
<span class="badge" [style.background]="tag.color" [style.color]="tag.text_color">{{tag.name}}</span>
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +1,6 @@
|
|||||||
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
|
|
||||||
import { provideHttpClientTesting } from '@angular/common/http/testing'
|
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing'
|
import { ComponentFixture, TestBed } from '@angular/core/testing'
|
||||||
import { By } from '@angular/platform-browser'
|
import { By } from '@angular/platform-browser'
|
||||||
import { of } from 'rxjs'
|
|
||||||
import { Tag } from 'src/app/data/tag'
|
import { Tag } from 'src/app/data/tag'
|
||||||
import { PermissionsService } from 'src/app/services/permissions.service'
|
|
||||||
import { TagService } from 'src/app/services/rest/tag.service'
|
|
||||||
import { TagComponent } from './tag.component'
|
import { TagComponent } from './tag.component'
|
||||||
|
|
||||||
const tag: Tag = {
|
const tag: Tag = {
|
||||||
@@ -17,20 +12,13 @@ const tag: Tag = {
|
|||||||
describe('TagComponent', () => {
|
describe('TagComponent', () => {
|
||||||
let component: TagComponent
|
let component: TagComponent
|
||||||
let fixture: ComponentFixture<TagComponent>
|
let fixture: ComponentFixture<TagComponent>
|
||||||
let permissionsService: PermissionsService
|
|
||||||
let tagService: TagService
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
providers: [
|
providers: [],
|
||||||
provideHttpClient(withInterceptorsFromDi()),
|
|
||||||
provideHttpClientTesting(),
|
|
||||||
],
|
|
||||||
imports: [TagComponent],
|
imports: [TagComponent],
|
||||||
}).compileComponents()
|
}).compileComponents()
|
||||||
|
|
||||||
permissionsService = TestBed.inject(PermissionsService)
|
|
||||||
tagService = TestBed.inject(TagService)
|
|
||||||
fixture = TestBed.createComponent(TagComponent)
|
fixture = TestBed.createComponent(TagComponent)
|
||||||
component = fixture.componentInstance
|
component = fixture.componentInstance
|
||||||
fixture.detectChanges()
|
fixture.detectChanges()
|
||||||
@@ -59,13 +47,4 @@ describe('TagComponent', () => {
|
|||||||
fixture.detectChanges()
|
fixture.detectChanges()
|
||||||
expect(fixture.debugElement.query(By.css('a.badge'))).not.toBeNull()
|
expect(fixture.debugElement.query(By.css('a.badge'))).not.toBeNull()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support retrieving tag by ID', () => {
|
|
||||||
jest.spyOn(permissionsService, 'currentUserCan').mockReturnValue(true)
|
|
||||||
const getCachedSpy = jest.spyOn(tagService, 'getCached')
|
|
||||||
getCachedSpy.mockReturnValue(of(tag))
|
|
||||||
component.tagID = 1
|
|
||||||
expect(getCachedSpy).toHaveBeenCalledWith(1)
|
|
||||||
expect(component.tag).toEqual(tag)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
@@ -1,11 +1,5 @@
|
|||||||
import { Component, Input } from '@angular/core'
|
import { Component, Input } from '@angular/core'
|
||||||
import { Tag } from 'src/app/data/tag'
|
import { Tag } from 'src/app/data/tag'
|
||||||
import {
|
|
||||||
PermissionAction,
|
|
||||||
PermissionsService,
|
|
||||||
PermissionType,
|
|
||||||
} from 'src/app/services/permissions.service'
|
|
||||||
import { TagService } from 'src/app/services/rest/tag.service'
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'pngx-tag',
|
selector: 'pngx-tag',
|
||||||
@@ -13,39 +7,10 @@ import { TagService } from 'src/app/services/rest/tag.service'
|
|||||||
styleUrls: ['./tag.component.scss'],
|
styleUrls: ['./tag.component.scss'],
|
||||||
})
|
})
|
||||||
export class TagComponent {
|
export class TagComponent {
|
||||||
private _tag: Tag
|
constructor() {}
|
||||||
private _tagID: number
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private permissionsService: PermissionsService,
|
|
||||||
private tagService: TagService
|
|
||||||
) {}
|
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
public set tag(tag: Tag) {
|
tag: Tag
|
||||||
this._tag = tag
|
|
||||||
}
|
|
||||||
|
|
||||||
public get tag(): Tag {
|
|
||||||
return this._tag
|
|
||||||
}
|
|
||||||
|
|
||||||
@Input()
|
|
||||||
set tagID(tagID: number) {
|
|
||||||
if (tagID !== this._tagID) {
|
|
||||||
this._tagID = tagID
|
|
||||||
if (
|
|
||||||
this.permissionsService.currentUserCan(
|
|
||||||
PermissionAction.View,
|
|
||||||
PermissionType.Tag
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
this.tagService.getCached(this._tagID).subscribe((tag) => {
|
|
||||||
this.tag = tag
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
linkTitle: string = ''
|
linkTitle: string = ''
|
||||||
|
@@ -50,45 +50,22 @@
|
|||||||
}
|
}
|
||||||
@case (DisplayField.CORRESPONDENT) {
|
@case (DisplayField.CORRESPONDENT) {
|
||||||
@if (doc.correspondent) {
|
@if (doc.correspondent) {
|
||||||
<a class="btn-link text-dark text-decoration-none" type="button" (click)="clickCorrespondent(doc.correspondent, $event)" title="Filter by correspondent" i18n-title>{{doc.correspondent | correspondentName | async}}</a>
|
<a class="btn-link text-dark text-decoration-none" type="button" (click)="clickCorrespondent(doc.correspondent, $event)" title="Filter by correspondent" i18n-title>{{(doc.correspondent$ | async)?.name}}</a>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@case (DisplayField.TAGS) {
|
@case (DisplayField.TAGS) {
|
||||||
@for (tagID of doc.tags; track tagID) {
|
@for (t of doc.tags$ | async; track t) {
|
||||||
<pngx-tag [tagID]="tagID" class="ms-1" (click)="clickTag(tagID, $event)" [clickable]="true" linkTitle="Filter by tag" i18n-title></pngx-tag>
|
<pngx-tag [tag]="t" class="ms-1" (click)="clickTag(t.id, $event)" [clickable]="true" linkTitle="Filter by tag" i18n-title></pngx-tag>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@case (DisplayField.DOCUMENT_TYPE) {
|
@case (DisplayField.DOCUMENT_TYPE) {
|
||||||
@if (doc.document_type) {
|
@if (doc.document_type) {
|
||||||
<a class="btn-link text-dark text-decoration-none" type="button" (click)="clickDocType(doc.document_type, $event)" title="Filter by document type" i18n-title>{{doc.document_type | documentTypeName | async}}</a>
|
<a class="btn-link text-dark text-decoration-none" type="button" (click)="clickDocType(doc.document_type, $event)" title="Filter by document type" i18n-title>{{(doc.document_type$ | async)?.name}}</a>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@case (DisplayField.STORAGE_PATH) {
|
@case (DisplayField.STORAGE_PATH) {
|
||||||
@if (doc.storage_path) {
|
@if (doc.storage_path) {
|
||||||
<a class="btn-link text-dark text-decoration-none" type="button" (click)="clickStoragePath(doc.storage_path, $event)" title="Filter by storage path" i18n-title>{{doc.storage_path | storagePathName | async}}</a>
|
<a class="btn-link text-dark text-decoration-none" type="button" (click)="clickStoragePath(doc.storage_path, $event)" title="Filter by storage path" i18n-title>{{(doc.storage_path$ | async)?.name}}</a>
|
||||||
}
|
|
||||||
}
|
|
||||||
@case (DisplayField.OWNER) {
|
|
||||||
@if (doc.owner) {
|
|
||||||
<a class="btn-link text-dark text-decoration-none" type="button" (click)="clickOwner(doc.owner, $event)" title="Filter by owner" i18n-title>{{doc.owner | username | async}}</a>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@case (DisplayField.ASN) {
|
|
||||||
{{doc.archive_serial_number}}
|
|
||||||
}
|
|
||||||
@case (DisplayField.PAGE_COUNT) {
|
|
||||||
{{ doc.page_count }}
|
|
||||||
}
|
|
||||||
@case (DisplayField.SHARED) {
|
|
||||||
@if (doc.is_shared_by_requester) { <ng-container i18n>Yes</ng-container> } @else { <ng-container i18n>No</ng-container> }
|
|
||||||
}
|
|
||||||
@case (DisplayField.NOTES) {
|
|
||||||
@if (doc.notes.length) {
|
|
||||||
<a routerLink="/documents/{{doc.id}}/notes" class="btn btn-sm p-0">
|
|
||||||
<span class="badge rounded-pill bg-light border text-primary">
|
|
||||||
<i-bs width="1.2em" height="1.2em" class="ms-1 me-1" name="chat-left-text"></i-bs>
|
|
||||||
{{doc.notes.length}}</span>
|
|
||||||
</a>
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -24,7 +24,6 @@ import {
|
|||||||
FILTER_DOCUMENT_TYPE,
|
FILTER_DOCUMENT_TYPE,
|
||||||
FILTER_FULLTEXT_MORELIKE,
|
FILTER_FULLTEXT_MORELIKE,
|
||||||
FILTER_HAS_TAGS_ALL,
|
FILTER_HAS_TAGS_ALL,
|
||||||
FILTER_OWNER_ANY,
|
|
||||||
FILTER_STORAGE_PATH,
|
FILTER_STORAGE_PATH,
|
||||||
} from 'src/app/data/filter-rule-type'
|
} from 'src/app/data/filter-rule-type'
|
||||||
import { SavedView } from 'src/app/data/saved-view'
|
import { SavedView } from 'src/app/data/saved-view'
|
||||||
@@ -296,15 +295,6 @@ describe('SavedViewWidgetComponent', () => {
|
|||||||
component.clickStoragePath(11) // coverage
|
component.clickStoragePath(11) // coverage
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should navigate via quickfilter on click owner', () => {
|
|
||||||
const qfSpy = jest.spyOn(documentListViewService, 'quickFilter')
|
|
||||||
component.clickOwner(11, new MouseEvent('click'))
|
|
||||||
expect(qfSpy).toHaveBeenCalledWith([
|
|
||||||
{ rule_type: FILTER_OWNER_ANY, value: '11' },
|
|
||||||
])
|
|
||||||
component.clickOwner(11) // coverage
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should navigate via quickfilter on click more like', () => {
|
it('should navigate via quickfilter on click more like', () => {
|
||||||
const qfSpy = jest.spyOn(documentListViewService, 'quickFilter')
|
const qfSpy = jest.spyOn(documentListViewService, 'quickFilter')
|
||||||
component.clickMoreLike(11)
|
component.clickMoreLike(11)
|
||||||
|
@@ -31,17 +31,12 @@ import {
|
|||||||
FILTER_DOCUMENT_TYPE,
|
FILTER_DOCUMENT_TYPE,
|
||||||
FILTER_FULLTEXT_MORELIKE,
|
FILTER_FULLTEXT_MORELIKE,
|
||||||
FILTER_HAS_TAGS_ALL,
|
FILTER_HAS_TAGS_ALL,
|
||||||
FILTER_OWNER_ANY,
|
|
||||||
FILTER_STORAGE_PATH,
|
FILTER_STORAGE_PATH,
|
||||||
} from 'src/app/data/filter-rule-type'
|
} from 'src/app/data/filter-rule-type'
|
||||||
import { SavedView } from 'src/app/data/saved-view'
|
import { SavedView } from 'src/app/data/saved-view'
|
||||||
import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive'
|
import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive'
|
||||||
import { CorrespondentNamePipe } from 'src/app/pipes/correspondent-name.pipe'
|
|
||||||
import { CustomDatePipe } from 'src/app/pipes/custom-date.pipe'
|
import { CustomDatePipe } from 'src/app/pipes/custom-date.pipe'
|
||||||
import { DocumentTitlePipe } from 'src/app/pipes/document-title.pipe'
|
import { DocumentTitlePipe } from 'src/app/pipes/document-title.pipe'
|
||||||
import { DocumentTypeNamePipe } from 'src/app/pipes/document-type-name.pipe'
|
|
||||||
import { StoragePathNamePipe } from 'src/app/pipes/storage-path-name.pipe'
|
|
||||||
import { UsernamePipe } from 'src/app/pipes/username.pipe'
|
|
||||||
import { ConsumerStatusService } from 'src/app/services/consumer-status.service'
|
import { ConsumerStatusService } from 'src/app/services/consumer-status.service'
|
||||||
import { DocumentListViewService } from 'src/app/services/document-list-view.service'
|
import { DocumentListViewService } from 'src/app/services/document-list-view.service'
|
||||||
import { OpenDocumentsService } from 'src/app/services/open-documents.service'
|
import { OpenDocumentsService } from 'src/app/services/open-documents.service'
|
||||||
@@ -67,10 +62,6 @@ import { WidgetFrameComponent } from '../widget-frame/widget-frame.component'
|
|||||||
TagComponent,
|
TagComponent,
|
||||||
WidgetFrameComponent,
|
WidgetFrameComponent,
|
||||||
IfPermissionsDirective,
|
IfPermissionsDirective,
|
||||||
UsernamePipe,
|
|
||||||
CorrespondentNamePipe,
|
|
||||||
DocumentTypeNamePipe,
|
|
||||||
StoragePathNamePipe,
|
|
||||||
AsyncPipe,
|
AsyncPipe,
|
||||||
DocumentTitlePipe,
|
DocumentTitlePipe,
|
||||||
CustomDatePipe,
|
CustomDatePipe,
|
||||||
@@ -238,15 +229,6 @@ export class SavedViewWidgetComponent
|
|||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
clickOwner(ownerID: number, event: MouseEvent = null) {
|
|
||||||
event?.preventDefault()
|
|
||||||
event?.stopImmediatePropagation()
|
|
||||||
|
|
||||||
this.list.quickFilter([
|
|
||||||
{ rule_type: FILTER_OWNER_ANY, value: ownerID.toString() },
|
|
||||||
])
|
|
||||||
}
|
|
||||||
|
|
||||||
openDocumentDetail(document: Document) {
|
openDocumentDetail(document: Document) {
|
||||||
this.router.navigate(['documents', document.id])
|
this.router.navigate(['documents', document.id])
|
||||||
}
|
}
|
||||||
|
@@ -848,14 +848,12 @@ export class DocumentDetailComponent
|
|||||||
)
|
)
|
||||||
.pipe(
|
.pipe(
|
||||||
switchMap(({ nextDocId, updateResult }) => {
|
switchMap(({ nextDocId, updateResult }) => {
|
||||||
if (nextDocId && updateResult) {
|
if (nextDocId && updateResult)
|
||||||
this.openDocumentService.setDirty(this.document, false)
|
|
||||||
return this.openDocumentService
|
return this.openDocumentService
|
||||||
.closeDocument(this.document)
|
.closeDocument(this.document)
|
||||||
.pipe(
|
.pipe(
|
||||||
map((closeResult) => ({ updateResult, nextDocId, closeResult }))
|
map((closeResult) => ({ updateResult, nextDocId, closeResult }))
|
||||||
)
|
)
|
||||||
}
|
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.pipe(first())
|
.pipe(first())
|
||||||
|
@@ -22,9 +22,9 @@
|
|||||||
@if (document) {
|
@if (document) {
|
||||||
@if (displayFields.includes(DisplayField.CORRESPONDENT) && document.correspondent) {
|
@if (displayFields.includes(DisplayField.CORRESPONDENT) && document.correspondent) {
|
||||||
@if (clickCorrespondent.observers.length ) {
|
@if (clickCorrespondent.observers.length ) {
|
||||||
<a title="Filter by correspondent" i18n-title (click)="clickCorrespondent.emit(document.correspondent);$event.stopPropagation()" class="fw-bold btn-link">{{document.correspondent | correspondentName | async}}</a>
|
<a title="Filter by correspondent" i18n-title (click)="clickCorrespondent.emit(document.correspondent);$event.stopPropagation()" class="fw-bold btn-link">{{(document.correspondent$ | async)?.name}}</a>
|
||||||
} @else {
|
} @else {
|
||||||
{{document.correspondent | correspondentName | async}}
|
{{(document.correspondent$ | async)?.name}}
|
||||||
}
|
}
|
||||||
@if (displayFields.includes(DisplayField.TITLE)) {:}
|
@if (displayFields.includes(DisplayField.TITLE)) {:}
|
||||||
}
|
}
|
||||||
@@ -32,8 +32,8 @@
|
|||||||
{{document.title | documentTitle}}
|
{{document.title | documentTitle}}
|
||||||
}
|
}
|
||||||
@if (displayFields.includes(DisplayField.TAGS)) {
|
@if (displayFields.includes(DisplayField.TAGS)) {
|
||||||
@for (tagID of document.tags; track t) {
|
@for (t of document.tags$ | async; track t) {
|
||||||
<pngx-tag [tagID]="tagID" linkTitle="Filter by tag" i18n-linkTitle class="ms-1" (click)="clickTag.emit(tagID);$event.stopPropagation()" [clickable]="clickTag.observers.length"></pngx-tag>
|
<pngx-tag [tag]="t" linkTitle="Filter by tag" i18n-linkTitle class="ms-1" (click)="clickTag.emit(t.id);$event.stopPropagation()" [clickable]="clickTag.observers.length"></pngx-tag>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} @else {
|
} @else {
|
||||||
@@ -95,13 +95,13 @@
|
|||||||
@if (displayFields.includes(DisplayField.DOCUMENT_TYPE) && document.document_type) {
|
@if (displayFields.includes(DisplayField.DOCUMENT_TYPE) && document.document_type) {
|
||||||
<button type="button" class="list-group-item btn btn-sm bg-light text-dark p-1 border-0 me-2 d-flex align-items-center" title="Filter by document type" i18n-title
|
<button type="button" class="list-group-item btn btn-sm bg-light text-dark p-1 border-0 me-2 d-flex align-items-center" title="Filter by document type" i18n-title
|
||||||
(click)="clickDocumentType.emit(document.document_type);$event.stopPropagation()">
|
(click)="clickDocumentType.emit(document.document_type);$event.stopPropagation()">
|
||||||
<i-bs width=".9em" height=".9em" class="me-2 text-muted" name="file-earmark"></i-bs><small>{{document.document_type | documentTypeName | async}}</small>
|
<i-bs width=".9em" height=".9em" class="me-2 text-muted" name="file-earmark"></i-bs><small>{{(document.document_type$ | async)?.name}}</small>
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
@if (displayFields.includes(DisplayField.STORAGE_PATH) && document.storage_path) {
|
@if (displayFields.includes(DisplayField.STORAGE_PATH) && document.storage_path) {
|
||||||
<button type="button" class="list-group-item btn btn-sm bg-light text-dark p-1 border-0 me-2 d-flex align-items-center" title="Filter by storage path" i18n-title
|
<button type="button" class="list-group-item btn btn-sm bg-light text-dark p-1 border-0 me-2 d-flex align-items-center" title="Filter by storage path" i18n-title
|
||||||
(click)="clickStoragePath.emit(document.storage_path);$event.stopPropagation()">
|
(click)="clickStoragePath.emit(document.storage_path);$event.stopPropagation()">
|
||||||
<i-bs width=".9em" height=".9em" class="me-2 text-muted" name="archive"></i-bs><small>{{document.storage_path | storagePathName | async}}</small>
|
<i-bs width=".9em" height=".9em" class="me-2 text-muted" name="archive"></i-bs><small>{{(document.storage_path$ | async)?.name}}</small>
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
@if (displayFields.includes(DisplayField.ASN) && document.archive_serial_number | isNumber) {
|
@if (displayFields.includes(DisplayField.ASN) && document.archive_serial_number | isNumber) {
|
||||||
@@ -136,7 +136,7 @@
|
|||||||
}
|
}
|
||||||
@if (displayFields.includes(DisplayField.OWNER) && document.owner && document.owner !== settingsService.currentUser.id) {
|
@if (displayFields.includes(DisplayField.OWNER) && document.owner && document.owner !== settingsService.currentUser.id) {
|
||||||
<div class="list-group-item bg-light text-dark p-1 border-0 d-flex align-items-center">
|
<div class="list-group-item bg-light text-dark p-1 border-0 d-flex align-items-center">
|
||||||
<i-bs width=".9em" height=".9em" class="me-2 text-muted" name="person-fill-lock"></i-bs><small>{{document.owner | username | async}}</small>
|
<i-bs width=".9em" height=".9em" class="me-2 text-muted" name="person-fill-lock"></i-bs><small>{{document.owner | username}}</small>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@if (displayFields.includes(DisplayField.SHARED) && document.is_shared_by_requester) {
|
@if (displayFields.includes(DisplayField.SHARED) && document.is_shared_by_requester) {
|
||||||
|
@@ -13,7 +13,6 @@ import {
|
|||||||
NgbTooltipModule,
|
NgbTooltipModule,
|
||||||
} from '@ng-bootstrap/ng-bootstrap'
|
} from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
||||||
import { delay, of } from 'rxjs'
|
|
||||||
import {
|
import {
|
||||||
DEFAULT_DISPLAY_FIELDS,
|
DEFAULT_DISPLAY_FIELDS,
|
||||||
DisplayField,
|
DisplayField,
|
||||||
@@ -21,12 +20,9 @@ import {
|
|||||||
} from 'src/app/data/document'
|
} from 'src/app/data/document'
|
||||||
import { SETTINGS_KEYS } from 'src/app/data/ui-settings'
|
import { SETTINGS_KEYS } from 'src/app/data/ui-settings'
|
||||||
import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive'
|
import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive'
|
||||||
import { CorrespondentNamePipe } from 'src/app/pipes/correspondent-name.pipe'
|
|
||||||
import { CustomDatePipe } from 'src/app/pipes/custom-date.pipe'
|
import { CustomDatePipe } from 'src/app/pipes/custom-date.pipe'
|
||||||
import { DocumentTitlePipe } from 'src/app/pipes/document-title.pipe'
|
import { DocumentTitlePipe } from 'src/app/pipes/document-title.pipe'
|
||||||
import { DocumentTypeNamePipe } from 'src/app/pipes/document-type-name.pipe'
|
|
||||||
import { IsNumberPipe } from 'src/app/pipes/is-number.pipe'
|
import { IsNumberPipe } from 'src/app/pipes/is-number.pipe'
|
||||||
import { StoragePathNamePipe } from 'src/app/pipes/storage-path-name.pipe'
|
|
||||||
import { UsernamePipe } from 'src/app/pipes/username.pipe'
|
import { UsernamePipe } from 'src/app/pipes/username.pipe'
|
||||||
import { DocumentService } from 'src/app/services/rest/document.service'
|
import { DocumentService } from 'src/app/services/rest/document.service'
|
||||||
import { SettingsService } from 'src/app/services/settings.service'
|
import { SettingsService } from 'src/app/services/settings.service'
|
||||||
@@ -47,9 +43,6 @@ import { LoadingComponentWithPermissions } from '../../loading-component/loading
|
|||||||
CustomFieldDisplayComponent,
|
CustomFieldDisplayComponent,
|
||||||
AsyncPipe,
|
AsyncPipe,
|
||||||
UsernamePipe,
|
UsernamePipe,
|
||||||
CorrespondentNamePipe,
|
|
||||||
DocumentTypeNamePipe,
|
|
||||||
StoragePathNamePipe,
|
|
||||||
IfPermissionsDirective,
|
IfPermissionsDirective,
|
||||||
CustomDatePipe,
|
CustomDatePipe,
|
||||||
RouterModule,
|
RouterModule,
|
||||||
@@ -111,11 +104,9 @@ export class DocumentCardLargeComponent
|
|||||||
popoverHidden = true
|
popoverHidden = true
|
||||||
|
|
||||||
ngAfterViewInit(): void {
|
ngAfterViewInit(): void {
|
||||||
of(true)
|
setInterval(() => {
|
||||||
.pipe(delay(50))
|
this.show = true
|
||||||
.subscribe(() => {
|
}, 100)
|
||||||
this.show = true
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get searchScoreClass() {
|
get searchScoreClass() {
|
||||||
|
@@ -16,8 +16,8 @@
|
|||||||
|
|
||||||
@if (document && displayFields?.includes(DisplayField.TAGS)) {
|
@if (document && displayFields?.includes(DisplayField.TAGS)) {
|
||||||
<div class="tags d-flex flex-column text-end position-absolute me-1 fs-6">
|
<div class="tags d-flex flex-column text-end position-absolute me-1 fs-6">
|
||||||
@for (tagID of tagIDs; track tagID) {
|
@for (t of getTagsLimited$() | async; track t) {
|
||||||
<pngx-tag [tagID]="tagID" (click)="clickTag.emit(tagID);$event.stopPropagation()" [clickable]="true" linkTitle="Toggle tag filter" i18n-linkTitle></pngx-tag>
|
<pngx-tag [tag]="t" (click)="clickTag.emit(t.id);$event.stopPropagation()" [clickable]="true" linkTitle="Toggle tag filter" i18n-linkTitle></pngx-tag>
|
||||||
}
|
}
|
||||||
@if (moreTags) {
|
@if (moreTags) {
|
||||||
<div>
|
<div>
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
<p class="card-text">
|
<p class="card-text">
|
||||||
@if (document) {
|
@if (document) {
|
||||||
@if (displayFields.includes(DisplayField.CORRESPONDENT) && document.correspondent) {
|
@if (displayFields.includes(DisplayField.CORRESPONDENT) && document.correspondent) {
|
||||||
<a title="Toggle correspondent filter" i18n-title (click)="clickCorrespondent.emit(document.correspondent);$event.stopPropagation()" class="fw-bold btn-link">{{document.correspondent | correspondentName | async}}</a>
|
<a title="Toggle correspondent filter" i18n-title (click)="clickCorrespondent.emit(document.correspondent);$event.stopPropagation()" class="fw-bold btn-link">{{(document.correspondent$ | async)?.name ?? privateName}}</a>
|
||||||
@if (displayFields.includes(DisplayField.TITLE)) {:}
|
@if (displayFields.includes(DisplayField.TITLE)) {:}
|
||||||
}
|
}
|
||||||
@if (displayFields.includes(DisplayField.TITLE)) {
|
@if (displayFields.includes(DisplayField.TITLE)) {
|
||||||
@@ -59,14 +59,14 @@
|
|||||||
<button type="button" class="list-group-item list-group-item-action bg-transparent ps-0 p-1 border-0" title="Toggle document type filter" i18n-title
|
<button type="button" class="list-group-item list-group-item-action bg-transparent ps-0 p-1 border-0" title="Toggle document type filter" i18n-title
|
||||||
(click)="clickDocumentType.emit(document.document_type);$event.stopPropagation()">
|
(click)="clickDocumentType.emit(document.document_type);$event.stopPropagation()">
|
||||||
<i-bs width="1em" height="1em" class="me-2 text-muted" name="file-earmark"></i-bs>
|
<i-bs width="1em" height="1em" class="me-2 text-muted" name="file-earmark"></i-bs>
|
||||||
<small>{{document.document_type | documentTypeName | async}}</small>
|
<small>{{(document.document_type$ | async)?.name ?? privateName}}</small>
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
@if (displayFields.includes(DisplayField.STORAGE_PATH) && document.storage_path) {
|
@if (displayFields.includes(DisplayField.STORAGE_PATH) && document.storage_path) {
|
||||||
<button type="button" class="list-group-item list-group-item-action bg-transparent ps-0 p-1 border-0" title="Toggle storage path filter" i18n-title
|
<button type="button" class="list-group-item list-group-item-action bg-transparent ps-0 p-1 border-0" title="Toggle storage path filter" i18n-title
|
||||||
(click)="clickStoragePath.emit(document.storage_path);$event.stopPropagation()">
|
(click)="clickStoragePath.emit(document.storage_path);$event.stopPropagation()">
|
||||||
<i-bs width="1em" height="1em" class="me-2 text-muted" name="folder"></i-bs>
|
<i-bs width="1em" height="1em" class="me-2 text-muted" name="folder"></i-bs>
|
||||||
<small>{{document.storage_path | storagePathName | async}}</small>
|
<small>{{(document.storage_path$ | async)?.name ?? privateName}}</small>
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
@if (displayFields.includes(DisplayField.CREATED)) {
|
@if (displayFields.includes(DisplayField.CREATED)) {
|
||||||
@@ -116,7 +116,7 @@
|
|||||||
@if (displayFields.includes(DisplayField.OWNER) && document.owner && document.owner !== settingsService.currentUser.id) {
|
@if (displayFields.includes(DisplayField.OWNER) && document.owner && document.owner !== settingsService.currentUser.id) {
|
||||||
<div class="ps-0 p-1">
|
<div class="ps-0 p-1">
|
||||||
<i-bs width="1em" height="1em" class="me-2 text-muted" name="person-fill-lock"></i-bs>
|
<i-bs width="1em" height="1em" class="me-2 text-muted" name="person-fill-lock"></i-bs>
|
||||||
<small>{{document.owner | username | async}}</small>
|
<small>{{document.owner | username}}</small>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@if (displayFields.includes(DisplayField.SHARED) && document.is_shared_by_requester) {
|
@if (displayFields.includes(DisplayField.SHARED) && document.is_shared_by_requester) {
|
||||||
|
@@ -5,6 +5,8 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'
|
|||||||
import { By } from '@angular/platform-browser'
|
import { By } from '@angular/platform-browser'
|
||||||
import { RouterTestingModule } from '@angular/router/testing'
|
import { RouterTestingModule } from '@angular/router/testing'
|
||||||
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
|
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
|
||||||
|
import { of } from 'rxjs'
|
||||||
|
import { Tag } from 'src/app/data/tag'
|
||||||
import { TagComponent } from '../../common/tag/tag.component'
|
import { TagComponent } from '../../common/tag/tag.component'
|
||||||
import { DocumentCardSmallComponent } from './document-card-small.component'
|
import { DocumentCardSmallComponent } from './document-card-small.component'
|
||||||
|
|
||||||
@@ -22,6 +24,16 @@ const doc = {
|
|||||||
note: 'This is some note content bananas',
|
note: 'This is some note content bananas',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
tags$: of([
|
||||||
|
{ id: 1, name: 'Tag1' },
|
||||||
|
{ id: 2, name: 'Tag2' },
|
||||||
|
{ id: 3, name: 'Tag3' },
|
||||||
|
{ id: 4, name: 'Tag4' },
|
||||||
|
{ id: 5, name: 'Tag5' },
|
||||||
|
{ id: 6, name: 'Tag6' },
|
||||||
|
{ id: 7, name: 'Tag7' },
|
||||||
|
{ id: 8, name: 'Tag8' },
|
||||||
|
]),
|
||||||
content:
|
content:
|
||||||
'Cupcake ipsum dolor sit amet ice cream. Donut shortbread cheesecake caramels tiramisu pastry caramels chocolate bar. Tart tootsie roll muffin icing cotton candy topping sweet roll. Pie lollipop dragée sesame snaps donut tart pudding. Oat cake apple pie danish danish candy canes. Shortbread candy canes sesame snaps muffin tiramisu marshmallow chocolate bar halvah. Cake lemon drops candy apple pie carrot cake bonbon halvah pastry gummi bears. Sweet roll candy ice cream sesame snaps marzipan cookie ice cream. Cake cheesecake apple pie muffin candy toffee lollipop. Carrot cake oat cake cookie biscuit cupcake cake marshmallow. Sweet roll jujubes carrot cake cheesecake cake candy canes sweet roll gingerbread jelly beans. Apple pie sugar plum oat cake halvah cake. Pie oat cake chocolate cake cookie gingerbread marzipan. Lemon drops cheesecake lollipop danish marzipan candy.',
|
'Cupcake ipsum dolor sit amet ice cream. Donut shortbread cheesecake caramels tiramisu pastry caramels chocolate bar. Tart tootsie roll muffin icing cotton candy topping sweet roll. Pie lollipop dragée sesame snaps donut tart pudding. Oat cake apple pie danish danish candy canes. Shortbread candy canes sesame snaps muffin tiramisu marshmallow chocolate bar halvah. Cake lemon drops candy apple pie carrot cake bonbon halvah pastry gummi bears. Sweet roll candy ice cream sesame snaps marzipan cookie ice cream. Cake cheesecake apple pie muffin candy toffee lollipop. Carrot cake oat cake cookie biscuit cupcake cake marshmallow. Sweet roll jujubes carrot cake cheesecake cake candy canes sweet roll gingerbread jelly beans. Apple pie sugar plum oat cake halvah cake. Pie oat cake chocolate cake cookie gingerbread marzipan. Lemon drops cheesecake lollipop danish marzipan candy.',
|
||||||
}
|
}
|
||||||
@@ -68,6 +80,7 @@ describe('DocumentCardSmallComponent', () => {
|
|||||||
fixture.debugElement.queryAll(By.directive(TagComponent))
|
fixture.debugElement.queryAll(By.directive(TagComponent))
|
||||||
).toHaveLength(5)
|
).toHaveLength(5)
|
||||||
component.document.tags = [1, 2]
|
component.document.tags = [1, 2]
|
||||||
|
component.document.tags$ = of([{ id: 1 } as Tag, { id: 2 } as Tag])
|
||||||
fixture.detectChanges()
|
fixture.detectChanges()
|
||||||
expect(
|
expect(
|
||||||
fixture.debugElement.queryAll(By.directive(TagComponent))
|
fixture.debugElement.queryAll(By.directive(TagComponent))
|
||||||
|
@@ -13,8 +13,7 @@ import {
|
|||||||
NgbTooltipModule,
|
NgbTooltipModule,
|
||||||
} from '@ng-bootstrap/ng-bootstrap'
|
} from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
||||||
import { of } from 'rxjs'
|
import { map } from 'rxjs/operators'
|
||||||
import { delay } from 'rxjs/operators'
|
|
||||||
import {
|
import {
|
||||||
DEFAULT_DISPLAY_FIELDS,
|
DEFAULT_DISPLAY_FIELDS,
|
||||||
DisplayField,
|
DisplayField,
|
||||||
@@ -22,12 +21,9 @@ import {
|
|||||||
} from 'src/app/data/document'
|
} from 'src/app/data/document'
|
||||||
import { SETTINGS_KEYS } from 'src/app/data/ui-settings'
|
import { SETTINGS_KEYS } from 'src/app/data/ui-settings'
|
||||||
import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive'
|
import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive'
|
||||||
import { CorrespondentNamePipe } from 'src/app/pipes/correspondent-name.pipe'
|
|
||||||
import { CustomDatePipe } from 'src/app/pipes/custom-date.pipe'
|
import { CustomDatePipe } from 'src/app/pipes/custom-date.pipe'
|
||||||
import { DocumentTitlePipe } from 'src/app/pipes/document-title.pipe'
|
import { DocumentTitlePipe } from 'src/app/pipes/document-title.pipe'
|
||||||
import { DocumentTypeNamePipe } from 'src/app/pipes/document-type-name.pipe'
|
|
||||||
import { IsNumberPipe } from 'src/app/pipes/is-number.pipe'
|
import { IsNumberPipe } from 'src/app/pipes/is-number.pipe'
|
||||||
import { StoragePathNamePipe } from 'src/app/pipes/storage-path-name.pipe'
|
|
||||||
import { UsernamePipe } from 'src/app/pipes/username.pipe'
|
import { UsernamePipe } from 'src/app/pipes/username.pipe'
|
||||||
import { DocumentService } from 'src/app/services/rest/document.service'
|
import { DocumentService } from 'src/app/services/rest/document.service'
|
||||||
import { SettingsService } from 'src/app/services/settings.service'
|
import { SettingsService } from 'src/app/services/settings.service'
|
||||||
@@ -48,9 +44,6 @@ import { LoadingComponentWithPermissions } from '../../loading-component/loading
|
|||||||
CustomFieldDisplayComponent,
|
CustomFieldDisplayComponent,
|
||||||
AsyncPipe,
|
AsyncPipe,
|
||||||
UsernamePipe,
|
UsernamePipe,
|
||||||
CorrespondentNamePipe,
|
|
||||||
DocumentTypeNamePipe,
|
|
||||||
StoragePathNamePipe,
|
|
||||||
IfPermissionsDirective,
|
IfPermissionsDirective,
|
||||||
CustomDatePipe,
|
CustomDatePipe,
|
||||||
RouterModule,
|
RouterModule,
|
||||||
@@ -104,11 +97,9 @@ export class DocumentCardSmallComponent
|
|||||||
@ViewChild('popupPreview') popupPreview: PreviewPopupComponent
|
@ViewChild('popupPreview') popupPreview: PreviewPopupComponent
|
||||||
|
|
||||||
ngAfterViewInit(): void {
|
ngAfterViewInit(): void {
|
||||||
of(true)
|
setInterval(() => {
|
||||||
.pipe(delay(50))
|
this.show = true
|
||||||
.subscribe(() => {
|
}, 50)
|
||||||
this.show = true
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getIsThumbInverted() {
|
getIsThumbInverted() {
|
||||||
@@ -123,14 +114,22 @@ export class DocumentCardSmallComponent
|
|||||||
return this.documentService.getDownloadUrl(this.document.id)
|
return this.documentService.getDownloadUrl(this.document.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
get tagIDs() {
|
get privateName() {
|
||||||
|
return $localize`Private`
|
||||||
|
}
|
||||||
|
|
||||||
|
getTagsLimited$() {
|
||||||
const limit = this.document.notes.length > 0 ? 6 : 7
|
const limit = this.document.notes.length > 0 ? 6 : 7
|
||||||
if (this.document.tags.length > limit) {
|
return this.document.tags$?.pipe(
|
||||||
this.moreTags = this.document.tags.length - (limit - 1)
|
map((tags) => {
|
||||||
return this.document.tags.slice(0, limit - 1)
|
if (tags.length > limit) {
|
||||||
} else {
|
this.moreTags = tags.length - (limit - 1)
|
||||||
return this.document.tags
|
return tags.slice(0, limit - 1)
|
||||||
}
|
} else {
|
||||||
|
return tags
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
mouseLeaveCard() {
|
mouseLeaveCard() {
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="btn-group flex-fill" role="group">
|
<div class="btn-group flex-fill" role="group">
|
||||||
<input type="radio" class="btn-check" [(ngModel)]="list.displayMode" value="table" id="displayModeDetails" name="displayModeDetails">
|
<input type="radio" class="btn-check" [(ngModel)]="list.displayMode" value="table" id="displayModeDetails" name="displayModeDetails">
|
||||||
<label for="displayModeDetails" class="btn btn-outline-primary btn-sm">
|
<label for="displayModeDetails" class="btn btn-outline-primary btn-sm">
|
||||||
@@ -42,6 +43,13 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="btn-group flex-fill" role="group">
|
||||||
|
<input type="checkbox" class="btn-check" [(ngModel)]="list.showPreviewPane" value="table" id="previewPane" name="previewPane">
|
||||||
|
<label for="previewPane" class="btn btn-outline-primary btn-sm">
|
||||||
|
<i-bs name="window-split"></i-bs>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div ngbDropdown class="btn-group flex-fill">
|
<div ngbDropdown class="btn-group flex-fill">
|
||||||
<button class="btn btn-outline-primary btn-sm" id="dropdownBasic1" ngbDropdownToggle>
|
<button class="btn btn-outline-primary btn-sm" id="dropdownBasic1" ngbDropdownToggle>
|
||||||
<i-bs name="arrow-down-up"></i-bs>
|
<i-bs name="arrow-down-up"></i-bs>
|
||||||
@@ -105,298 +113,335 @@
|
|||||||
<pngx-bulk-editor [hidden]="!isBulkEditing" [disabled]="!isBulkEditing"></pngx-bulk-editor>
|
<pngx-bulk-editor [hidden]="!isBulkEditing" [disabled]="!isBulkEditing"></pngx-bulk-editor>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
<ng-template #pagination>
|
<div [class.col-lg-6]="list.showPreviewPane" [class.col]="!list.showPreviewPane">
|
||||||
<div class="d-flex flex-wrap gap-3 justify-content-between align-items-center mb-3">
|
<ng-template #pagination>
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex flex-wrap gap-3 justify-content-between align-items-center mb-3">
|
||||||
@if (list.isReloading) {
|
<div class="d-flex align-items-center">
|
||||||
<div class="spinner-border spinner-border-sm me-2" role="status"></div>
|
@if (list.isReloading) {
|
||||||
<ng-container i18n>Loading...</ng-container>
|
<div class="spinner-border spinner-border-sm me-2" role="status"></div>
|
||||||
}
|
<ng-container i18n>Loading...</ng-container>
|
||||||
@if (list.selected.size > 0) {
|
|
||||||
<span i18n>{list.collectionSize, plural, =1 {Selected {{list.selected.size}} of one document} other {Selected {{list.selected.size}} of {{list.collectionSize || 0}} documents}}</span>
|
|
||||||
}
|
|
||||||
@if (!list.isReloading) {
|
|
||||||
@if (list.selected.size === 0) {
|
|
||||||
<span i18n>{list.collectionSize, plural, =1 {One document} other {{{list.collectionSize || 0}} documents}}</span>
|
|
||||||
} @if (isFiltered) {
|
|
||||||
<span i18n>(filtered)</span>
|
|
||||||
}
|
}
|
||||||
}
|
@if (list.selected.size > 0) {
|
||||||
@if (!list.isReloading && isFiltered) {
|
<span i18n>{list.collectionSize, plural, =1 {Selected {{list.selected.size}} of one document} other {Selected {{list.selected.size}} of {{list.collectionSize || 0}} documents}}</span>
|
||||||
<button class="btn btn-link py-0" (click)="resetFilters()">
|
}
|
||||||
<i-bs width="1em" height="1em" name="x"></i-bs><small i18n>Reset filters</small>
|
@if (!list.isReloading) {
|
||||||
</button>
|
@if (list.selected.size === 0) {
|
||||||
|
<span i18n>{list.collectionSize, plural, =1 {One document} other {{{list.collectionSize || 0}} documents}}</span>
|
||||||
|
} @if (isFiltered) {
|
||||||
|
<span i18n>(filtered)</span>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@if (!list.isReloading && isFiltered) {
|
||||||
|
<button class="btn btn-link py-0" (click)="resetFilters()">
|
||||||
|
<i-bs width="1em" height="1em" name="x"></i-bs><small i18n>Reset filters</small>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
@if (list.collectionSize) {
|
||||||
|
<ngb-pagination [pageSize]="list.pageSize" [collectionSize]="list.collectionSize" [(page)]="list.currentPage" [maxSize]="5"
|
||||||
|
[rotate]="true" aria-label="Default pagination" size="sm"></ngb-pagination>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@if (list.collectionSize) {
|
</ng-template>
|
||||||
<ngb-pagination [pageSize]="list.pageSize" [collectionSize]="list.collectionSize" [(page)]="list.currentPage" [maxSize]="5"
|
|
||||||
[rotate]="true" aria-label="Default pagination" size="sm"></ngb-pagination>
|
<div tourAnchor="tour.documents">
|
||||||
}
|
<ng-container *ngTemplateOutlet="pagination"></ng-container>
|
||||||
</div>
|
</div>
|
||||||
</ng-template>
|
|
||||||
|
|
||||||
<div tourAnchor="tour.documents">
|
@if (list.error ) {
|
||||||
<ng-container *ngTemplateOutlet="pagination"></ng-container>
|
<div class="alert alert-danger" role="alert"><ng-container i18n>Error while loading documents</ng-container>: {{list.error}}</div>
|
||||||
</div>
|
} @else {
|
||||||
|
@if (list.displayMode === DisplayMode.LARGE_CARDS) {
|
||||||
@if (list.error ) {
|
<div>
|
||||||
<div class="alert alert-danger" role="alert"><ng-container i18n>Error while loading documents</ng-container>: {{list.error}}</div>
|
@for (d of list.documents; track d.id) {
|
||||||
} @else {
|
<pngx-document-card-large
|
||||||
@if (list.displayMode === DisplayMode.LARGE_CARDS) {
|
[selected]="list.isSelected(d)"
|
||||||
<div>
|
(toggleSelected)="toggleSelected(d, $event)"
|
||||||
@for (d of list.documents; track d.id) {
|
(dblClickDocument)="openDocumentDetail(d)"
|
||||||
<pngx-document-card-large
|
[document]="d"
|
||||||
[selected]="list.isSelected(d)"
|
[displayFields]="activeDisplayFields"
|
||||||
(toggleSelected)="toggleSelected(d, $event)"
|
(clickTag)="clickTag($event)"
|
||||||
(dblClickDocument)="openDocumentDetail(d)"
|
(clickCorrespondent)="clickCorrespondent($event)"
|
||||||
[document]="d"
|
(clickDocumentType)="clickDocumentType($event)"
|
||||||
[displayFields]="activeDisplayFields"
|
(clickStoragePath)="clickStoragePath($event)"
|
||||||
(clickTag)="clickTag($event)"
|
(clickMoreLike)="clickMoreLike(d.id)">
|
||||||
(clickCorrespondent)="clickCorrespondent($event)"
|
</pngx-document-card-large>
|
||||||
(clickDocumentType)="clickDocumentType($event)"
|
}
|
||||||
(clickStoragePath)="clickStoragePath($event)"
|
</div>
|
||||||
(clickMoreLike)="clickMoreLike(d.id)">
|
}
|
||||||
</pngx-document-card-large>
|
@if (list.displayMode === DisplayMode.TABLE) {
|
||||||
}
|
<div class="table-responsive">
|
||||||
</div>
|
<table class="table table-sm align-middle border shadow-sm">
|
||||||
}
|
<thead>
|
||||||
@if (list.displayMode === DisplayMode.TABLE) {
|
<tr>
|
||||||
<div class="table-responsive">
|
<th></th>
|
||||||
<table class="table table-sm align-middle border shadow-sm">
|
@if (activeDisplayFields.includes(DisplayField.ASN)) {
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th></th>
|
|
||||||
@if (activeDisplayFields.includes(DisplayField.ASN)) {
|
|
||||||
<th class="cursor-pointer"
|
|
||||||
pngxSortable="archive_serial_number"
|
|
||||||
title="Sort by ASN" i18n-title
|
|
||||||
[currentSortField]="list.sortField"
|
|
||||||
[currentSortReverse]="list.sortReverse"
|
|
||||||
(sort)="onSort($event)"
|
|
||||||
i18n>ASN</th>
|
|
||||||
}
|
|
||||||
@if (activeDisplayFields.includes(DisplayField.CORRESPONDENT) && permissionService.currentUserCan(PermissionAction.View, PermissionType.Correspondent)) {
|
|
||||||
<th class="cursor-pointer"
|
|
||||||
pngxSortable="correspondent__name"
|
|
||||||
title="Sort by correspondent" i18n-title
|
|
||||||
[currentSortField]="list.sortField"
|
|
||||||
[currentSortReverse]="list.sortReverse"
|
|
||||||
(sort)="onSort($event)"
|
|
||||||
i18n>Correspondent</th>
|
|
||||||
}
|
|
||||||
@if (activeDisplayFields.includes(DisplayField.TITLE)) {
|
|
||||||
<th class="cursor-pointer"
|
|
||||||
pngxSortable="title"
|
|
||||||
title="Sort by title" i18n-title
|
|
||||||
[currentSortField]="list.sortField"
|
|
||||||
[currentSortReverse]="list.sortReverse"
|
|
||||||
(sort)="onSort($event)"
|
|
||||||
style="min-width: 150px;"
|
|
||||||
i18n>Title</th>
|
|
||||||
}
|
|
||||||
@if (activeDisplayFields.includes(DisplayField.TAGS) && !activeDisplayFields.includes(DisplayField.TITLE)) {
|
|
||||||
<th i18n>Tags</th>
|
|
||||||
}
|
|
||||||
@if (activeDisplayFields.includes(DisplayField.OWNER) && permissionService.currentUserCan(PermissionAction.View, PermissionType.User)) {
|
|
||||||
<th class="cursor-pointer"
|
|
||||||
pngxSortable="owner"
|
|
||||||
title="Sort by owner" i18n-title
|
|
||||||
[currentSortField]="list.sortField"
|
|
||||||
[currentSortReverse]="list.sortReverse"
|
|
||||||
(sort)="onSort($event)"
|
|
||||||
i18n>Owner</th>
|
|
||||||
}
|
|
||||||
@if (activeDisplayFields.includes(DisplayField.NOTES) && notesEnabled) {
|
|
||||||
<th class="cursor-pointer"
|
|
||||||
pngxSortable="num_notes"
|
|
||||||
title="Sort by notes" i18n-title
|
|
||||||
[currentSortField]="list.sortField"
|
|
||||||
[currentSortReverse]="list.sortReverse"
|
|
||||||
(sort)="onSort($event)"
|
|
||||||
i18n>Notes</th>
|
|
||||||
}
|
|
||||||
@if (activeDisplayFields.includes(DisplayField.DOCUMENT_TYPE) && permissionService.currentUserCan(PermissionAction.View, PermissionType.DocumentType)) {
|
|
||||||
<th class="cursor-pointer"
|
|
||||||
pngxSortable="document_type__name"
|
|
||||||
title="Sort by document type" i18n-title
|
|
||||||
[currentSortField]="list.sortField"
|
|
||||||
[currentSortReverse]="list.sortReverse"
|
|
||||||
(sort)="onSort($event)"
|
|
||||||
i18n>Document type</th>
|
|
||||||
}
|
|
||||||
@if (activeDisplayFields.includes(DisplayField.STORAGE_PATH) && permissionService.currentUserCan(PermissionAction.View, PermissionType.StoragePath)) {
|
|
||||||
<th class="cursor-pointer"
|
|
||||||
pngxSortable="storage_path__name"
|
|
||||||
title="Sort by storage path" i18n-title
|
|
||||||
[currentSortField]="list.sortField"
|
|
||||||
[currentSortReverse]="list.sortReverse"
|
|
||||||
(sort)="onSort($event)"
|
|
||||||
i18n>Storage path</th>
|
|
||||||
}
|
|
||||||
@if (activeDisplayFields.includes(DisplayField.CREATED)) {
|
|
||||||
<th class="cursor-pointer"
|
|
||||||
pngxSortable="created"
|
|
||||||
title="Sort by created date" i18n-title
|
|
||||||
[currentSortField]="list.sortField"
|
|
||||||
[currentSortReverse]="list.sortReverse"
|
|
||||||
(sort)="onSort($event)"
|
|
||||||
i18n>Created</th>
|
|
||||||
}
|
|
||||||
@if (activeDisplayFields.includes(DisplayField.ADDED)) {
|
|
||||||
<th class="cursor-pointer"
|
|
||||||
pngxSortable="added"
|
|
||||||
title="Sort by added date" i18n-title
|
|
||||||
[currentSortField]="list.sortField"
|
|
||||||
[currentSortReverse]="list.sortReverse"
|
|
||||||
(sort)="onSort($event)"
|
|
||||||
i18n>Added</th>
|
|
||||||
}
|
|
||||||
@if (activeDisplayFields.includes(DisplayField.PAGE_COUNT)) {
|
|
||||||
<th class="cursor-pointer"
|
<th class="cursor-pointer"
|
||||||
pngxSortable="page_count"
|
pngxSortable="archive_serial_number"
|
||||||
title="Sort by number of pages" i18n-title
|
title="Sort by ASN" i18n-title
|
||||||
[currentSortField]="list.sortField"
|
[currentSortField]="list.sortField"
|
||||||
[currentSortReverse]="list.sortReverse"
|
[currentSortReverse]="list.sortReverse"
|
||||||
(sort)="onSort($event)"
|
(sort)="onSort($event)"
|
||||||
i18n>Pages</th>
|
i18n>ASN</th>
|
||||||
}
|
|
||||||
@if (activeDisplayFields.includes(DisplayField.SHARED)) {
|
|
||||||
<th i18n>
|
|
||||||
Shared
|
|
||||||
</th>
|
|
||||||
}
|
|
||||||
@for (field_id of activeDisplayCustomFields; track field_id) {
|
|
||||||
<th class="cursor-pointer"
|
|
||||||
pngxSortable="{{field_id}}"
|
|
||||||
title="Sort by {{getDisplayCustomFieldTitle(field_id)}}" i18n-title
|
|
||||||
[currentSortField]="list.sortField"
|
|
||||||
[currentSortReverse]="list.sortReverse"
|
|
||||||
(sort)="onSort($event)">
|
|
||||||
{{getDisplayCustomFieldTitle(field_id)}}
|
|
||||||
</th>
|
|
||||||
}
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@for (d of list.documents; track d.id) {
|
|
||||||
<tr (click)="toggleSelected(d, $event); $event.stopPropagation();" (dblclick)="openDocumentDetail(d)" [ngClass]="list.isSelected(d) ? 'table-row-selected' : ''">
|
|
||||||
<td>
|
|
||||||
<div class="form-check">
|
|
||||||
<input type="checkbox" class="form-check-input" id="docCheck{{d.id}}" [checked]="list.isSelected(d)" (click)="toggleSelected(d, $event); $event.stopPropagation();">
|
|
||||||
<label class="form-check-label" for="docCheck{{d.id}}"></label>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
@if (activeDisplayFields.includes(DisplayField.ASN)) {
|
|
||||||
<td class="">
|
|
||||||
{{d.archive_serial_number}}
|
|
||||||
</td>
|
|
||||||
}
|
}
|
||||||
@if (activeDisplayFields.includes(DisplayField.CORRESPONDENT) && permissionService.currentUserCan(PermissionAction.View, PermissionType.Correspondent)) {
|
@if (activeDisplayFields.includes(DisplayField.CORRESPONDENT) && permissionService.currentUserCan(PermissionAction.View, PermissionType.Correspondent)) {
|
||||||
<td class="">
|
<th class="cursor-pointer"
|
||||||
@if (d.correspondent) {
|
pngxSortable="correspondent__name"
|
||||||
<a (click)="clickCorrespondent(d.correspondent);$event.stopPropagation()" title="Filter by correspondent" i18n-title>{{d.correspondent | correspondentName | async}}</a>
|
title="Sort by correspondent" i18n-title
|
||||||
}
|
[currentSortField]="list.sortField"
|
||||||
</td>
|
[currentSortReverse]="list.sortReverse"
|
||||||
|
(sort)="onSort($event)"
|
||||||
|
i18n>Correspondent</th>
|
||||||
}
|
}
|
||||||
@if (activeDisplayFields.includes(DisplayField.TITLE) || activeDisplayFields.includes(DisplayField.TAGS)) {
|
@if (activeDisplayFields.includes(DisplayField.TITLE)) {
|
||||||
<td width="30%">
|
<th class="cursor-pointer"
|
||||||
@if (activeDisplayFields.includes(DisplayField.TITLE)) {
|
pngxSortable="title"
|
||||||
<div class="d-inline-block" (mouseleave)="popupPreview.close()">
|
title="Sort by title" i18n-title
|
||||||
<a routerLink="/documents/{{d.id}}" title="Edit document" i18n-title style="overflow-wrap: anywhere;">{{d.title | documentTitle}}</a>
|
[currentSortField]="list.sortField"
|
||||||
<pngx-preview-popup [document]="d" linkClasses="btn btn-sm btn-link text-secondary" linkTitle="Preview document" (click)="$event.stopPropagation()" i18n-linkTitle #popupPreview>
|
[currentSortReverse]="list.sortReverse"
|
||||||
<i-bs name="eye"></i-bs>
|
(sort)="onSort($event)"
|
||||||
</pngx-preview-popup>
|
style="min-width: 150px;"
|
||||||
</div>
|
i18n>Title</th>
|
||||||
}
|
}
|
||||||
@if (activeDisplayFields.includes(DisplayField.TAGS)) {
|
@if (activeDisplayFields.includes(DisplayField.TAGS) && !activeDisplayFields.includes(DisplayField.TITLE)) {
|
||||||
@for (tagID of d.tags; track t) {
|
<th i18n>Tags</th>
|
||||||
<pngx-tag [tagID]="tagID" class="ms-1" clickable="true" linkTitle="Filter by tag" i18n-linkTitle (click)="clickTag(tagID);$event.stopPropagation()"></pngx-tag>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</td>
|
|
||||||
}
|
}
|
||||||
@if (activeDisplayFields.includes(DisplayField.OWNER) && permissionService.currentUserCan(PermissionAction.View, PermissionType.User)) {
|
@if (activeDisplayFields.includes(DisplayField.OWNER) && permissionService.currentUserCan(PermissionAction.View, PermissionType.User)) {
|
||||||
<td>
|
<th class="cursor-pointer"
|
||||||
{{d.owner | username | async}}
|
pngxSortable="owner"
|
||||||
</td>
|
title="Sort by owner" i18n-title
|
||||||
|
[currentSortField]="list.sortField"
|
||||||
|
[currentSortReverse]="list.sortReverse"
|
||||||
|
(sort)="onSort($event)"
|
||||||
|
i18n>Owner</th>
|
||||||
}
|
}
|
||||||
@if (activeDisplayFields.includes(DisplayField.NOTES) && notesEnabled) {
|
@if (activeDisplayFields.includes(DisplayField.NOTES) && notesEnabled) {
|
||||||
<td class="">
|
<th class="cursor-pointer"
|
||||||
@if (d.notes.length) {
|
pngxSortable="num_notes"
|
||||||
<a routerLink="/documents/{{d.id}}/notes" class="btn btn-sm p-0">
|
title="Sort by notes" i18n-title
|
||||||
<span class="badge rounded-pill bg-light border text-primary">
|
[currentSortField]="list.sortField"
|
||||||
<i-bs width="1.2em" height="1.2em" class="ms-1 me-1" name="chat-left-text"></i-bs>
|
[currentSortReverse]="list.sortReverse"
|
||||||
{{d.notes.length}}</span>
|
(sort)="onSort($event)"
|
||||||
</a>
|
i18n>Notes</th>
|
||||||
}
|
|
||||||
</td>
|
|
||||||
}
|
}
|
||||||
@if (activeDisplayFields.includes(DisplayField.DOCUMENT_TYPE) && permissionService.currentUserCan(PermissionAction.View, PermissionType.DocumentType)) {
|
@if (activeDisplayFields.includes(DisplayField.DOCUMENT_TYPE) && permissionService.currentUserCan(PermissionAction.View, PermissionType.DocumentType)) {
|
||||||
<td class="">
|
<th class="cursor-pointer"
|
||||||
@if (d.document_type) {
|
pngxSortable="document_type__name"
|
||||||
<a (click)="clickDocumentType(d.document_type);$event.stopPropagation()" title="Filter by document type" i18n-title>{{d.document_type | documentTypeName | async}}</a>
|
title="Sort by document type" i18n-title
|
||||||
}
|
[currentSortField]="list.sortField"
|
||||||
</td>
|
[currentSortReverse]="list.sortReverse"
|
||||||
|
(sort)="onSort($event)"
|
||||||
|
i18n>Document type</th>
|
||||||
}
|
}
|
||||||
@if (activeDisplayFields.includes(DisplayField.STORAGE_PATH) && permissionService.currentUserCan(PermissionAction.View, PermissionType.StoragePath)) {
|
@if (activeDisplayFields.includes(DisplayField.STORAGE_PATH) && permissionService.currentUserCan(PermissionAction.View, PermissionType.StoragePath)) {
|
||||||
<td class="">
|
<th class="cursor-pointer"
|
||||||
@if (d.storage_path) {
|
pngxSortable="storage_path__name"
|
||||||
<a (click)="clickStoragePath(d.storage_path);$event.stopPropagation()" title="Filter by storage path" i18n-title>{{d.storage_path | storagePathName | async}}</a>
|
title="Sort by storage path" i18n-title
|
||||||
}
|
[currentSortField]="list.sortField"
|
||||||
</td>
|
[currentSortReverse]="list.sortReverse"
|
||||||
|
(sort)="onSort($event)"
|
||||||
|
i18n>Storage path</th>
|
||||||
}
|
}
|
||||||
@if (activeDisplayFields.includes(DisplayField.CREATED)) {
|
@if (activeDisplayFields.includes(DisplayField.CREATED)) {
|
||||||
<td>
|
<th class="cursor-pointer"
|
||||||
{{d.created_date | customDate}}
|
pngxSortable="created"
|
||||||
</td>
|
title="Sort by created date" i18n-title
|
||||||
|
[currentSortField]="list.sortField"
|
||||||
|
[currentSortReverse]="list.sortReverse"
|
||||||
|
(sort)="onSort($event)"
|
||||||
|
i18n>Created</th>
|
||||||
}
|
}
|
||||||
@if (activeDisplayFields.includes(DisplayField.ADDED)) {
|
@if (activeDisplayFields.includes(DisplayField.ADDED)) {
|
||||||
<td>
|
<th class="cursor-pointer"
|
||||||
{{d.added | customDate}}
|
pngxSortable="added"
|
||||||
</td>
|
title="Sort by added date" i18n-title
|
||||||
|
[currentSortField]="list.sortField"
|
||||||
|
[currentSortReverse]="list.sortReverse"
|
||||||
|
(sort)="onSort($event)"
|
||||||
|
i18n>Added</th>
|
||||||
}
|
}
|
||||||
@if (activeDisplayFields.includes(DisplayField.PAGE_COUNT)) {
|
@if (activeDisplayFields.includes(DisplayField.PAGE_COUNT)) {
|
||||||
<td>
|
<th class="cursor-pointer"
|
||||||
{{ d.page_count }}
|
pngxSortable="page_count"
|
||||||
</td>
|
title="Sort by number of pages" i18n-title
|
||||||
}
|
[currentSortField]="list.sortField"
|
||||||
|
[currentSortReverse]="list.sortReverse"
|
||||||
|
(sort)="onSort($event)"
|
||||||
|
i18n>Pages</th>
|
||||||
|
}
|
||||||
@if (activeDisplayFields.includes(DisplayField.SHARED)) {
|
@if (activeDisplayFields.includes(DisplayField.SHARED)) {
|
||||||
<td>
|
<th i18n>
|
||||||
@if (d.is_shared_by_requester) { <ng-container i18n>Yes</ng-container> } @else { <ng-container i18n>No</ng-container> }
|
Shared
|
||||||
</td>
|
</th>
|
||||||
}
|
}
|
||||||
@for (field of activeDisplayCustomFields; track field) {
|
@for (field_id of activeDisplayCustomFields; track field_id) {
|
||||||
<td class="">
|
<th class="cursor-pointer"
|
||||||
<pngx-custom-field-display [document]="d" [fieldDisplayKey]="field"></pngx-custom-field-display>
|
pngxSortable="{{field_id}}"
|
||||||
</td>
|
title="Sort by {{getDisplayCustomFieldTitle(field_id)}}" i18n-title
|
||||||
|
[currentSortField]="list.sortField"
|
||||||
|
[currentSortReverse]="list.sortReverse"
|
||||||
|
(sort)="onSort($event)">
|
||||||
|
{{getDisplayCustomFieldTitle(field_id)}}
|
||||||
|
</th>
|
||||||
}
|
}
|
||||||
</tr>
|
</tr>
|
||||||
}
|
</thead>
|
||||||
</tbody>
|
<tbody>
|
||||||
</table>
|
@for (d of list.documents; track d.id) {
|
||||||
</div>
|
<tr (click)="toggleSelected(d, $event); $event.stopPropagation();" (dblclick)="openDocumentDetail(d)" [ngClass]="list.isSelected(d) ? 'table-row-selected' : ''">
|
||||||
|
<td>
|
||||||
|
<div class="form-check">
|
||||||
|
<input type="checkbox" class="form-check-input" id="docCheck{{d.id}}" [checked]="list.isSelected(d)" (click)="toggleSelected(d, $event); $event.stopPropagation();">
|
||||||
|
<label class="form-check-label" for="docCheck{{d.id}}"></label>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
@if (activeDisplayFields.includes(DisplayField.ASN)) {
|
||||||
|
<td class="">
|
||||||
|
{{d.archive_serial_number}}
|
||||||
|
</td>
|
||||||
|
}
|
||||||
|
@if (activeDisplayFields.includes(DisplayField.CORRESPONDENT) && permissionService.currentUserCan(PermissionAction.View, PermissionType.Correspondent)) {
|
||||||
|
<td class="">
|
||||||
|
@if (d.correspondent) {
|
||||||
|
<a (click)="clickCorrespondent(d.correspondent);$event.stopPropagation()" title="Filter by correspondent" i18n-title>{{(d.correspondent$ | async)?.name}}</a>
|
||||||
|
}
|
||||||
|
</td>
|
||||||
|
}
|
||||||
|
@if (activeDisplayFields.includes(DisplayField.TITLE) || activeDisplayFields.includes(DisplayField.TAGS)) {
|
||||||
|
<td width="30%">
|
||||||
|
@if (activeDisplayFields.includes(DisplayField.TITLE)) {
|
||||||
|
<div class="d-inline-block" (mouseleave)="popupPreview.close()">
|
||||||
|
<a routerLink="/documents/{{d.id}}" title="Edit document" i18n-title style="overflow-wrap: anywhere;">{{d.title | documentTitle}}</a>
|
||||||
|
<pngx-preview-popup [document]="d" linkClasses="btn btn-sm btn-link text-secondary" linkTitle="Preview document" (click)="$event.stopPropagation()" i18n-linkTitle #popupPreview>
|
||||||
|
<i-bs name="eye"></i-bs>
|
||||||
|
</pngx-preview-popup>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@if (activeDisplayFields.includes(DisplayField.TAGS)) {
|
||||||
|
@for (t of d.tags$ | async; track t) {
|
||||||
|
<pngx-tag [tag]="t" class="ms-1" clickable="true" linkTitle="Filter by tag" i18n-linkTitle (click)="clickTag(t.id);$event.stopPropagation()"></pngx-tag>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</td>
|
||||||
|
}
|
||||||
|
@if (activeDisplayFields.includes(DisplayField.OWNER) && permissionService.currentUserCan(PermissionAction.View, PermissionType.User)) {
|
||||||
|
<td>
|
||||||
|
{{d.owner | username}}
|
||||||
|
</td>
|
||||||
|
}
|
||||||
|
@if (activeDisplayFields.includes(DisplayField.NOTES) && notesEnabled) {
|
||||||
|
<td class="">
|
||||||
|
@if (d.notes.length) {
|
||||||
|
<a routerLink="/documents/{{d.id}}/notes" class="btn btn-sm p-0">
|
||||||
|
<span class="badge rounded-pill bg-light border text-primary">
|
||||||
|
<i-bs width="1.2em" height="1.2em" class="ms-1 me-1" name="chat-left-text"></i-bs>
|
||||||
|
{{d.notes.length}}</span>
|
||||||
|
</a>
|
||||||
|
}
|
||||||
|
</td>
|
||||||
|
}
|
||||||
|
@if (activeDisplayFields.includes(DisplayField.DOCUMENT_TYPE) && permissionService.currentUserCan(PermissionAction.View, PermissionType.DocumentType)) {
|
||||||
|
<td class="">
|
||||||
|
@if (d.document_type) {
|
||||||
|
<a (click)="clickDocumentType(d.document_type);$event.stopPropagation()" title="Filter by document type" i18n-title>{{(d.document_type$ | async)?.name}}</a>
|
||||||
|
}
|
||||||
|
</td>
|
||||||
|
}
|
||||||
|
@if (activeDisplayFields.includes(DisplayField.STORAGE_PATH) && permissionService.currentUserCan(PermissionAction.View, PermissionType.StoragePath)) {
|
||||||
|
<td class="">
|
||||||
|
@if (d.storage_path) {
|
||||||
|
<a (click)="clickStoragePath(d.storage_path);$event.stopPropagation()" title="Filter by storage path" i18n-title>{{(d.storage_path$ | async)?.name}}</a>
|
||||||
|
}
|
||||||
|
</td>
|
||||||
|
}
|
||||||
|
@if (activeDisplayFields.includes(DisplayField.CREATED)) {
|
||||||
|
<td>
|
||||||
|
{{d.created_date | customDate}}
|
||||||
|
</td>
|
||||||
|
}
|
||||||
|
@if (activeDisplayFields.includes(DisplayField.ADDED)) {
|
||||||
|
<td>
|
||||||
|
{{d.added | customDate}}
|
||||||
|
</td>
|
||||||
|
}
|
||||||
|
@if (activeDisplayFields.includes(DisplayField.PAGE_COUNT)) {
|
||||||
|
<td>
|
||||||
|
{{ d.page_count }}
|
||||||
|
</td>
|
||||||
|
}
|
||||||
|
@if (activeDisplayFields.includes(DisplayField.SHARED)) {
|
||||||
|
<td>
|
||||||
|
@if (d.is_shared_by_requester) { <ng-container i18n>Yes</ng-container> } @else { <ng-container i18n>No</ng-container> }
|
||||||
|
</td>
|
||||||
|
}
|
||||||
|
@for (field of activeDisplayCustomFields; track field) {
|
||||||
|
<td class="">
|
||||||
|
<pngx-custom-field-display [document]="d" [fieldDisplayKey]="field"></pngx-custom-field-display>
|
||||||
|
</td>
|
||||||
|
}
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@if (list.displayMode === DisplayMode.SMALL_CARDS) {
|
||||||
|
<div class="row row-cols-paperless-cards">
|
||||||
|
@for (d of list.documents; track d.id) {
|
||||||
|
<pngx-document-card-small class="p-0"
|
||||||
|
[selected]="list.isSelected(d)"
|
||||||
|
(toggleSelected)="toggleSelected(d, $event)"
|
||||||
|
(dblClickDocument)="openDocumentDetail(d)"
|
||||||
|
[document]="d"
|
||||||
|
(clickTag)="clickTag($event)"
|
||||||
|
[displayFields]="activeDisplayFields"
|
||||||
|
(clickCorrespondent)="clickCorrespondent($event)"
|
||||||
|
(clickStoragePath)="clickStoragePath($event)"
|
||||||
|
(clickDocumentType)="clickDocumentType($event)">
|
||||||
|
</pngx-document-card-small>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@if (list.documents?.length > 15) {
|
||||||
|
<div class="mt-3">
|
||||||
|
<ng-container *ngTemplateOutlet="pagination"></ng-container>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@if (list.displayMode === DisplayMode.SMALL_CARDS) {
|
</div>
|
||||||
<div class="row row-cols-paperless-cards">
|
@if (list.showPreviewPane) {
|
||||||
@for (d of list.documents; track d.id) {
|
<div class="col-lg-6">
|
||||||
<pngx-document-card-small class="p-0"
|
<div class="row">
|
||||||
[selected]="list.isSelected(d)"
|
<div class="btn-toolbar mb-1 border-bottom align-items-center">
|
||||||
(toggleSelected)="toggleSelected(d, $event)"
|
<div class="btn-group pb-3">
|
||||||
(dblClickDocument)="openDocumentDetail(d)"
|
<button type="button" class="btn btn-sm btn-outline-secondary" i18n-title title="Previous" (click)="previousDoc()" [disabled]="list.documents.length === 0 || !hasPrevious">
|
||||||
[document]="d"
|
<i-bs width="1.2em" height="1.2em" name="arrow-left" class="me-1"></i-bs><ng-container i18n>Previous</ng-container>
|
||||||
(clickTag)="clickTag($event)"
|
</button>
|
||||||
[displayFields]="activeDisplayFields"
|
<button type="button" class="btn btn-sm btn-outline-secondary" i18n-title title="Next" (click)="nextDoc()" [disabled]="list.documents.length === 0 || !hasNext">
|
||||||
(clickCorrespondent)="clickCorrespondent($event)"
|
<ng-container i18n>Next</ng-container><i-bs width="1.2em" height="1.2em" name="arrow-right" class="ms-1"></i-bs>
|
||||||
(clickStoragePath)="clickStoragePath($event)"
|
</button>
|
||||||
(clickDocumentType)="clickDocumentType($event)">
|
</div>
|
||||||
</pngx-document-card-small>
|
<div class="input-group pb-3 ms-auto">
|
||||||
}
|
<h5 class="mb-0">
|
||||||
|
{{list.firstSelectedDocument?.title}}
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
<div class="row">
|
||||||
@if (list.documents?.length > 15) {
|
<div class="col preview-pane">
|
||||||
<div class="mt-3">
|
@if (list.selected.size > 0) {
|
||||||
<ng-container *ngTemplateOutlet="pagination"></ng-container>
|
<pngx-preview-popup [document]="list.firstSelectedDocument" [previewOnly]="true"></pngx-preview-popup>
|
||||||
|
} @else {
|
||||||
|
<div class="w-100 h-100 position-relative">
|
||||||
|
<p class="fst-italic">
|
||||||
|
<ng-container i18n>No document selected</ng-container>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
</div>
|
||||||
}
|
}
|
||||||
|
</div>
|
||||||
|
@@ -80,3 +80,9 @@ a {
|
|||||||
pngx-page-header .dropdown-menu {
|
pngx-page-header .dropdown-menu {
|
||||||
--bs-dropdown-min-width: 12em;
|
--bs-dropdown-min-width: 12em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.preview-pane {
|
||||||
|
height: 60rem;
|
||||||
|
top: 70px;
|
||||||
|
position: sticky;
|
||||||
|
}
|
||||||
|
@@ -57,21 +57,21 @@ const docs: Document[] = [
|
|||||||
id: 1,
|
id: 1,
|
||||||
title: 'Doc1',
|
title: 'Doc1',
|
||||||
notes: [],
|
notes: [],
|
||||||
tags: [],
|
tags$: new Subject(),
|
||||||
content: 'document content 1',
|
content: 'document content 1',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 2,
|
id: 2,
|
||||||
title: 'Doc2',
|
title: 'Doc2',
|
||||||
notes: [],
|
notes: [],
|
||||||
tags: [],
|
tags$: new Subject(),
|
||||||
content: 'document content 2',
|
content: 'document content 2',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 3,
|
id: 3,
|
||||||
title: 'Doc3',
|
title: 'Doc3',
|
||||||
notes: [],
|
notes: [],
|
||||||
tags: [],
|
tags$: new Subject(),
|
||||||
content: 'document content 3',
|
content: 'document content 3',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@@ -650,6 +650,7 @@ describe('DocumentListComponent', () => {
|
|||||||
id: i + 1,
|
id: i + 1,
|
||||||
title: `Doc${i + 1}`,
|
title: `Doc${i + 1}`,
|
||||||
notes: [],
|
notes: [],
|
||||||
|
tags$: new Subject(),
|
||||||
content: `document content ${i + 1}`,
|
content: `document content ${i + 1}`,
|
||||||
}))
|
}))
|
||||||
jest
|
jest
|
||||||
|
@@ -37,11 +37,8 @@ import {
|
|||||||
SortableDirective,
|
SortableDirective,
|
||||||
SortEvent,
|
SortEvent,
|
||||||
} from 'src/app/directives/sortable.directive'
|
} from 'src/app/directives/sortable.directive'
|
||||||
import { CorrespondentNamePipe } from 'src/app/pipes/correspondent-name.pipe'
|
|
||||||
import { CustomDatePipe } from 'src/app/pipes/custom-date.pipe'
|
import { CustomDatePipe } from 'src/app/pipes/custom-date.pipe'
|
||||||
import { DocumentTitlePipe } from 'src/app/pipes/document-title.pipe'
|
import { DocumentTitlePipe } from 'src/app/pipes/document-title.pipe'
|
||||||
import { DocumentTypeNamePipe } from 'src/app/pipes/document-type-name.pipe'
|
|
||||||
import { StoragePathNamePipe } from 'src/app/pipes/storage-path-name.pipe'
|
|
||||||
import { UsernamePipe } from 'src/app/pipes/username.pipe'
|
import { UsernamePipe } from 'src/app/pipes/username.pipe'
|
||||||
import { ConsumerStatusService } from 'src/app/services/consumer-status.service'
|
import { ConsumerStatusService } from 'src/app/services/consumer-status.service'
|
||||||
import { DocumentListViewService } from 'src/app/services/document-list-view.service'
|
import { DocumentListViewService } from 'src/app/services/document-list-view.service'
|
||||||
@@ -84,9 +81,6 @@ import { SaveViewConfigDialogComponent } from './save-view-config-dialog/save-vi
|
|||||||
IfPermissionsDirective,
|
IfPermissionsDirective,
|
||||||
SortableDirective,
|
SortableDirective,
|
||||||
UsernamePipe,
|
UsernamePipe,
|
||||||
CorrespondentNamePipe,
|
|
||||||
DocumentTypeNamePipe,
|
|
||||||
StoragePathNamePipe,
|
|
||||||
NgxBootstrapIconsModule,
|
NgxBootstrapIconsModule,
|
||||||
AsyncPipe,
|
AsyncPipe,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
@@ -332,24 +326,36 @@ export class DocumentListComponent
|
|||||||
this.hotKeyService
|
this.hotKeyService
|
||||||
.addShortcut({
|
.addShortcut({
|
||||||
keys: 'control.arrowleft',
|
keys: 'control.arrowleft',
|
||||||
description: $localize`Previous page`,
|
description: $localize`Previous page / document`,
|
||||||
})
|
})
|
||||||
.pipe(takeUntil(this.unsubscribeNotifier))
|
.pipe(takeUntil(this.unsubscribeNotifier))
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
if (this.list.currentPage > 1) {
|
if (this.list.showPreviewPane) {
|
||||||
this.list.currentPage--
|
if (this.hasPrevious) {
|
||||||
|
this.previousDoc()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (this.list.currentPage > 1) {
|
||||||
|
this.list.currentPage--
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
this.hotKeyService
|
this.hotKeyService
|
||||||
.addShortcut({
|
.addShortcut({
|
||||||
keys: 'control.arrowright',
|
keys: 'control.arrowright',
|
||||||
description: $localize`Next page`,
|
description: $localize`Next page / document`,
|
||||||
})
|
})
|
||||||
.pipe(takeUntil(this.unsubscribeNotifier))
|
.pipe(takeUntil(this.unsubscribeNotifier))
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
if (this.list.currentPage < this.list.getLastPage()) {
|
if (this.list.showPreviewPane) {
|
||||||
this.list.currentPage++
|
if (this.hasNext) {
|
||||||
|
this.nextDoc()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (this.list.currentPage < this.list.getLastPage()) {
|
||||||
|
this.list.currentPage++
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -479,4 +485,45 @@ export class DocumentListComponent
|
|||||||
resetFilters() {
|
resetFilters() {
|
||||||
this.filterEditor.resetSelected()
|
this.filterEditor.resetSelected()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get hasPrevious(): boolean {
|
||||||
|
return (
|
||||||
|
(this.list.selected.size > 0 &&
|
||||||
|
this.list.documents.indexOf(this.list.firstSelectedDocument) > 0) ||
|
||||||
|
(this.list.selected.size === 0 && this.list.documents.length > 0)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public get hasNext(): boolean {
|
||||||
|
return (
|
||||||
|
(this.list.selected.size > 0 &&
|
||||||
|
this.list.documents.indexOf(this.list.firstSelectedDocument) <
|
||||||
|
this.list.documents.length - 1) ||
|
||||||
|
(this.list.selected.size === 0 && this.list.documents.length > 0)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public nextDoc(): void {
|
||||||
|
const index =
|
||||||
|
this.list.selected.size === 0
|
||||||
|
? 0
|
||||||
|
: Math.min(
|
||||||
|
this.list.documents.indexOf(this.list.firstSelectedDocument) + 1,
|
||||||
|
this.list.documents.length - 1
|
||||||
|
)
|
||||||
|
this.list.selected.clear()
|
||||||
|
this.list.selected.add(this.list.documents[index].id)
|
||||||
|
}
|
||||||
|
|
||||||
|
public previousDoc(): void {
|
||||||
|
const index =
|
||||||
|
this.list.selected.size === 0
|
||||||
|
? 0
|
||||||
|
: Math.max(
|
||||||
|
this.list.documents.indexOf(this.list.firstSelectedDocument) - 1,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
this.list.selected.clear()
|
||||||
|
this.list.selected.add(this.list.documents[index].id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,11 @@
|
|||||||
|
import { Observable } from 'rxjs'
|
||||||
|
import { Correspondent } from './correspondent'
|
||||||
import { CustomFieldInstance } from './custom-field-instance'
|
import { CustomFieldInstance } from './custom-field-instance'
|
||||||
import { DocumentNote } from './document-note'
|
import { DocumentNote } from './document-note'
|
||||||
|
import { DocumentType } from './document-type'
|
||||||
import { ObjectWithPermissions } from './object-with-permissions'
|
import { ObjectWithPermissions } from './object-with-permissions'
|
||||||
|
import { StoragePath } from './storage-path'
|
||||||
|
import { Tag } from './tag'
|
||||||
|
|
||||||
export enum DisplayMode {
|
export enum DisplayMode {
|
||||||
TABLE = 'table',
|
TABLE = 'table',
|
||||||
@@ -113,16 +118,24 @@ export interface SearchHit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface Document extends ObjectWithPermissions {
|
export interface Document extends ObjectWithPermissions {
|
||||||
|
correspondent$?: Observable<Correspondent>
|
||||||
|
|
||||||
correspondent?: number
|
correspondent?: number
|
||||||
|
|
||||||
|
document_type$?: Observable<DocumentType>
|
||||||
|
|
||||||
document_type?: number
|
document_type?: number
|
||||||
|
|
||||||
|
storage_path$?: Observable<StoragePath>
|
||||||
|
|
||||||
storage_path?: number
|
storage_path?: number
|
||||||
|
|
||||||
title?: string
|
title?: string
|
||||||
|
|
||||||
content?: string
|
content?: string
|
||||||
|
|
||||||
|
tags$?: Observable<Tag[]>
|
||||||
|
|
||||||
tags?: number[]
|
tags?: number[]
|
||||||
|
|
||||||
checksum?: string
|
checksum?: string
|
||||||
|
@@ -7,7 +7,7 @@ export enum MailFilterAttachmentType {
|
|||||||
|
|
||||||
export enum MailRuleConsumptionScope {
|
export enum MailRuleConsumptionScope {
|
||||||
Attachments = 1,
|
Attachments = 1,
|
||||||
EmailOnly = 2,
|
Email_Only = 2,
|
||||||
Everything = 3,
|
Everything = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,28 +0,0 @@
|
|||||||
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
|
|
||||||
import { provideHttpClientTesting } from '@angular/common/http/testing'
|
|
||||||
import { TestBed } from '@angular/core/testing'
|
|
||||||
import { PermissionsService } from '../services/permissions.service'
|
|
||||||
import { CorrespondentService } from '../services/rest/correspondent.service'
|
|
||||||
import { CorrespondentNamePipe } from './correspondent-name.pipe'
|
|
||||||
|
|
||||||
describe('CorrespondentNamePipe', () => {
|
|
||||||
let pipe: CorrespondentNamePipe
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
TestBed.configureTestingModule({
|
|
||||||
providers: [
|
|
||||||
provideHttpClient(withInterceptorsFromDi()),
|
|
||||||
provideHttpClientTesting(),
|
|
||||||
],
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
// The pipe is a simple wrapper around ObjectNamePipe, see ObjectNamePipe for the actual tests.
|
|
||||||
it('should be created', () => {
|
|
||||||
pipe = new CorrespondentNamePipe(
|
|
||||||
TestBed.inject(PermissionsService),
|
|
||||||
TestBed.inject(CorrespondentService)
|
|
||||||
)
|
|
||||||
expect(pipe).toBeTruthy()
|
|
||||||
})
|
|
||||||
})
|
|
@@ -1,22 +0,0 @@
|
|||||||
import { Pipe, PipeTransform } from '@angular/core'
|
|
||||||
import {
|
|
||||||
PermissionsService,
|
|
||||||
PermissionType,
|
|
||||||
} from '../services/permissions.service'
|
|
||||||
import { CorrespondentService } from '../services/rest/correspondent.service'
|
|
||||||
import { ObjectNamePipe } from './object-name.pipe'
|
|
||||||
|
|
||||||
@Pipe({
|
|
||||||
name: 'correspondentName',
|
|
||||||
})
|
|
||||||
export class CorrespondentNamePipe
|
|
||||||
extends ObjectNamePipe
|
|
||||||
implements PipeTransform
|
|
||||||
{
|
|
||||||
constructor(
|
|
||||||
permissionsService: PermissionsService,
|
|
||||||
objectService: CorrespondentService
|
|
||||||
) {
|
|
||||||
super(permissionsService, PermissionType.Correspondent, objectService)
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,28 +0,0 @@
|
|||||||
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
|
|
||||||
import { provideHttpClientTesting } from '@angular/common/http/testing'
|
|
||||||
import { TestBed } from '@angular/core/testing'
|
|
||||||
import { PermissionsService } from '../services/permissions.service'
|
|
||||||
import { DocumentTypeService } from '../services/rest/document-type.service'
|
|
||||||
import { DocumentTypeNamePipe } from './document-type-name.pipe'
|
|
||||||
|
|
||||||
describe('DocumentTypeNamePipe', () => {
|
|
||||||
let pipe: DocumentTypeNamePipe
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
TestBed.configureTestingModule({
|
|
||||||
providers: [
|
|
||||||
provideHttpClient(withInterceptorsFromDi()),
|
|
||||||
provideHttpClientTesting(),
|
|
||||||
],
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
// The pipe is a simple wrapper around ObjectNamePipe, see ObjectNamePipe for the actual tests.
|
|
||||||
it('should be created', () => {
|
|
||||||
pipe = new DocumentTypeNamePipe(
|
|
||||||
TestBed.inject(PermissionsService),
|
|
||||||
TestBed.inject(DocumentTypeService)
|
|
||||||
)
|
|
||||||
expect(pipe).toBeTruthy()
|
|
||||||
})
|
|
||||||
})
|
|
@@ -1,22 +0,0 @@
|
|||||||
import { Pipe, PipeTransform } from '@angular/core'
|
|
||||||
import {
|
|
||||||
PermissionsService,
|
|
||||||
PermissionType,
|
|
||||||
} from '../services/permissions.service'
|
|
||||||
import { DocumentTypeService } from '../services/rest/document-type.service'
|
|
||||||
import { ObjectNamePipe } from './object-name.pipe'
|
|
||||||
|
|
||||||
@Pipe({
|
|
||||||
name: 'documentTypeName',
|
|
||||||
})
|
|
||||||
export class DocumentTypeNamePipe
|
|
||||||
extends ObjectNamePipe
|
|
||||||
implements PipeTransform
|
|
||||||
{
|
|
||||||
constructor(
|
|
||||||
permissionsService: PermissionsService,
|
|
||||||
objectService: DocumentTypeService
|
|
||||||
) {
|
|
||||||
super(permissionsService, PermissionType.DocumentType, objectService)
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,88 +0,0 @@
|
|||||||
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
|
|
||||||
import { provideHttpClientTesting } from '@angular/common/http/testing'
|
|
||||||
import { TestBed } from '@angular/core/testing'
|
|
||||||
import { of, throwError } from 'rxjs'
|
|
||||||
import { MatchingModel } from '../data/matching-model'
|
|
||||||
import { PermissionsService } from '../services/permissions.service'
|
|
||||||
import { AbstractNameFilterService } from '../services/rest/abstract-name-filter-service'
|
|
||||||
import { CorrespondentService } from '../services/rest/correspondent.service'
|
|
||||||
import { CorrespondentNamePipe } from './correspondent-name.pipe'
|
|
||||||
import { ObjectNamePipe } from './object-name.pipe'
|
|
||||||
|
|
||||||
describe('ObjectNamePipe', () => {
|
|
||||||
/*
|
|
||||||
ObjectNamePipe is an abstract class to prevent instantiation,
|
|
||||||
so we test the concrete implementation CorrespondentNamePipe instead.
|
|
||||||
*/
|
|
||||||
let pipe: CorrespondentNamePipe
|
|
||||||
let permissionsService: PermissionsService
|
|
||||||
let objectService: AbstractNameFilterService<MatchingModel>
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
TestBed.configureTestingModule({
|
|
||||||
providers: [
|
|
||||||
ObjectNamePipe,
|
|
||||||
provideHttpClient(withInterceptorsFromDi()),
|
|
||||||
provideHttpClientTesting(),
|
|
||||||
],
|
|
||||||
})
|
|
||||||
|
|
||||||
permissionsService = TestBed.inject(PermissionsService)
|
|
||||||
objectService = TestBed.inject(CorrespondentService)
|
|
||||||
pipe = new CorrespondentNamePipe(permissionsService, objectService)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should return object name if user has permission', (done) => {
|
|
||||||
const mockObjects = {
|
|
||||||
results: [
|
|
||||||
{ id: 1, name: 'Object 1' },
|
|
||||||
{ id: 2, name: 'Object 2' },
|
|
||||||
],
|
|
||||||
count: 2,
|
|
||||||
all: [1, 2],
|
|
||||||
}
|
|
||||||
jest.spyOn(permissionsService, 'currentUserCan').mockReturnValue(true)
|
|
||||||
jest.spyOn(objectService, 'listAll').mockReturnValue(of(mockObjects))
|
|
||||||
|
|
||||||
pipe.transform(1).subscribe((result) => {
|
|
||||||
expect(result).toBe('Object 1')
|
|
||||||
done()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should return empty string if object not found', (done) => {
|
|
||||||
const mockObjects = {
|
|
||||||
results: [{ id: 2, name: 'Object 2' }],
|
|
||||||
count: 1,
|
|
||||||
all: [2],
|
|
||||||
}
|
|
||||||
jest.spyOn(permissionsService, 'currentUserCan').mockReturnValue(true)
|
|
||||||
jest.spyOn(objectService, 'listAll').mockReturnValue(of(mockObjects))
|
|
||||||
|
|
||||||
pipe.transform(1).subscribe((result) => {
|
|
||||||
expect(result).toBe('')
|
|
||||||
done()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should return "Private" if user does not have permission', (done) => {
|
|
||||||
jest.spyOn(permissionsService, 'currentUserCan').mockReturnValue(false)
|
|
||||||
|
|
||||||
pipe.transform(1).subscribe((result) => {
|
|
||||||
expect(result).toBe('Private')
|
|
||||||
done()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle error and return empty string', (done) => {
|
|
||||||
jest.spyOn(permissionsService, 'currentUserCan').mockReturnValue(true)
|
|
||||||
jest
|
|
||||||
.spyOn(objectService, 'listAll')
|
|
||||||
.mockReturnValueOnce(throwError(() => new Error('Error getting objects')))
|
|
||||||
|
|
||||||
pipe.transform(1).subscribe((result) => {
|
|
||||||
expect(result).toBe('')
|
|
||||||
done()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
@@ -1,46 +0,0 @@
|
|||||||
import { Pipe, PipeTransform } from '@angular/core'
|
|
||||||
import { catchError, map, Observable, of } from 'rxjs'
|
|
||||||
import { MatchingModel } from '../data/matching-model'
|
|
||||||
import {
|
|
||||||
PermissionAction,
|
|
||||||
PermissionsService,
|
|
||||||
PermissionType,
|
|
||||||
} from '../services/permissions.service'
|
|
||||||
import { AbstractNameFilterService } from '../services/rest/abstract-name-filter-service'
|
|
||||||
|
|
||||||
@Pipe({
|
|
||||||
name: 'objectName',
|
|
||||||
})
|
|
||||||
export abstract class ObjectNamePipe implements PipeTransform {
|
|
||||||
/*
|
|
||||||
ObjectNamePipe is an abstract class to prevent instantiation,
|
|
||||||
object-specific pipes extend this class and provide the
|
|
||||||
correct permission type, and object service.
|
|
||||||
*/
|
|
||||||
protected objects: MatchingModel[]
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
protected permissionsService: PermissionsService,
|
|
||||||
protected permissionType: PermissionType,
|
|
||||||
protected objectService: AbstractNameFilterService<MatchingModel>
|
|
||||||
) {}
|
|
||||||
|
|
||||||
transform(obejctId: number): Observable<string> {
|
|
||||||
if (
|
|
||||||
this.permissionsService.currentUserCan(
|
|
||||||
PermissionAction.View,
|
|
||||||
this.permissionType
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return this.objectService.listAll().pipe(
|
|
||||||
map((objects) => {
|
|
||||||
this.objects = objects.results
|
|
||||||
return this.objects.find((o) => o.id === obejctId)?.name || ''
|
|
||||||
}),
|
|
||||||
catchError(() => of(''))
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
return of($localize`Private`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,28 +0,0 @@
|
|||||||
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
|
|
||||||
import { provideHttpClientTesting } from '@angular/common/http/testing'
|
|
||||||
import { TestBed } from '@angular/core/testing'
|
|
||||||
import { PermissionsService } from '../services/permissions.service'
|
|
||||||
import { StoragePathService } from '../services/rest/storage-path.service'
|
|
||||||
import { StoragePathNamePipe } from './storage-path-name.pipe'
|
|
||||||
|
|
||||||
describe('StoragePathNamePipe', () => {
|
|
||||||
let pipe: StoragePathNamePipe
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
TestBed.configureTestingModule({
|
|
||||||
providers: [
|
|
||||||
provideHttpClient(withInterceptorsFromDi()),
|
|
||||||
provideHttpClientTesting(),
|
|
||||||
],
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
// The pipe is a simple wrapper around ObjectNamePipe, see ObjectNamePipe for the actual tests.
|
|
||||||
it('should be created', () => {
|
|
||||||
pipe = new StoragePathNamePipe(
|
|
||||||
TestBed.inject(PermissionsService),
|
|
||||||
TestBed.inject(StoragePathService)
|
|
||||||
)
|
|
||||||
expect(pipe).toBeTruthy()
|
|
||||||
})
|
|
||||||
})
|
|
@@ -1,22 +0,0 @@
|
|||||||
import { Pipe, PipeTransform } from '@angular/core'
|
|
||||||
import {
|
|
||||||
PermissionsService,
|
|
||||||
PermissionType,
|
|
||||||
} from '../services/permissions.service'
|
|
||||||
import { StoragePathService } from '../services/rest/storage-path.service'
|
|
||||||
import { ObjectNamePipe } from './object-name.pipe'
|
|
||||||
|
|
||||||
@Pipe({
|
|
||||||
name: 'storagePathName',
|
|
||||||
})
|
|
||||||
export class StoragePathNamePipe
|
|
||||||
extends ObjectNamePipe
|
|
||||||
implements PipeTransform
|
|
||||||
{
|
|
||||||
constructor(
|
|
||||||
permissionsService: PermissionsService,
|
|
||||||
objectService: StoragePathService
|
|
||||||
) {
|
|
||||||
super(permissionsService, PermissionType.StoragePath, objectService)
|
|
||||||
}
|
|
||||||
}
|
|
@@ -37,11 +37,7 @@ describe('UsernamePipe', () => {
|
|||||||
httpTestingController.verify()
|
httpTestingController.verify()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should transform user id to username', (done) => {
|
it('should transform user id to username', () => {
|
||||||
pipe.transform(2).subscribe((username) => {
|
|
||||||
expect(username).toEqual('username2')
|
|
||||||
})
|
|
||||||
|
|
||||||
const req = httpTestingController.expectOne(
|
const req = httpTestingController.expectOne(
|
||||||
`${environment.apiBaseUrl}users/?page=1&page_size=100000`
|
`${environment.apiBaseUrl}users/?page=1&page_size=100000`
|
||||||
)
|
)
|
||||||
@@ -59,39 +55,24 @@ describe('UsernamePipe', () => {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
pipe.transform(3).subscribe((username) => {
|
|
||||||
expect(username).toEqual('User Name3')
|
|
||||||
})
|
|
||||||
|
|
||||||
pipe.transform(4).subscribe((username) => {
|
let username = pipe.transform(2)
|
||||||
expect(username).toEqual('')
|
expect(username).toEqual('username2')
|
||||||
done()
|
|
||||||
})
|
username = pipe.transform(3)
|
||||||
|
expect(username).toEqual('User Name3')
|
||||||
|
|
||||||
|
username = pipe.transform(4)
|
||||||
|
expect(username).toEqual('')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should show generic label when insufficient permissions', (done) => {
|
it('should show generic label when no users retrieved', () => {
|
||||||
jest
|
|
||||||
.spyOn(permissionsService, 'currentUserCan')
|
|
||||||
.mockImplementation((action, type) => {
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
pipe.transform(4).subscribe((username) => {
|
|
||||||
expect(username).toEqual('Shared')
|
|
||||||
done()
|
|
||||||
})
|
|
||||||
httpTestingController.expectNone(
|
|
||||||
`${environment.apiBaseUrl}users/?page=1&page_size=100000`
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should show empty string when no users retrieved due to error', (done) => {
|
|
||||||
pipe.transform(4).subscribe((username) => {
|
|
||||||
expect(username).toEqual('')
|
|
||||||
done()
|
|
||||||
})
|
|
||||||
const req = httpTestingController.expectOne(
|
const req = httpTestingController.expectOne(
|
||||||
`${environment.apiBaseUrl}users/?page=1&page_size=100000`
|
`${environment.apiBaseUrl}users/?page=1&page_size=100000`
|
||||||
)
|
)
|
||||||
req.error(new ProgressEvent('error'))
|
req.flush(null)
|
||||||
|
|
||||||
|
let username = pipe.transform(4)
|
||||||
|
expect(username).toEqual('Shared')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@@ -1,10 +1,9 @@
|
|||||||
import { Pipe, PipeTransform } from '@angular/core'
|
import { Pipe, PipeTransform } from '@angular/core'
|
||||||
import { catchError, map, Observable, of } from 'rxjs'
|
|
||||||
import { User } from '../data/user'
|
import { User } from '../data/user'
|
||||||
import {
|
import {
|
||||||
PermissionAction,
|
PermissionAction,
|
||||||
PermissionsService,
|
|
||||||
PermissionType,
|
PermissionType,
|
||||||
|
PermissionsService,
|
||||||
} from '../services/permissions.service'
|
} from '../services/permissions.service'
|
||||||
import { UserService } from '../services/rest/user.service'
|
import { UserService } from '../services/rest/user.service'
|
||||||
|
|
||||||
@@ -15,29 +14,25 @@ export class UsernamePipe implements PipeTransform {
|
|||||||
users: User[]
|
users: User[]
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private permissionsService: PermissionsService,
|
permissionsService: PermissionsService,
|
||||||
private userService: UserService
|
userService: UserService
|
||||||
) {}
|
) {
|
||||||
|
|
||||||
transform(userID: number): Observable<string> {
|
|
||||||
if (
|
if (
|
||||||
this.permissionsService.currentUserCan(
|
permissionsService.currentUserCan(
|
||||||
PermissionAction.View,
|
PermissionAction.View,
|
||||||
PermissionType.User
|
PermissionType.User
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
return this.userService.listAll().pipe(
|
userService.listAll().subscribe((r) => (this.users = r.results))
|
||||||
map((users) => {
|
|
||||||
this.users = users.results
|
|
||||||
return this.getName(this.users.find((u) => u.id === userID))
|
|
||||||
}),
|
|
||||||
catchError(() => of(''))
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
return of($localize`Shared`)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
transform(userID: number): string {
|
||||||
|
return this.users
|
||||||
|
? (this.getName(this.users.find((u) => u.id === userID)) ?? '')
|
||||||
|
: $localize`Shared`
|
||||||
|
}
|
||||||
|
|
||||||
getName(user: User): string {
|
getName(user: User): string {
|
||||||
if (!user) return ''
|
if (!user) return ''
|
||||||
const name = [user.first_name, user.last_name].join(' ')
|
const name = [user.first_name, user.last_name].join(' ')
|
||||||
|
@@ -79,6 +79,11 @@ export interface ListViewState {
|
|||||||
* The fields to display in the document list.
|
* The fields to display in the document list.
|
||||||
*/
|
*/
|
||||||
displayFields?: DisplayField[]
|
displayFields?: DisplayField[]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the preview pane is shown.
|
||||||
|
*/
|
||||||
|
showPreviewPane?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -165,6 +170,7 @@ export class DocumentListViewService {
|
|||||||
sortReverse: true,
|
sortReverse: true,
|
||||||
filterRules: [],
|
filterRules: [],
|
||||||
selected: new Set<number>(),
|
selected: new Set<number>(),
|
||||||
|
showPreviewPane: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -451,6 +457,15 @@ export class DocumentListViewService {
|
|||||||
this.saveDocumentListView()
|
this.saveDocumentListView()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get showPreviewPane(): boolean {
|
||||||
|
return this.activeListViewState.showPreviewPane
|
||||||
|
}
|
||||||
|
|
||||||
|
set showPreviewPane(show: boolean) {
|
||||||
|
this.activeListViewState.showPreviewPane = show
|
||||||
|
this.saveDocumentListView()
|
||||||
|
}
|
||||||
|
|
||||||
private saveDocumentListView() {
|
private saveDocumentListView() {
|
||||||
if (this._activeSavedViewId == null) {
|
if (this._activeSavedViewId == null) {
|
||||||
let savedState: ListViewState = {
|
let savedState: ListViewState = {
|
||||||
@@ -461,6 +476,7 @@ export class DocumentListViewService {
|
|||||||
sortReverse: this.activeListViewState.sortReverse,
|
sortReverse: this.activeListViewState.sortReverse,
|
||||||
displayMode: this.activeListViewState.displayMode,
|
displayMode: this.activeListViewState.displayMode,
|
||||||
displayFields: this.activeListViewState.displayFields,
|
displayFields: this.activeListViewState.displayFields,
|
||||||
|
showPreviewPane: this.activeListViewState.showPreviewPane,
|
||||||
}
|
}
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
DOCUMENT_LIST_SERVICE.CURRENT_VIEW_CONFIG,
|
DOCUMENT_LIST_SERVICE.CURRENT_VIEW_CONFIG,
|
||||||
@@ -626,4 +642,8 @@ export class DocumentListViewService {
|
|||||||
documentIndexInCurrentView(documentID: number): number {
|
documentIndexInCurrentView(documentID: number): number {
|
||||||
return this.documents.map((d) => d.id).indexOf(documentID)
|
return this.documents.map((d) => d.id).indexOf(documentID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get firstSelectedDocument(): Document {
|
||||||
|
return this.documents.find((d) => this.selected.has(d.id))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -101,13 +101,13 @@ export const commonAbstractPaperlessServiceTests = (endpoint, ServiceClass) => {
|
|||||||
test('should call appropriate api endpoint for get a few objects', () => {
|
test('should call appropriate api endpoint for get a few objects', () => {
|
||||||
subscription = service.getFew([1, 2, 3]).subscribe()
|
subscription = service.getFew([1, 2, 3]).subscribe()
|
||||||
const req = httpTestingController.expectOne(
|
const req = httpTestingController.expectOne(
|
||||||
`${environment.apiBaseUrl}${endpoint}/?id__in=1,2,3&ordering=-id&page_size=1000`
|
`${environment.apiBaseUrl}${endpoint}/?id__in=1,2,3&ordering=-id`
|
||||||
)
|
)
|
||||||
expect(req.request.method).toEqual('GET')
|
expect(req.request.method).toEqual('GET')
|
||||||
req.flush([])
|
req.flush([])
|
||||||
subscription = service.getFew([4, 5, 6], { foo: 'bar' }).subscribe()
|
subscription = service.getFew([4, 5, 6], { foo: 'bar' }).subscribe()
|
||||||
const req2 = httpTestingController.expectOne(
|
const req2 = httpTestingController.expectOne(
|
||||||
`${environment.apiBaseUrl}${endpoint}/?id__in=4,5,6&ordering=-id&page_size=1000&foo=bar`
|
`${environment.apiBaseUrl}${endpoint}/?id__in=4,5,6&ordering=-id&foo=bar`
|
||||||
)
|
)
|
||||||
expect(req2.request.method).toEqual('GET')
|
expect(req2.request.method).toEqual('GET')
|
||||||
req2.flush([])
|
req2.flush([])
|
||||||
|
@@ -95,7 +95,6 @@ export abstract class AbstractPaperlessService<T extends ObjectWithId> {
|
|||||||
let httpParams = new HttpParams()
|
let httpParams = new HttpParams()
|
||||||
httpParams = httpParams.set('id__in', ids.join(','))
|
httpParams = httpParams.set('id__in', ids.join(','))
|
||||||
httpParams = httpParams.set('ordering', '-id')
|
httpParams = httpParams.set('ordering', '-id')
|
||||||
httpParams = httpParams.set('page_size', 1000)
|
|
||||||
for (let extraParamKey in extraParams) {
|
for (let extraParamKey in extraParams) {
|
||||||
if (extraParams[extraParamKey] != null) {
|
if (extraParams[extraParamKey] != null) {
|
||||||
httpParams = httpParams.set(extraParamKey, extraParams[extraParamKey])
|
httpParams = httpParams.set(extraParamKey, extraParams[extraParamKey])
|
||||||
|
@@ -251,12 +251,32 @@ describe(`DocumentService`, () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should add observables to document', () => {
|
||||||
|
subscription = service
|
||||||
|
.listFiltered(1, 25, 'title', false, [])
|
||||||
|
.subscribe((result) => {
|
||||||
|
expect(result.results).toHaveLength(3)
|
||||||
|
const doc = result.results[0]
|
||||||
|
expect(doc.correspondent$).not.toBeNull()
|
||||||
|
expect(doc.document_type$).not.toBeNull()
|
||||||
|
expect(doc.tags$).not.toBeNull()
|
||||||
|
expect(doc.storage_path$).not.toBeNull()
|
||||||
|
})
|
||||||
|
httpTestingController
|
||||||
|
.expectOne(
|
||||||
|
`${environment.apiBaseUrl}${endpoint}/?page=1&page_size=25&ordering=title`
|
||||||
|
)
|
||||||
|
.flush({
|
||||||
|
results: documents,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
it('should set search query', () => {
|
it('should set search query', () => {
|
||||||
const searchQuery = 'hello'
|
const searchQuery = 'hello'
|
||||||
service.searchQuery = searchQuery
|
service.searchQuery = searchQuery
|
||||||
let url = service.getPreviewUrl(documents[0].id)
|
let url = service.getPreviewUrl(documents[0].id)
|
||||||
expect(url).toEqual(
|
expect(url).toEqual(
|
||||||
`${environment.apiBaseUrl}${endpoint}/${documents[0].id}/preview/#search=%22${searchQuery}%22`
|
`${environment.apiBaseUrl}${endpoint}/${documents[0].id}/preview/#search="${searchQuery}"`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import { HttpClient } from '@angular/common/http'
|
import { HttpClient } from '@angular/common/http'
|
||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import { Observable } from 'rxjs'
|
import { Observable } from 'rxjs'
|
||||||
import { map } from 'rxjs/operators'
|
import { map, tap } from 'rxjs/operators'
|
||||||
import { AuditLogEntry } from 'src/app/data/auditlog-entry'
|
import { AuditLogEntry } from 'src/app/data/auditlog-entry'
|
||||||
import { CustomField } from 'src/app/data/custom-field'
|
import { CustomField } from 'src/app/data/custom-field'
|
||||||
import {
|
import {
|
||||||
@@ -22,7 +22,11 @@ import {
|
|||||||
} from '../permissions.service'
|
} from '../permissions.service'
|
||||||
import { SettingsService } from '../settings.service'
|
import { SettingsService } from '../settings.service'
|
||||||
import { AbstractPaperlessService } from './abstract-paperless-service'
|
import { AbstractPaperlessService } from './abstract-paperless-service'
|
||||||
|
import { CorrespondentService } from './correspondent.service'
|
||||||
import { CustomFieldsService } from './custom-fields.service'
|
import { CustomFieldsService } from './custom-fields.service'
|
||||||
|
import { DocumentTypeService } from './document-type.service'
|
||||||
|
import { StoragePathService } from './storage-path.service'
|
||||||
|
import { TagService } from './tag.service'
|
||||||
|
|
||||||
export interface SelectionDataItem {
|
export interface SelectionDataItem {
|
||||||
id: number
|
id: number
|
||||||
@@ -57,6 +61,10 @@ export class DocumentService extends AbstractPaperlessService<Document> {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
http: HttpClient,
|
http: HttpClient,
|
||||||
|
private correspondentService: CorrespondentService,
|
||||||
|
private documentTypeService: DocumentTypeService,
|
||||||
|
private tagService: TagService,
|
||||||
|
private storagePathService: StoragePathService,
|
||||||
private permissionsService: PermissionsService,
|
private permissionsService: PermissionsService,
|
||||||
private settingsService: SettingsService,
|
private settingsService: SettingsService,
|
||||||
private customFieldService: CustomFieldsService
|
private customFieldService: CustomFieldsService
|
||||||
@@ -129,6 +137,54 @@ export class DocumentService extends AbstractPaperlessService<Document> {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addObservablesToDocument(doc: Document) {
|
||||||
|
if (
|
||||||
|
doc.correspondent &&
|
||||||
|
this.permissionsService.currentUserCan(
|
||||||
|
PermissionAction.View,
|
||||||
|
PermissionType.Correspondent
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
doc.correspondent$ = this.correspondentService.getCached(
|
||||||
|
doc.correspondent
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
doc.document_type &&
|
||||||
|
this.permissionsService.currentUserCan(
|
||||||
|
PermissionAction.View,
|
||||||
|
PermissionType.DocumentType
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
doc.document_type$ = this.documentTypeService.getCached(doc.document_type)
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
doc.tags &&
|
||||||
|
this.permissionsService.currentUserCan(
|
||||||
|
PermissionAction.View,
|
||||||
|
PermissionType.Tag
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
doc.tags$ = this.tagService
|
||||||
|
.getCachedMany(doc.tags)
|
||||||
|
.pipe(
|
||||||
|
tap((tags) =>
|
||||||
|
tags.sort((tagA, tagB) => tagA.name.localeCompare(tagB.name))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
doc.storage_path &&
|
||||||
|
this.permissionsService.currentUserCan(
|
||||||
|
PermissionAction.View,
|
||||||
|
PermissionType.StoragePath
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
doc.storage_path$ = this.storagePathService.getCached(doc.storage_path)
|
||||||
|
}
|
||||||
|
return doc
|
||||||
|
}
|
||||||
|
|
||||||
listFiltered(
|
listFiltered(
|
||||||
page?: number,
|
page?: number,
|
||||||
pageSize?: number,
|
pageSize?: number,
|
||||||
@@ -143,6 +199,11 @@ export class DocumentService extends AbstractPaperlessService<Document> {
|
|||||||
sortField,
|
sortField,
|
||||||
sortReverse,
|
sortReverse,
|
||||||
Object.assign(extraParams, queryParamsFromFilterRules(filterRules))
|
Object.assign(extraParams, queryParamsFromFilterRules(filterRules))
|
||||||
|
).pipe(
|
||||||
|
map((results) => {
|
||||||
|
results.results.forEach((doc) => this.addObservablesToDocument(doc))
|
||||||
|
return results
|
||||||
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,12 +222,12 @@ export class DocumentService extends AbstractPaperlessService<Document> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getPreviewUrl(id: number, original: boolean = false): string {
|
getPreviewUrl(id: number, original: boolean = false): string {
|
||||||
let url = new URL(this.getResourceUrl(id, 'preview'))
|
let url = this.getResourceUrl(id, 'preview')
|
||||||
if (this._searchQuery) url.hash = `#search="${this.searchQuery}"`
|
if (this._searchQuery) url += `#search="${this._searchQuery}"`
|
||||||
if (original) {
|
if (original) {
|
||||||
url.searchParams.append('original', 'true')
|
url += '?original=true'
|
||||||
}
|
}
|
||||||
return url.toString()
|
return url
|
||||||
}
|
}
|
||||||
|
|
||||||
getThumbUrl(id: number): string {
|
getThumbUrl(id: number): string {
|
||||||
@@ -248,10 +309,6 @@ export class DocumentService extends AbstractPaperlessService<Document> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public set searchQuery(query: string) {
|
public set searchQuery(query: string) {
|
||||||
this._searchQuery = query.trim()
|
this._searchQuery = query
|
||||||
}
|
|
||||||
|
|
||||||
public get searchQuery(): string {
|
|
||||||
return this._searchQuery
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -425,12 +425,6 @@ export class SettingsService {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
this._renderer.setAttribute(
|
|
||||||
this.document.documentElement,
|
|
||||||
'data-bs-theme',
|
|
||||||
'dark-flat'
|
|
||||||
)
|
|
||||||
|
|
||||||
if (themeColor?.length) {
|
if (themeColor?.length) {
|
||||||
const hsl = hexToHsl(themeColor)
|
const hsl = hexToHsl(themeColor)
|
||||||
const bgBrightnessEstimate = estimateBrightnessForColor(themeColor)
|
const bgBrightnessEstimate = estimateBrightnessForColor(themeColor)
|
||||||
|
@@ -125,6 +125,7 @@ import {
|
|||||||
trash,
|
trash,
|
||||||
uiRadios,
|
uiRadios,
|
||||||
upcScan,
|
upcScan,
|
||||||
|
windowSplit,
|
||||||
windowStack,
|
windowStack,
|
||||||
x,
|
x,
|
||||||
xCircle,
|
xCircle,
|
||||||
@@ -180,9 +181,6 @@ 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 localeZh from '@angular/common/locales/zh'
|
import localeZh from '@angular/common/locales/zh'
|
||||||
import { CorrespondentNamePipe } from './app/pipes/correspondent-name.pipe'
|
|
||||||
import { DocumentTypeNamePipe } from './app/pipes/document-type-name.pipe'
|
|
||||||
import { StoragePathNamePipe } from './app/pipes/storage-path-name.pipe'
|
|
||||||
|
|
||||||
registerLocaleData(localeAf)
|
registerLocaleData(localeAf)
|
||||||
registerLocaleData(localeAr)
|
registerLocaleData(localeAr)
|
||||||
@@ -326,6 +324,7 @@ const icons = {
|
|||||||
trash,
|
trash,
|
||||||
uiRadios,
|
uiRadios,
|
||||||
upcScan,
|
upcScan,
|
||||||
|
windowSplit,
|
||||||
windowStack,
|
windowStack,
|
||||||
x,
|
x,
|
||||||
xCircle,
|
xCircle,
|
||||||
@@ -378,9 +377,6 @@ bootstrapApplication(AppComponent, {
|
|||||||
DirtyDocGuard,
|
DirtyDocGuard,
|
||||||
DirtySavedViewGuard,
|
DirtySavedViewGuard,
|
||||||
UsernamePipe,
|
UsernamePipe,
|
||||||
CorrespondentNamePipe,
|
|
||||||
DocumentTypeNamePipe,
|
|
||||||
StoragePathNamePipe,
|
|
||||||
provideHttpClient(withInterceptorsFromDi()),
|
provideHttpClient(withInterceptorsFromDi()),
|
||||||
],
|
],
|
||||||
}).catch((err) => console.error(err))
|
}).catch((err) => console.error(err))
|
||||||
|
@@ -366,52 +366,3 @@ $form-check-radio-checked-bg-image-dark: url("data:image/svg+xml,<svg xmlns='htt
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-bs-theme="dark-flat"] {
|
|
||||||
body:not(.primary-light):not(.primary-dark) {
|
|
||||||
@include paperless-green-dark-mode;
|
|
||||||
|
|
||||||
.navbar.bg-primary {
|
|
||||||
// navbar is og green in dark mode
|
|
||||||
@include paperless-green;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include dark-mode;
|
|
||||||
|
|
||||||
.btn-outline-primary, .btn-outline-secondary {
|
|
||||||
border-color: var(--pngx-bg-alt) !important;
|
|
||||||
background-color: var(--pngx-bg-alt) !important;
|
|
||||||
color: var(--bs-body-color) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-outline-secondary:hover, .btn-outline-secondary:focus, .btn-outline-secondary:active, .btn-outline-secondary.active {
|
|
||||||
background-color: var(--pngx-bg-darker) !important;
|
|
||||||
color: var(--pngx-body-color-accent) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-outline-danger {
|
|
||||||
border-color: var(--pngx-bg-alt) !important;
|
|
||||||
background-color: var(--pngx-bg-alt) !important;
|
|
||||||
color: var(--bs-danger) !important;
|
|
||||||
|
|
||||||
&:hover, &:focus, &.active, &:active {
|
|
||||||
background-color: var(--pngx-bg-darker) !important;
|
|
||||||
color: var(--bs-danger) !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-control:not(.btn), input, select, textarea,
|
|
||||||
.form-select:not(.is-invalid):not(:disabled), .form-check-input,
|
|
||||||
.ng-select .ng-select-container {
|
|
||||||
background-color: var(--pngx-bg-darker) !important;
|
|
||||||
color: var(--bs-body-color) !important;
|
|
||||||
border-color: var(--pngx-bg-alt) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-group .input-group-text {
|
|
||||||
background-color: var(--pngx-bg-alt);
|
|
||||||
color: var(--bs-body-color);
|
|
||||||
border-color: var(--pngx-bg-alt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@@ -79,8 +79,7 @@ class BogusClient:
|
|||||||
flag = args[2]
|
flag = args[2]
|
||||||
if flag == "processed":
|
if flag == "processed":
|
||||||
message._raw_flag_data.append(b"+FLAGS (processed)")
|
message._raw_flag_data.append(b"+FLAGS (processed)")
|
||||||
if hasattr(message, "flags"):
|
MailMessage.flags.fget.cache_clear()
|
||||||
del message.flags
|
|
||||||
|
|
||||||
|
|
||||||
class BogusMailBox(AbstractContextManager):
|
class BogusMailBox(AbstractContextManager):
|
||||||
@@ -177,8 +176,7 @@ class BogusMailBox(AbstractContextManager):
|
|||||||
message.seen = value
|
message.seen = value
|
||||||
if flag == "processed":
|
if flag == "processed":
|
||||||
message._raw_flag_data.append(b"+FLAGS (processed)")
|
message._raw_flag_data.append(b"+FLAGS (processed)")
|
||||||
if hasattr(message, "flags"):
|
MailMessage.flags.fget.cache_clear()
|
||||||
del message.flags
|
|
||||||
|
|
||||||
def move(self, uid_list, folder):
|
def move(self, uid_list, folder):
|
||||||
if folder == "spam":
|
if folder == "spam":
|
||||||
@@ -265,8 +263,7 @@ class MessageBuilder:
|
|||||||
imap_msg.flagged = flagged
|
imap_msg.flagged = flagged
|
||||||
if processed:
|
if processed:
|
||||||
imap_msg._raw_flag_data.append(b"+FLAGS (processed)")
|
imap_msg._raw_flag_data.append(b"+FLAGS (processed)")
|
||||||
if hasattr(imap_msg, "flags"):
|
MailMessage.flags.fget.cache_clear()
|
||||||
del imap_msg.flags
|
|
||||||
|
|
||||||
return imap_msg
|
return imap_msg
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user