mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-11-04 05:49:23 +00:00
Merge branch 'dev' into feature/ocr-templates
This commit is contained in:
167 files changed
+46845
-33694
No files matched your search
@@ -9,11 +9,7 @@ import {
|
||||
} from '@angular/common/http/testing'
|
||||
import { TestBed } from '@angular/core/testing'
|
||||
import { environment } from 'src/environments/environment'
|
||||
import {
|
||||
PaperlessTaskStatus,
|
||||
PaperlessTaskTriggerSource,
|
||||
PaperlessTaskType,
|
||||
} from '../data/paperless-task'
|
||||
import { PaperlessTaskType } from '../data/paperless-task'
|
||||
import { TasksService } from './tasks.service'
|
||||
|
||||
describe('TasksService', () => {
|
||||
@@ -38,23 +34,23 @@ describe('TasksService', () => {
|
||||
httpTestingController.verify()
|
||||
})
|
||||
|
||||
it('calls tasks api endpoint on reload', () => {
|
||||
it('calls tasks status counts api endpoint on reload', () => {
|
||||
tasksService.reload()
|
||||
const req = httpTestingController.expectOne(
|
||||
(req: HttpRequest<unknown>) =>
|
||||
req.url === `${environment.apiBaseUrl}tasks/` &&
|
||||
req.params.get('acknowledged') === 'false' &&
|
||||
req.params.get('page_size') === '1000'
|
||||
req.url === `${environment.apiBaseUrl}tasks/status_counts/` &&
|
||||
req.params.get('acknowledged') === 'false'
|
||||
)
|
||||
expect(req.request.method).toEqual('GET')
|
||||
req.flush({ count: 0, results: [] })
|
||||
req.flush({ all: 5, needs_attention: 3, in_progress: 1, completed: 1 })
|
||||
expect(tasksService.needsAttentionTasksCount).toEqual(3)
|
||||
})
|
||||
|
||||
it('cancels an in-progress reload when reloading again', () => {
|
||||
tasksService.reload()
|
||||
const staleReload = httpTestingController.expectOne(
|
||||
(req: HttpRequest<unknown>) =>
|
||||
req.url === `${environment.apiBaseUrl}tasks/`
|
||||
req.url === `${environment.apiBaseUrl}tasks/status_counts/`
|
||||
)
|
||||
tasksService.reload()
|
||||
|
||||
@@ -62,9 +58,9 @@ describe('TasksService', () => {
|
||||
httpTestingController
|
||||
.expectOne(
|
||||
(req: HttpRequest<unknown>) =>
|
||||
req.url === `${environment.apiBaseUrl}tasks/`
|
||||
req.url === `${environment.apiBaseUrl}tasks/status_counts/`
|
||||
)
|
||||
.flush({ count: 0, results: [] })
|
||||
.flush({ all: 0, needs_attention: 0, in_progress: 0, completed: 0 })
|
||||
})
|
||||
|
||||
it('continues reloading after a reload request fails', () => {
|
||||
@@ -72,7 +68,7 @@ describe('TasksService', () => {
|
||||
httpTestingController
|
||||
.expectOne(
|
||||
(req: HttpRequest<unknown>) =>
|
||||
req.url === `${environment.apiBaseUrl}tasks/`
|
||||
req.url === `${environment.apiBaseUrl}tasks/status_counts/`
|
||||
)
|
||||
.flush('error', { status: 500, statusText: 'error' })
|
||||
|
||||
@@ -82,16 +78,16 @@ describe('TasksService', () => {
|
||||
httpTestingController
|
||||
.expectOne(
|
||||
(req: HttpRequest<unknown>) =>
|
||||
req.url === `${environment.apiBaseUrl}tasks/`
|
||||
req.url === `${environment.apiBaseUrl}tasks/status_counts/`
|
||||
)
|
||||
.flush({ count: 0, results: [] })
|
||||
.flush({ all: 0, needs_attention: 0, in_progress: 0, completed: 0 })
|
||||
})
|
||||
|
||||
it('reloads after dismissing a task while a reload is already in progress', () => {
|
||||
tasksService.reload()
|
||||
const staleReload = httpTestingController.expectOne(
|
||||
(req: HttpRequest<unknown>) =>
|
||||
req.url === `${environment.apiBaseUrl}tasks/` &&
|
||||
req.url === `${environment.apiBaseUrl}tasks/status_counts/` &&
|
||||
req.params.get('acknowledged') === 'false'
|
||||
)
|
||||
|
||||
@@ -104,12 +100,12 @@ describe('TasksService', () => {
|
||||
httpTestingController
|
||||
.expectOne(
|
||||
(req: HttpRequest<unknown>) =>
|
||||
req.url === `${environment.apiBaseUrl}tasks/` &&
|
||||
req.url === `${environment.apiBaseUrl}tasks/status_counts/` &&
|
||||
req.params.get('acknowledged') === 'false'
|
||||
)
|
||||
.flush({ count: 0, results: [] })
|
||||
.flush({ all: 50, needs_attention: 42, in_progress: 3, completed: 5 })
|
||||
|
||||
expect(tasksService.needsAttentionTasks).toHaveLength(0)
|
||||
expect(tasksService.needsAttentionTasksCount).toEqual(42)
|
||||
})
|
||||
|
||||
it('calls acknowledge_tasks api endpoint on dismiss and reloads', () => {
|
||||
@@ -126,11 +122,10 @@ describe('TasksService', () => {
|
||||
httpTestingController
|
||||
.expectOne(
|
||||
(req: HttpRequest<unknown>) =>
|
||||
req.url === `${environment.apiBaseUrl}tasks/` &&
|
||||
req.params.get('acknowledged') === 'false' &&
|
||||
req.params.get('page_size') === '1000'
|
||||
req.url === `${environment.apiBaseUrl}tasks/status_counts/` &&
|
||||
req.params.get('acknowledged') === 'false'
|
||||
)
|
||||
.flush({ count: 0, results: [] })
|
||||
.flush({ all: 0, needs_attention: 0, in_progress: 0, completed: 0 })
|
||||
})
|
||||
|
||||
it('calls acknowledge_tasks api endpoint on dismiss all and reloads', () => {
|
||||
@@ -147,65 +142,10 @@ describe('TasksService', () => {
|
||||
httpTestingController
|
||||
.expectOne(
|
||||
(req: HttpRequest<unknown>) =>
|
||||
req.url === `${environment.apiBaseUrl}tasks/` &&
|
||||
req.params.get('acknowledged') === 'false' &&
|
||||
req.params.get('page_size') === '1000'
|
||||
req.url === `${environment.apiBaseUrl}tasks/status_counts/` &&
|
||||
req.params.get('acknowledged') === 'false'
|
||||
)
|
||||
.flush({ count: 0, results: [] })
|
||||
})
|
||||
|
||||
it('includes revoked tasks in needs attention', () => {
|
||||
const mockTasks = [
|
||||
{
|
||||
task_type: PaperlessTaskType.SanityCheck,
|
||||
trigger_source: PaperlessTaskTriggerSource.System,
|
||||
status: PaperlessTaskStatus.Failure,
|
||||
acknowledged: false,
|
||||
task_id: '1235',
|
||||
input_data: {},
|
||||
date_created: new Date(),
|
||||
related_document_ids: [],
|
||||
},
|
||||
{
|
||||
task_type: PaperlessTaskType.MailFetch,
|
||||
trigger_source: PaperlessTaskTriggerSource.Scheduled,
|
||||
status: PaperlessTaskStatus.Revoked,
|
||||
acknowledged: false,
|
||||
task_id: '1236',
|
||||
input_data: {},
|
||||
date_created: new Date(),
|
||||
related_document_ids: [],
|
||||
},
|
||||
{
|
||||
task_type: PaperlessTaskType.EmptyTrash,
|
||||
trigger_source: PaperlessTaskTriggerSource.Manual,
|
||||
status: PaperlessTaskStatus.Success,
|
||||
acknowledged: false,
|
||||
task_id: '1238',
|
||||
input_data: {},
|
||||
date_created: new Date(),
|
||||
related_document_ids: [],
|
||||
},
|
||||
]
|
||||
|
||||
tasksService.reload()
|
||||
|
||||
const req = httpTestingController.expectOne(
|
||||
(req: HttpRequest<unknown>) =>
|
||||
req.url === `${environment.apiBaseUrl}tasks/` &&
|
||||
req.params.get('acknowledged') === 'false' &&
|
||||
req.params.get('page_size') === '1000'
|
||||
)
|
||||
|
||||
req.flush({ count: mockTasks.length, results: mockTasks })
|
||||
|
||||
expect(tasksService.needsAttentionTasks).toHaveLength(2)
|
||||
expect(tasksService.needsAttentionTasks.map((task) => task.status)).toEqual(
|
||||
expect.arrayContaining([
|
||||
PaperlessTaskStatus.Failure,
|
||||
PaperlessTaskStatus.Revoked,
|
||||
])
|
||||
)
|
||||
.flush({ all: 0, needs_attention: 0, in_progress: 0, completed: 0 })
|
||||
})
|
||||
|
||||
it('supports running tasks', () => {
|
||||
|
||||
@@ -5,14 +5,12 @@ import {
|
||||
catchError,
|
||||
finalize,
|
||||
first,
|
||||
map,
|
||||
switchMap,
|
||||
takeUntil,
|
||||
tap,
|
||||
} from 'rxjs/operators'
|
||||
import {
|
||||
PaperlessTask,
|
||||
PaperlessTaskStatus,
|
||||
PaperlessTaskStatusCounts,
|
||||
PaperlessTaskType,
|
||||
} from 'src/app/data/paperless-task'
|
||||
@@ -27,50 +25,42 @@ export class TasksService {
|
||||
|
||||
private baseUrl: string = environment.apiBaseUrl
|
||||
private endpoint: string = 'tasks'
|
||||
private readonly defaultReloadPageSize = 1000
|
||||
|
||||
public loading: boolean = false
|
||||
|
||||
private readonly tasks = signal<PaperlessTask[]>([])
|
||||
private readonly tasksStatusCounts = signal<PaperlessTaskStatusCounts>({
|
||||
all: 0,
|
||||
needs_attention: 0,
|
||||
in_progress: 0,
|
||||
completed: 0,
|
||||
})
|
||||
private readonly reloadNotifier = new Subject<void>()
|
||||
|
||||
private unsubscribeNotifer: Subject<any> = new Subject()
|
||||
|
||||
constructor() {
|
||||
this.reloadNotifier
|
||||
.pipe(
|
||||
switchMap(() => {
|
||||
this.loading = true
|
||||
return this.http
|
||||
.get<Results<PaperlessTask>>(`${this.baseUrl}${this.endpoint}/`, {
|
||||
params: {
|
||||
acknowledged: 'false',
|
||||
page_size: this.defaultReloadPageSize,
|
||||
},
|
||||
})
|
||||
.pipe(
|
||||
map((response) => response.results),
|
||||
takeUntil(this.unsubscribeNotifer),
|
||||
catchError(() => EMPTY),
|
||||
finalize(() => {
|
||||
this.loading = false
|
||||
})
|
||||
)
|
||||
})
|
||||
)
|
||||
.subscribe((tasks) => {
|
||||
this.tasks.set(tasks)
|
||||
.pipe(switchMap(() => this.fetchUnacknowledgedTasksCounts()))
|
||||
.subscribe((taskStatusCounts) => {
|
||||
this.tasksStatusCounts.set(taskStatusCounts)
|
||||
})
|
||||
}
|
||||
|
||||
public get needsAttentionTasks(): PaperlessTask[] {
|
||||
return this.tasks().filter((t) =>
|
||||
[PaperlessTaskStatus.Failure, PaperlessTaskStatus.Revoked].includes(
|
||||
t.status
|
||||
)
|
||||
private fetchUnacknowledgedTasksCounts(): Observable<PaperlessTaskStatusCounts> {
|
||||
this.loading = true
|
||||
return this.statusCounts({ acknowledged: false }).pipe(
|
||||
takeUntil(this.unsubscribeNotifer),
|
||||
catchError(() => EMPTY),
|
||||
finalize(() => {
|
||||
this.loading = false
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
public get needsAttentionTasksCount(): number {
|
||||
return this.tasksStatusCounts().needs_attention
|
||||
}
|
||||
|
||||
public reload() {
|
||||
this.reloadNotifier.next()
|
||||
}
|
||||
@@ -105,7 +95,7 @@ export class TasksService {
|
||||
|
||||
public dismissTasks(task_ids: Set<number>): Observable<any> {
|
||||
return this.http
|
||||
.post(`${this.baseUrl}tasks/acknowledge/`, {
|
||||
.post(`${this.baseUrl}${this.endpoint}/acknowledge/`, {
|
||||
tasks: [...task_ids],
|
||||
})
|
||||
.pipe(
|
||||
@@ -119,7 +109,7 @@ export class TasksService {
|
||||
|
||||
public dismissAllTasks(): Observable<any> {
|
||||
return this.http
|
||||
.post(`${this.baseUrl}tasks/acknowledge/`, {
|
||||
.post(`${this.baseUrl}${this.endpoint}/acknowledge/`, {
|
||||
all: true,
|
||||
})
|
||||
.pipe(
|
||||
|
||||
Reference in new issue
Block a user