diff --git a/src-ui/src/app/components/manage/tasks/tasks.component.html b/src-ui/src/app/components/manage/tasks/tasks.component.html index c9f64041c..45fc02666 100644 --- a/src-ui/src/app/components/manage/tasks/tasks.component.html +++ b/src-ui/src/app/components/manage/tasks/tasks.component.html @@ -1,12 +1,24 @@ - - - - Refresh - + + + + + Clear selection + + + + + {{dismissButtonText}} + + + + + Refresh + + - + Loading... @@ -17,8 +29,7 @@ - - + @@ -32,8 +43,7 @@ - - + @@ -61,23 +71,23 @@ - - - Incomplete {{tasksService.incomplete.length}} + + + Incomplete {{tasksService.incompleteFileTasks.length}} - + - - Completed {{tasksService.completed.length}} + + Completed {{tasksService.completedFileTasks.length}} - + - - Failed {{tasksService.failed.length}} + + Failed {{tasksService.failedFileTasks.length}} - + diff --git a/src-ui/src/app/components/manage/tasks/tasks.component.ts b/src-ui/src/app/components/manage/tasks/tasks.component.ts index 1e32be303..873325b7d 100644 --- a/src-ui/src/app/components/manage/tasks/tasks.component.ts +++ b/src-ui/src/app/components/manage/tasks/tasks.component.ts @@ -9,8 +9,16 @@ import { TasksService } from 'src/app/services/tasks.service' styleUrls: ['./tasks.component.scss'], }) export class TasksComponent implements OnInit, OnDestroy { + public activeTab: string + public selectedTasks: Set = new Set() private unsubscribeNotifer = new Subject() + get dismissButtonText(): string { + return this.selectedTasks.size > 0 + ? $localize`Dismiss selected` + : $localize`Dismiss all` + } + constructor(public tasksService: TasksService) {} ngOnInit() { @@ -21,7 +29,50 @@ export class TasksComponent implements OnInit, OnDestroy { this.unsubscribeNotifer.next(true) } - acknowledgeTask(task: PaperlessTask) { - throw new Error('Not implemented' + task) + dismissTask(task: PaperlessTask) { + this.dismissTasks(task) + } + + dismissTasks(task: PaperlessTask = undefined) { + let tasks = task ? new Set([task.id]) : this.selectedTasks + if (this.selectedTasks.size == 0) + tasks = new Set(this.currentTasks.map((t) => t.id)) + this.tasksService.dismissTasks(tasks) + } + + toggleSelected(task: PaperlessTask) { + this.selectedTasks.has(task.id) + ? this.selectedTasks.delete(task.id) + : this.selectedTasks.add(task.id) + } + + get currentTasks(): PaperlessTask[] { + let tasks: PaperlessTask[] + switch (this.activeTab) { + case 'incomplete': + tasks = this.tasksService.incompleteFileTasks + break + case 'completed': + tasks = this.tasksService.completedFileTasks + break + case 'failed': + tasks = this.tasksService.failedFileTasks + break + default: + break + } + return tasks + } + + toggleAll(event: PointerEvent) { + if ((event.target as HTMLInputElement).checked) { + this.selectedTasks = new Set(this.currentTasks.map((t) => t.id)) + } else { + this.clearSelection() + } + } + + clearSelection() { + this.selectedTasks = new Set() } } diff --git a/src-ui/src/app/data/paperless-task.ts b/src-ui/src/app/data/paperless-task.ts index 35ec50a0b..15582913c 100644 --- a/src-ui/src/app/data/paperless-task.ts +++ b/src-ui/src/app/data/paperless-task.ts @@ -1,9 +1,25 @@ import { ObjectWithId } from './object-with-id' +export enum PaperlessTaskType { + // just file tasks, for now + File = 'file', +} + +export enum PaperlessTaskStatus { + Incomplete = 'incomplete', + Complete = 'complete', + Failed = 'failed', + Unknown = 'unknown', +} + export interface PaperlessTask extends ObjectWithId { + type: PaperlessTaskType + + status: PaperlessTaskStatus + acknowledged: boolean - q_task_id: string + task_id: string name: string diff --git a/src-ui/src/app/services/tasks.service.ts b/src-ui/src/app/services/tasks.service.ts index c657e6a30..f6faccaa6 100644 --- a/src-ui/src/app/services/tasks.service.ts +++ b/src-ui/src/app/services/tasks.service.ts @@ -1,16 +1,13 @@ import { HttpClient } from '@angular/common/http' import { Injectable } from '@angular/core' -import { Observable } from 'rxjs' import { first, map } from 'rxjs/operators' -import { PaperlessTask } from 'src/app/data/paperless-task' +import { + PaperlessTask, + PaperlessTaskStatus, + PaperlessTaskType, +} from 'src/app/data/paperless-task' import { environment } from 'src/environments/environment' -interface TasksAPIResponse { - incomplete: Array - completed: Array - failed: Array -} - @Injectable({ providedIn: 'root', }) @@ -19,19 +16,26 @@ export class TasksService { loading: boolean - private incompleteTasks: PaperlessTask[] = [] - public get incomplete(): PaperlessTask[] { - return this.incompleteTasks + private fileTasks: PaperlessTask[] = [] + + public get total(): number { + return this.fileTasks?.length } - private completedTasks: PaperlessTask[] = [] - public get completed(): PaperlessTask[] { - return this.completedTasks + public get incompleteFileTasks(): PaperlessTask[] { + return this.fileTasks.filter( + (t) => t.status == PaperlessTaskStatus.Incomplete + ) } - private failedTasks: PaperlessTask[] = [] - public get failed(): PaperlessTask[] { - return this.failedTasks + public get completedFileTasks(): PaperlessTask[] { + return this.fileTasks.filter( + (t) => t.status == PaperlessTaskStatus.Complete + ) + } + + public get failedFileTasks(): PaperlessTask[] { + return this.fileTasks.filter((t) => t.status == PaperlessTaskStatus.Failed) } constructor(private http: HttpClient) {} @@ -40,46 +44,23 @@ export class TasksService { this.loading = true this.http - .get(`${this.baseUrl}consumption_tasks/`) + .get(`${this.baseUrl}tasks/`) .pipe(first()) .subscribe((r) => { - this.incompleteTasks = r.incomplete - this.completedTasks = r.completed - this.failedTasks = r.failed + this.fileTasks = r.filter((t) => t.type == PaperlessTaskType.File) // they're all File tasks, for now this.loading = false return true }) } - // private savedViews: PaperlessSavedView[] = [] - - // get allViews() { - // return this.savedViews - // } - - // get sidebarViews() { - // return this.savedViews.filter((v) => v.show_in_sidebar) - // } - - // get dashboardViews() { - // return this.savedViews.filter((v) => v.show_on_dashboard) - // } - - // create(o: PaperlessSavedView) { - // return super.create(o).pipe(tap(() => this.reload())) - // } - - // update(o: PaperlessSavedView) { - // return super.update(o).pipe(tap(() => this.reload())) - // } - - // patchMany(objects: PaperlessSavedView[]): Observable { - // return combineLatest(objects.map((o) => super.patch(o))).pipe( - // tap(() => this.reload()) - // ) - // } - - // delete(o: PaperlessSavedView) { - // return super.delete(o).pipe(tap(() => this.reload())) - // } + public dismissTasks(task_ids: Set) { + this.http + .post(`${this.baseUrl}acknowledge_tasks/`, { + tasks: [...task_ids], + }) + .pipe(first()) + .subscribe((r) => { + this.reload() + }) + } }