This commit is contained in:
@@ -1,11 +1,15 @@
|
||||
import { useEffect, useMemo, useState, type FC } from "react";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { toast } from "react-toastify";
|
||||
import PageLoading from "../../components/PageLoading";
|
||||
import { ErrorType } from "../../helpers/types";
|
||||
import AddNewColumn from "./components/AddNewColumn";
|
||||
import Column from "./components/Column";
|
||||
import HeaderWorkspace from "./components/HeaderWorkspace";
|
||||
import TaskDetailModal from "./components/task-detail/TaskDetailModal";
|
||||
import { useGetProject } from "./project/hooks/useProjectData";
|
||||
import { useUpdateTaskPhase } from "./task-phase/hooks/useTaskPhaseData";
|
||||
import { useChangeTaskPhase } from "./task/hooks/useTaskData";
|
||||
import { mapTaskItemToTask } from "./task/utils/mapTaskItemToTask";
|
||||
import type { TaskItemType } from "./task/types/TaskTypes";
|
||||
import type { TaskPhaseItemType } from "./task-phase/types/TaskPhaseTypes";
|
||||
@@ -16,6 +20,8 @@ import { reorderTasks } from "./utils/reorderTasks";
|
||||
const Workspace: FC = () => {
|
||||
const { slug: projectId = "" } = useParams<{ slug: string }>();
|
||||
const { data: project, isPending } = useGetProject(projectId);
|
||||
const changeTaskPhase = useChangeTaskPhase();
|
||||
const updateTaskPhase = useUpdateTaskPhase();
|
||||
const [columns, setColumns] = useState<ColumnType[]>([]);
|
||||
const [tasks, setTasks] = useState<Task[]>([]);
|
||||
const [draggedTaskId, setDraggedTaskId] = useState<string | null>(null);
|
||||
@@ -66,8 +72,48 @@ const Workspace: FC = () => {
|
||||
|
||||
const handleDrop = (columnId: string, index: number) => {
|
||||
if (!draggedTaskId) return;
|
||||
setTasks((prev) => reorderTasks(prev, draggedTaskId, columnId, index));
|
||||
|
||||
const draggedTask = tasks.find((task) => task.id === draggedTaskId);
|
||||
if (!draggedTask) return;
|
||||
|
||||
const previousTasks = tasks;
|
||||
const columnChanged = draggedTask.columnId !== columnId;
|
||||
const nextTasks = reorderTasks(tasks, draggedTaskId, columnId, index);
|
||||
const movedTask = nextTasks.find((task) => task.id === draggedTaskId) ?? null;
|
||||
|
||||
setTasks(nextTasks);
|
||||
setDraggedTaskId(null);
|
||||
|
||||
if (selectedTask?.id === draggedTaskId && movedTask) {
|
||||
setSelectedTask(movedTask);
|
||||
}
|
||||
|
||||
if (!columnChanged) return;
|
||||
|
||||
changeTaskPhase.mutate(
|
||||
{ id: draggedTaskId, params: { taskPhaseId: columnId }, projectId },
|
||||
{
|
||||
onError: (error: ErrorType) => {
|
||||
setTasks(previousTasks);
|
||||
if (selectedTask?.id === draggedTaskId) {
|
||||
setSelectedTask(draggedTask);
|
||||
}
|
||||
toast.error(error.response?.data?.error.message[0]);
|
||||
},
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
const handleTaskPhaseChanged = (taskId: string, taskPhaseId: string) => {
|
||||
setTasks((prev) => {
|
||||
const task = prev.find((item) => item.id === taskId);
|
||||
if (!task || task.columnId === taskPhaseId) return prev;
|
||||
|
||||
const destinationIndex = prev.filter((item) => item.columnId === taskPhaseId).length;
|
||||
return reorderTasks(prev, taskId, taskPhaseId, destinationIndex);
|
||||
});
|
||||
|
||||
setSelectedTask((prev) => (prev?.id === taskId ? { ...prev, columnId: taskPhaseId } : prev));
|
||||
};
|
||||
|
||||
const handleColumnDragStart = (columnId: string) => {
|
||||
@@ -80,20 +126,37 @@ const Workspace: FC = () => {
|
||||
|
||||
const handleColumnDrop = (overColumnId: string) => {
|
||||
if (!draggedColumnId || draggedColumnId === overColumnId) return;
|
||||
setColumns((prev) => reorderColumns(prev, draggedColumnId, overColumnId));
|
||||
|
||||
const previousColumns = columns;
|
||||
const nextColumns = reorderColumns(columns, draggedColumnId, overColumnId);
|
||||
const movedColumn = nextColumns.find((column) => column.id === draggedColumnId);
|
||||
|
||||
setColumns(nextColumns);
|
||||
setDraggedColumnId(null);
|
||||
|
||||
if (!movedColumn?.order) return;
|
||||
|
||||
updateTaskPhase.mutate(
|
||||
{ id: draggedColumnId, params: { order: movedColumn.order }, projectId },
|
||||
{
|
||||
onError: (error: ErrorType) => {
|
||||
setColumns(previousColumns);
|
||||
toast.error(error.response?.data?.error.message[0]);
|
||||
},
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
const nextColumnOrder = columns.length
|
||||
? Math.max(...columns.map((column) => column.order ?? 0)) + 1
|
||||
: 1;
|
||||
|
||||
const handleColumnCreated = (phase: TaskPhaseItemType) => {
|
||||
setColumns((prev) => [
|
||||
...prev,
|
||||
{
|
||||
id: phase.id,
|
||||
title: phase.name,
|
||||
color: phase.color,
|
||||
order: phase.order,
|
||||
},
|
||||
]);
|
||||
setColumns((prev) =>
|
||||
[...prev, { id: phase.id, title: phase.name, color: phase.color, order: phase.order }].sort(
|
||||
(a, b) => (a.order ?? 0) - (b.order ?? 0),
|
||||
),
|
||||
);
|
||||
};
|
||||
|
||||
const handleColumnDeleted = (columnId: string) => {
|
||||
@@ -111,8 +174,6 @@ const Workspace: FC = () => {
|
||||
]);
|
||||
};
|
||||
|
||||
const selectedTaskColumn = selectedTask ? columns.find((column) => column.id === selectedTask.columnId) : null;
|
||||
|
||||
if (isPending) {
|
||||
return <PageLoading />;
|
||||
}
|
||||
@@ -144,7 +205,7 @@ const Workspace: FC = () => {
|
||||
|
||||
<AddNewColumn
|
||||
projectId={projectId}
|
||||
nextOrder={columns.length}
|
||||
nextOrder={nextColumnOrder}
|
||||
onColumnCreated={handleColumnCreated}
|
||||
/>
|
||||
</div>
|
||||
@@ -153,8 +214,10 @@ const Workspace: FC = () => {
|
||||
<TaskDetailModal
|
||||
open={selectedTask !== null}
|
||||
task={selectedTask}
|
||||
statusLabel={selectedTaskColumn?.title ?? ""}
|
||||
columns={columns}
|
||||
projectId={projectId}
|
||||
onClose={() => setSelectedTask(null)}
|
||||
onTaskPhaseChanged={handleTaskPhaseChanged}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user