Compare commits

..
Author SHA1 Message Date
shamoon aad70575b7 Tweak/fix: auto-close CF dropdown 2026-11-13 10:10:06 -08:00
19 changed files with 134 additions and 287 deletions

No files matched your search

+3 -4
View File
@@ -587,10 +587,9 @@ documents from the web UI:
- From the document list, select one or more documents and choose **Run workflow** from the "Actions" menu.
- From an individual document, choose **Run workflow** from the "Actions" menu.
You will be asked which workflow to run. From the document list, the workflow's trigger filters apply by default, so
documents that do not match are skipped. You can choose to **run on all selected documents** to ignore the filters.
From an individual document, the option to ignore trigger filters is selected by default. Clear it to run the workflow
only if the document matches its trigger filters.
You will be asked which workflow to run. By default the workflow's trigger filters still apply, so documents that do
not match are skipped. You can instead choose to **run on all selected documents**, which ignores the trigger filters
and runs the workflow's actions on every selected document.
Manual runs happen in the background. As with scheduled workflows, the document list is not refreshed automatically when
they finish, so you may need to reload the list to see the results.
+80 -101
View File
@@ -1366,7 +1366,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1973</context>
<context context-type="linenumber">1971</context>
</context-group>
</trans-unit>
<trans-unit id="1577733187050997705" datatype="html">
@@ -3420,23 +3420,23 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1974</context>
<context context-type="linenumber">1972</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">1034</context>
<context context-type="linenumber">1019</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">1073</context>
<context context-type="linenumber">1058</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">1096</context>
<context context-type="linenumber">1081</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">1132</context>
<context context-type="linenumber">1117</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/custom-fields/custom-fields.component.ts</context>
@@ -4199,27 +4199,27 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">652</context>
<context context-type="linenumber">637</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">692</context>
<context context-type="linenumber">677</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">730</context>
<context context-type="linenumber">715</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">768</context>
<context context-type="linenumber">753</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">830</context>
<context context-type="linenumber">815</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">968</context>
<context context-type="linenumber">953</context>
</context-group>
</trans-unit>
<trans-unit id="6088768251338567957" datatype="html">
@@ -4339,7 +4339,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">2027</context>
<context context-type="linenumber">2025</context>
</context-group>
</trans-unit>
<trans-unit id="6661109599266152398" datatype="html">
@@ -4350,7 +4350,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">2028</context>
<context context-type="linenumber">2026</context>
</context-group>
</trans-unit>
<trans-unit id="5162686434580248853" datatype="html">
@@ -4361,7 +4361,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">2029</context>
<context context-type="linenumber">2027</context>
</context-group>
</trans-unit>
<trans-unit id="6665634854532231106" datatype="html">
@@ -4413,32 +4413,18 @@
<context context-type="linenumber">13,14</context>
</context-group>
</trans-unit>
<trans-unit id="261810320774538615" datatype="html">
<source>Run on this document regardless of trigger filters</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-dialog/run-workflow-confirm-dialog/run-workflow-confirm-dialog.component.html</context>
<context context-type="linenumber">22,23</context>
</context-group>
</trans-unit>
<trans-unit id="2322522720854680528" datatype="html">
<source>Ignore the workflow&apos;s trigger filters for this document.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-dialog/run-workflow-confirm-dialog/run-workflow-confirm-dialog.component.html</context>
<context context-type="linenumber">23,24</context>
</context-group>
</trans-unit>
<trans-unit id="4512110365422311821" datatype="html">
<source>Run on all selected documents</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-dialog/run-workflow-confirm-dialog/run-workflow-confirm-dialog.component.html</context>
<context context-type="linenumber">25,26</context>
<context context-type="linenumber">21,22</context>
</context-group>
</trans-unit>
<trans-unit id="6575910678008555513" datatype="html">
<source>Ignore the workflow&apos;s trigger filters and run on every selected document.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-dialog/run-workflow-confirm-dialog/run-workflow-confirm-dialog.component.html</context>
<context context-type="linenumber">26,27</context>
<context context-type="linenumber">22,23</context>
</context-group>
</trans-unit>
<trans-unit id="2509141182388535183" datatype="html">
@@ -6668,7 +6654,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">972</context>
<context context-type="linenumber">957</context>
</context-group>
</trans-unit>
<trans-unit id="1616074213645042277" datatype="html">
@@ -8445,7 +8431,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">597</context>
<context context-type="linenumber">582</context>
</context-group>
<note priority="1" from="description">this string is used to separate processing, failed and added on the file upload widget</note>
</trans-unit>
@@ -8774,7 +8760,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">320</context>
<context context-type="linenumber">318</context>
</context-group>
</trans-unit>
<trans-unit id="7049887240439736400" datatype="html">
@@ -9261,7 +9247,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">970</context>
<context context-type="linenumber">955</context>
</context-group>
</trans-unit>
<trans-unit id="5992101894268263750" datatype="html">
@@ -9286,7 +9272,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">1030</context>
<context context-type="linenumber">1015</context>
</context-group>
</trans-unit>
<trans-unit id="2951161989614003846" datatype="html">
@@ -9318,7 +9304,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1609</context>
<context context-type="linenumber">1607</context>
</context-group>
</trans-unit>
<trans-unit id="838042392151392247" datatype="html">
@@ -9336,88 +9322,88 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">322</context>
<context context-type="linenumber">320</context>
</context-group>
</trans-unit>
<trans-unit id="523213570140181690" datatype="html">
<source>Workflow will run on &quot;<x id="PH" equiv-text="this.document().title"/>&quot; in the background.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1602</context>
<context context-type="linenumber">1600</context>
</context-group>
</trans-unit>
<trans-unit id="6030453331794586802" datatype="html">
<source>Error downloading document</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1673</context>
<context context-type="linenumber">1671</context>
</context-group>
</trans-unit>
<trans-unit id="4458954481601077369" datatype="html">
<source>Page Fit</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1751</context>
<context context-type="linenumber">1749</context>
</context-group>
</trans-unit>
<trans-unit id="4663705961777238777" datatype="html">
<source>PDF edit operation for &quot;<x id="PH" equiv-text="this.document().title"/>&quot; will begin in the background.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1994</context>
<context context-type="linenumber">1992</context>
</context-group>
</trans-unit>
<trans-unit id="9043972994040261999" datatype="html">
<source>Error executing PDF edit operation</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">2006</context>
<context context-type="linenumber">2004</context>
</context-group>
</trans-unit>
<trans-unit id="6172690334763056188" datatype="html">
<source>Please enter the current password before attempting to remove it.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">2017</context>
<context context-type="linenumber">2015</context>
</context-group>
</trans-unit>
<trans-unit id="968660764814228922" datatype="html">
<source>Password removal operation for &quot;<x id="PH" equiv-text="this.document().title"/>&quot; will begin in the background.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">2051</context>
<context context-type="linenumber">2049</context>
</context-group>
</trans-unit>
<trans-unit id="2282118435712883014" datatype="html">
<source>Error executing password removal operation</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">2065</context>
<context context-type="linenumber">2063</context>
</context-group>
</trans-unit>
<trans-unit id="3740891324955700797" datatype="html">
<source>Print failed.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">2115</context>
<context context-type="linenumber">2113</context>
</context-group>
</trans-unit>
<trans-unit id="6457245677384603573" datatype="html">
<source>Error loading document for printing.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">2124</context>
<context context-type="linenumber">2122</context>
</context-group>
</trans-unit>
<trans-unit id="6085793215710522488" datatype="html">
<source>An error occurred loading tiff: <x id="PH" equiv-text="err.toString()"/></source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">2207</context>
<context context-type="linenumber">2205</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">2213</context>
<context context-type="linenumber">2211</context>
</context-group>
</trans-unit>
<trans-unit id="4958946940233632319" datatype="html">
@@ -9701,7 +9687,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">1130</context>
<context context-type="linenumber">1115</context>
</context-group>
</trans-unit>
<trans-unit id="7251533806673754434" datatype="html">
@@ -9736,53 +9722,46 @@
<source>Run a workflow on <x id="PH" equiv-text="this.getSelectionSize()"/> selected document(s).</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">321</context>
</context-group>
</trans-unit>
<trans-unit id="8161885405686762788" datatype="html">
<source>Workflow will run on the selected documents in the background.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">339</context>
<context context-type="linenumber">319</context>
</context-group>
</trans-unit>
<trans-unit id="3401633333450192408" datatype="html">
<source>Bulk operation queued.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">373</context>
<context context-type="linenumber">358</context>
</context-group>
</trans-unit>
<trans-unit id="5709555629190115111" datatype="html">
<source>View task</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">377</context>
<context context-type="linenumber">362</context>
</context-group>
</trans-unit>
<trans-unit id="1215215387232313677" datatype="html">
<source>Error executing bulk operation</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">429</context>
<context context-type="linenumber">414</context>
</context-group>
</trans-unit>
<trans-unit id="7894972847287473517" datatype="html">
<source>&quot;<x id="PH" equiv-text="items[0].name"/>&quot;</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">589</context>
<context context-type="linenumber">574</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">595</context>
<context context-type="linenumber">580</context>
</context-group>
</trans-unit>
<trans-unit id="8639884465898458690" datatype="html">
<source>&quot;<x id="PH" equiv-text="items[0].name"/>&quot; and &quot;<x id="PH_1" equiv-text="items[1].name"/>&quot;</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">591</context>
<context context-type="linenumber">576</context>
</context-group>
<note priority="1" from="description">This is for messages like &apos;modify &quot;tag1&quot; and &quot;tag2&quot;&apos;</note>
</trans-unit>
@@ -9790,7 +9769,7 @@
<source><x id="PH" equiv-text="list"/> and &quot;<x id="PH_1" equiv-text="items[items.length - 1].name"/>&quot;</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">599,601</context>
<context context-type="linenumber">584,586</context>
</context-group>
<note priority="1" from="description">this is for messages like &apos;modify &quot;tag1&quot;, &quot;tag2&quot; and &quot;tag3&quot;&apos;</note>
</trans-unit>
@@ -9798,14 +9777,14 @@
<source>Confirm tags assignment</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">616</context>
<context context-type="linenumber">601</context>
</context-group>
</trans-unit>
<trans-unit id="6619516195038467207" datatype="html">
<source>This operation will add the tag &quot;<x id="PH" equiv-text="tag.name"/>&quot; to <x id="PH_1" equiv-text="this.getSelectionSize()"/> selected document(s).</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">622</context>
<context context-type="linenumber">607</context>
</context-group>
</trans-unit>
<trans-unit id="1894412783609570695" datatype="html">
@@ -9814,14 +9793,14 @@
)"/> to <x id="PH_1" equiv-text="this.getSelectionSize()"/> selected document(s).</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">627,629</context>
<context context-type="linenumber">612,614</context>
</context-group>
</trans-unit>
<trans-unit id="7181166515756808573" datatype="html">
<source>This operation will remove the tag &quot;<x id="PH" equiv-text="tag.name"/>&quot; from <x id="PH_1" equiv-text="this.getSelectionSize()"/> selected document(s).</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">635</context>
<context context-type="linenumber">620</context>
</context-group>
</trans-unit>
<trans-unit id="3819792277998068944" datatype="html">
@@ -9830,7 +9809,7 @@
)"/> from <x id="PH_1" equiv-text="this.getSelectionSize()"/> selected document(s).</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">640,642</context>
<context context-type="linenumber">625,627</context>
</context-group>
</trans-unit>
<trans-unit id="2739066218579571288" datatype="html">
@@ -9841,84 +9820,84 @@
)"/> on <x id="PH_2" equiv-text="this.getSelectionSize()"/> selected document(s).</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">644,648</context>
<context context-type="linenumber">629,633</context>
</context-group>
</trans-unit>
<trans-unit id="2996713129519325161" datatype="html">
<source>Confirm correspondent assignment</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">685</context>
<context context-type="linenumber">670</context>
</context-group>
</trans-unit>
<trans-unit id="6900893559485781849" datatype="html">
<source>This operation will assign the correspondent &quot;<x id="PH" equiv-text="correspondent.name"/>&quot; to <x id="PH_1" equiv-text="this.getSelectionSize()"/> selected document(s).</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">687</context>
<context context-type="linenumber">672</context>
</context-group>
</trans-unit>
<trans-unit id="1257522660364398440" datatype="html">
<source>This operation will remove the correspondent from <x id="PH" equiv-text="this.getSelectionSize()"/> selected document(s).</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">689</context>
<context context-type="linenumber">674</context>
</context-group>
</trans-unit>
<trans-unit id="5393409374423140648" datatype="html">
<source>Confirm document type assignment</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">723</context>
<context context-type="linenumber">708</context>
</context-group>
</trans-unit>
<trans-unit id="332180123895325027" datatype="html">
<source>This operation will assign the document type &quot;<x id="PH" equiv-text="documentType.name"/>&quot; to <x id="PH_1" equiv-text="this.getSelectionSize()"/> selected document(s).</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">725</context>
<context context-type="linenumber">710</context>
</context-group>
</trans-unit>
<trans-unit id="2236642492594872779" datatype="html">
<source>This operation will remove the document type from <x id="PH" equiv-text="this.getSelectionSize()"/> selected document(s).</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">727</context>
<context context-type="linenumber">712</context>
</context-group>
</trans-unit>
<trans-unit id="6386555513013840736" datatype="html">
<source>Confirm storage path assignment</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">761</context>
<context context-type="linenumber">746</context>
</context-group>
</trans-unit>
<trans-unit id="8750527458618415924" datatype="html">
<source>This operation will assign the storage path &quot;<x id="PH" equiv-text="storagePath.name"/>&quot; to <x id="PH_1" equiv-text="this.getSelectionSize()"/> selected document(s).</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">763</context>
<context context-type="linenumber">748</context>
</context-group>
</trans-unit>
<trans-unit id="60728365335056946" datatype="html">
<source>This operation will remove the storage path from <x id="PH" equiv-text="this.getSelectionSize()"/> selected document(s).</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">765</context>
<context context-type="linenumber">750</context>
</context-group>
</trans-unit>
<trans-unit id="4187352575310415704" datatype="html">
<source>Confirm custom field assignment</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">794</context>
<context context-type="linenumber">779</context>
</context-group>
</trans-unit>
<trans-unit id="7966494636326273856" datatype="html">
<source>This operation will assign the custom field &quot;<x id="PH" equiv-text="customField.name"/>&quot; to <x id="PH_1" equiv-text="this.getSelectionSize()"/> selected document(s).</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">800</context>
<context context-type="linenumber">785</context>
</context-group>
</trans-unit>
<trans-unit id="5789455969634598553" datatype="html">
@@ -9927,14 +9906,14 @@
)"/> to <x id="PH_1" equiv-text="this.getSelectionSize()"/> selected document(s).</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">805,807</context>
<context context-type="linenumber">790,792</context>
</context-group>
</trans-unit>
<trans-unit id="5648572354333199245" datatype="html">
<source>This operation will remove the custom field &quot;<x id="PH" equiv-text="customField.name"/>&quot; from <x id="PH_1" equiv-text="this.getSelectionSize()"/> selected document(s).</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">813</context>
<context context-type="linenumber">798</context>
</context-group>
</trans-unit>
<trans-unit id="6666899594015948817" datatype="html">
@@ -9943,7 +9922,7 @@
)"/> from <x id="PH_1" equiv-text="this.getSelectionSize()"/> selected document(s).</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">818,820</context>
<context context-type="linenumber">803,805</context>
</context-group>
</trans-unit>
<trans-unit id="8050047262594964176" datatype="html">
@@ -9954,105 +9933,105 @@
)"/> on <x id="PH_2" equiv-text="this.getSelectionSize()"/> selected document(s).</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">822,826</context>
<context context-type="linenumber">807,811</context>
</context-group>
</trans-unit>
<trans-unit id="8615059324209654051" datatype="html">
<source>Move <x id="PH" equiv-text="this.getSelectionSize()"/> selected document(s) to the trash?</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">969</context>
<context context-type="linenumber">954</context>
</context-group>
</trans-unit>
<trans-unit id="135114644550399974" datatype="html">
<source>Moved <x id="PH" equiv-text="count"/> document(s) to the trash</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">996</context>
<context context-type="linenumber">981</context>
</context-group>
</trans-unit>
<trans-unit id="8585195717323764335" datatype="html">
<source>This operation will permanently recreate the archive files for <x id="PH" equiv-text="this.getSelectionSize()"/> selected document(s).</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">1031</context>
<context context-type="linenumber">1016</context>
</context-group>
</trans-unit>
<trans-unit id="7366623494074776040" datatype="html">
<source>The archive files will be re-generated with the current settings.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">1032</context>
<context context-type="linenumber">1017</context>
</context-group>
</trans-unit>
<trans-unit id="6555329262222566158" datatype="html">
<source>Rotate confirm</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">1070</context>
<context context-type="linenumber">1055</context>
</context-group>
</trans-unit>
<trans-unit id="5203024009814367559" datatype="html">
<source>This operation will add rotated versions of the <x id="PH" equiv-text="this.getSelectionSize()"/> document(s).</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">1071</context>
<context context-type="linenumber">1056</context>
</context-group>
</trans-unit>
<trans-unit id="7910756456450124185" datatype="html">
<source>Merge confirm</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">1094</context>
<context context-type="linenumber">1079</context>
</context-group>
</trans-unit>
<trans-unit id="7643543647233874431" datatype="html">
<source>This operation will merge <x id="PH" equiv-text="this.getSelectionSize()"/> selected documents into a new document.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">1095</context>
<context context-type="linenumber">1080</context>
</context-group>
</trans-unit>
<trans-unit id="7869008840945899895" datatype="html">
<source>Merged document will be queued for consumption.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">1118</context>
<context context-type="linenumber">1103</context>
</context-group>
</trans-unit>
<trans-unit id="1549333914563613027" datatype="html">
<source>The selected documents will become versions of the root document.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">1131</context>
<context context-type="linenumber">1116</context>
</context-group>
</trans-unit>
<trans-unit id="7099667366799629283" datatype="html">
<source>Documents merged as versions.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">1146</context>
<context context-type="linenumber">1131</context>
</context-group>
</trans-unit>
<trans-unit id="3873496751167944011" datatype="html">
<source>Error updating custom fields.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">1176</context>
<context context-type="linenumber">1161</context>
</context-group>
</trans-unit>
<trans-unit id="6144801143088984138" datatype="html">
<source>Share link bundle creation requested.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">1224</context>
<context context-type="linenumber">1209</context>
</context-group>
</trans-unit>
<trans-unit id="46019676931295023" datatype="html">
<source>Share link bundle creation is not available yet.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
<context context-type="linenumber">1231</context>
<context context-type="linenumber">1216</context>
</context-group>
</trans-unit>
<trans-unit id="6307402210351946694" datatype="html">
@@ -18,13 +18,8 @@
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="runWorkflowForce" [(ngModel)]="force" />
@if (singleDocument) {
<label class="form-check-label" for="runWorkflowForce" i18n>Run on this document regardless of trigger filters</label>
<div class="form-text" i18n>Ignore the workflow's trigger filters for this document.</div>
} @else {
<label class="form-check-label" for="runWorkflowForce" i18n>Run on all selected documents</label>
<div class="form-text" i18n>Ignore the workflow's trigger filters and run on every selected document.</div>
}
<label class="form-check-label" for="runWorkflowForce" i18n>Run on all selected documents</label>
<div class="form-text" i18n>Ignore the workflow's trigger filters and run on every selected document.</div>
</div>
</div>
<div class="modal-footer">
@@ -39,25 +39,4 @@ describe('RunWorkflowConfirmDialogComponent', () => {
expect(options).toHaveLength(2)
expect(options[1].textContent).toContain('Manual workflow')
})
it('should describe the checkbox for a selection or a single document', async () => {
const checkbox = fixture.nativeElement.querySelector('#runWorkflowForce')
expect(checkbox.checked).toBe(false)
expect(fixture.nativeElement.textContent).toContain(
'Run on all selected documents'
)
component.singleDocument = true
component.force = true
fixture.detectChanges()
await fixture.whenStable()
fixture.detectChanges()
expect(checkbox.checked).toBe(true)
expect(fixture.nativeElement.textContent).toContain(
'Run on this document regardless of trigger filters'
)
expect(fixture.nativeElement.textContent).not.toContain(
'Run on all selected documents'
)
})
})
@@ -13,8 +13,6 @@ export class RunWorkflowConfirmDialogComponent extends ConfirmDialogComponent {
public workflowId: number = null
public singleDocument: boolean = false
// i.e. ignore the workflow's trigger filters
public force: boolean = false
@@ -4,6 +4,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { By } from '@angular/platform-browser'
import {
NgbDropdown,
NgbDropdownModule,
NgbModal,
NgbModalModule,
@@ -250,4 +251,14 @@ describe('CustomFieldsDropdownComponent', () => {
expect(createFieldSpy).not.toHaveBeenCalled()
expect(addFieldSpy).not.toHaveBeenCalled()
})
it('should close the dropdown after selecting a filtered field', () => {
const dropdown = fixture.debugElement
.query(By.directive(NgbDropdown))
.injector.get(NgbDropdown)
dropdown.open()
component.filterText = 'Field 1'
component.listFilterEnter()
expect(dropdown.isOpen()).toBe(false)
})
})
@@ -11,7 +11,11 @@ import {
signal,
} from '@angular/core'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { NgbDropdownModule, NgbModal } from '@ng-bootstrap/ng-bootstrap'
import {
NgbDropdown,
NgbDropdownModule,
NgbModal,
} from '@ng-bootstrap/ng-bootstrap'
import { first, takeUntil } from 'rxjs'
import { BootstrapIconComponent } from 'src/app/components/common/bootstrap-icon/bootstrap-icon.component'
import { CustomField, DATA_TYPE_LABELS } from 'src/app/data/custom-field'
@@ -63,6 +67,7 @@ export class CustomFieldsDropdownComponent extends LoadingComponentWithPermissio
created: EventEmitter<CustomField> = new EventEmitter()
@ViewChild('listFilterTextInput') listFilterTextInput: ElementRef
@ViewChild('fieldDropdown') fieldDropdown: NgbDropdown
@ViewChildren('button') buttons: QueryList<ElementRef>
private customFields: CustomField[] = []
@@ -120,6 +125,7 @@ export class CustomFieldsDropdownComponent extends LoadingComponentWithPermissio
addField(field: CustomField) {
this.added.emit(field)
this.fieldDropdown.close()
this.updateUnusedFields()
}
@@ -1038,10 +1038,9 @@ describe('DocumentDetailComponent', () => {
modalService.activeInstances.subscribe((modal) => (openModal = modal[0]))
const toastSpy = jest.spyOn(toastService, 'showInfo')
component.runWorkflow()
expect(openModal.componentInstance.singleDocument).toBe(true)
expect(openModal.componentInstance.force).toBe(true)
const modalCloseSpy = jest.spyOn(openModal, 'close')
openModal.componentInstance.workflowId = 5
openModal.componentInstance.force = true
openModal.componentInstance.confirmClicked.next()
expect(bulkEditSpy).toHaveBeenCalledWith(
{ documents: [doc.id] },
@@ -1052,23 +1051,6 @@ describe('DocumentDetailComponent', () => {
expect(modalCloseSpy).toHaveBeenCalled()
})
it('should apply workflow filters when the single-document checkbox is cleared', () => {
initNormally()
const bulkEditSpy = jest.spyOn(documentService, 'bulkEdit')
bulkEditSpy.mockReturnValue(of(true))
let openModal: NgbModalRef
modalService.activeInstances.subscribe((modal) => (openModal = modal[0]))
component.runWorkflow()
openModal.componentInstance.workflowId = 5
openModal.componentInstance.force = false
openModal.componentInstance.confirmClicked.next()
expect(bulkEditSpy).toHaveBeenCalledWith(
{ documents: [doc.id] },
'run_workflow',
{ workflow: 5, filter_documents: true }
)
})
it('should pass remote OCR choice when reprocessing', () => {
initNormally()
const reprocessSpy = jest.spyOn(documentService, 'reprocessDocuments')
@@ -1587,8 +1587,6 @@ export class DocumentDetailComponent
modal.componentInstance.message = $localize`Run a workflow on "${this.document().title}".`
modal.componentInstance.btnCaption = $localize`Run`
modal.componentInstance.workflows = this.manualWorkflows()
modal.componentInstance.singleDocument = true
modal.componentInstance.force = true
modal.componentInstance.confirmClicked.subscribe(() => {
modal.componentInstance.buttonsEnabled.set(false)
this.documentsService
@@ -686,8 +686,6 @@ describe('BulkEditorComponent', () => {
})
it('should run a workflow on the selection via the run workflow dialog', () => {
const toast = jest.spyOn(toastService, 'show')
const infoToast = jest.spyOn(toastService, 'showInfo')
let modal: NgbModalRef
modalService.activeInstances.subscribe((m) => (modal = m[0]))
jest.spyOn(permissionsService, 'currentUserCan').mockReturnValue(true)
@@ -701,8 +699,6 @@ describe('BulkEditorComponent', () => {
component.runWorkflowSelected()
expect(modal).not.toBeUndefined()
expect(modal.componentInstance.workflows).toEqual(component.manualWorkflows)
expect(modal.componentInstance.singleDocument).toBe(false)
expect(modal.componentInstance.force).toBe(false)
modal.componentInstance.workflowId = 5
modal.componentInstance.force = true
modal.componentInstance.confirm()
@@ -714,12 +710,7 @@ describe('BulkEditorComponent', () => {
workflow: 5,
filter_documents: false,
})
req.flush({ result: 'OK' })
expect(infoToast).toHaveBeenCalledWith(
'Workflow will run on the selected documents in the background.'
)
expect(toast.mock.calls.at(-1)[0].actionName).toBeUndefined()
expect(documentListViewService.selected.size).toBe(0)
req.flush(true)
httpTestingController.match(
`${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true&include_selection_data=true`
) // list reload
@@ -728,27 +719,6 @@ describe('BulkEditorComponent', () => {
) // listAllFilteredIds
})
it('should require ownership of selected documents to run a workflow', () => {
component.manualWorkflows = [{ id: 5 }] as any
jest.spyOn(permissionsService, 'currentUserCan').mockReturnValue(true)
jest
.spyOn(permissionsService, 'currentUserHasObjectPermissions')
.mockReturnValue(true)
const ownsDocument = jest
.spyOn(permissionsService, 'currentUserOwnsObject')
.mockReturnValue(false)
jest
.spyOn(documentListViewService, 'documents', 'get')
.mockReturnValue([{ id: 3 }])
jest
.spyOn(documentListViewService, 'selected', 'get')
.mockReturnValue(new Set([3]))
expect(component.canRunWorkflow).toBe(false)
ownsDocument.mockReturnValue(true)
expect(component.canRunWorkflow).toBe(true)
})
it('should set modal dialog text accordingly for tag edit confirmation', () => {
let modal: NgbModalRef
modalService.activeInstances.subscribe((m) => (modal = m[m.length - 1]))
@@ -308,9 +308,7 @@ export class BulkEditorComponent
}
get canRunWorkflow(): boolean {
return (
this.userCanEditAll && this.userOwnsAll && this.manualWorkflows.length > 0
)
return this.userCanEditAll && this.manualWorkflows.length > 0
}
runWorkflowSelected() {
@@ -324,23 +322,10 @@ export class BulkEditorComponent
modal.componentInstance.confirmClicked
.pipe(takeUntil(this.unsubscribeNotifier))
.subscribe(() => {
modal.componentInstance.buttonsEnabled.set(false)
this.documentService
.bulkEdit(this.getSelectionQuery(), 'run_workflow', {
workflow: modal.componentInstance.workflowId,
filter_documents: !modal.componentInstance.force,
})
.pipe(first())
.subscribe({
next: () => {
modal.close()
this.list.selectNone()
this.toastService.showInfo(
$localize`Workflow will run on the selected documents in the background.`
)
},
error: (error) => this.handleOperationError(modal, error),
})
this.executeBulkEditMethod(modal, 'run_workflow', {
workflow: modal.componentInstance.workflowId,
filter_documents: !modal.componentInstance.force,
})
})
}
-1
View File
@@ -789,7 +789,6 @@ def has_document_operation_permissions(
bulk_edit.edit_pdf,
bulk_edit.merge_as_versions,
bulk_edit.remove_password,
bulk_edit.run_workflow,
]
)
or (
+2 -3
View File
@@ -703,12 +703,11 @@ class TestBulkEditAPI(DirectoriesMixin, APITestCase):
@mock.patch("documents.views.bulk_edit.run_workflow")
def test_run_workflow_requires_ownership(self, m) -> None:
"""A non-owner with change permission cannot run mutating workflow actions."""
"""A non-owner without document ownership is forbidden (actions mutate docs)."""
self.setup_mock(m, "run_workflow")
user = UserFactory(username="non_owner")
user = UserFactory(username="no_perms")
grant_all_global(user)
doc = DocumentFactory(owner=UserFactory(username="other"))
grant_object(user, doc, "change_document")
workflow = self._make_manual_workflow()
self.client.force_authenticate(user=user)
-23
View File
@@ -1,23 +0,0 @@
from rest_framework import serializers
OBFUSCATED_PASSWORD_MASK = "*" * 10
def is_obfuscated_password(value: str) -> bool:
"""
True if the value is only mask characters (or empty), meaning a client echoed
the placeholder back rather than supplying a new secret
"""
return value.replace("*", "") == ""
class ObfuscatedPasswordField(serializers.CharField):
"""
Sends a constant mask string instead of the password in the clear
"""
def to_representation(self, value) -> str:
return OBFUSCATED_PASSWORD_MASK
def to_internal_value(self, data):
return data
+3 -4
View File
@@ -20,19 +20,18 @@ from rest_framework import serializers
from rest_framework.authtoken.serializers import AuthTokenSerializer
from paperless.config import OCR_RESERVED_USER_ARGS
from paperless.fields import ObfuscatedPasswordField
from paperless.fields import is_obfuscated_password
from paperless.models import ApplicationConfiguration
from paperless.network import validate_outbound_http_url
from paperless.validators import reject_dangerous_svg
from paperless.validators import validate_raster_image
from paperless_mail.serialisers import ObfuscatedPasswordField
logger = logging.getLogger("paperless.settings")
class PasswordValidationMixin:
def _has_real_password(self, value: str | None) -> bool:
return bool(value) and not is_obfuscated_password(value)
return bool(value) and value.replace("*", "") != ""
def validate_password(self, value: str) -> str:
if not self._has_real_password(value):
@@ -286,7 +285,7 @@ class ApplicationConfigurationSerializer(
if data[field] == "":
data[field] = None
# Not a real value, don't overwrite the stored one
elif is_obfuscated_password(data[field]):
elif len(data[field].replace("*", "")) == 0:
del data[field]
return super().run_validation(data)
@@ -1,39 +0,0 @@
import pytest
from paperless.fields import OBFUSCATED_PASSWORD_MASK
from paperless.fields import ObfuscatedPasswordField
from paperless.fields import is_obfuscated_password
class TestObfuscatedPasswordField:
@pytest.mark.parametrize(
"secret",
[
"a",
"short",
"exactly10!",
"a-much-longer-secret-that-should-not-leak-its-length",
],
)
def test_representation_is_constant_regardless_of_length(self, secret: str) -> None:
assert (
ObfuscatedPasswordField().to_representation(secret)
== OBFUSCATED_PASSWORD_MASK
)
class TestIsObfuscatedPassword:
@pytest.mark.parametrize(
("value", "expected"),
[
("", True),
("*", True),
("******", True),
(OBFUSCATED_PASSWORD_MASK, True),
("real-secret", False),
("***x***", False),
(" ", False),
],
)
def test_detects_placeholder(self, value: str, *, expected: bool) -> None:
assert is_obfuscated_password(value) is expected
+1 -2
View File
@@ -41,7 +41,6 @@ from documents.models import PaperlessTask
from documents.permissions import PaperlessModelPermissions
from documents.permissions import PaperlessObjectPermissions
from documents.tasks import llmindex_index
from paperless.fields import is_obfuscated_password
from paperless.filters import GroupFilterSet
from paperless.filters import UserFilterSet
from paperless.models import ApplicationConfiguration
@@ -261,7 +260,7 @@ class ProfileView(GenericAPIView[Any]):
user = self.request.user if hasattr(self.request, "user") else None
password = serializer.validated_data.pop("password", None)
if password and not is_obfuscated_password(password):
if password and password.replace("*", ""):
user.set_password(password)
user.save()
+15 -4
View File
@@ -8,13 +8,23 @@ from documents.serialisers import CorrespondentField
from documents.serialisers import DocumentTypeField
from documents.serialisers import OwnedObjectSerializer
from documents.serialisers import TagsField
from paperless.fields import ObfuscatedPasswordField
from paperless.fields import is_obfuscated_password
from paperless_mail.models import MailAccount
from paperless_mail.models import MailRule
from paperless_mail.models import ProcessedMail
class ObfuscatedPasswordField(serializers.CharField):
"""
Sends *** string instead of password in the clear
"""
def to_representation(self, value) -> str:
return "*" * max(10, len(value))
def to_internal_value(self, data):
return data
class MailAccountSerializer(OwnedObjectSerializer):
password = ObfuscatedPasswordField()
imap_port = serializers.IntegerField(required=True, allow_null=False)
@@ -40,8 +50,9 @@ class MailAccountSerializer(OwnedObjectSerializer):
]
def update(self, instance, validated_data):
if "password" in validated_data and is_obfuscated_password(
validated_data["password"],
if (
"password" in validated_data
and len(validated_data.get("password").replace("*", "")) == 0
):
validated_data.pop("password")
super().update(instance, validated_data)
+3 -3
View File
@@ -30,7 +30,6 @@ from documents.permissions import PaperlessObjectPermissions
from documents.permissions import has_perms_owner_aware
from documents.permissions import permitted_object_ids
from documents.views import PassUserMixin
from paperless.fields import is_obfuscated_password
from paperless.views import StandardPagination
from paperless_mail.filters import ProcessedMailFilterSet
from paperless_mail.mail import MailError
@@ -127,8 +126,9 @@ class MailAccountViewSet(PassUserMixin, ModelViewSet[MailAccount]):
return HttpResponseForbidden("Insufficient permissions")
# account exists, use the password from there instead of ***
if existing_account is not None and is_obfuscated_password(
serializer.validated_data.get("password"),
if (
len(serializer.validated_data.get("password").replace("*", "")) == 0
and existing_account is not None
):
serializer.validated_data["password"] = existing_account.password
serializer.validated_data["account_type"] = existing_account.account_type