From fa5fd80769044f633609ff843ebe8ccfeca92bf9 Mon Sep 17 00:00:00 2001 From: Minh Duong Date: Thu, 30 Nov 2023 18:05:14 -0600 Subject: [PATCH] Finish tool handling (#20) --- client/src/components/Board/index.tsx | 108 ++++++++++++++++---------- client/src/components/Task/index.tsx | 53 +++++++------ 2 files changed, 95 insertions(+), 66 deletions(-) diff --git a/client/src/components/Board/index.tsx b/client/src/components/Board/index.tsx index 1dca116..d38cced 100644 --- a/client/src/components/Board/index.tsx +++ b/client/src/components/Board/index.tsx @@ -114,28 +114,25 @@ export default function Board() { switch (t) { case Tool.Pointer: console.log('Selected pointer tool'); - handleSetPointerTool(); break; case Tool.Move: console.log('Selected move tool'); - handleSetMoveTool(); + resetPointerToolState(); break; case Tool.Task: console.log('Selected task tool'); - handleAddTask(); + resetPointerToolState(); + // handleAddTask(); break; case Tool.Arrow: console.log('Selected arrow tool'); - setArrowToolState({ - ...arrowToolState, - _firstId: -1 - }); + resetPointerToolState(); + resetArrowToolState(); break; }; }; const handleTaskClick = (id: number) => { - console.log(`Clicked task ${id}`); switch (selectedTool) { case Tool.Pointer: const selected_task = tasks.find((t) => t.id == id); @@ -152,7 +149,7 @@ export default function Board() { break; case Tool.Arrow: if (id == arrowToolState._firstId) { - break; + resetArrowToolState(); } else if (arrowToolState._firstId == -1) { setArrowToolState({ ...arrowToolState, @@ -160,37 +157,45 @@ export default function Board() { }); } else { addArrow(arrowToolState._firstId, id); - setArrowToolState({ - ...arrowToolState, - _firstId: -1 - }); - // TODO: Support switching back to previous tool - // setSelectedTool(Tool.Pointer); + resetArrowToolState(); } break; }; }; - const handleSetPointerTool = () => { - // TODO: Set CSS cursor to 'default' - }; - - const handleSetMoveTool = () => { - // TODO: Set CSS cursor to 'move' - }; - - const handleAddTask = () => { - var newTasks = tasks.slice(); - newTasks.push({ - id: tasks.length + 1, - title: 'Untitled', + const handleAddNewTask = (e: React.MouseEvent) => { + // TODO: Technically, we should do more calculations to account for a panned canvas + const { clientX, clientY } = e.nativeEvent; + const newTask: Task = { + id: tasks.length + 1, // TODO: Better way of assigning task IDs + title: "Untitled task", + description: "", width: 200, height: 100, - posX: 50, - posY: 150, + posX: clientX, + posY: clientY, color: "#faedcb" + }; + setTaskList([...tasks, newTask]); + setSelectedTool(Tool.Pointer); + setPointerToolState({ + ...pointerToolState, + _selected_task: newTask + }); + } + + const resetPointerToolState = () => { + setPointerToolState({ + ...pointerToolState, + _selected_task: null + }); + }; + + const resetArrowToolState = () => { + setArrowToolState({ + ...arrowToolState, + _firstId: -1 }); - setTaskList(newTasks); }; const updateTask = (task: Task) => { @@ -225,18 +230,39 @@ export default function Board() {
- {tasks.map((task, idx) => ( - // TODO: Conditional styles based on selected tool - - ))} + {tasks.map((task, idx) => { + let className = ''; + if (pointerToolState._selected_task?.id == task.id) { + className += 'ring ring-offset-2 ring-primary '; + } else if (selectedTool == Tool.Pointer) { + className += 'hover:cursor-pointer hover:ring hover:ring-secondary '; + } + if (arrowToolState._firstId == task.id) { + className += 'ring ring-offset-2 ring-secondary '; + } + switch (selectedTool) { + case Tool.Move: + className += 'hover:cursor-move '; + break; + case Tool.Arrow: + className += 'hover:cursor-alias '; + break; + }; + return ( + + ); + })} {arrows.map((arrow, idx) => ( void; handleTaskUpdate: (task: Task) => void; }; export default function Task(props: Props) { - const { task, handleTaskClick, handleTaskUpdate } = props; + const { task, className, isMoveable, handleTaskClick, handleTaskUpdate } = props; const target_ref = useRef(null); const updateXarrow = useXarrow(); // Event handlers @@ -55,10 +57,10 @@ export default function Task(props: Props) { }; return ( - +
handleTaskClick(task.id)} >

{useDeferredValue(task.title)}

- + {isMoveable ? ( + + ) : null}
); }