diff --git a/src-ui/src/app/components/admin/tasks/tasks.component.html b/src-ui/src/app/components/admin/tasks/tasks.component.html index 116d35f89..1d86597c0 100644 --- a/src-ui/src/app/components/admin/tasks/tasks.component.html +++ b/src-ui/src/app/components/admin/tasks/tasks.component.html @@ -81,7 +81,7 @@ diff --git a/src-ui/src/app/components/admin/tasks/tasks.component.ts b/src-ui/src/app/components/admin/tasks/tasks.component.ts index 884ede0d6..d57fae428 100644 --- a/src-ui/src/app/components/admin/tasks/tasks.component.ts +++ b/src-ui/src/app/components/admin/tasks/tasks.component.ts @@ -40,7 +40,7 @@ export enum TaskSection { Completed = 'completed', } -enum TaskFilterTargetID { +export enum TaskFilterTargetID { Name, Result, } @@ -167,6 +167,12 @@ export class TasksComponent public readonly pageSize = 25 public page: number = 1 public totalTasks: number = 0 + public sectionCounts: Record = { + [TaskSection.All]: 0, + [TaskSection.NeedsAttention]: 0, + [TaskSection.InProgress]: 0, + [TaskSection.Completed]: 0, + } public pagedTasks: PaperlessTask[] = [] public selectedSection: TaskSection = TaskSection.All public selectedTaskType: PaperlessTaskType | null = null @@ -282,6 +288,7 @@ export class TasksComponent .subscribe((query) => { this._filterText = query this.clearSelection() + this.reloadPage(true) }) } @@ -446,9 +453,7 @@ export class TasksComponent } sectionCount(section: TaskSection): number { - return this.pagedTasks.filter((task) => - this.taskBelongsToSection(task, section) - ).length + return this.sectionCounts[section] } sectionShowsResults(section: TaskSection): boolean { @@ -458,16 +463,27 @@ export class TasksComponent setSection(section: TaskSection) { this.selectedSection = section this.clearSelection() + this.reloadPage(true) } setTaskType(taskType: PaperlessTaskType | null) { this.selectedTaskType = taskType this.clearSelection() + this.reloadPage(true) } setTriggerSource(triggerSource: PaperlessTaskTriggerSource | null) { this.selectedTriggerSource = triggerSource this.clearSelection() + this.reloadPage(true) + } + + setFilterTarget(filterTargetID: TaskFilterTargetID) { + this.filterTargetID = filterTargetID + if (this._filterText.length) { + this.clearSelection() + this.reloadPage(true) + } } taskTypeOptionCount(taskType: PaperlessTaskType | null): number { @@ -505,19 +521,32 @@ export class TasksComponent } public resetFilter() { + if (!this._filterText.length) { + return + } + this._filterText = '' + this.clearSelection() + this.reloadPage(true) } public resetFilters() { + const hadFilter = this.isFiltered this.selectedTaskType = null this.selectedTriggerSource = null - this.resetFilter() + this._filterText = '' this.clearSelection() + + if (hadFilter) { + this.reloadPage(true) + } } filterInputKeyup(event: KeyboardEvent) { if (event.key == 'Enter') { this._filterText = (event.target as HTMLInputElement).value + this.clearSelection() + this.reloadPage(true) } else if (event.key === 'Escape') { this.resetFilter() } @@ -606,19 +635,86 @@ export class TasksComponent ) } + private reloadSectionCounts() { + this.tasksService + .statusCounts(this.getParamsForSection(TaskSection.All)) + .pipe(first(), takeUntil(this.unsubscribeNotifier)) + .subscribe((counts) => { + this.sectionCounts[TaskSection.All] = counts.all + this.sectionCounts[TaskSection.NeedsAttention] = counts.needs_attention + this.sectionCounts[TaskSection.InProgress] = counts.in_progress + this.sectionCounts[TaskSection.Completed] = counts.completed + }) + } + + private getParamsForSection( + section: TaskSection + ): Record { + const params: Record< + string, + string | number | boolean | readonly string[] + > = { + acknowledged: false, + } + + const statuses = this.statusesForSection(section) + if (statuses.length) { + params.status = statuses + } + + if (this.selectedTaskType !== null) { + params.task_type = this.selectedTaskType + } + + if (this.selectedTriggerSource !== null) { + params.trigger_source = this.selectedTriggerSource + } + + if (this._filterText.length) { + params[ + this.filterTargetID === TaskFilterTargetID.Name ? 'name' : 'result' + ] = this._filterText + } + + return params + } + + private statusesForSection(section: TaskSection): PaperlessTaskStatus[] { + switch (section) { + case TaskSection.NeedsAttention: + return [PaperlessTaskStatus.Failure, PaperlessTaskStatus.Revoked] + case TaskSection.InProgress: + return [PaperlessTaskStatus.Pending, PaperlessTaskStatus.Started] + case TaskSection.Completed: + return [PaperlessTaskStatus.Success] + default: + return [] + } + } + private reloadPage(resetToFirstPage: boolean = false) { if (resetToFirstPage) { this.page = 1 } + this.reloadSectionCounts() + this.loading = true this.tasksService - .list(this.page, this.pageSize, { acknowledged: false }) + .list( + this.page, + this.pageSize, + this.getParamsForSection(this.selectedSection) + ) .pipe(first(), takeUntil(this.unsubscribeNotifier)) .subscribe({ next: (result) => { this.pagedTasks = result.results this.totalTasks = result.count + this.sectionCounts[TaskSection.All] = result.count + if (this.selectedSection !== TaskSection.All) { + this.sectionCounts[this.selectedSection] = result.count + } this.loading = false if ( this.page > 1 &&