Skip to content

Commit

Permalink
feat: task reopen
Browse files Browse the repository at this point in the history
  • Loading branch information
roanrobersson committed May 4, 2022
1 parent 2ddf725 commit 55cb65e
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 25 deletions.
35 changes: 29 additions & 6 deletions src/components/ProjectViewer/ProjectViewer.jsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { useContext, useState } from "react";
import { useContext, useEffect, useState } from "react";
import { LeftMenuContext } from "@/providers/LeftMenuProvider";
import { useSelector, useDispatch } from "react-redux";
import { Main } from "./styles";
import { CLOSE_TASK } from "@/state/slices/tasksSlice";
import { CLOSE_TASK, REOPEN_TASK } from "@/state/slices/tasksSlice";
import TaskList from "@/components/TaskList";
import TaskListItem from "@/components/TaskListItem";
import TaskSnackBar from "@/components/TaskSnackBar";
import { Typography, Container } from "@mui/material";

const ProjectViewer = () => {
const { isOpen, setIsOpen } = useContext(LeftMenuContext);
const dispatch = useDispatch();
const [isSnackBarOpen, setIsSnackBarOpen] = useState(false);
const selectedProjectId = useSelector(
(state) => state.projects.selectedProjectId
);
Expand All @@ -19,6 +21,13 @@ const ProjectViewer = () => {
const tasks = useSelector((state) => state.tasks.data).filter(
(task) => task.projectId == selectedProjectId
);
const lastClosedTaskId = useSelector((state) => state.tasks.lastClosedTaskId);

useEffect(() => {
if (lastClosedTaskId != null) {
setIsSnackBarOpen(true);
}
}, [lastClosedTaskId]);

const normalizeProjectName = (projectName) => {
return projectName == "Inbox" ? "Entrada" : projectName;
Expand All @@ -34,6 +43,14 @@ const ProjectViewer = () => {

const handleTaskOptionsClick = (taskId) => {};

const handleSnackBarClose = () => {
setIsSnackBarOpen(false);
};

const handleSnackBarUndo = () => {
dispatch(REOPEN_TASK(lastClosedTaskId));
};

if (!selectedProject) return null;

return (
Expand All @@ -50,10 +67,10 @@ const ProjectViewer = () => {
<TaskListItem
key={task.id}
task={task}
onTaskCheckToggle={handleTaskCheckToggle}
onTaskClick={handleTaskClick}
onTaskEditClick={handleTaskEditClick}
onTaskOptionsClick={handleTaskOptionsClick}
onCheckToggle={handleTaskCheckToggle}
onClick={handleTaskClick}
onEditClick={handleTaskEditClick}
onOptionsClick={handleTaskOptionsClick}
/>
))}
</TaskList>
Expand All @@ -62,6 +79,12 @@ const ProjectViewer = () => {
<Typography>Nenhum projeto selecionado</Typography>
)}
</Main>

<TaskSnackBar
isOpen={isSnackBarOpen}
onClose={handleSnackBarClose}
onUndo={handleSnackBarUndo}
/>
</Container>
);
};
Expand Down
32 changes: 16 additions & 16 deletions src/components/TaskListItem/TaskListItem.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ import {

const TaskListItem = ({
task,
onTaskCheckToggle,
onTaskClick,
onTaskEditClick,
onTaskOptionsClick,
onCheckToggle,
onClick,
onEditClick,
onOptionsClick,
}) => {
const [checked, setChecked] = useState([0]);
const [hoveredTaskId, setHoveredTaskId] = useState(null);

const handleTaskCheckToggle = (taskId) => {
const handleCheckToggle = (taskId) => {
const currentIndex = checked.indexOf(taskId);
const newChecked = [...checked];
if (currentIndex === -1) {
Expand All @@ -33,19 +33,19 @@ const TaskListItem = ({
}
setChecked(newChecked);

onTaskCheckToggle(taskId);
onCheckToggle(taskId);
};

const handleTaskClick = (taskId) => {
onTaskClick(taskId);
const handleClick = (taskId) => {
onClick(taskId);
};

const handleTaskEditClick = (taskId) => {
onTaskEditClick(taskId);
const handleEditClick = (taskId) => {
onEditClick(taskId);
};

const handleTaskOptionsClick = (taskId) => {
onTaskOptionsClick(taskId);
const handleOptionsClick = (taskId) => {
onOptionsClick(taskId);
};

return (
Expand All @@ -64,10 +64,10 @@ const TaskListItem = ({
}),
}}
>
<IconButton edge="end" sx={{ mr: 1 }} onClick={handleTaskEditClick}>
<IconButton edge="end" sx={{ mr: 1 }} onClick={handleEditClick}>
<BorderColorIcon />
</IconButton>
<IconButton edge="end" onClick={handleTaskOptionsClick}>
<IconButton edge="end" onClick={handleOptionsClick}>
<MoreHorizIcon />
</IconButton>
</Box>
Expand All @@ -76,12 +76,12 @@ const TaskListItem = ({
<Checkbox
edge="start"
checked={checked.indexOf(task.id) !== -1}
onClick={() => handleTaskCheckToggle(task.id)}
onClick={() => handleCheckToggle(task.id)}
disableRipple
/>
<ListItemButton
dense
onClick={handleTaskClick}
onClick={handleClick}
sx={{
"&.MuiListItemButton-root:hover": {
backgroundColor: "transparent",
Expand Down
43 changes: 43 additions & 0 deletions src/components/TaskSnackBar/TaskSnackBar.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Button, IconButton, Snackbar, Fade } from "@mui/material";
import { Close as CloseIcon } from "@mui/icons-material";

const TaskSnackBar = ({ isOpen, onClose, onUndo }) => {
const handleClose = (event, reason) => {
if (reason === "clickaway") {
return;
}
onClose();
};

const handleUndoClick = () => {
onUndo();
handleClose();
};

const action = (
<>
<Button color="error" size="small" onClick={handleUndoClick}>
Desfazer
</Button>
<IconButton size="small" color="inherit" onClick={handleClose}>
<CloseIcon fontSize="small" />
</IconButton>
</>
);

return (
<Snackbar
open={isOpen}
autoHideDuration={6000}
onClose={handleClose}
message="1 tarefa concluída!"
action={action}
anchorOrigin={{ vertical: "bottom", horizontal: "center" }}
TransitionComponent={Fade}
key={Fade.name}
sx={{ "& .MuiPaper-root": { color: "black", backgroundColor: "white" } }}
/>
);
};

export default TaskSnackBar;
3 changes: 3 additions & 0 deletions src/components/TaskSnackBar/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import TaskSnackBar from "./TaskSnackBar";

export default TaskSnackBar;
7 changes: 5 additions & 2 deletions src/state/rootSaga.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { all, takeLatest } from "redux-saga/effects";
import { all, takeLatest, takeEvery } from "redux-saga/effects";
import {
FETCH_INITIAL_DATA,
onAuthorized as commonSliceOnAuthorized,
Expand Down Expand Up @@ -27,8 +27,10 @@ import {
import {
FETCH_TASKS,
CLOSE_TASK,
REOPEN_TASK,
onRequestTasks,
onCloseTasks,
onReopenTask,
} from "./slices/tasksSlice.js";

export default function* rootSaga() {
Expand All @@ -44,6 +46,7 @@ export default function* rootSaga() {
takeLatest(UPDATE_PROJECT.type, onUpdateProject),
takeLatest(DELETE_PROJECT.type, onDeleteProject),
takeLatest(DELETE_PROJECT_SUCCESS.type, onDeleteProjectSuccess),
takeLatest(CLOSE_TASK.type, onCloseTasks),
takeEvery(CLOSE_TASK.type, onCloseTasks),
takeLatest(REOPEN_TASK.type, onReopenTask),
]);
}
31 changes: 30 additions & 1 deletion src/state/slices/tasksSlice.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,22 @@ export function* onCloseTasks(action) {
}
}

export function* onReopenTask(action) {
const taskId = action.payload;
try {
yield call(() => getApi().reopenTask(taskId));
yield put(REOPEN_TASK_SUCCESS(taskId));
} catch (error) {
yield put(REOPEN_TASK_ERROR());
}
}

const initialState = {
data: [],
loading: false,
error: false,
lastClosedTaskId: null,
lastClosedTask: null,
};

export const tasksSlice = createSlice({
Expand All @@ -52,13 +63,28 @@ export const tasksSlice = createSlice({
CLOSE_TASK_SUCCESS: (state, action) => {
const taskId = action.payload;
state.loading = false;
state.data = state.data.filter((task) => task.id != taskId);
state.lastClosedTask = state.data.find((task) => task.id == taskId);
state.lastClosedTaskId = taskId;
state.data = state.data.filter((task) => task.id != taskId);
},
CLOSE_TASK_ERROR: (state) => {
state.loading = false;
state.error = true;
},
REOPEN_TASK: (state) => {
state.loading = true;
state.error = false;
},
REOPEN_TASK_SUCCESS: (state, action) => {
state.loading = false;
state.data = [...state.data, state.lastClosedTask];
state.lastClosedTaskId = null;
state.lastClosedTask = null;
},
REOPEN_TASK_ERROR: (state) => {
state.loading = false;
state.error = true;
},
},
});

Expand All @@ -69,5 +95,8 @@ export const {
CLOSE_TASK,
CLOSE_TASK_SUCCESS,
CLOSE_TASK_ERROR,
REOPEN_TASK,
REOPEN_TASK_SUCCESS,
REOPEN_TASK_ERROR,
} = tasksSlice.actions;
export default tasksSlice.reducer;

0 comments on commit 55cb65e

Please sign in to comment.