Skip to content

Commit

Permalink
Feat: Add logic to handle updates for repeated tasks in TaskDetail view
Browse files Browse the repository at this point in the history
  • Loading branch information
trisDeveloper committed Oct 28, 2024
1 parent 456f748 commit 40da348
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 61 deletions.
107 changes: 90 additions & 17 deletions backend/focusty/focusty_app/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@
from rest_framework import status
from rest_framework.decorators import api_view
import json
from django.db.models import Count
from django.db.models import Sum
from django.db.models import Count, Sum
from .task_repeat import repeat_task


Expand Down Expand Up @@ -61,21 +60,95 @@ def perform_create(self, serializer):
class TaskDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Task.objects.all()
serializer_class = TaskSerializer
"""def update(self, request, *args, **kwargs):
instance = self.get_object()
repeat_id = instance.repeatId
this_or_all = request.data.get("thisOrAll", "this")
if this_or_all == "this":
return super().update(request, *args, **kwargs)
elif this_or_all == "all" and repeat_id:
# Update all tasks with the same repeatId
tasks = Task.objects.filter(repeatId=repeat_id)
for task in tasks:
for key, value in request.data.items():
setattr(task, key, value)
task.save()
return Response({"status": "updated all tasks"}, status=status.HTTP_200_OK)"""

def perform_update(self, serializer):
task = self.get_object()
repeat_id = task.repeatId
update_data = serializer.validated_data
update_scope = self.request.data.get("thisOrAll", "this") # "all" or "this"
repeat_params = update_data.get("repeatParameters", None)

# If updating a repeat series
if repeat_id:
if update_scope == "all":
# Removing repeat settings if `repeatParameters` is None
if repeat_params is None:
task.repeatId = None
task.repeatParameters = None
task.save()
Task.objects.filter(repeatId=repeat_id).delete()

else:
# Update all tasks in the series with new repeat parameters
repeat_start_date = (
Task.objects.filter(repeatId=repeat_id).earliest("date").date
)
Task.objects.filter(repeatId=repeat_id).delete()
new_dates = repeat_task(repeat_params, repeat_start_date)

# Recreate tasks with updated repeat parameters
for date in new_dates:
new_task_data = {
**update_data,
"user": task.user_id,
"date": date.date(),
"repeatId": repeat_id,
}
serializer_class = self.get_serializer(data=new_task_data)
serializer_class.is_valid(raise_exception=True)
serializer_class.save()
else:
# Update only the selected task
if repeat_params is not None and repeat_params != task.repeatParameters:
# New repeat series with updated repeatParameters for this task only
new_repeat_id = str(uuid.uuid4())
start_date = task.date
Task.objects.filter(id=task.id).delete()
# Generate repeated instances
new_dates = repeat_task(repeat_params, start_date)
for date in new_dates:
new_task_data = {
**update_data,
"user": task.user_id,
"date": date.date(),
"repeatId": new_repeat_id,
}
serializer_class = self.get_serializer(data=new_task_data)
serializer_class.is_valid(raise_exception=True)
serializer_class.save()
else:
for field, value in update_data.items():
setattr(task, field, value)

# Set repeat fields to None
task.repeatId = None
task.repeatParameters = None

# Save the task with all changes
task.save()

# If the task is not currently repeated but needs to be set as repeated
elif repeat_params:
# Assign a new repeatId for the new repeat series
new_repeat_id = str(uuid.uuid4())
start_date = task.date
Task.objects.filter(id=task.id).delete()
# Generate repeated instances
new_dates = repeat_task(repeat_params, start_date)
for date in new_dates:
new_task_data = {
**update_data,
"user": task.user_id,
"date": date.date(),
"repeatId": new_repeat_id,
}
serializer_class = self.get_serializer(data=new_task_data)
serializer_class.is_valid(raise_exception=True)
serializer_class.save()

else:
# If no repeat action is needed, update the task as usual
serializer.save()


@api_view(["GET"])
Expand Down
62 changes: 20 additions & 42 deletions frontend/src/utils/save-task-logic.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,65 +38,43 @@ export const saveTaskLogic = async (
// don't repeat task or remove repeating a task
if (thisOrAll == 'all') {
if (store.selectedTask.repeatParameters == null) {
const updatedTasks = localTasks.filter(
(task) =>
task.repeatId !== store.selectedTask.repeatId || task.id === store.selectedTask.id
)
store.selectedTask.repeatId = null
store.selectedTask.repeatParameters = null

const index = updatedTasks.findIndex((task) => task.id === store.selectedTask.id)
const index = localTasks.findIndex((task) => task.id === store.selectedTask.id)
if (index !== -1) {
updatedTasks[index] = { ...store.selectedTask }
localTasks[index] = { ...store.selectedTask }
}
const updatedTasks = localTasks.filter(
(task) => task.repeatId == store.selectedTask.repeatId
)
localStorage.setItem('tasks', JSON.stringify(updatedTasks))
}
// repeat task
else {
// change repeat parameters for all repeating tasks

let index = localTasks.findIndex((t) => t.repeatId === store.selectedTask.repeatId)
if (
JSON.stringify(store.selectedTask.repeatParameters) !==
JSON.stringify(localTasks[index].repeatParameters)
) {
const updatedTasks = localTasks.filter(
(t) => t.repeatId !== String(Number(store.selectedTask.repeatId))
)
repeatTask(
store,
store.selectedTask.repeatParameters,
localTasks[index].date,
updatedTasks
)
} else {
// Update the existing tasks with the same repeatId
const updatedTasks = localTasks.map((task) => {
if (task.repeatId === store.selectedTask.repeatId) {
task.title = store.selectedTask.title
task.time = store.selectedTask.time
task.description = store.selectedTask.description
}
return task
})

// Save the updated tasks to localStorage
localStorage.setItem('tasks', JSON.stringify(updatedTasks))
}
const updatedTasks = localTasks.filter(
(t) => t.repeatId !== String(Number(store.selectedTask.repeatId))
)
repeatTask(
store,
store.selectedTask.repeatParameters,
localTasks[index].date,
updatedTasks
)
// Save the updated tasks to localStorage
localStorage.setItem('tasks', JSON.stringify(updatedTasks))
}

// change repeat parameters for this task only
} else {
let index = localTasks.findIndex((t) => t.id === store.selectedTask.id)
if (store.selectedTask.repeatParameters == null) {
store.selectedTask.repeatId = null
store.selectedTask.repeatParameters = null
localTasks[index] = store.selectedTask
// Save the updated task to localStorage
localStorage.setItem('tasks', JSON.stringify(localTasks))
localStorage.setItem('nextTaskId', nextTaskId++)
} else if (
if (
store.selectedTask.repeatParameters !== null &&
JSON.stringify(store.selectedTask.repeatParameters) !==
JSON.stringify(localTasks[index].repeatParameters)
JSON.stringify(localTasks[index].repeatParameters)
) {
const updatedTasks = localTasks.filter(
(t) => t.id !== String(Number(store.selectedTask.id))
Expand Down
7 changes: 5 additions & 2 deletions frontend/src/views/calendar-view.vue
Original file line number Diff line number Diff line change
Expand Up @@ -213,11 +213,14 @@ const handleSaveThisOrAll = () => {
(t) => t.repeatId === store.selectedTask.repeatId
)
const localTasks = JSON.parse(localStorage.getItem('tasks')) || []
let index = localTasks.findIndex((t) => t.id === store.selectedTask.id)
let index =
localTasks.length !== 0
? localTasks[localTasks.findIndex((t) => t.id === store.selectedTask.id)]
: tasks.value[tasks.value.findIndex((task) => task.id === store.selectedTask.id)]
if (
tasksWithSameRepeatId.length > 1 &&
store.selectedTask.repeatId &&
JSON.stringify(localTasks[index]) !== JSON.stringify(store.selectedTask)
JSON.stringify(index) !== JSON.stringify(store.selectedTask)
) {
// open card for choosing updating this task or all tasks
openThisOrAll('save')
Expand Down

0 comments on commit 40da348

Please sign in to comment.