diff --git a/src/components/Home/HomePage.jsx b/src/components/Home/HomePage.jsx index 92977ff..cce8f21 100644 --- a/src/components/Home/HomePage.jsx +++ b/src/components/Home/HomePage.jsx @@ -48,6 +48,7 @@ const Home = () => { if (projectModalType == "add") dispatch(ADD_PROJECT(project)); else dispatch(UPDATE_PROJECT(project)); setProjectModalType(null); + setProjectModalInitialData(null); }; const handleEditProjectClick = (projectId) => { diff --git a/src/components/ProjectViewer/ProjectViewer.jsx b/src/components/ProjectViewer/ProjectViewer.jsx index cccdfb3..e89aa9d 100644 --- a/src/components/ProjectViewer/ProjectViewer.jsx +++ b/src/components/ProjectViewer/ProjectViewer.jsx @@ -12,8 +12,9 @@ import { Add as AddIcon } from "@mui/icons-material"; import { CLOSE_TASK, ADD_TASK, - REOPEN_TASK, + UPDATE_TASK, DELETE_TASK, + REOPEN_TASK, } from "@/state/slices/tasksSlice"; const ProjectViewer = () => { @@ -36,6 +37,10 @@ const ProjectViewer = () => { ); const lastClosedTaskId = useSelector((state) => state.tasks.lastClosedTaskId); + const findTaskById = (taskId) => { + return tasks.find((task) => task.id == taskId); + }; + useEffect(() => { if (lastClosedTaskId != null) { setIsSnackBarOpen(true); @@ -50,9 +55,14 @@ const ProjectViewer = () => { dispatch(CLOSE_TASK(taskId)); }; - const handleTaskClick = (taskId) => {}; + const handleTaskClick = (taskId) => { + // + }; - const handleTaskEditClick = (taskId) => {}; + const handleTaskEditClick = (taskId) => { + setTaskEditorType("edit"); + setTaskEditorInitialData(findTaskById(taskId)); + }; const handleTaskOptionsClick = (event, taskId) => { setTaskOptionsMenuAnchorEl(event.currentTarget); @@ -71,7 +81,7 @@ const ProjectViewer = () => { setTaskOptionsMenuAnchorEl(null); }; - const handleTaskMenuEditClick = (taskId) => { + const handleTaskMenuClipboardClick = (taskId) => { // }; @@ -92,8 +102,9 @@ const ProjectViewer = () => { task.project_id = selectedProjectId; dispatch(ADD_TASK(task)); } - //else dispatch(UPDATE_TASK(task)); + else dispatch(UPDATE_TASK(task)); setTaskEditorType(null); + setTaskEditorInitialData(findTaskById(null)); }; if (!selectedProject) return null; @@ -108,19 +119,31 @@ const ProjectViewer = () => { {tasks .sort((a, b) => a.order > b.order) - .map((task) => ( - - ))} + .map((task) => { + return taskEditorType === "edit" && + task.id === taskEditorInitialData?.id ? ( + + ) : ( + + ); + })} - {taskEditorType ? ( + {taskEditorType === "add" ? ( { anchorEl={taskOptionsMenuAnchorEl} taskId={taskOptionsMenuTaskId} onClose={handleTaskMenuClose} - onEditClick={handleTaskMenuEditClick} onDeleteClick={handleTaskMenuDeleteClick} + onCopyToClipboardClick={handleTaskMenuClipboardClick} /> {!selectedProject && ( diff --git a/src/components/TaskEditor/TaskEditor.jsx b/src/components/TaskEditor/TaskEditor.jsx index 487a840..f31bb29 100644 --- a/src/components/TaskEditor/TaskEditor.jsx +++ b/src/components/TaskEditor/TaskEditor.jsx @@ -38,6 +38,7 @@ const TaskEditor = ({ border: "1px solid LightGray", borderRadius: 3, p: "10px", + mt: 1, }} > { - const currentIndex = checked.indexOf(taskId); + const handleCheckToggle = () => { + const currentIndex = checked.indexOf(task.id); const newChecked = [...checked]; if (currentIndex === -1) { - newChecked.push(taskId); + newChecked.push(task.id); } else { newChecked.splice(currentIndex, 1); } setChecked(newChecked); - onCheckToggle(taskId); + onCheckToggle(task.id); }; - const handleClick = (taskId) => { - onClick(taskId); + const handleClick = () => { + onClick(task.id); }; - const handleEditClick = (taskId) => { - onEditClick(taskId); + const handleEditClick = () => { + onEditClick(task.id); }; - const handleOptionsClick = (event, taskId) => { + const handleOptionsClick = (event) => { event.stopPropagation(); - onOptionsClick(event, taskId); + onOptionsClick(event, task.id); }; return ( @@ -66,22 +66,23 @@ const TaskListItem = ({ }), }} > - - - - handleOptionsClick(event, task.id)} - > - - + + + + + + + + + + } > handleCheckToggle(task.id)} + onClick={handleCheckToggle} disableRipple /> - + diff --git a/src/components/TaskOptionsMenu/TaskOptionsMenu.jsx b/src/components/TaskOptionsMenu/TaskOptionsMenu.jsx index 07b0773..6b63ea3 100644 --- a/src/components/TaskOptionsMenu/TaskOptionsMenu.jsx +++ b/src/components/TaskOptionsMenu/TaskOptionsMenu.jsx @@ -10,12 +10,12 @@ const TaskOptionsMenu = ({ anchorEl, taskId, onClose, - onEditClick, onDeleteClick, + onCopyToClipboardClick, }) => { - const handleEditClick = (taskId) => { + const handleCopyToClipboardClick = (taskId) => { onClose(); - onEditClick(taskId); + onCopyToClipboardClick(taskId); }; const handleDeleteClick = (taskId) => { @@ -30,7 +30,7 @@ const TaskOptionsMenu = ({ onClose={onClose} sx={{ color: "gray" }} > - handleEditClick(taskId)}> + handleCopyToClipboardClick(taskId)}> diff --git a/src/components/TopBar/TopBar.jsx b/src/components/TopBar/TopBar.jsx index 19f98b4..5e540ea 100644 --- a/src/components/TopBar/TopBar.jsx +++ b/src/components/TopBar/TopBar.jsx @@ -141,7 +141,7 @@ const TopBar = () => { edge="start" color="inherit" sx={{ mr: 1 }} - onClick={() => navigate("/app")} + onClick={() => navigate("/app/projects")} > diff --git a/src/state/rootSaga.js b/src/state/rootSaga.js index 438c3af..43c8e8e 100644 --- a/src/state/rootSaga.js +++ b/src/state/rootSaga.js @@ -27,11 +27,13 @@ import { import { FETCH_TASKS, ADD_TASK, + UPDATE_TASK, DELETE_TASK, CLOSE_TASK, REOPEN_TASK, onRequestTasks, onAddTask, + onUpdateTask, onDeleteTask, onCloseTasks, onReopenTask, @@ -50,9 +52,10 @@ export default function* rootSaga() { takeLatest(UPDATE_PROJECT.type, onUpdateProject), takeLatest(DELETE_PROJECT.type, onDeleteProject), takeLatest(DELETE_PROJECT_SUCCESS.type, onDeleteProjectSuccess), - + takeLatest(FETCH_TASKS.type, onRequestTasks), takeLatest(ADD_TASK.type, onAddTask), + takeLatest(UPDATE_TASK.type, onUpdateTask), takeLatest(DELETE_TASK.type, onDeleteTask), takeEvery(CLOSE_TASK.type, onCloseTasks), takeLatest(REOPEN_TASK.type, onReopenTask), diff --git a/src/state/slices/tasksSlice.js b/src/state/slices/tasksSlice.js index 6e1954b..6ac9a7d 100644 --- a/src/state/slices/tasksSlice.js +++ b/src/state/slices/tasksSlice.js @@ -21,6 +21,16 @@ export function* onAddTask(action) { } } +export function* onUpdateTask(action) { + const task = action.payload; + try { + yield call(() => getApi().updateTask(task.id, task)); + yield put(UPDATE_TASK_SUCCESS(task)); + } catch (error) { + yield put(UPDATE_TASK_ERROR()); + } +} + export function* onDeleteTask(action) { const taskId = action.payload; try { @@ -88,6 +98,22 @@ export const tasksSlice = createSlice({ state.loading = false; state.error = true; }, + UPDATE_TASK: (state, action) => { + state.loading = true; + }, + UPDATE_TASK_SUCCESS: (state, action) => { + const updatedTask = action.payload; + const newStateData = state.data.filter( + (task) => task.id != updatedTask.id + ); + newStateData.push(updatedTask); + state.loading = false; + state.data = newStateData; + }, + UPDATE_TASK_ERROR: (state, action) => { + state.loading = false; + state.error = true; + }, DELETE_TASK: (state, action) => { state.loading = true; }, @@ -139,6 +165,9 @@ export const { ADD_TASK, ADD_TASK_SUCCESS, ADD_TASK_ERROR, + UPDATE_TASK, + UPDATE_TASK_SUCCESS, + UPDATE_TASK_ERROR, DELETE_TASK, DELETE_TASK_SUCCESS, DELETE_TASK_ERROR,