fix: improve priority handling based on feedback

- Fix TaskEditModal falsy check for task_order === 0 (use nullish check)
- Remove local optimistic state from TaskCard (derive directly from task.task_order)
- TaskCard now relies on TanStack Query optimistic updates from useUpdateTask mutation

Priority changes now use proper optimistic update pattern:
- onMutate: cancels queries, snapshots data, updates cache immediately
- onError: rolls back cache, shows error toast
- onSettled: ensures consistency with backend

This eliminates the dual state management and ensures consistent behavior.
This commit is contained in:
leex279
2025-09-10 08:54:15 +02:00
parent 217b4402ec
commit 66b2e54ba5
3 changed files with 13 additions and 22 deletions

View File

@@ -1,10 +1,10 @@
import { Tag } from "lucide-react";
import type React from "react";
import { useCallback, useEffect, useState } from "react";
import { useCallback } from "react";
import { useDrag, useDrop } from "react-dnd";
import { useTaskActions } from "../hooks";
import type { Assignee, Task } from "../types";
import { getTaskPriorityFromTaskOrder, TASK_PRIORITY_OPTIONS } from "../types/priority";
import { getTaskPriorityFromTaskOrder } from "../types/priority";
import { getOrderColor, getOrderGlow, ItemTypes } from "../utils/task-styles";
import { TaskAssignee } from "./TaskAssignee";
import { TaskCardActions } from "./TaskCardActions";
@@ -35,16 +35,8 @@ export const TaskCard: React.FC<TaskCardProps> = ({
selectedTasks,
onTaskSelect,
}) => {
// Derive priority from task_order (backend field) instead of separate priority field
const [localPriority, setLocalPriority] = useState<Priority>(() =>
getTaskPriorityFromTaskOrder(task.task_order)
);
// Sync local priority when task_order changes
useEffect(() => {
const priorityFromTaskOrder = getTaskPriorityFromTaskOrder(task.task_order);
setLocalPriority(priorityFromTaskOrder);
}, [task.task_order]);
// Derive priority directly from task_order (backend field)
const currentPriority = getTaskPriorityFromTaskOrder(task.task_order);
// Use business logic hook
const { changeAssignee, changePriority, isUpdating } = useTaskActions(projectId);
@@ -68,10 +60,8 @@ export const TaskCard: React.FC<TaskCardProps> = ({
}, [onDelete, task]);
const handlePriorityChange = useCallback((priority: Priority) => {
// Update backend via task_order (conversion handled in hook)
// Update backend via task_order (optimistic updates handled in hook)
changePriority(task.id, priority);
// Also update local state for immediate UI feedback
setLocalPriority(priority);
}, [changePriority, task.id]);
const handleAssigneeChange = useCallback(
@@ -229,7 +219,7 @@ export const TaskCard: React.FC<TaskCardProps> = ({
<TaskAssignee assignee={task.assignee} onAssigneeChange={handleAssigneeChange} isLoading={isUpdating} />
{/* Priority display with backend sync */}
<TaskPriority priority={localPriority} onPriorityChange={handlePriorityChange} isLoading={isUpdating} />
<TaskPriority priority={currentPriority} onPriorityChange={handlePriorityChange} isLoading={isUpdating} />
</div>
</div>
</div>

View File

@@ -134,11 +134,12 @@ export const TaskEditModal = memo(
<FormField>
<Label>Priority</Label>
<Select
value={
localTask?.task_order
? getTaskPriorityFromTaskOrder(localTask.task_order)
: "medium"
}
value={(() => {
const order = localTask?.task_order;
return order !== undefined
? getTaskPriorityFromTaskOrder(order)
: "medium";
})()}
onValueChange={(value) => {
// Convert priority to task_order value
const priorityOption = TASK_PRIORITY_OPTIONS.find(

View File

@@ -22,7 +22,7 @@ export const useTaskActions = (projectId: string): UseTaskActionsReturn => {
[updateTaskMutation],
);
// Priority change handler - maps priority to task_order
// Priority change handler - maps priority to task_order with optimistic updates
const changePriority = useCallback(
(taskId: string, newPriority: TaskPriority) => {
// Convert priority to task_order value for backend