mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-04-02 13:45:10 -05:00
Basic option selection
This commit is contained in:
parent
62b470f691
commit
ec12e71487
@ -82,9 +82,7 @@
|
|||||||
<td scope="row">
|
<td scope="row">
|
||||||
<div class="btn-group" role="group">
|
<div class="btn-group" role="group">
|
||||||
@if (task.status === PaperlessTaskStatus.Failed) {
|
@if (task.status === PaperlessTaskStatus.Failed) {
|
||||||
<button class="btn btn-sm btn-outline-primary" (click)="retryTask(task); $event.stopPropagation();" *pngxIfPermissions="{ action: PermissionAction.Change, type: PermissionType.PaperlessTask }">
|
<ng-container *ngTemplateOutlet="retryDropdown; context: { task: task }"></ng-container>
|
||||||
<i-bs name="arrow-repeat"></i-bs> <ng-container i18n>Retry</ng-container>
|
|
||||||
</button>
|
|
||||||
}
|
}
|
||||||
<button class="btn btn-sm btn-outline-secondary" (click)="dismissTask(task); $event.stopPropagation();" *pngxIfPermissions="{ action: PermissionAction.Change, type: PermissionType.PaperlessTask }">
|
<button class="btn btn-sm btn-outline-secondary" (click)="dismissTask(task); $event.stopPropagation();" *pngxIfPermissions="{ action: PermissionAction.Change, type: PermissionType.PaperlessTask }">
|
||||||
<i-bs name="check"></i-bs> <ng-container i18n>Dismiss</ng-container>
|
<i-bs name="check"></i-bs> <ng-container i18n>Dismiss</ng-container>
|
||||||
@ -158,3 +156,25 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div [ngbNavOutlet]="nav"></div>
|
<div [ngbNavOutlet]="nav"></div>
|
||||||
|
|
||||||
|
<ng-template #retryDropdown let-task="task">
|
||||||
|
<div ngbDropdown>
|
||||||
|
<button class="btn btn-sm btn-outline-primary" (click)="$event.stopImmediatePropagation()" ngbDropdownToggle>
|
||||||
|
<i-bs name="arrow-repeat"></i-bs> <ng-container i18n>Retry</ng-container>
|
||||||
|
</button>
|
||||||
|
<div ngbDropdownMenu class="shadow retry-dropdown">
|
||||||
|
<div class="p-2">
|
||||||
|
<ul class="list-group list-group-flush">
|
||||||
|
<li class="list-group-item small" i18n>
|
||||||
|
<pngx-input-check [(ngModel)]="retryClean" i18n-title title="Attempt to clean pdf"></pngx-input-check>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="d-flex justify-content-end">
|
||||||
|
<button class="btn btn-sm btn-outline-primary" (click)="retryTask(task); $event.stopPropagation();">
|
||||||
|
<ng-container i18n>Proceed</ng-container>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
@ -26,3 +26,7 @@ pre {
|
|||||||
max-width: 150px;
|
max-width: 150px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.retry-dropdown {
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
@ -33,6 +33,7 @@ import { FormsModule } from '@angular/forms'
|
|||||||
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
|
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
|
||||||
import { ToastService } from 'src/app/services/toast.service'
|
import { ToastService } from 'src/app/services/toast.service'
|
||||||
import { of, throwError } from 'rxjs'
|
import { of, throwError } from 'rxjs'
|
||||||
|
import { CheckComponent } from '../../common/input/check/check.component'
|
||||||
|
|
||||||
const tasks: PaperlessTask[] = [
|
const tasks: PaperlessTask[] = [
|
||||||
{
|
{
|
||||||
@ -128,6 +129,7 @@ describe('TasksComponent', () => {
|
|||||||
IfPermissionsDirective,
|
IfPermissionsDirective,
|
||||||
CustomDatePipe,
|
CustomDatePipe,
|
||||||
ConfirmDialogComponent,
|
ConfirmDialogComponent,
|
||||||
|
CheckComponent,
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
NgbModule,
|
NgbModule,
|
||||||
@ -177,8 +179,10 @@ describe('TasksComponent', () => {
|
|||||||
`Failed${currentTasksLength}`
|
`Failed${currentTasksLength}`
|
||||||
)
|
)
|
||||||
expect(
|
expect(
|
||||||
fixture.debugElement.queryAll(By.css('table input[type="checkbox"]'))
|
fixture.debugElement.queryAll(
|
||||||
).toHaveLength(currentTasksLength + 1)
|
By.css('table td > .form-check input[type="checkbox"]')
|
||||||
|
)
|
||||||
|
).toHaveLength(currentTasksLength)
|
||||||
|
|
||||||
currentTasksLength = tasks.filter(
|
currentTasksLength = tasks.filter(
|
||||||
(t) => t.status === PaperlessTaskStatus.Complete
|
(t) => t.status === PaperlessTaskStatus.Complete
|
||||||
@ -300,7 +304,7 @@ describe('TasksComponent', () => {
|
|||||||
const toastErrorSpy = jest.spyOn(toastService, 'showError')
|
const toastErrorSpy = jest.spyOn(toastService, 'showError')
|
||||||
retrySpy.mockReturnValueOnce(of({ task_id: '123' }))
|
retrySpy.mockReturnValueOnce(of({ task_id: '123' }))
|
||||||
component.retryTask(tasks[0])
|
component.retryTask(tasks[0])
|
||||||
expect(retrySpy).toHaveBeenCalledWith(tasks[0])
|
expect(retrySpy).toHaveBeenCalledWith(tasks[0], false)
|
||||||
expect(toastInfoSpy).toHaveBeenCalledWith('Retrying task...')
|
expect(toastInfoSpy).toHaveBeenCalledWith('Retrying task...')
|
||||||
retrySpy.mockReturnValueOnce(throwError(() => new Error('test')))
|
retrySpy.mockReturnValueOnce(throwError(() => new Error('test')))
|
||||||
component.retryTask(tasks[0])
|
component.retryTask(tasks[0])
|
||||||
|
@ -28,6 +28,8 @@ export class TasksComponent
|
|||||||
|
|
||||||
public autoRefreshInterval: any
|
public autoRefreshInterval: any
|
||||||
|
|
||||||
|
public retryClean: boolean = false
|
||||||
|
|
||||||
get dismissButtonText(): string {
|
get dismissButtonText(): string {
|
||||||
return this.selectedTasks.size > 0
|
return this.selectedTasks.size > 0
|
||||||
? $localize`Dismiss selected`
|
? $localize`Dismiss selected`
|
||||||
@ -87,7 +89,7 @@ export class TasksComponent
|
|||||||
}
|
}
|
||||||
|
|
||||||
retryTask(task: PaperlessTask) {
|
retryTask(task: PaperlessTask) {
|
||||||
this.tasksService.retryTask(task).subscribe({
|
this.tasksService.retryTask(task, this.retryClean).subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.toastService.showInfo($localize`Retrying task...`)
|
this.toastService.showInfo($localize`Retrying task...`)
|
||||||
},
|
},
|
||||||
|
@ -130,14 +130,14 @@ describe('TasksService', () => {
|
|||||||
date_created: new Date(),
|
date_created: new Date(),
|
||||||
}
|
}
|
||||||
|
|
||||||
tasksService.retryTask(task).subscribe()
|
tasksService.retryTask(task, true).subscribe()
|
||||||
const reloadSpy = jest.spyOn(tasksService, 'reload')
|
const reloadSpy = jest.spyOn(tasksService, 'reload')
|
||||||
const req = httpTestingController.expectOne(
|
const req = httpTestingController.expectOne(
|
||||||
`${environment.apiBaseUrl}tasks/${task.id}/retry/`
|
`${environment.apiBaseUrl}tasks/${task.id}/retry/`
|
||||||
)
|
)
|
||||||
expect(req.request.method).toEqual('POST')
|
expect(req.request.method).toEqual('POST')
|
||||||
expect(req.request.body).toEqual({
|
expect(req.request.body).toEqual({
|
||||||
task_id: task.id,
|
clean: true,
|
||||||
})
|
})
|
||||||
req.flush({ task_id: 12345 })
|
req.flush({ task_id: 12345 })
|
||||||
expect(reloadSpy).toHaveBeenCalled()
|
expect(reloadSpy).toHaveBeenCalled()
|
||||||
|
@ -73,10 +73,10 @@ export class TasksService {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
public retryTask(task: PaperlessTask): Observable<any> {
|
public retryTask(task: PaperlessTask, clean: boolean): Observable<any> {
|
||||||
return this.http
|
return this.http
|
||||||
.post(`${this.baseUrl}tasks/${task.id}/retry/`, {
|
.post(`${this.baseUrl}tasks/${task.id}/retry/`, {
|
||||||
task_id: task.id,
|
clean,
|
||||||
})
|
})
|
||||||
.pipe(
|
.pipe(
|
||||||
takeUntil(this.unsubscribeNotifer),
|
takeUntil(this.unsubscribeNotifer),
|
||||||
|
@ -1585,6 +1585,14 @@ class TasksViewSerializer(serializers.ModelSerializer):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
class RetryTaskSerializer(serializers.Serializer):
|
||||||
|
clean = serializers.BooleanField(
|
||||||
|
default=False,
|
||||||
|
write_only=True,
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class AcknowledgeTasksViewSerializer(serializers.Serializer):
|
class AcknowledgeTasksViewSerializer(serializers.Serializer):
|
||||||
tasks = serializers.ListField(
|
tasks = serializers.ListField(
|
||||||
required=True,
|
required=True,
|
||||||
|
@ -136,6 +136,7 @@ from documents.serialisers import DocumentListSerializer
|
|||||||
from documents.serialisers import DocumentSerializer
|
from documents.serialisers import DocumentSerializer
|
||||||
from documents.serialisers import DocumentTypeSerializer
|
from documents.serialisers import DocumentTypeSerializer
|
||||||
from documents.serialisers import PostDocumentSerializer
|
from documents.serialisers import PostDocumentSerializer
|
||||||
|
from documents.serialisers import RetryTaskSerializer
|
||||||
from documents.serialisers import SavedViewSerializer
|
from documents.serialisers import SavedViewSerializer
|
||||||
from documents.serialisers import SearchResultSerializer
|
from documents.serialisers import SearchResultSerializer
|
||||||
from documents.serialisers import ShareLinkSerializer
|
from documents.serialisers import ShareLinkSerializer
|
||||||
@ -1722,9 +1723,16 @@ class TasksViewSet(ReadOnlyModelViewSet):
|
|||||||
@action(methods=["post"], detail=True)
|
@action(methods=["post"], detail=True)
|
||||||
def retry(self, request, pk=None):
|
def retry(self, request, pk=None):
|
||||||
task = self.get_object()
|
task = self.get_object()
|
||||||
|
|
||||||
|
serializer = RetryTaskSerializer(data=request.data)
|
||||||
|
serializer.is_valid(raise_exception=True)
|
||||||
|
clean = serializer.validated_data.get("clean")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
new_task_id = retry_failed_file(task.task_id, True)
|
new_task_id = retry_failed_file(task.task_id, clean)
|
||||||
return Response({"task_id": new_task_id})
|
return Response({"task_id": new_task_id})
|
||||||
|
except FileNotFoundError:
|
||||||
|
return HttpResponseBadRequest("Original file not found")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"An error occurred retrying task: {e!s}")
|
logger.warning(f"An error occurred retrying task: {e!s}")
|
||||||
return HttpResponseBadRequest(
|
return HttpResponseBadRequest(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user