Add kanban position manage api

This commit is contained in:
sosokker 2023-11-21 02:38:57 +07:00
parent 72934d9175
commit 6873d0a174
2 changed files with 131 additions and 3 deletions

View File

@ -1,5 +1,6 @@
from rest_framework import serializers from rest_framework import serializers
from ..models import Todo, RecurrenceTask, Habit from boards.models import ListBoard
from tasks.models import Todo, RecurrenceTask, Habit
class TaskSerializer(serializers.ModelSerializer): class TaskSerializer(serializers.ModelSerializer):
class Meta: class Meta:
@ -14,7 +15,43 @@ class TaskCreateSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Todo model = Todo
exclude = ('tags',) exclude = ('tags',)
class ChangeTaskOrderSerializer(serializers.Serializer):
list_board_id = serializers.IntegerField(
help_text='ID of the ListBoard for which the task order should be updated.'
)
todo_order = serializers.ListField(
child=serializers.IntegerField(),
required=False,
help_text='New order of Todo IDs in the ListBoard.'
)
def validate(self, data):
list_board_id = data.get('list_board_id')
todo_order = data.get('todo_order', [])
if not ListBoard.objects.filter(id=list_board_id).exists():
raise serializers.ValidationError('ListBoard does not exist.')
return data
class ChangeTaskListBoardSerializer(serializers.Serializer):
todo_id = serializers.IntegerField()
new_list_board_id = serializers.IntegerField()
new_index = serializers.IntegerField(required=False)
def validate(self, data):
todo_id = data.get('todo_id')
new_list_board_id = data.get('new_list_board_id')
new_index = data.get('new_index')
if not Todo.objects.filter(id=todo_id, user=self.context['request'].user).exists():
raise serializers.ValidationError('Todo does not exist for the authenticated user.')
if not ListBoard.objects.filter(id=new_list_board_id).exists():
raise serializers.ValidationError('ListBoard does not exist.')
return data
class RecurrenceTaskSerializer(serializers.ModelSerializer): class RecurrenceTaskSerializer(serializers.ModelSerializer):
class Meta: class Meta:

View File

@ -1,5 +1,12 @@
from rest_framework import viewsets from django.shortcuts import get_object_or_404
from django.db import IntegrityError
from rest_framework import viewsets, status, serializers
from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticated from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from .serializers import ChangeTaskListBoardSerializer, ChangeTaskOrderSerializer
from boards.models import ListBoard, KanbanTaskOrder
from tasks.models import Todo, RecurrenceTask, Habit from tasks.models import Todo, RecurrenceTask, Habit
from tasks.tasks.serializers import (TaskCreateSerializer, from tasks.tasks.serializers import (TaskCreateSerializer,
TaskSerializer, TaskSerializer,
@ -23,6 +30,90 @@ class TodoViewSet(viewsets.ModelViewSet):
if self.action == 'create': if self.action == 'create':
return TaskCreateSerializer return TaskCreateSerializer
return TaskSerializer return TaskSerializer
def create(self, request, *args, **kwargs):
try:
new_task_data = request.data
new_task_data['user'] = self.request.user
serializer = self.get_serializer(data=new_task_data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
except IntegrityError as e:
return Response({'error': 'IntegrityError - Duplicate Entry'}, status=status.HTTP_400_BAD_REQUEST)
except Exception as e:
return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
@action(detail=False, methods=['put'])
def change_task_order(self, request):
try:
serializer = ChangeTaskOrderSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
list_board_id = serializer.validated_data['list_board_id']
new_order = serializer.validated_data.get('todo_order', [])
list_board = get_object_or_404(ListBoard, id=list_board_id)
kanban_order, created = KanbanTaskOrder.objects.get_or_create(list_board=list_board)
kanban_order.todo_order = new_order
kanban_order.save()
return Response({'message': 'Task order updated successfully'})
except serializers.ValidationError as e:
return Response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST)
except Exception as e:
return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
@action(detail=False, methods=['put'])
def change_task_list_board(self, request):
try:
serializer = ChangeTaskListBoardSerializer(data=request.data, context={'request': request})
serializer.is_valid(raise_exception=True)
todo_id = serializer.validated_data['todo_id']
new_list_board_id = serializer.validated_data['new_list_board_id']
new_index = serializer.validated_data.get('new_index')
todo_id = request.data.get('todo_id')
new_list_board_id = request.data.get('new_list_board_id')
todo = get_object_or_404(Todo, id=todo_id, user=self.request.user)
old_list_board = todo.list_board
# Remove todoId from todo_order of the old list board
old_kanban_order, _ = KanbanTaskOrder.objects.get_or_create(list_board=old_list_board)
old_kanban_order.todo_order = [t_id for t_id in old_kanban_order.todo_order if t_id != todo.id]
old_kanban_order.save()
# Get the index to insert the todo in the new list board's todo_order
new_list_board = get_object_or_404(ListBoard, id=new_list_board_id)
new_kanban_order, _ = KanbanTaskOrder.objects.get_or_create(list_board=new_list_board)
# Index where todo need to insert (start from 0)
new_index = request.data.get('new_index', None)
if new_index is not None and 0 <= new_index <= len(new_kanban_order.todo_order):
new_kanban_order.todo_order.insert(new_index, todo.id)
else:
new_kanban_order.todo_order.append(todo.id)
new_kanban_order.save()
todo.list_board = new_list_board
todo.save()
return Response({'message': 'ListBoard updated successfully'})
except serializers.ValidationError as e:
return Response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST)
except Exception as e:
return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
class RecurrenceTaskViewSet(viewsets.ModelViewSet): class RecurrenceTaskViewSet(viewsets.ModelViewSet):