Skip to content

Commit

Permalink
update task status logic fix; add task store update fix; garbage clea…
Browse files Browse the repository at this point in the history
…ning
  • Loading branch information
SimonMatveev committed Feb 19, 2024
1 parent a1277e5 commit e45f658
Show file tree
Hide file tree
Showing 22 changed files with 237 additions and 348 deletions.
20 changes: 15 additions & 5 deletions src/api/api.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { baseUrl as api } from 'constants/baseUrl';
import { TResults, TUpdateTaskStatusApi } from 'types/types';

const checkResponse = (res: Response) => {
if (!res.ok) {
Expand All @@ -10,10 +11,12 @@ const checkResponse = (res: Response) => {
return res.json();
};

export const request = (url: string, config?: RequestInit): Promise<any> =>
fetch(`${process.env.API || api}${url}`, { ...config, credentials: 'include' }).then(
checkResponse
);
export function request<T = any>(url: string, config?: RequestInit): Promise<T> {
return fetch(`${process.env.API || api}${url}`, {
...config,
credentials: 'include',
}).then(checkResponse);
}

export const authUser = (userData: any) =>
request('auth/login/', {
Expand Down Expand Up @@ -44,12 +47,19 @@ export const createTask = (taskData: any) =>
body: JSON.stringify(taskData),
});
export const updateTaskApi = (taskData: any) =>
request(`tasks/${taskData.id}`, {
request<{ tasks: TResults[] }>(`tasks/${taskData.id}`, {
method: 'PATCH',
headers: new Headers([['Content-Type', 'application/json']]),
body: JSON.stringify(taskData.data),
});

export const updateTaskStatus = (taskData: TUpdateTaskStatusApi) =>
request<{ tasks: TResults[] }>(`tasks/${taskData.id}`, {
method: 'PATCH',
headers: new Headers([['Content-Type', 'application/json']]),
body: JSON.stringify({ status: taskData.newStatus }),
});

export const getTask = (p: string) => request(`tasks/?status=${p}`, { method: 'GET' });

export const getTodoTask = () => getTask('to do');
Expand Down
14 changes: 6 additions & 8 deletions src/components/Popup/CreateTask/CreateTask.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import React, { BaseSyntheticEvent, SyntheticEvent, useEffect, useState } from 'react';
import { v4 as uuidv4 } from 'uuid';
import styles from './CreateTask.module.scss';
import CheckBox from '../../../ui-lib/CheckBoxes/CheckBox/CheckBox';
import UniversalTextarea from '../../../ui-lib/Inputs/Textarea/UniversalTextarea';
import Calendar from '../../Calendar/Calendar';
import UniversalInput from '../../../ui-lib/Inputs/UniversalInput/UniversalInput';
import { UniversalButton } from '../../../ui-lib/Buttons';
import { useDispatch, useSelector } from '../../../services/hooks';
import { closeModal } from '../../../store';
import createTaskThunk from '../../../thunks/create-task-thunk';
import getTaskThunk from '../../../thunks/get-task-thunks';
import { UniversalButton } from '../../../ui-lib/Buttons';
import CheckBox from '../../../ui-lib/CheckBoxes/CheckBox/CheckBox';
import UniversalTextarea from '../../../ui-lib/Inputs/Textarea/UniversalTextarea';
import UniversalInput from '../../../ui-lib/Inputs/UniversalInput/UniversalInput';
import Calendar from '../../Calendar/Calendar';
import styles from './CreateTask.module.scss';

type CheckboxValues = Record<string, boolean>;
const CreateTask = () => {
Expand All @@ -36,7 +35,6 @@ const CreateTask = () => {
performers: performersId,
})
);
dispatch(getTaskThunk(true));
dispatch(closeModal());
};
const showCheckboxes = () => {
Expand Down
6 changes: 3 additions & 3 deletions src/components/Task/Task.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export interface TaskProps {
taskCreatorId: number;
isCurrentUserLead: boolean;
currentUserId: number;
performer: number;
}

export const Task: React.FC<TaskProps> = ({
Expand All @@ -32,13 +33,11 @@ export const Task: React.FC<TaskProps> = ({
taskCreatorId,
isCurrentUserLead,
currentUserId,
performer,
}) => {
const [isMenuOpened, setIsMenuOpened] = React.useState(false);
const dispatch = useDispatch();
const taskMenuActiveId = useSelector((state) => state.taskMenuActive).value;
// const userName = useSelector(
// (state) => `${state.user.first_name} ${state.user.last_name}`
// );

const handleToggleEditMenu = () => {
if (isMenuOpened) {
Expand Down Expand Up @@ -92,6 +91,7 @@ export const Task: React.FC<TaskProps> = ({
taskCreatorId={taskCreatorId}
isCurrentUserLead={isCurrentUserLead}
currentUserId={currentUserId}
performer={performer}
/>
)}

Expand Down
2 changes: 1 addition & 1 deletion src/components/TaskEditMenu/TaskEditMenu.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
.container {
position: absolute;
top: 13px;
left: 226px;
right: -135px;
z-index: 1;
background-color: v.$white-color;
display: grid;
Expand Down
13 changes: 5 additions & 8 deletions src/components/TaskEditMenu/TaskEditMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { TaskStatus } from 'types/types';
import { UniversalButton } from 'ui-lib/Buttons';
import { BallpenIcon, TrashIcon } from 'ui-lib/Icons';
import { useClose, useDispatch } from '../../services/hooks';
import updateTaskThunk from '../../thunks/update-task-thunk';
import updateTaskThunk from '../../thunks/update-task-status-thunk';
import styles from './TaskEditMenu.module.scss';
// import { changeTaskStatus } from '../../store/taskSlice';

Expand All @@ -19,6 +19,7 @@ export interface TaskEditMenuProps {
taskCreatorId: number;
isCurrentUserLead: boolean;
currentUserId: number;
performer: number;
}

export const TaskEditMenu: React.FC<TaskEditMenuProps> = ({
Expand All @@ -32,6 +33,7 @@ export const TaskEditMenu: React.FC<TaskEditMenuProps> = ({
taskCreatorId,
isCurrentUserLead,
currentUserId,
performer,
}) => {
const [currentStatus, setStatus] = React.useState(status);
const dispatch = useDispatch();
Expand Down Expand Up @@ -63,13 +65,8 @@ export const TaskEditMenu: React.FC<TaskEditMenuProps> = ({
dispatch(
updateTaskThunk({
id: taskID,
data: {
description,
status: currentStatus,
deadline_date: deadlineDate,
// performers,
performers: [2],
},
curStatus: status,
newStatus: currentStatus,
})
);
};
Expand Down
13 changes: 7 additions & 6 deletions src/components/TasksDND/TasksDND.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { FC } from 'react';
import { Draggable, Droppable } from '@hello-pangea/dnd';
import { TResults } from '../../types/types';
import { useSelector } from '../../services/hooks';
import styles from './TasksDND.module.scss';
import { FC } from 'react';
import Tasks from '../../pages/Tasks/Tasks';
import { handleCheckIfTaskForMe } from '../../services/functions';
import { useSelector } from '../../services/hooks';
import { TResults } from '../../types/types';
import styles from './TasksDND.module.scss';

interface ITaskSort {
tasksArray: TResults[];
tasksArray: TResults[] | [];
droppableId: string;
}

Expand All @@ -30,7 +30,7 @@ const TaskSort: FC<ITaskSort> = ({ tasksArray, droppableId }) => {

return (
<Droppable droppableId={droppableId}>
{(provided, snapshot) => (
{(provided) => (
<div ref={provided.innerRef} {...provided.droppableProps}>
<div className={styles.taskColumn}>
{tasksArray.map((task, index) => (
Expand All @@ -53,6 +53,7 @@ const TaskSort: FC<ITaskSort> = ({ tasksArray, droppableId }) => {
completedTime={task.deadline_date}
status={task.status}
taskID={task.id}
performer={task.performer.id}
taskCreatorId={task.creator.id}
isCurrentUserLead={isCurrentUserLead}
currentUserId={currentUserId}
Expand Down
109 changes: 40 additions & 69 deletions src/pages/Main/Lead/Lead.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,74 +2,33 @@ import { DragDropContext } from '@hello-pangea/dnd';
import Search from 'components/Search/Search';
import SideBar from 'components/SideBar/SideBar';
import Status from 'components/Status/Status';
import { FC, useEffect, useMemo, useState } from 'react';
import { handleCheckIfTaskForMe } from 'services/functions';
import { useDispatch, useSelector } from 'services/hooks';
import { FC } from 'react';
import { useDispatch, useSelector, useTasksToRender } from 'services/hooks';
import { openCreateTaskModal } from 'store';
import { resetActiveMenu } from 'store/taskMenuActiveSlice';
import { TResults, TTask, TaskStatus } from 'types/types';
import { TaskStatus, TtaskState } from 'types/types';
import { UniversalButton } from 'ui-lib/Buttons';
import updateTaskThunk from '../../../thunks/update-task-thunk';
import styles from './Lead.module.scss';
import TaskSort from '../../../components/TasksDND/TasksDND';
import updateTaskStatusThunk from '../../../thunks/update-task-status-thunk';
import styles from './Lead.module.scss';

interface ITaskCard {
allTasks: TTask;
allTasks: TtaskState;
}

const Lead: FC<ITaskCard> = ({ allTasks }) => {
const { count, results } = allTasks;
const { toDo, inProgress, done, hold } = allTasks;
const dispatch = useDispatch();
const currentUser = useSelector((state) => state.user);
const tasksOfUserId = useSelector((state) => state.tasksOfUser).id;
const resultsToRender = useMemo(
() =>
tasksOfUserId !== -1
? results.filter((task) => handleCheckIfTaskForMe(tasksOfUserId, task.performer))
: results,
[results, tasksOfUserId]
);
const todoTasks = useTasksToRender(toDo);
const inProgressTasks = useTasksToRender(inProgress);
const doneTasks = useTasksToRender(done);
const holdTasks = useTasksToRender(hold);

const openCreateTask = () => {
dispatch(openCreateTaskModal());
};

// eslint-disable-next-line react-hooks/rules-of-hooks
const [todoTasks, setTodoTasks] = useState<TResults[]>([]);
const [inProgressTasks, setInProgressTasks] = useState<TResults[]>([]);
const [doneTasks, setDoneTasks] = useState<TResults[]>([]);
const [holdTasks, setHoldTasks] = useState<TResults[]>([]);

const parseTasks = () => {
const todo: TResults[] = [];
const inProgress: TResults[] = [];
const done: TResults[] = [];
const hold: TResults[] = [];
// eslint-disable-next-line no-plusplus
for (let i = 0; i < resultsToRender.length; i++) {
if (resultsToRender[i].status === TaskStatus.TO_DO) {
todo.push(resultsToRender[i]);
}
if (resultsToRender[i].status === TaskStatus.IN_PROGRESS) {
inProgress.push(resultsToRender[i]);
}
if (resultsToRender[i].status === TaskStatus.DONE) {
done.push(resultsToRender[i]);
}
if (resultsToRender[i].status === TaskStatus.HOLD) {
hold.push(results[i]);
}
}
setTodoTasks(todo);
setInProgressTasks(inProgress);
setDoneTasks(done);
setHoldTasks(hold);
};

useEffect(() => {
parseTasks();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [resultsToRender]);

const onDragStart = () => dispatch(resetActiveMenu());

const onDragEnd = (result: any) => {
Expand All @@ -81,10 +40,14 @@ const Lead: FC<ITaskCard> = ({ allTasks }) => {
}
const sInd = source.droppableId;
const dInd = destination.droppableId;
const itemIndex = allTasks.results.findIndex(
(elem) => elem.id === Number(draggableId)
);
const item = allTasks.results[itemIndex];
const allTasksArr = [
...todoTasks.tasksToRender,
...inProgressTasks.tasksToRender,
...doneTasks.tasksToRender,
...holdTasks.tasksToRender,
];
const itemIndex = allTasksArr.findIndex((elem) => elem.id === Number(draggableId));
const item = allTasksArr[itemIndex];

const { status } = item;
const isCurrentUserLead = currentUser.is_team_lead;
Expand All @@ -110,14 +73,10 @@ const Lead: FC<ITaskCard> = ({ allTasks }) => {

const updateTaskStatus = () => {
dispatch(
updateTaskThunk({
id: draggableId,
data: {
description: item.description,
status: dInd,
deadline_date: item.deadline_date,
performer: item.performer.id,
},
updateTaskStatusThunk({
id: +draggableId,
curStatus: status,
newStatus: dInd,
})
);
};
Expand All @@ -140,10 +99,22 @@ const Lead: FC<ITaskCard> = ({ allTasks }) => {
<Status />
<div className={styles.tasksWrapper}>
<DragDropContext onDragEnd={onDragEnd} onDragStart={onDragStart}>
<TaskSort tasksArray={todoTasks} droppableId='to do' />
<TaskSort tasksArray={inProgressTasks} droppableId='in progress' />
<TaskSort tasksArray={doneTasks} droppableId='done' />
<TaskSort tasksArray={holdTasks} droppableId={TaskStatus.HOLD} />
<TaskSort
tasksArray={todoTasks.tasksToRender}
droppableId={TaskStatus.TO_DO}
/>
<TaskSort
tasksArray={inProgressTasks.tasksToRender}
droppableId={TaskStatus.IN_PROGRESS}
/>
<TaskSort
tasksArray={doneTasks.tasksToRender}
droppableId={TaskStatus.DONE}
/>
<TaskSort
tasksArray={holdTasks.tasksToRender}
droppableId={TaskStatus.HOLD}
/>
</DragDropContext>
</div>
</div>
Expand Down
10 changes: 4 additions & 6 deletions src/pages/Main/Main.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import Login from 'pages/Login/Login';
import { useEffect } from 'react';
import { useDispatch, useSelector } from 'services/hooks';
import getTaskThunk from 'thunks/get-task-thunks';
import getUsersThunk from 'thunks/get-users-thunks';
import { TTask } from 'types/types';
import getTasksThunk from 'thunks/get-tasks-thunks';
import getUsersThunk from 'thunks/get-users-thunks';
import { TtaskState } from 'types/types';
import Lead from './Lead/Lead';
import styles from './Main.module.scss';
import User from './User/User';
Expand All @@ -13,15 +12,14 @@ const Main = () => {
const dispatch = useDispatch();
const { isLoggedIn } = useSelector((state) => state.system);
const isLead = useSelector((state) => state.user).is_team_lead;
const tasks: TTask = useSelector((state) => state.task);
const tasks: TtaskState = useSelector((state) => state.tasks);

// const isLead = true;
useEffect(() => {
dispatch(getTaskThunk(isLoggedIn));
dispatch(getTasksThunk(isLoggedIn));
dispatch(getUsersThunk(isLoggedIn));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isLoggedIn, tasks.results.length]);
}, [isLoggedIn, tasks.count]);

return (
<main className={styles.main}>
Expand Down
Loading

0 comments on commit e45f658

Please sign in to comment.