mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-10-24 03:26:11 -05:00 
			
		
		
		
	acknowledge_tasks endpoint & basic UI
Update tasks.service.ts
This commit is contained in:
		| @@ -5,7 +5,7 @@ | ||||
|         <use xlink:href="assets/bootstrap-icons.svg#x"/> | ||||
|       </svg> <ng-container i18n>Clear selection</ng-container> | ||||
|     </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"> | ||||
|         <use xlink:href="assets/bootstrap-icons.svg#check2-all"/> | ||||
|       </svg> <ng-container i18n>{{dismissButtonText}}</ng-container> | ||||
|   | ||||
| @@ -30,11 +30,13 @@ export class TasksComponent implements OnInit, OnDestroy { | ||||
|   } | ||||
|  | ||||
|   dismissTask(task: PaperlessTask) { | ||||
|     throw new Error('Not implemented' + task) | ||||
|     this.dismissTasks(task) | ||||
|   } | ||||
|  | ||||
|   dismissMany() { | ||||
|     throw new Error('Not implemented') | ||||
|   dismissTasks(task: PaperlessTask = undefined) { | ||||
|     this.tasksService.dismissTasks( | ||||
|       task ? new Set([task.id]) : this.selectedTasks | ||||
|     ) | ||||
|   } | ||||
|  | ||||
|   toggleSelected(task: PaperlessTask) { | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| 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 { environment } from 'src/environments/environment' | ||||
| @@ -43,7 +42,7 @@ export class TasksService { | ||||
|     this.loading = true | ||||
|  | ||||
|     this.http | ||||
|       .get<TasksAPIResponse>(`${this.baseUrl}consumption_tasks/`) | ||||
|       .get<TasksAPIResponse>(`${this.baseUrl}tasks/`) | ||||
|       .pipe(first()) | ||||
|       .subscribe((r) => { | ||||
|         this.total = r.total | ||||
| @@ -55,35 +54,14 @@ export class TasksService { | ||||
|       }) | ||||
|   } | ||||
|  | ||||
|   // 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<PaperlessSavedView[]> { | ||||
|   //   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<number>) { | ||||
|     this.http | ||||
|       .post(`${this.baseUrl}acknowledge_tasks/`, { | ||||
|         tasks: [...task_ids], | ||||
|       }) | ||||
|       .pipe(first()) | ||||
|       .subscribe((r) => { | ||||
|         this.reload() | ||||
|       }) | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -12,6 +12,7 @@ from .models import Correspondent | ||||
| from .models import Document | ||||
| from .models import DocumentType | ||||
| from .models import MatchingModel | ||||
| from .models import PaperlessTask | ||||
| from .models import SavedView | ||||
| from .models import SavedViewFilterRule | ||||
| from .models import StoragePath | ||||
| @@ -597,9 +598,35 @@ class UiSettingsViewSerializer(serializers.ModelSerializer): | ||||
|         return ui_settings | ||||
|  | ||||
|  | ||||
| class ConsupmtionTasksViewSerializer(serializers.Serializer): | ||||
| class TasksViewSerializer(serializers.Serializer): | ||||
|  | ||||
|     type = serializers.ChoiceField( | ||||
|         choices=["all", "incomplete", "complete", "failed"], | ||||
|         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 | ||||
|   | ||||
| @@ -69,9 +69,9 @@ from .models import SavedView | ||||
| from .models import StoragePath | ||||
| from .models import Tag | ||||
| from .parsers import get_parser_class_for_mime_type | ||||
| from .serialisers import AcknowledgeTasksViewSerializer | ||||
| from .serialisers import BulkDownloadSerializer | ||||
| from .serialisers import BulkEditSerializer | ||||
| from .serialisers import ConsupmtionTasksViewSerializer | ||||
| from .serialisers import CorrespondentSerializer | ||||
| from .serialisers import DocumentListSerializer | ||||
| from .serialisers import DocumentSerializer | ||||
| @@ -81,6 +81,7 @@ from .serialisers import SavedViewSerializer | ||||
| from .serialisers import StoragePathSerializer | ||||
| from .serialisers import TagSerializer | ||||
| from .serialisers import TagSerializerVersion1 | ||||
| from .serialisers import TasksViewSerializer | ||||
| from .serialisers import UiSettingsViewSerializer | ||||
|  | ||||
| logger = logging.getLogger("paperless.api") | ||||
| @@ -799,37 +800,37 @@ class UiSettingsView(GenericAPIView): | ||||
|         ) | ||||
|  | ||||
|  | ||||
| class ConsupmtionTasksView(GenericAPIView): | ||||
| class TasksView(GenericAPIView): | ||||
|  | ||||
|     permission_classes = (IsAuthenticated,) | ||||
|     serializer_class = ConsupmtionTasksViewSerializer | ||||
|     serializer_class = TasksViewSerializer | ||||
|  | ||||
|     def get(self, request, format=None): | ||||
|         serializer = self.get_serializer(data=request.data) | ||||
|         serializer.is_valid(raise_exception=True) | ||||
|  | ||||
|         consumption_tasks = ( | ||||
|         tasks = ( | ||||
|             PaperlessTask.objects.filter( | ||||
|                 acknowledged=False, | ||||
|             ) | ||||
|             .order_by("attempted_task__started") | ||||
|             .reverse() | ||||
|         ) | ||||
|         incomplete_tasks = consumption_tasks.filter(task=None).values( | ||||
|         incomplete_tasks = tasks.filter(attempted_task=None).values( | ||||
|             "id", | ||||
|             "task_id", | ||||
|             "name", | ||||
|             "created", | ||||
|             "acknowledged", | ||||
|         ) | ||||
|         failed_tasks = consumption_tasks.filter(attempted_task__success=0).values( | ||||
|         failed_tasks = tasks.filter(attempted_task__success=0).values( | ||||
|             "id", | ||||
|             "task_id", | ||||
|             "name", | ||||
|             "created", | ||||
|             "acknowledged", | ||||
|         ) | ||||
|         completed_tasks = consumption_tasks.filter(attempted_task__success=1).values( | ||||
|         completed_tasks = tasks.filter(attempted_task__success=1).values( | ||||
|             "id", | ||||
|             "task_id", | ||||
|             "name", | ||||
| @@ -838,9 +839,31 @@ class ConsupmtionTasksView(GenericAPIView): | ||||
|         ) | ||||
|         return Response( | ||||
|             { | ||||
|                 "total": consumption_tasks.count(), | ||||
|                 "total": tasks.count(), | ||||
|                 "incomplete": incomplete_tasks, | ||||
|                 "failed": failed_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)) | ||||
|   | ||||
| @@ -7,9 +7,9 @@ from django.urls import re_path | ||||
| from django.utils.translation import gettext_lazy as _ | ||||
| from django.views.decorators.csrf import csrf_exempt | ||||
| from django.views.generic import RedirectView | ||||
| from documents.views import AcknowledgeTasksView | ||||
| from documents.views import BulkDownloadView | ||||
| from documents.views import BulkEditView | ||||
| from documents.views import ConsupmtionTasksView | ||||
| from documents.views import CorrespondentViewSet | ||||
| from documents.views import DocumentTypeViewSet | ||||
| from documents.views import IndexView | ||||
| @@ -22,6 +22,7 @@ from documents.views import SelectionDataView | ||||
| from documents.views import StatisticsView | ||||
| from documents.views import StoragePathViewSet | ||||
| from documents.views import TagViewSet | ||||
| from documents.views import TasksView | ||||
| from documents.views import UiSettingsView | ||||
| from documents.views import UnifiedSearchViewSet | ||||
| from paperless.consumers import StatusConsumer | ||||
| @@ -88,9 +89,14 @@ urlpatterns = [ | ||||
|                     name="ui_settings", | ||||
|                 ), | ||||
|                 re_path( | ||||
|                     r"^consumption_tasks/", | ||||
|                     ConsupmtionTasksView.as_view(), | ||||
|                     name="consumption_tasks", | ||||
|                     r"^tasks/", | ||||
|                     TasksView.as_view(), | ||||
|                     name="tasks", | ||||
|                 ), | ||||
|                 re_path( | ||||
|                     r"^acknowledge_tasks/", | ||||
|                     AcknowledgeTasksView.as_view(), | ||||
|                     name="acknowledge_tasks", | ||||
|                 ), | ||||
|                 path("token/", views.obtain_auth_token), | ||||
|             ] | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Michael Shamoon
					Michael Shamoon