acknowledge_tasks endpoint & basic UI

Update tasks.service.ts
This commit is contained in:
Michael Shamoon 2022-05-23 10:45:14 -07:00
parent 4bbaf5f89c
commit 0a06c291e2
6 changed files with 86 additions and 50 deletions

View File

@ -5,7 +5,7 @@
<use xlink:href="assets/bootstrap-icons.svg#x"/> <use xlink:href="assets/bootstrap-icons.svg#x"/>
</svg>&nbsp;<ng-container i18n>Clear selection</ng-container> </svg>&nbsp;<ng-container i18n>Clear selection</ng-container>
</button> </button>
<button class="btn btn-sm btn-outline-primary me-4" (click)="dismissMany()" [disabled]="tasksService.total == 0"> <button class="btn btn-sm btn-outline-primary me-4" (click)="dismissTasks()" [disabled]="tasksService.total == 0">
<svg class="sidebaricon" fill="currentColor"> <svg class="sidebaricon" fill="currentColor">
<use xlink:href="assets/bootstrap-icons.svg#check2-all"/> <use xlink:href="assets/bootstrap-icons.svg#check2-all"/>
</svg>&nbsp;<ng-container i18n>{{dismissButtonText}}</ng-container> </svg>&nbsp;<ng-container i18n>{{dismissButtonText}}</ng-container>

View File

@ -30,11 +30,13 @@ export class TasksComponent implements OnInit, OnDestroy {
} }
dismissTask(task: PaperlessTask) { dismissTask(task: PaperlessTask) {
throw new Error('Not implemented' + task) this.dismissTasks(task)
} }
dismissMany() { dismissTasks(task: PaperlessTask = undefined) {
throw new Error('Not implemented') this.tasksService.dismissTasks(
task ? new Set([task.id]) : this.selectedTasks
)
} }
toggleSelected(task: PaperlessTask) { toggleSelected(task: PaperlessTask) {

View File

@ -1,6 +1,5 @@
import { HttpClient } from '@angular/common/http' import { HttpClient } from '@angular/common/http'
import { Injectable } from '@angular/core' import { Injectable } from '@angular/core'
import { Observable } from 'rxjs'
import { first, map } from 'rxjs/operators' import { first, map } from 'rxjs/operators'
import { PaperlessTask } from 'src/app/data/paperless-task' import { PaperlessTask } from 'src/app/data/paperless-task'
import { environment } from 'src/environments/environment' import { environment } from 'src/environments/environment'
@ -43,7 +42,7 @@ export class TasksService {
this.loading = true this.loading = true
this.http this.http
.get<TasksAPIResponse>(`${this.baseUrl}consumption_tasks/`) .get<TasksAPIResponse>(`${this.baseUrl}tasks/`)
.pipe(first()) .pipe(first())
.subscribe((r) => { .subscribe((r) => {
this.total = r.total this.total = r.total
@ -55,35 +54,14 @@ export class TasksService {
}) })
} }
// private savedViews: PaperlessSavedView[] = [] public dismissTasks(task_ids: Set<number>) {
this.http
// get allViews() { .post(`${this.baseUrl}acknowledge_tasks/`, {
// return this.savedViews tasks: [...task_ids],
// } })
.pipe(first())
// get sidebarViews() { .subscribe((r) => {
// return this.savedViews.filter((v) => v.show_in_sidebar) this.reload()
// } })
}
// 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<PaperlessSavedView[]> {
// return combineLatest(objects.map((o) => super.patch(o))).pipe(
// tap(() => this.reload())
// )
// }
// delete(o: PaperlessSavedView) {
// return super.delete(o).pipe(tap(() => this.reload()))
// }
} }

View File

@ -12,6 +12,7 @@ from .models import Correspondent
from .models import Document from .models import Document
from .models import DocumentType from .models import DocumentType
from .models import MatchingModel from .models import MatchingModel
from .models import PaperlessTask
from .models import SavedView from .models import SavedView
from .models import SavedViewFilterRule from .models import SavedViewFilterRule
from .models import StoragePath from .models import StoragePath
@ -597,9 +598,35 @@ class UiSettingsViewSerializer(serializers.ModelSerializer):
return ui_settings return ui_settings
class ConsupmtionTasksViewSerializer(serializers.Serializer): class TasksViewSerializer(serializers.Serializer):
type = serializers.ChoiceField( type = serializers.ChoiceField(
choices=["all", "incomplete", "complete", "failed"], choices=["all", "incomplete", "complete", "failed"],
default="all", default="all",
) )
class AcknowledgeTasksViewSerializer(serializers.Serializer):
tasks = serializers.ListField(
required=True,
label="Tasks",
write_only=True,
child=serializers.IntegerField(),
)
def _validate_task_id_list(self, tasks, name="tasks"):
pass
if not type(tasks) == list:
raise serializers.ValidationError(f"{name} must be a list")
if not all([type(i) == int for i in tasks]):
raise serializers.ValidationError(f"{name} must be a list of integers")
count = PaperlessTask.objects.filter(id__in=tasks).count()
if not count == len(tasks):
raise serializers.ValidationError(
f"Some tasks in {name} don't exist or were " f"specified twice.",
)
def validate_tasks(self, tasks):
self._validate_task_id_list(tasks)
return tasks

View File

@ -69,9 +69,9 @@ from .models import SavedView
from .models import StoragePath from .models import StoragePath
from .models import Tag from .models import Tag
from .parsers import get_parser_class_for_mime_type from .parsers import get_parser_class_for_mime_type
from .serialisers import AcknowledgeTasksViewSerializer
from .serialisers import BulkDownloadSerializer from .serialisers import BulkDownloadSerializer
from .serialisers import BulkEditSerializer from .serialisers import BulkEditSerializer
from .serialisers import ConsupmtionTasksViewSerializer
from .serialisers import CorrespondentSerializer from .serialisers import CorrespondentSerializer
from .serialisers import DocumentListSerializer from .serialisers import DocumentListSerializer
from .serialisers import DocumentSerializer from .serialisers import DocumentSerializer
@ -81,6 +81,7 @@ from .serialisers import SavedViewSerializer
from .serialisers import StoragePathSerializer from .serialisers import StoragePathSerializer
from .serialisers import TagSerializer from .serialisers import TagSerializer
from .serialisers import TagSerializerVersion1 from .serialisers import TagSerializerVersion1
from .serialisers import TasksViewSerializer
from .serialisers import UiSettingsViewSerializer from .serialisers import UiSettingsViewSerializer
logger = logging.getLogger("paperless.api") logger = logging.getLogger("paperless.api")
@ -799,37 +800,37 @@ class UiSettingsView(GenericAPIView):
) )
class ConsupmtionTasksView(GenericAPIView): class TasksView(GenericAPIView):
permission_classes = (IsAuthenticated,) permission_classes = (IsAuthenticated,)
serializer_class = ConsupmtionTasksViewSerializer serializer_class = TasksViewSerializer
def get(self, request, format=None): def get(self, request, format=None):
serializer = self.get_serializer(data=request.data) serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True) serializer.is_valid(raise_exception=True)
consumption_tasks = ( tasks = (
PaperlessTask.objects.filter( PaperlessTask.objects.filter(
acknowledged=False, acknowledged=False,
) )
.order_by("attempted_task__started") .order_by("attempted_task__started")
.reverse() .reverse()
) )
incomplete_tasks = consumption_tasks.filter(task=None).values( incomplete_tasks = tasks.filter(attempted_task=None).values(
"id", "id",
"task_id", "task_id",
"name", "name",
"created", "created",
"acknowledged", "acknowledged",
) )
failed_tasks = consumption_tasks.filter(attempted_task__success=0).values( failed_tasks = tasks.filter(attempted_task__success=0).values(
"id", "id",
"task_id", "task_id",
"name", "name",
"created", "created",
"acknowledged", "acknowledged",
) )
completed_tasks = consumption_tasks.filter(attempted_task__success=1).values( completed_tasks = tasks.filter(attempted_task__success=1).values(
"id", "id",
"task_id", "task_id",
"name", "name",
@ -838,9 +839,31 @@ class ConsupmtionTasksView(GenericAPIView):
) )
return Response( return Response(
{ {
"total": consumption_tasks.count(), "total": tasks.count(),
"incomplete": incomplete_tasks, "incomplete": incomplete_tasks,
"failed": failed_tasks, "failed": failed_tasks,
"completed": completed_tasks, "completed": completed_tasks,
}, },
) )
class AcknowledgeTasksView(GenericAPIView):
permission_classes = (IsAuthenticated,)
serializer_class = AcknowledgeTasksViewSerializer
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
tasks = serializer.validated_data.get("tasks")
try:
logger.debug(tasks)
result = PaperlessTask.objects.filter(id__in=tasks).update(
acknowledged=True,
)
return Response({"result": result})
pass
except Exception as e:
return HttpResponseBadRequest(str(e))

View File

@ -7,9 +7,9 @@ from django.urls import re_path
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
from django.views.generic import RedirectView from django.views.generic import RedirectView
from documents.views import AcknowledgeTasksView
from documents.views import BulkDownloadView from documents.views import BulkDownloadView
from documents.views import BulkEditView from documents.views import BulkEditView
from documents.views import ConsupmtionTasksView
from documents.views import CorrespondentViewSet from documents.views import CorrespondentViewSet
from documents.views import DocumentTypeViewSet from documents.views import DocumentTypeViewSet
from documents.views import IndexView from documents.views import IndexView
@ -22,6 +22,7 @@ from documents.views import SelectionDataView
from documents.views import StatisticsView from documents.views import StatisticsView
from documents.views import StoragePathViewSet from documents.views import StoragePathViewSet
from documents.views import TagViewSet from documents.views import TagViewSet
from documents.views import TasksView
from documents.views import UiSettingsView from documents.views import UiSettingsView
from documents.views import UnifiedSearchViewSet from documents.views import UnifiedSearchViewSet
from paperless.consumers import StatusConsumer from paperless.consumers import StatusConsumer
@ -88,9 +89,14 @@ urlpatterns = [
name="ui_settings", name="ui_settings",
), ),
re_path( re_path(
r"^consumption_tasks/", r"^tasks/",
ConsupmtionTasksView.as_view(), TasksView.as_view(),
name="consumption_tasks", name="tasks",
),
re_path(
r"^acknowledge_tasks/",
AcknowledgeTasksView.as_view(),
name="acknowledge_tasks",
), ),
path("token/", views.obtain_auth_token), path("token/", views.obtain_auth_token),
] ]