mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-10-28 18:45:43 +00:00
Compare commits
4
Commits
dbce393604
...
ff6ba7526c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ff6ba7526c | ||
|
|
610702d757 | ||
|
|
bbda3808a9 | ||
|
|
d6e45093e8 |
No files matched your search
+49
-49
@@ -1834,7 +1834,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">53</context>
|
||||
<context context-type="linenumber">54</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html</context>
|
||||
@@ -1873,7 +1873,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">202</context>
|
||||
<context context-type="linenumber">208</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="131016739441837046" datatype="html">
|
||||
@@ -1884,7 +1884,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">214</context>
|
||||
<context context-type="linenumber">220</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4880728824338713664" datatype="html">
|
||||
@@ -1913,18 +1913,18 @@
|
||||
<source>{VAR_PLURAL, plural, =1 {1 task} other {<x id="INTERPOLATION"/> tasks}}</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
|
||||
<context context-type="linenumber">108</context>
|
||||
<context context-type="linenumber">120</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8953033926734869941" datatype="html">
|
||||
<source>Name</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
|
||||
<context context-type="linenumber">130</context>
|
||||
<context context-type="linenumber">142</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">48</context>
|
||||
<context context-type="linenumber">49</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/trash/trash.component.html</context>
|
||||
@@ -2031,7 +2031,7 @@
|
||||
<source>Created</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
|
||||
<context context-type="linenumber">131</context>
|
||||
<context context-type="linenumber">143</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/common/dates-dropdown/dates-dropdown.component.html</context>
|
||||
@@ -2062,21 +2062,21 @@
|
||||
<source>Results</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
|
||||
<context context-type="linenumber">133</context>
|
||||
<context context-type="linenumber">145</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="314315645942131479" datatype="html">
|
||||
<source>Info</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
|
||||
<context context-type="linenumber">135</context>
|
||||
<context context-type="linenumber">147</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3193976279273491157" datatype="html">
|
||||
<source>Actions</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
|
||||
<context context-type="linenumber">136</context>
|
||||
<context context-type="linenumber">148</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/trash/trash.component.html</context>
|
||||
@@ -2147,18 +2147,18 @@
|
||||
<source>click for full output</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
|
||||
<context context-type="linenumber">187</context>
|
||||
<context context-type="linenumber">199</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1536087519743707362" datatype="html">
|
||||
<source>Dismiss</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
|
||||
<context context-type="linenumber">200</context>
|
||||
<context context-type="linenumber">212</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">298</context>
|
||||
<context context-type="linenumber">309</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||
@@ -2173,28 +2173,28 @@
|
||||
<source>Open Document</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
|
||||
<context context-type="linenumber">205</context>
|
||||
<context context-type="linenumber">217</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5404759957685833020" datatype="html">
|
||||
<source>Result message</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
|
||||
<context context-type="linenumber">218</context>
|
||||
<context context-type="linenumber">230</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="6621329748219109148" datatype="html">
|
||||
<source>Duplicate</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
|
||||
<context context-type="linenumber">225</context>
|
||||
<context context-type="linenumber">237</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="7593555694782789615" datatype="html">
|
||||
<source>Open</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
|
||||
<context context-type="linenumber">233</context>
|
||||
<context context-type="linenumber">245</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/app-frame/global-search/global-search.component.html</context>
|
||||
@@ -2225,77 +2225,77 @@
|
||||
<source>Input data</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
|
||||
<context context-type="linenumber">243</context>
|
||||
<context context-type="linenumber">255</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1585185618099050920" datatype="html">
|
||||
<source>Result data</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
|
||||
<context context-type="linenumber">249</context>
|
||||
<context context-type="linenumber">261</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="7976920528153858271" datatype="html">
|
||||
<source>No tasks match the current filters.</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
|
||||
<context context-type="linenumber">271</context>
|
||||
<context context-type="linenumber">283</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2525230676386818985" datatype="html">
|
||||
<source>Result</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">49</context>
|
||||
<context context-type="linenumber">50</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2952127331314675199" datatype="html">
|
||||
<source>Needs attention</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">54</context>
|
||||
<context context-type="linenumber">55</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3307214558906712688" datatype="html">
|
||||
<source>In progress</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">55</context>
|
||||
<context context-type="linenumber">56</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1371178633976505412" datatype="html">
|
||||
<source>Recently completed</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">56</context>
|
||||
<context context-type="linenumber">57</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2936452645673957909" datatype="html">
|
||||
<source>Consume File</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">65</context>
|
||||
<context context-type="linenumber">66</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5622386857946132209" datatype="html">
|
||||
<source>Train Classifier</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">69</context>
|
||||
<context context-type="linenumber">70</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="776309955507105337" datatype="html">
|
||||
<source>Sanity Check</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">73</context>
|
||||
<context context-type="linenumber">74</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="7502272564743467653" datatype="html">
|
||||
<source>Mail Fetch</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">75</context>
|
||||
<context context-type="linenumber">76</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context>
|
||||
@@ -2306,56 +2306,56 @@
|
||||
<source>LLM Index</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">76</context>
|
||||
<context context-type="linenumber">77</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="6402092370576716734" datatype="html">
|
||||
<source>Empty Trash</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">79</context>
|
||||
<context context-type="linenumber">80</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4173754487295857311" datatype="html">
|
||||
<source>Check Workflows</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">83</context>
|
||||
<context context-type="linenumber">84</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2065831805515896240" datatype="html">
|
||||
<source>Bulk Update</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">87</context>
|
||||
<context context-type="linenumber">88</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5062348912423871240" datatype="html">
|
||||
<source>Reprocess Document</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">91</context>
|
||||
<context context-type="linenumber">92</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="6903696804811148799" datatype="html">
|
||||
<source>Build Share Link</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">95</context>
|
||||
<context context-type="linenumber">96</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="6581973658756561124" datatype="html">
|
||||
<source>Bulk Delete</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">99</context>
|
||||
<context context-type="linenumber">100</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9172233176401579786" datatype="html">
|
||||
<source>Scheduled</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">109</context>
|
||||
<context context-type="linenumber">110</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context>
|
||||
@@ -2366,7 +2366,7 @@
|
||||
<source>Web UI</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">111</context>
|
||||
<context context-type="linenumber">112</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context>
|
||||
@@ -2377,7 +2377,7 @@
|
||||
<source>API Upload</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">114</context>
|
||||
<context context-type="linenumber">115</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context>
|
||||
@@ -2388,77 +2388,77 @@
|
||||
<source>Folder Consume</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">118</context>
|
||||
<context context-type="linenumber">119</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1456901843819961615" datatype="html">
|
||||
<source>Email Consume</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">122</context>
|
||||
<context context-type="linenumber">123</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="29832309535656200" datatype="html">
|
||||
<source>System</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">124</context>
|
||||
<context context-type="linenumber">125</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2233560223291461480" datatype="html">
|
||||
<source>Manual</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">125</context>
|
||||
<context context-type="linenumber">126</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5404910960991552159" datatype="html">
|
||||
<source>Dismiss selected</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">226</context>
|
||||
<context context-type="linenumber">232</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9169677036332103838" datatype="html">
|
||||
<source>Dismiss visible</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">227</context>
|
||||
<context context-type="linenumber">233</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3169751690815214293" datatype="html">
|
||||
<source>Confirm Dismiss</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">295</context>
|
||||
<context context-type="linenumber">306</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5029621907742319073" datatype="html">
|
||||
<source>Dismiss <x id="PH" equiv-text="tasks.size"/> tasks?</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">296</context>
|
||||
<context context-type="linenumber">307</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3597309129998924778" datatype="html">
|
||||
<source>Error dismissing tasks</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">304</context>
|
||||
<context context-type="linenumber">318</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2132179171926568807" datatype="html">
|
||||
<source>Error dismissing task</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">313</context>
|
||||
<context context-type="linenumber">330</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8760066891202884337" datatype="html">
|
||||
<source>Duplicate of document #<x id="PH" equiv-text="this.duplicateDocumentId(task)"/></source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
|
||||
<context context-type="linenumber">408</context>
|
||||
<context context-type="linenumber">425</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3418677553313974490" datatype="html">
|
||||
|
||||
@@ -98,6 +98,18 @@
|
||||
<i-bs width="1em" height="1em" name="x"></i-bs><small i18n>Reset filters</small>
|
||||
</button>
|
||||
}
|
||||
|
||||
<ngb-pagination
|
||||
class="ms-md-3 mb-0"
|
||||
[pageSize]="pageSize"
|
||||
[collectionSize]="totalTasks"
|
||||
[page]="page"
|
||||
[maxSize]="5"
|
||||
[rotate]="true"
|
||||
size="sm"
|
||||
aria-label="Tasks pagination"
|
||||
(pageChange)="setPage($event)">
|
||||
</ngb-pagination>
|
||||
</div>
|
||||
|
||||
<ng-template let-tasks="tasks" let-section="section" #tasksTemplate>
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
PaperlessTaskTriggerSource,
|
||||
PaperlessTaskType,
|
||||
} from 'src/app/data/paperless-task'
|
||||
import { Results } from 'src/app/data/results'
|
||||
import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive'
|
||||
import { PermissionsGuard } from 'src/app/guards/permissions.guard'
|
||||
import { CustomDatePipe } from 'src/app/pipes/custom-date.pipe'
|
||||
@@ -148,6 +149,11 @@ const tasks: PaperlessTask[] = [
|
||||
},
|
||||
]
|
||||
|
||||
const paginatedTasks: Results<PaperlessTask> = {
|
||||
count: tasks.length,
|
||||
results: tasks,
|
||||
}
|
||||
|
||||
describe('TasksComponent', () => {
|
||||
let component: TasksComponent
|
||||
let fixture: ComponentFixture<TasksComponent>
|
||||
@@ -196,9 +202,25 @@ describe('TasksComponent', () => {
|
||||
component = fixture.componentInstance
|
||||
jest.useFakeTimers()
|
||||
fixture.detectChanges()
|
||||
|
||||
httpTestingController
|
||||
.expectOne(`${environment.apiBaseUrl}tasks/?acknowledged=false`)
|
||||
.flush(tasks)
|
||||
.expectOne(
|
||||
(req) =>
|
||||
req.url === `${environment.apiBaseUrl}tasks/` &&
|
||||
req.params.get('acknowledged') === 'false' &&
|
||||
req.params.get('page_size') === '1000'
|
||||
)
|
||||
.flush(paginatedTasks)
|
||||
|
||||
httpTestingController
|
||||
.expectOne(
|
||||
(req) =>
|
||||
req.url === `${environment.apiBaseUrl}tasks/` &&
|
||||
req.params.get('acknowledged') === 'false' &&
|
||||
req.params.get('page_size') === '25' &&
|
||||
req.params.get('page') === '1'
|
||||
)
|
||||
.flush(paginatedTasks)
|
||||
})
|
||||
|
||||
it('should display task sections with counts', () => {
|
||||
@@ -294,6 +316,40 @@ describe('TasksComponent', () => {
|
||||
).toBeTruthy()
|
||||
})
|
||||
|
||||
it('should render pagination controls next to the task filter', () => {
|
||||
fixture.detectChanges()
|
||||
|
||||
const controls = fixture.debugElement.query(By.css('.task-controls'))
|
||||
const search = controls.query(By.css('.task-search'))
|
||||
const pagination = controls.query(By.css('ngb-pagination'))
|
||||
|
||||
expect(search).not.toBeNull()
|
||||
expect(pagination).not.toBeNull()
|
||||
})
|
||||
|
||||
it('should load a different task page when pagination changes', () => {
|
||||
component.setPage(2)
|
||||
|
||||
const pageTwoTasks = {
|
||||
count: 30,
|
||||
results: [tasks[0]],
|
||||
}
|
||||
|
||||
httpTestingController
|
||||
.expectOne(
|
||||
(req) =>
|
||||
req.url === `${environment.apiBaseUrl}tasks/` &&
|
||||
req.params.get('acknowledged') === 'false' &&
|
||||
req.params.get('page_size') === '25' &&
|
||||
req.params.get('page') === '2'
|
||||
)
|
||||
.flush(pageTwoTasks)
|
||||
|
||||
expect(component.page).toBe(2)
|
||||
expect(component.totalTasks).toBe(30)
|
||||
expect(component.pagedTasks).toEqual([tasks[0]])
|
||||
})
|
||||
|
||||
it('should expose stable task type options and disable empty ones', () => {
|
||||
expect(component.taskTypeOptions.map((option) => option.value)).toContain(
|
||||
PaperlessTaskType.TrainClassifier
|
||||
@@ -470,7 +526,7 @@ describe('TasksComponent', () => {
|
||||
|
||||
component.toggleSection(TaskSection.NeedsAttention, {
|
||||
target: { checked: false },
|
||||
} as PointerEvent)
|
||||
} as unknown as PointerEvent)
|
||||
|
||||
expect(component.selectedTasks).toEqual(new Set())
|
||||
})
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
NgbCollapseModule,
|
||||
NgbDropdownModule,
|
||||
NgbModal,
|
||||
NgbPaginationModule,
|
||||
NgbPopoverModule,
|
||||
} from '@ng-bootstrap/ng-bootstrap'
|
||||
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
||||
@@ -139,6 +140,7 @@ const TRIGGER_SOURCE_OPTIONS: Array<{
|
||||
NgTemplateOutlet,
|
||||
NgbCollapseModule,
|
||||
NgbDropdownModule,
|
||||
NgbPaginationModule,
|
||||
NgbPopoverModule,
|
||||
NgxBootstrapIconsModule,
|
||||
],
|
||||
@@ -161,6 +163,10 @@ export class TasksComponent
|
||||
public selectedTasks: Set<number> = new Set()
|
||||
public expandedTask: number
|
||||
public autoRefreshEnabled: boolean = true
|
||||
public readonly pageSize = 25
|
||||
public page: number = 1
|
||||
public totalTasks: number = 0
|
||||
public pagedTasks: PaperlessTask[] = []
|
||||
public selectedSection: TaskSection = TaskSection.All
|
||||
public selectedTaskType: PaperlessTaskType | null = null
|
||||
public selectedTriggerSource: PaperlessTaskTriggerSource | null = null
|
||||
@@ -254,6 +260,7 @@ export class TasksComponent
|
||||
|
||||
ngOnInit() {
|
||||
this.tasksService.reload()
|
||||
this.reloadPage()
|
||||
timer(5000, 5000)
|
||||
.pipe(
|
||||
filter(() => this.autoRefreshEnabled),
|
||||
@@ -261,6 +268,7 @@ export class TasksComponent
|
||||
)
|
||||
.subscribe(() => {
|
||||
this.tasksService.reload()
|
||||
this.reloadPage(false)
|
||||
})
|
||||
|
||||
this.filterDebounce
|
||||
@@ -270,7 +278,10 @@ export class TasksComponent
|
||||
distinctUntilChanged(),
|
||||
filter((query) => !query.length || query.length > 2)
|
||||
)
|
||||
.subscribe((query) => (this._filterText = query))
|
||||
.subscribe((query) => {
|
||||
this._filterText = query
|
||||
this.clearSelection()
|
||||
})
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
@@ -300,6 +311,9 @@ export class TasksComponent
|
||||
modal.componentInstance.buttonsEnabled = false
|
||||
modal.close()
|
||||
this.tasksService.dismissTasks(tasks).subscribe({
|
||||
next: () => {
|
||||
this.reloadPage(false)
|
||||
},
|
||||
error: (e) => {
|
||||
this.toastService.showError($localize`Error dismissing tasks`, e)
|
||||
modal.componentInstance.buttonsEnabled = true
|
||||
@@ -309,6 +323,9 @@ export class TasksComponent
|
||||
})
|
||||
} else if (tasks.size === 1) {
|
||||
this.tasksService.dismissTasks(tasks).subscribe({
|
||||
next: () => {
|
||||
this.reloadPage(false)
|
||||
},
|
||||
error: (e) =>
|
||||
this.toastService.showError($localize`Error dismissing task`, e),
|
||||
})
|
||||
@@ -421,7 +438,7 @@ export class TasksComponent
|
||||
}
|
||||
|
||||
tasksForSection(section: TaskSection): PaperlessTask[] {
|
||||
let tasks = this.tasksService.allFileTasks.filter((task) =>
|
||||
let tasks = this.pagedTasks.filter((task) =>
|
||||
this.taskBelongsToSection(task, section)
|
||||
)
|
||||
|
||||
@@ -433,7 +450,7 @@ export class TasksComponent
|
||||
}
|
||||
|
||||
sectionCount(section: TaskSection): number {
|
||||
return this.tasksService.allFileTasks.filter((task) =>
|
||||
return this.pagedTasks.filter((task) =>
|
||||
this.taskBelongsToSection(task, section)
|
||||
).length
|
||||
}
|
||||
@@ -481,6 +498,16 @@ export class TasksComponent
|
||||
this.selectedTasks.clear()
|
||||
}
|
||||
|
||||
setPage(page: number) {
|
||||
if (this.page === page) {
|
||||
return
|
||||
}
|
||||
|
||||
this.page = page
|
||||
this.clearSelection()
|
||||
this.reloadPage()
|
||||
}
|
||||
|
||||
public resetFilter() {
|
||||
this._filterText = ''
|
||||
}
|
||||
@@ -576,10 +603,39 @@ export class TasksComponent
|
||||
? this.sections
|
||||
: [this.selectedSection]
|
||||
|
||||
return this.tasksService.allFileTasks.filter(
|
||||
return this.pagedTasks.filter(
|
||||
(task) =>
|
||||
sections.some((section) => this.taskBelongsToSection(task, section)) &&
|
||||
this.taskMatchesFilters(task, { taskType, triggerSource })
|
||||
)
|
||||
}
|
||||
|
||||
private reloadPage(resetToFirstPage: boolean = false) {
|
||||
if (resetToFirstPage) {
|
||||
this.page = 1
|
||||
}
|
||||
|
||||
this.loading = true
|
||||
this.tasksService
|
||||
.list(this.page, this.pageSize, { acknowledged: false })
|
||||
.pipe(first(), takeUntil(this.unsubscribeNotifier))
|
||||
.subscribe({
|
||||
next: (result) => {
|
||||
this.pagedTasks = result.results
|
||||
this.totalTasks = result.count
|
||||
this.loading = false
|
||||
if (
|
||||
this.page > 1 &&
|
||||
this.pagedTasks.length === 0 &&
|
||||
this.totalTasks > 0
|
||||
) {
|
||||
this.page -= 1
|
||||
this.reloadPage()
|
||||
}
|
||||
},
|
||||
error: () => {
|
||||
this.loading = false
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,8 @@
|
||||
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
|
||||
import {
|
||||
HttpRequest,
|
||||
provideHttpClient,
|
||||
withInterceptorsFromDi,
|
||||
} from '@angular/common/http'
|
||||
import {
|
||||
HttpTestingController,
|
||||
provideHttpClientTesting,
|
||||
@@ -37,16 +41,21 @@ describe('TasksService', () => {
|
||||
it('calls tasks api endpoint on reload', () => {
|
||||
tasksService.reload()
|
||||
const req = httpTestingController.expectOne(
|
||||
`${environment.apiBaseUrl}tasks/?acknowledged=false`
|
||||
(req: HttpRequest<unknown>) =>
|
||||
req.url === `${environment.apiBaseUrl}tasks/` &&
|
||||
req.params.get('acknowledged') === 'false' &&
|
||||
req.params.get('page_size') === '1000'
|
||||
)
|
||||
expect(req.request.method).toEqual('GET')
|
||||
req.flush({ count: 0, results: [] })
|
||||
})
|
||||
|
||||
it('does not call tasks api endpoint on reload if already loading', () => {
|
||||
tasksService.loading = true
|
||||
tasksService.reload()
|
||||
httpTestingController.expectNone(
|
||||
`${environment.apiBaseUrl}tasks/?acknowledged=false`
|
||||
(req: HttpRequest<unknown>) =>
|
||||
req.url === `${environment.apiBaseUrl}tasks/`
|
||||
)
|
||||
})
|
||||
|
||||
@@ -62,8 +71,13 @@ describe('TasksService', () => {
|
||||
req.flush([])
|
||||
// reload is then called
|
||||
httpTestingController
|
||||
.expectOne(`${environment.apiBaseUrl}tasks/?acknowledged=false`)
|
||||
.flush([])
|
||||
.expectOne(
|
||||
(req: HttpRequest<unknown>) =>
|
||||
req.url === `${environment.apiBaseUrl}tasks/` &&
|
||||
req.params.get('acknowledged') === 'false' &&
|
||||
req.params.get('page_size') === '1000'
|
||||
)
|
||||
.flush({ count: 0, results: [] })
|
||||
})
|
||||
|
||||
it('groups mixed task types by status when reloading', () => {
|
||||
@@ -124,10 +138,13 @@ describe('TasksService', () => {
|
||||
tasksService.reload()
|
||||
|
||||
const req = httpTestingController.expectOne(
|
||||
`${environment.apiBaseUrl}tasks/?acknowledged=false`
|
||||
(req: HttpRequest<unknown>) =>
|
||||
req.url === `${environment.apiBaseUrl}tasks/` &&
|
||||
req.params.get('acknowledged') === 'false' &&
|
||||
req.params.get('page_size') === '1000'
|
||||
)
|
||||
|
||||
req.flush(mockTasks)
|
||||
req.flush({ count: mockTasks.length, results: mockTasks })
|
||||
|
||||
expect(tasksService.allFileTasks).toHaveLength(5)
|
||||
expect(tasksService.completedFileTasks).toHaveLength(2)
|
||||
@@ -173,10 +190,13 @@ describe('TasksService', () => {
|
||||
tasksService.reload()
|
||||
|
||||
const req = httpTestingController.expectOne(
|
||||
`${environment.apiBaseUrl}tasks/?acknowledged=false`
|
||||
(req: HttpRequest<unknown>) =>
|
||||
req.url === `${environment.apiBaseUrl}tasks/` &&
|
||||
req.params.get('acknowledged') === 'false' &&
|
||||
req.params.get('page_size') === '1000'
|
||||
)
|
||||
|
||||
req.flush(mockTasks)
|
||||
req.flush({ count: mockTasks.length, results: mockTasks })
|
||||
|
||||
expect(tasksService.needsAttentionTasks).toHaveLength(2)
|
||||
expect(tasksService.needsAttentionTasks.map((task) => task.status)).toEqual(
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { HttpClient } from '@angular/common/http'
|
||||
import { Injectable, inject } from '@angular/core'
|
||||
import { Observable, Subject } from 'rxjs'
|
||||
import { first, takeUntil, tap } from 'rxjs/operators'
|
||||
import { first, map, takeUntil, tap } from 'rxjs/operators'
|
||||
import {
|
||||
PaperlessTask,
|
||||
PaperlessTaskStatus,
|
||||
PaperlessTaskType,
|
||||
} from 'src/app/data/paperless-task'
|
||||
import { Results } from 'src/app/data/results'
|
||||
import { environment } from 'src/environments/environment'
|
||||
|
||||
@Injectable({
|
||||
@@ -17,6 +18,7 @@ export class TasksService {
|
||||
|
||||
private baseUrl: string = environment.apiBaseUrl
|
||||
private endpoint: string = 'tasks'
|
||||
private readonly defaultReloadPageSize = 1000
|
||||
|
||||
public loading: boolean = false
|
||||
|
||||
@@ -69,9 +71,13 @@ export class TasksService {
|
||||
this.loading = true
|
||||
|
||||
this.http
|
||||
.get<PaperlessTask[]>(
|
||||
`${this.baseUrl}${this.endpoint}/?acknowledged=false`
|
||||
)
|
||||
.get<Results<PaperlessTask>>(`${this.baseUrl}${this.endpoint}/`, {
|
||||
params: {
|
||||
acknowledged: 'false',
|
||||
page_size: this.defaultReloadPageSize,
|
||||
},
|
||||
})
|
||||
.pipe(map((r) => r.results))
|
||||
.pipe(takeUntil(this.unsubscribeNotifer), first())
|
||||
.subscribe((r) => {
|
||||
this.fileTasks = r
|
||||
@@ -79,6 +85,23 @@ export class TasksService {
|
||||
})
|
||||
}
|
||||
|
||||
public list(
|
||||
page: number,
|
||||
pageSize: number,
|
||||
extraParams?: Record<string, string | number | boolean>
|
||||
): Observable<Results<PaperlessTask>> {
|
||||
return this.http.get<Results<PaperlessTask>>(
|
||||
`${this.baseUrl}${this.endpoint}/`,
|
||||
{
|
||||
params: {
|
||||
page,
|
||||
page_size: pageSize,
|
||||
...extraParams,
|
||||
},
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
public dismissTasks(task_ids: Set<number>): Observable<any> {
|
||||
return this.http
|
||||
.post(`${this.baseUrl}tasks/acknowledge/`, {
|
||||
|
||||
@@ -31,6 +31,20 @@ ACCEPT_V9 = "application/json; version=9"
|
||||
|
||||
@pytest.mark.django_db()
|
||||
class TestGetTasksV10:
|
||||
def test_list_response_has_paginated_structure(
|
||||
self,
|
||||
admin_client: APIClient,
|
||||
) -> None:
|
||||
"""GET /api/tasks/ returns a paginated envelope with count and results."""
|
||||
PaperlessTaskFactory.create_batch(3)
|
||||
|
||||
response = admin_client.get(ENDPOINT)
|
||||
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert "count" in response.data
|
||||
assert "results" in response.data
|
||||
assert response.data["count"] == 3
|
||||
|
||||
def test_list_returns_tasks(self, admin_client: APIClient) -> None:
|
||||
"""GET /api/tasks/ returns all tasks visible to the admin."""
|
||||
PaperlessTaskFactory.create_batch(2)
|
||||
@@ -38,7 +52,7 @@ class TestGetTasksV10:
|
||||
response = admin_client.get(ENDPOINT)
|
||||
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert len(response.data) == 2
|
||||
assert response.data["count"] == 2
|
||||
|
||||
def test_related_document_ids_populated_from_result_data(
|
||||
self,
|
||||
@@ -53,7 +67,7 @@ class TestGetTasksV10:
|
||||
response = admin_client.get(ENDPOINT)
|
||||
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert response.data[0]["related_document_ids"] == [7]
|
||||
assert response.data["results"][0]["related_document_ids"] == [7]
|
||||
|
||||
def test_related_document_ids_includes_duplicate_of(
|
||||
self,
|
||||
@@ -68,7 +82,7 @@ class TestGetTasksV10:
|
||||
response = admin_client.get(ENDPOINT)
|
||||
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert response.data[0]["related_document_ids"] == [12]
|
||||
assert response.data["results"][0]["related_document_ids"] == [12]
|
||||
|
||||
def test_filter_by_task_type(self, admin_client: APIClient) -> None:
|
||||
"""?task_type= filters results to tasks of that type only."""
|
||||
@@ -81,8 +95,11 @@ class TestGetTasksV10:
|
||||
)
|
||||
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert len(response.data) == 1
|
||||
assert response.data[0]["task_type"] == PaperlessTask.TaskType.TRAIN_CLASSIFIER
|
||||
assert response.data["count"] == 1
|
||||
assert (
|
||||
response.data["results"][0]["task_type"]
|
||||
== PaperlessTask.TaskType.TRAIN_CLASSIFIER
|
||||
)
|
||||
|
||||
def test_filter_by_status(self, admin_client: APIClient) -> None:
|
||||
"""?status= filters results to tasks with that status only."""
|
||||
@@ -95,8 +112,8 @@ class TestGetTasksV10:
|
||||
)
|
||||
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert len(response.data) == 1
|
||||
assert response.data[0]["status"] == PaperlessTask.Status.SUCCESS
|
||||
assert response.data["count"] == 1
|
||||
assert response.data["results"][0]["status"] == PaperlessTask.Status.SUCCESS
|
||||
|
||||
def test_filter_by_task_id(self, admin_client: APIClient) -> None:
|
||||
"""?task_id= returns only the task with that UUID."""
|
||||
@@ -106,8 +123,8 @@ class TestGetTasksV10:
|
||||
response = admin_client.get(ENDPOINT, {"task_id": task.task_id})
|
||||
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert len(response.data) == 1
|
||||
assert response.data[0]["task_id"] == task.task_id
|
||||
assert response.data["count"] == 1
|
||||
assert response.data["results"][0]["task_id"] == task.task_id
|
||||
|
||||
def test_filter_by_acknowledged(self, admin_client: APIClient) -> None:
|
||||
"""?acknowledged=false returns only tasks that have not been acknowledged."""
|
||||
@@ -117,8 +134,8 @@ class TestGetTasksV10:
|
||||
response = admin_client.get(ENDPOINT, {"acknowledged": "false"})
|
||||
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert len(response.data) == 1
|
||||
assert response.data[0]["acknowledged"] is False
|
||||
assert response.data["count"] == 1
|
||||
assert response.data["results"][0]["acknowledged"] is False
|
||||
|
||||
def test_filter_is_complete_true(self, admin_client: APIClient) -> None:
|
||||
"""?is_complete=true returns only SUCCESS and FAILURE tasks."""
|
||||
@@ -129,8 +146,8 @@ class TestGetTasksV10:
|
||||
response = admin_client.get(ENDPOINT, {"is_complete": "true"})
|
||||
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert len(response.data) == 2
|
||||
returned_statuses = {t["status"] for t in response.data}
|
||||
assert response.data["count"] == 2
|
||||
returned_statuses = {t["status"] for t in response.data["results"]}
|
||||
assert returned_statuses == {
|
||||
PaperlessTask.Status.SUCCESS,
|
||||
PaperlessTask.Status.FAILURE,
|
||||
@@ -145,8 +162,8 @@ class TestGetTasksV10:
|
||||
response = admin_client.get(ENDPOINT, {"is_complete": "false"})
|
||||
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert len(response.data) == 2
|
||||
returned_statuses = {t["status"] for t in response.data}
|
||||
assert response.data["count"] == 2
|
||||
returned_statuses = {t["status"] for t in response.data["results"]}
|
||||
assert returned_statuses == {
|
||||
PaperlessTask.Status.PENDING,
|
||||
PaperlessTask.Status.STARTED,
|
||||
@@ -162,7 +179,7 @@ class TestGetTasksV10:
|
||||
response = admin_client.get(ENDPOINT)
|
||||
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
ids = [t["task_id"] for t in response.data]
|
||||
ids = [t["task_id"] for t in response.data["results"]]
|
||||
assert ids == [t3.task_id, t2.task_id, t1.task_id]
|
||||
|
||||
def test_list_scoped_to_own_and_unowned_tasks_for_regular_user(
|
||||
@@ -186,8 +203,8 @@ class TestGetTasksV10:
|
||||
response = client.get(ENDPOINT)
|
||||
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert len(response.data) == 2
|
||||
visible_ids = {t["task_id"] for t in response.data}
|
||||
assert response.data["count"] == 2
|
||||
visible_ids = {t["task_id"] for t in response.data["results"]}
|
||||
assert visible_ids == {own_task.task_id, unowned_task.task_id}
|
||||
|
||||
def test_list_admin_sees_all_tasks(
|
||||
@@ -204,7 +221,7 @@ class TestGetTasksV10:
|
||||
response = admin_client.get(ENDPOINT)
|
||||
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert len(response.data) == 3
|
||||
assert response.data["count"] == 3
|
||||
|
||||
|
||||
@pytest.mark.django_db()
|
||||
@@ -397,6 +414,16 @@ class TestGetTasksV9:
|
||||
assert len(response.data) == 1
|
||||
assert response.data[0]["task_name"] == "check_sanity"
|
||||
|
||||
def test_v9_list_returns_plain_list(self, v9_client: APIClient) -> None:
|
||||
"""v9 task list returns a plain JSON array, not a paginated envelope."""
|
||||
PaperlessTaskFactory.create_batch(3)
|
||||
|
||||
response = v9_client.get(ENDPOINT)
|
||||
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert isinstance(response.data, list)
|
||||
assert len(response.data) == 3
|
||||
|
||||
def test_v9_non_staff_sees_own_and_unowned_tasks(
|
||||
self,
|
||||
admin_user: User,
|
||||
@@ -510,7 +537,7 @@ class TestAcknowledge:
|
||||
response = admin_client.get(ENDPOINT, {"acknowledged": "false"})
|
||||
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert len(response.data) == 0
|
||||
assert response.data["count"] == 0
|
||||
|
||||
def test_requires_change_permission(self, user_client: APIClient) -> None:
|
||||
"""Regular users without change_paperlesstask permission receive 403."""
|
||||
|
||||
@@ -69,6 +69,7 @@ from django.views.decorators.http import condition
|
||||
from django.views.decorators.http import last_modified
|
||||
from django.views.generic import TemplateView
|
||||
from django_filters.rest_framework import DjangoFilterBackend
|
||||
from drf_spectacular.openapi import AutoSchema
|
||||
from drf_spectacular.types import OpenApiTypes
|
||||
from drf_spectacular.utils import OpenApiParameter
|
||||
from drf_spectacular.utils import extend_schema
|
||||
@@ -3799,6 +3800,15 @@ class RemoteVersionView(GenericAPIView[Any]):
|
||||
)
|
||||
|
||||
|
||||
class _TasksViewSetSchema(AutoSchema):
|
||||
_UNPAGINATED_ACTIONS = frozenset({"summary", "active"})
|
||||
|
||||
def _get_paginator(self):
|
||||
if getattr(self.view, "action", None) in self._UNPAGINATED_ACTIONS:
|
||||
return None
|
||||
return super()._get_paginator()
|
||||
|
||||
|
||||
@extend_schema_view(
|
||||
list=extend_schema(
|
||||
parameters=[
|
||||
@@ -3857,7 +3867,9 @@ class RemoteVersionView(GenericAPIView[Any]):
|
||||
),
|
||||
)
|
||||
class TasksViewSet(ReadOnlyModelViewSet[PaperlessTask]):
|
||||
schema = _TasksViewSetSchema()
|
||||
permission_classes = (IsAuthenticated, PaperlessObjectPermissions)
|
||||
pagination_class = StandardPagination
|
||||
filter_backends = (
|
||||
DjangoFilterBackend,
|
||||
OrderingFilter,
|
||||
@@ -3909,6 +3921,12 @@ class TasksViewSet(ReadOnlyModelViewSet[PaperlessTask]):
|
||||
return TaskSerializerV9
|
||||
return TaskSerializerV10
|
||||
|
||||
def paginate_queryset(self, queryset):
|
||||
# v9: tasks endpoint was not paginated; preserve plain-list response
|
||||
if self.request.version and int(self.request.version) < 10:
|
||||
return None
|
||||
return super().paginate_queryset(queryset)
|
||||
|
||||
def get_queryset(self):
|
||||
is_v9 = self.request.version and int(self.request.version) < 10
|
||||
if self.request.user.is_staff:
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: paperless-ngx\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-23 16:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-24 20:35+0000\n"
|
||||
"PO-Revision-Date: 2022-02-17 04:17\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: English\n"
|
||||
@@ -1352,8 +1352,8 @@ msgid "workflow runs"
|
||||
msgstr ""
|
||||
|
||||
#: documents/serialisers.py:463 documents/serialisers.py:815
|
||||
#: documents/serialisers.py:2681 documents/views.py:2258
|
||||
#: documents/views.py:2327 paperless_mail/serialisers.py:143
|
||||
#: documents/serialisers.py:2681 documents/views.py:2259
|
||||
#: documents/views.py:2328 paperless_mail/serialisers.py:143
|
||||
msgid "Insufficient permissions."
|
||||
msgstr ""
|
||||
|
||||
@@ -1393,7 +1393,7 @@ msgstr ""
|
||||
msgid "Duplicate document identifiers are not allowed."
|
||||
msgstr ""
|
||||
|
||||
#: documents/serialisers.py:2767 documents/views.py:4117
|
||||
#: documents/serialisers.py:2767 documents/views.py:4135
|
||||
#, python-format
|
||||
msgid "Documents not found: %(ids)s"
|
||||
msgstr ""
|
||||
@@ -1661,28 +1661,28 @@ msgstr ""
|
||||
msgid "Unable to parse URI {value}"
|
||||
msgstr ""
|
||||
|
||||
#: documents/views.py:2138
|
||||
#: documents/views.py:2139
|
||||
msgid "Specify only one of text, title_search, query, or more_like_id."
|
||||
msgstr ""
|
||||
|
||||
#: documents/views.py:2251 documents/views.py:2324
|
||||
#: documents/views.py:2252 documents/views.py:2325
|
||||
msgid "Invalid more_like_id"
|
||||
msgstr ""
|
||||
|
||||
#: documents/views.py:4129
|
||||
#: documents/views.py:4147
|
||||
#, python-format
|
||||
msgid "Insufficient permissions to share document %(id)s."
|
||||
msgstr ""
|
||||
|
||||
#: documents/views.py:4175
|
||||
#: documents/views.py:4193
|
||||
msgid "Bundle is already being processed."
|
||||
msgstr ""
|
||||
|
||||
#: documents/views.py:4235
|
||||
#: documents/views.py:4253
|
||||
msgid "The share link bundle is still being prepared. Please try again later."
|
||||
msgstr ""
|
||||
|
||||
#: documents/views.py:4245
|
||||
#: documents/views.py:4263
|
||||
msgid "The share link bundle is unavailable."
|
||||
msgstr ""
|
||||
|
||||
|
||||
Reference in new issue
Block a user