Merge branch 'task-105-feature/tbl_tasks_users' into 'development'

Task 105 feature/tbl tasks users

See merge request !84
parents 33e225e7 0750fd3d
......@@ -11,6 +11,7 @@ import Projects from "./containers/Projects/Projects";
import FullProject from "./containers/FullProject/FullProject";
import NewProject from "./containers/NewProject/NewProject";
import WeekCalendar from "./containers/WeekCalendar/WeekCalendar";
import UsersTasks from "./containers/UsersTasks/UsersTasks";
const ProtectedRoute = ({ isAllowed, roles, redirectUrl, children }) => {
const user = useSelector(state => state.users?.user);
......@@ -117,10 +118,11 @@ const App = () => {
<Route path={"/workers-tasks"} element={
<ProtectedRoute
roles={["superuser"]}
isAllowed={user}
redirectUrl={"/"}
>
<h1>workers tasks page</h1>
<UsersTasks/>
</ProtectedRoute>
} />
......
......@@ -31,10 +31,10 @@ const TableRowTask= ({
deleteHandle,
handleEditTask,
deleteDateTimeTask,
// handleEditDateTimeTask,
onChange,
onModalOpen,
onProjectChange,
onExecutorChange,
uniqueProjects,
onAuthorChange,
onDateChange,
......@@ -144,6 +144,10 @@ const TableRowTask= ({
/>
)}
<CustomTableCell
{...{
task,
......
import * as React from "react";
import TableCell from "@mui/material/TableCell";
import Input from "@mui/material/Input";
import moment from "moment";
const CustomTableCell = ({
task,
name,
value,
value2,
onChange,
onModalOpen,
placeholder,
user,
}) => {
const styles = placeholder ? { width: "100%" } : { width: "auto" };
const divStyle = {
display: "flex",
justifyContent: "space-between",
flexDirection: "column",
fontSize: "12px",
};
const duration = moment.duration(
moment(task?.dateTimeTasks[0]?.dateTimeDue).diff(
moment(task?.dateTimeTasks[0]?.dateTimeStart)
)
);
const hours = Math.round(duration.asHours());
if (task) {
return (
<>
<TableCell
onClick={(e) => (onModalOpen ? onModalOpen(e, task) : null)}
align="left"
// style={styles}
>
{(task.isEditMode &&
onChange &&
name !== "author" &&
task.author?.id === user?.id) ||
placeholder ? (
<Input
placeholder={placeholder}
value={value}
name={name}
onChange={(e) => onChange(e, task)}
style={styles}
/>
) : name !== "dateTimeStart" ? (
<span>{value}</span>
) : (
<div style={divStyle}>
<span>{value}</span>
<span>{value2}</span>
<span>часы:{hours}</span>
</div>
)}
</TableCell>
</>
);
}
};
export default CustomTableCell;
import * as React from "react";
import TextField from "@mui/material/TextField";
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
import { DateTimePicker } from "@mui/x-date-pickers/DateTimePicker";
import { AdapterMoment } from "@mui/x-date-pickers/AdapterMoment";
export default function MaterialUIPickers(props) {
return (
<LocalizationProvider
dateAdapter={AdapterMoment}
sx={{ width: "100%", fontSize: 5, fontWeight: "200" }}
>
<DateTimePicker
inputFormat="DD-MM-YY kk:mm A"
disabled={props.task.readOnly}
renderInput={(params) => (
<TextField
{...params}
sx={{ width: "auto", fontWeight: "200", fontSize: 5 }}
name={props.name}
/>
)}
value={props.task[props.name]}
onChange={(newValue) => {
props.onChange(props.task.id, newValue, props.name);
}}
/>
</LocalizationProvider>
);
}
import * as React from "react";
import {
Table,
TableBody,
TableCell,
TableContainer,
TableRow,
TableHead,
IconButton,
Tooltip,
Typography,
Divider,
} from "@mui/material";
import { useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { AddBox } from "@mui/icons-material";
import moment from "moment";
import CustomTableCell from "./CustomTableCell";
import MaterialUIPickers from "./DateTimePicker/DateTimePicker";
import BasicSelect from "../UI/Select/Select";
import { addTask } from "../../store/actions/tasksActions";
import TaskModal from "./TaskModal/TaskModal";
export default function NewTaskForm({
projects,
currentProject,
setAddTaskForm,
}) {
const dispatch = useDispatch();
const user = useSelector((state) => state.users.user);
const currentDateTime = new Date();
const dateTime = moment(currentDateTime).utc().format();
const [task, setTask] = useState({
id: 0,
title: "",
description: "",
createdAt: dateTime,
dateTimeStart: null,
dateTimeDeadLine: null,
dateTimeTasks: [],
dateTimeDue: null,
project: projects[0],
accomplish: "opened",
priority: "B",
author: { id: user.id },
authorDisplayName: user.displayName,
executor:null,
isEditMode: true,
});
const [modal, setModal] = useState(false);
const onModalOpen = (event, task) => {
event.stopPropagation();
setModal(true);
};
const handleClose = () => {
setModal(false);
};
const onChange = (e, task) => {
const value = e.target.value;
const name = e.target.name;
const newTask = { ...task, [name]: value };
setTask(newTask);
};
const onProjectChange = (e, task) => {
const value = e.target.value;
const project = projects.find((e) => e.id === value);
const newTask = { ...task };
newTask.project = project;
setTask(newTask);
};
const onExecutorChange = (e, task) => {
const value = e.target.value;
const executor = projects.find((e) => e.id === value);
const newTask = { ...task };
newTask.executor = executor;
setTask(newTask);
};
const onDateChange = (id, value, property) => {
const newTask = {
...task,
[property]: moment.parseZone(value, "DD/MM/YYYY", true).format(),
};
setTask(newTask);
};
const handleAddTask = () => {
dispatch(addTask(task));
setAddTaskForm();
};
return (
<>
<Divider>
<Typography variant="overline">Добавить новую задачу</Typography>
</Divider>
<TableContainer
style={{
backgroundColor: "#E8E8E8",
marginBottom: "2em",
}}
>
<Table sx={{ minWidth: 600 }} aria-labelledby="tableTitle">
<TableHead>
<TableRow>
{header.map((headCell) => (
<TableCell
key={headCell.id}
align="center"
padding={headCell.disablePadding ? "none" : "normal"}
>
{headCell.label}
</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
<TableRow hover key={task.id}>
<TableCell component="th" scope="row" padding="none"></TableCell>
<TableCell>
<BasicSelect
items={[
{ value: "A", title: "A" },
{ value: "B", title: "B" },
{ value: "C", title: "C" },
]}
task={task}
value={task.priority}
onChange={onChange}
name="priority"
/>
</TableCell>
<CustomTableCell
{...{
task,
name: "createdAt",
value: moment(task.createdAt).format("DD-MM-YYYY hh:mm A"),
}}
/>
<CustomTableCell
{...{
task,
name: "title",
value: task.title,
onModalOpen,
user: user,
placeholder: "Кликните для ввода информации по задаче"
}}
/>
<TableCell>
<BasicSelect
items={projects.map((e) => ({
value: e?.id,
title: e?.title,
}))}
task={task}
onChange={onProjectChange}
name="project"
value={task.project?.id}
/>
</TableCell>
<TableCell>
<BasicSelect
items={currentProject.members.map((member) => ({
value: member?.id,
title: member?.displayName,
}))}
task={task}
onChange={onExecutorChange}
name="executor"
value={task.executor?.id}
/>
</TableCell>
{/* <TableCell>
<MaterialUIPickers
task={task}
name="dateTimeStart"
onChange={onDateChange}
/>
</TableCell> */}
<TableCell>
<MaterialUIPickers
task={task}
name="dateTimeDeadLine"
onChange={onDateChange}
/>
</TableCell>
<TableCell>
<Tooltip title="Добавить">
<IconButton size="large" onClick={handleAddTask}>
<AddBox fontSize="large" />
</IconButton>
</Tooltip>
</TableCell>
</TableRow>
</TableBody>
</Table>
<TaskModal
task={task}
open={modal}
handleClose={handleClose}
onChange={onChange}
user={user}
/>
</TableContainer>
<Divider />
</>
);
}
export const header = [
{
id: "id",
numeric: true,
disablePadding: true,
label: "",
},
{
id: "priority",
numeric: false,
disablePadding: true,
label: "Приоритет",
},
{
id: "createdAt",
numeric: true,
disablePadding: false,
label: "Дата создания",
},
{
id: "title",
numeric: false,
disablePadding: false,
label: "Заголовок",
},
{
id: "projectName",
numeric: true,
disablePadding: false,
label: "Проект",
},
{
id: "executorName",
numeric: false,
disablePadding: false,
label: "Исполнитель",
},
{
id: "dateTimeDue",
numeric: true,
disablePadding: false,
label: "Дедлайн",
},
{
id: "add",
numeric: false,
disablePadding: false,
label: "",
},
];
import * as React from "react";
import {
TableCell,
TableRow,
IconButton,
Tooltip,
Collapse,
Box,
Table,
TableBody,
TableHead,
Typography
} from "@mui/material";
import { Done, Edit } from "@mui/icons-material";
import RemoveIcon from '@mui/icons-material/Remove';
import DeleteIcon from "@mui/icons-material/Delete";
import moment from "moment";
import CustomTableCell from "../CustomTableCell";
import MaterialUIPickers from "../DateTimePicker/DateTimePicker";
import BasicSelect from "../../UI/Select/Select";
import CalendarMonthIcon from '@mui/icons-material/CalendarMonth';
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp';
const weekDays = ["Вс","Пн","Вт","Ср","Чт","Пт","Сб" ];
const TableRowTask= ({
user,
task,
deleteHandle,
handleEditTask,
deleteDateTimeTask,
onChange,
onModalOpen,
onProjectChange,
onExecutorChange,
uniqueProjects,
executors,
onAuthorChange,
onDateChange,
onToggleEditMode,
onToggleEditModeDone,
})=>{
const [open, setOpen] = React.useState(false);
const roudHourUp =(dateIso)=>{
let m = moment(dateIso);
let roundUp = m.minute() || m.second() || m.millisecond() ? m.add(1, 'hour').startOf('hour') : m.startOf('hour');
return roundUp
}
const timeTransform = (dateIso)=>{
const exp = roudHourUp(moment.utc(dateIso)).format("HH:"+"00")
return exp;
}
const getDayOfWeek = (dateIso) => {
const date = moment.utc(dateIso);
return weekDays[date.day()];
}
return (
<>
<TableRow hover key={task.id}>
<TableCell
component="th"
scope="row"
padding="none"
></TableCell>
{task.isEditMode && task.author.id===user.id ? (
<TableCell>
<BasicSelect
items={[
{ value: "A", title: "A" },
{ value: "B", title: "B" },
{ value: "C", title: "C" },
]}
task={task}
value={task.priority}
onChange={onChange}
name="priority"
user={user}
/>
</TableCell>
) : (
<CustomTableCell
{...{
task,
name: "priority",
value: task.priority,
user:user
}}
/>
)}
<CustomTableCell
{...{
task,
name: "createdAt",
value: moment(task.createdAt)
.utc()
.format("DD-MM-YY"),
user:user
}}
/>
<CustomTableCell
{...{
task,
name: "title",
value: task.title,
onChange,
onModalOpen,
user:user
}}
/>
{task.isEditMode && task.author.id===user.id ? (
<TableCell>
<BasicSelect
items={uniqueProjects.map((e) => ({
value: e?.id,
title: e?.title,
}))}
task={task}
onChange={onProjectChange}
name="project"
value={task.project?.id}
user={user}
/>
</TableCell>
) : (
<CustomTableCell
{...{
task,
name: "projectId",
value: task.project?.title,
user:user
}}
/>
)}
{/* executor cell display */}
{/* executor cell display */}
{/* executor cell display */}
{/* executor cell display */}
{task.isEditMode && task.author.id===user.id ? (
<TableCell>
<BasicSelect
items={executors.map((e) => ({
value: e?.id,
title: e?.displayName,
}))}
task={task}
onChange={onExecutorChange}
name="executor"
value={task.executor?.id}
/>
</TableCell>
) : (
<CustomTableCell
{...{
task,
name: "executor",
value: task.executor?.displayName,
user:user
}}
/>
)}
<CustomTableCell
{...{
task,
name: "author",
value: task.author.displayName,
// onChange: onAuthorChange,
user:user
}}
/>
{task.isEditMode && task.author.id===user.id ? (
<TableCell>
{/* <MaterialUIPickers
task={task}
name="dateTimeStart"
onChange={onDateChange}
user={user}
/> */}
<TableCell>
<Tooltip title="Перейти в календарь">
<IconButton
onClick={(id) => { deleteHandle(task.id);}}
>
<CalendarMonthIcon />
</IconButton>
</Tooltip>
</TableCell>
</TableCell>
) : (
task.dateTimeTasks.length>1 ?
<TableCell>
<IconButton
aria-label="expand row"
size="small"
onClick={() => setOpen(!open)}
>
{open ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />}
</IconButton>
</TableCell>
:
<CustomTableCell
{...{
task,
name: "dateTimeStart",
value: moment(task.dateTimeTasks[0]?.dateTimeStart)
.utc()
.format("DD-MM-YY "),
value2:moment(task.dateTimeTasks[0]?.dateTimeStart)
.utc()
.format("kk:mm")+" - "+
moment(task.dateTimeTasks[0]?.dateTimeDue)
.utc()
.format("kk:mm"),
user:user
}}>
</CustomTableCell>
)}
{/* <TableCell>
<MaterialUIPickers
task={task}
name="dateTimeStart"
onChange={onDateChange}
user={user}
/>
</TableCell> */}
{task.isEditMode && task.author.id===user.id ? (
<TableCell>
<MaterialUIPickers
task={task}
name="dateTimeDue"
onChange={onDateChange}
user={user}
/>
</TableCell>
) : (
<CustomTableCell
{...{
task,
name: "dateTimeDeadLine",
value: moment(task.dateTimeDeadLine
)
.utc()
.format("DD-MM-YY kk:mm"),
user:user
}}
/>
)}
{task.isEditMode ? (
<TableCell>
<BasicSelect
items={[
{ value: "opened", title: "opened" },
{ value: "done", title: "done" },
{ value: "failed", title: "failed" },
]}
task={task}
onChange={onChange}
name="accomplish"
value={task.accomplish}
user={user}
/>
</TableCell>
) : (
<CustomTableCell
{...{
task,
name: "accomplish",
value: task.accomplish,
user:user
}}
/>
)}
<TableCell>
<Tooltip title="Редактировать">
{task.isEditMode ? (
<IconButton
aria-label="done"
onClick={() => {
onToggleEditModeDone(task.id);
handleEditTask(task);
}}
>
<Done />
</IconButton>
) : (
<IconButton
aria-label="edit"
onClick={() => onToggleEditMode(task.id)}
>
<Edit />
</IconButton>
)}
</Tooltip>
</TableCell>
{task.author.id===user.id ?
(<TableCell>
<Tooltip title="Удалить">
<IconButton
onClick={(id) => {
deleteHandle(task.id);
}}
>
<DeleteIcon />
</IconButton>
</Tooltip>
</TableCell>):null}
</TableRow>
{task.dateTimeTasks.length>1?
<TableRow>
<TableCell style={{ paddingBottom: 0, paddingTop: 0 }} colSpan={11}>
<Collapse in={open} timeout="auto" unmountOnExit>
<Box sx={{ margin: 1 }}>
<Typography variant="h6" gutterBottom component="div">
Расписание
</Typography>
<Table size="small" aria-label="purchases" sx={{
backgroundColor: "#ebebeb"}}>
<TableHead>
<TableRow>
<TableCell colSpan={10} >Дата создания</TableCell>
<TableCell align="right">День недели</TableCell>
<TableCell align="right">Начало</TableCell>
<TableCell align="center" colSpan={1}>Окончание</TableCell>
<TableCell align="center" ></TableCell>
<TableCell align="center" ></TableCell>
</TableRow>
</TableHead>
<TableBody>
{task.dateTimeTasks.map((dateTimeTask, index) => (
<TableRow key={index}>
<TableCell component="th" scope="row" colSpan={10}>
{moment(task.createdAt)
.utc()
.format("DD/MM")}
</TableCell>
<TableCell align="right">
{getDayOfWeek(dateTimeTask.dateTimeStart)}, {moment(dateTimeTask.dateTimeStart)
.utc()
.format("DD/MM")}
</TableCell>
<TableCell align="right">
{timeTransform(dateTimeTask.dateTimeStart)}
</TableCell>
<TableCell align="center" colSpan={1}>
{timeTransform(dateTimeTask.dateTimeDue)}
</TableCell>
{/* Edit option datetimeTask */}
<TableCell
// style={{width:'0%'}}
>
{/* <Tooltip title="Редактировать Копию">
{task.isEditMode ? (
<IconButton
aria-label="done"
onClick={() => {
onToggleEditModeDone(dateTimeTask.id);
handleEditDateTimeTask(dateTimeTask);
}}
>
<Done />
</IconButton>
) : (
<IconButton
aria-label="edit"
onClick={() => onToggleEditMode(dateTimeTask.id)}
>
<Edit />
</IconButton>
)}
</Tooltip> */}
</TableCell >
{/* delete option datetimeTask */}
{task.author.id===user.id ?
(<TableCell style={{width:'0%'}}>
<Tooltip title="Удалить Копию">
<IconButton
onClick={(id) => {
deleteDateTimeTask(dateTimeTask.id);
}}
>
<RemoveIcon />
</IconButton>
</Tooltip>
</TableCell>):null}
</TableRow>
))}
</TableBody>
</Table>
</Box>
</Collapse>
</TableCell>
</TableRow>
:<></>}
</>
)
}
export default TableRowTask;
.modal{
display: flex;
flex-direction: column;
padding: 10px;
align-items: center;
position: absolute;
top: 200px;
left: 200px;
width: 300px;
height: 300px;
background-color: white;
border: 2px solid #000;
box-shadow: 24px;
border-radius:5px
}
.modalBox{
display: flex;
justify-content: space-around;
flex-direction: column;
}
\ No newline at end of file
import { Modal, IconButton } from "@mui/material";
import "./TaskModal.css";
import { Done } from "@mui/icons-material";
import Input from "@mui/material/Input";
import TextField from "@mui/material/Input";
const TaskModal = ({handleClose,open,task,onChange,user }) => {
return (
<Modal
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
BackdropProps={{ style: { backgroundColor: 'rgba(255,255,255, 0)' } }}
closeAfterTransition
onClose={handleClose}
open={open}
>
{task?.isEditMode && task.author.id===user.id ? (
<div className="modal">
<Input
label="название"
color="secondary"
value={task.title}
name="title"
onChange={(e) => onChange(e, task)}
style={{
width: "auto",
fontWeight: "600",
height: "40px",
fontWeight: "600",
width:"280px",
margin:"10px",
padding:"5px",
border: '2px solid #D3D3D3',
borderRadius:"5px"
}}
/>
<TextField
label="описание"
value={task.description}
name="description"
onChange={(e) => onChange(e, task)}
multiline={true}
sx={{
fontWeight: "400",
width:"280px",
margin:"10px",
padding:"5px",
border: '2px solid #D3D3D3',
borderRadius:"5px",
height:"300px",
whiteSpace:"normal"
}}
/>
<IconButton aria-label="done" onClick={handleClose}
sx={{margingBottom:"5px",marginTop:"auto"}}>
<Done />
</IconButton>
</div>
) : (
<div className="modal">
{task && task.title && (
<div
style={{
height: "40px",
fontWeight: "600",
width:"280px",
margin:"10px",
padding:"5px",
border: '2px solid #D3D3D3',
borderRadius:"5px"
}}
>
{task.title}
</div>
)}
{task && task.description && (
<div
style={{margin:"10px",
border: '2px solid #D3D3D3',
borderRadius:"5px",
width:"280px",
height: "200px",
margin:"10px",
padding:"5px",
}}>
{task.description}
</div>
)}
<IconButton
aria-label="close"
onClick={handleClose}
sx={{margingBottom:"5px",marginTop:"auto"}}
>
X
</IconButton>
</div>
)}
</Modal>
);
};
export default TaskModal;
import * as React from 'react';
import AppBar from '@mui/material/AppBar';
import Box from '@mui/material/Box';
import Toolbar from '@mui/material/Toolbar';
import Typography from '@mui/material/Typography';
import Button from '@mui/material/Button';
import MultipleSelect from '../UI/MultipleSelect/MultipleSelect';
import Add from "@mui/icons-material/Add";
import Close from "@mui/icons-material/Close";
export default function MyTaskToolBar({projects,onClose,projectName,setProjectName,formStatus,onClick}) {
let projectsFilter =
<></>
if (projects) {
projectsFilter=
<MultipleSelect
projects={projects}
onClose={onClose}
projectName={projectName}
setProjectName={setProjectName}
/>
}
return (
<Box sx={{ flexGrow: 1 }}>
<AppBar position="static">
<Toolbar>
<Typography variant="h6" component="div" sx={{ flexGrow: 1 }}>
Задачи сотрудников
</Typography>
{projectsFilter}
<Button
color={formStatus === true ? "info" : "inherit"}
style={{
backgroundColor: formStatus === true ? "white" : "inherit",
}}
onClick={onClick}
>
{formStatus === true ? (
<>
<Close />
<span style={{ lineHeight: "16px" }}>Скрыть задачу</span>
</>
) : (
<>
<Add />
<span style={{ lineHeight: "16px" }}>Добавить задачу</span>
</>
)}
</Button>
</Toolbar>
</AppBar>
</Box>
);
}
......@@ -6,6 +6,7 @@ export const workerMenuButtons = [
{ text: 'Проекты', path: '/projects' },
{ text: 'Неделя', path: '/week' },
{ text: 'Месяц', path: '/month' },
{ text: 'Задачи Сотрудников', path: '/workers-tasks' },
{ text: 'Мои задачи', path: '/my-tasks' }
]
......
import * as React from "react";
import {
Box,
Table,
TableBody,
TableContainer,
TablePagination,
Paper,
} from "@mui/material";
import { useState, useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import TaskModal from "../../components/UsersTasksCompoments/TaskModal/TaskModal";
import moment from "moment";
import MyTaskToolBar from "../../components/UsersTasksCompoments/UsersTaskToolBar";
import { fetchAllTasks, deleteTask,editTask, deleteDateTimeTask} from "../../store/actions/tasksActions";
import NewTaskForm from "../../components/UsersTasksCompoments/NewTaskForm";
import TableRowTask from "../../components/UsersTasksCompoments/TableRowTask/TableRowTask";
import UsersTasksHeader from "./UsersTasksHeader/UsersTasksHeader";
export default function UsersTasks() {
const dispatch = useDispatch();
const tasks = useSelector((state) => state.tasks.tasks);
const user = useSelector((state) => state.users.user);
const [executors, setExecutors]=useState([])
const [projects,setProjects]=useState([])
const [currentProject, setCurrentProject] = useState(null);
const [recievedTasks, setRecievedTasks] = useState([]);
const [addTaskForm, setAddTaskForm] = useState(false);
const [order, setOrder] = useState("asc");
const [orderBy, setOrderBy] = useState("id");
const [page, setPage] = useState(0);
const [rowsPerPage, setRowsPerPage] =useState(5);
const [modal, setModal] = useState({
open: false,
task: null,
});
useEffect(() => {
dispatch(fetchAllTasks());
filterProjectsNamesFromTasks()
if (tasks && tasks?.length > 0) {
setRecievedTasks(tasks);
}
}, [dispatch, tasks?.length]);
useEffect(() => {
dispatch(fetchAllTasks());
}, [addTaskForm, setAddTaskForm]);
const handleRequestSort = ( property) => {
const isAsc = orderBy === property && order === "asc";
setOrder(isAsc ? "desc" : "asc");
setOrderBy(property);
};
const handleChangePage = ( newPage) => {
setPage(newPage);
};
const handleChangeRowsPerPage = (event) => {
setRowsPerPage(parseInt(event.target.value, 10));
setPage(0);
};
const onChange = (e, task) => {
const value = e.target.value;
const name = e.target.name;
const { id } = task;
const newTasks = recievedTasks.map((task) => {
console.log('recievedTasks.map ',task)
if (task.id === id) {
return { ...task, [name]: value };
}
return task;
});
setRecievedTasks(newTasks);
};
const onAuthorChange = (e, task) => {
const value = e.target.value;
const { id } = task;
const newTasks = recievedTasks.map((task) => {
if (task.id === id) {
const updated = { ...task };
updated.author.displayName = value;
updated.authorDisplayName = value;
return updated;
}
return task;
});
setRecievedTasks(newTasks);
};
const onDateChange = (id, value, property) => {
const newTasks = recievedTasks.map((task) => {
if (task.id === id) {
return {
...task,
[property]: moment.parseZone(value, "DD/MM/YY", true).format(),
};
}
return task;
});
setRecievedTasks(newTasks);
};
const onProjectChange = (e, task) => {
const projectId = e.target.value;
const project = uniqueProjects.find((uniqueProject) => uniqueProject.id === projectId);
const { id } = task;
const newTasks = recievedTasks.map((task) => {
if (task.id === id) {
const updated = { ...task };
updated.project = project;
updated.projectName = project.title;
return updated;
}
return task;
});
setRecievedTasks(newTasks);
};
const onExecutorChange = (e, task) => {
const executorId = e.target.value;
const executor = executors.find((executor) => executor.id === executorId);
const { id } = task;
const newTasks = recievedTasks.map((task) => {
if (task.id === id) {
const updated = { ...task };
updated.executor = executor;
updated.executorName = executor.displayName;
return updated;
}
return task;
});
setRecievedTasks(newTasks);
};
const onToggleEditMode = (id) => {
const newTasks = recievedTasks.map((task) => {
if (task.id === id) {
return {
...task,
isEditMode: true,
readOnly: false,
};
}
return task;
});
setRecievedTasks(newTasks);
};
const onToggleEditModeDone = (id) => {
const newTasks = recievedTasks.map((task) => {
if (task.id === id) {
return {
...task,
isEditMode: false,
readOnly: true,
};
}
return task;
});
setRecievedTasks(newTasks);
};
const handleEditTask= (task)=>{
dispatch(editTask(task))
}
const deleteHandle = (id) => {
dispatch(deleteTask(id));
};
const deleteDateTimeTaskHandle=(dateTimeTaskId)=>{
console.log('delete by dateTimeTaskId ', dateTimeTaskId)
dispatch(deleteDateTimeTask(dateTimeTaskId))
}
const handleEditDateTimeTask=(dateTimeTask)=>{
console.log('edit by dateTImeTask')
// dispatch(handleEditDateTimeTask(dateTimeTask))
}
const onModalOpen = (event, task) => {
event.stopPropagation();
setModal({ ...modal, open: true, id: task.id });
};
const handleClose = () => {
setModal({ ...modal, open: false, id: null });
};
// ++++++++фильтрация по проектам+++++++++++++++
const [projectName, setProjectName] = React.useState([]);
const [filterProjectTumbler, setFilterProjectTumbler] = React.useState(false);
const onClose=(projectName)=>{
let tasksFilteredByProject = tasks
if (projectName.length>0) {
tasksFilteredByProject = tasks.filter(task=>projectName.includes(task.project?.title))
}
setRecievedTasks(tasksFilteredByProject)
setFilterProjectTumbler(true)
}
const rawProjects= tasks?.map(task=>task.project)
const filterProjectsNamesFromTasks = ()=>{
if (tasks && tasks?.length > 0) {
let rawSetProjectNames = []
for (let project of rawProjects){
if (project===null){
} else{
rawSetProjectNames.push(project.title)
}
}
let uniqueTitlesProjects = [...new Set(rawSetProjectNames)];
setProjects(uniqueTitlesProjects)
}
}
const uniqueProjects = rawProjects?.reduce((results, value, index) => {
const exist = results.find((v) => {
return v !== null && v.id === value?.id
});
if (!exist && value !== null) {
results.push(value);
}
return results;
}, []);
console.log('tasks', tasks)
if (
tasks &&
tasks?.length > 0 &&
recievedTasks &&
recievedTasks?.length > 0
) {
return (
<Box sx={{ width: "fullwidth" }}>
<Paper sx={{ width: "100%", mb: 2 }}>
<MyTaskToolBar
onClick={() => setAddTaskForm(!addTaskForm)}
formStatus={addTaskForm}
projects={projects}
onClose={onClose}
projectName={projectName}
setProjectName={setProjectName}
/>
{addTaskForm ? (
<NewTaskForm
projects={uniqueProjects}
currentProject={currentProject}
setAddTaskForm={()=>setAddTaskForm(false)}
/>
) : null}
<TableContainer>
<Table sx={{ minWidth: 600 }} aria-labelledby="tableTitle">
<UsersTasksHeader
order={order}
orderBy={orderBy}
onRequestSort={handleRequestSort}
rowCount={tasks.length}
/>
<TableBody>
{stableSort(recievedTasks, getComparator(order, orderBy))
.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
.map((task, index) => {
return (
<TableRowTask
key ={index}
user={user}
task={task}
deleteHandle={deleteHandle}
handleEditTask ={handleEditTask}
handleEditDateTimeTask={handleEditDateTimeTask}
deleteDateTimeTask={deleteDateTimeTaskHandle}
onChange={onChange}
onModalOpen={onModalOpen}
onProjectChange={onProjectChange}
executors={executors}
onExecutorChange={onExecutorChange}
uniqueProjects={uniqueProjects}
// onAuthorChange={onAuthorChange}
onDateChange={onDateChange}
onToggleEditMode={onToggleEditMode}
onToggleEditModeDone={onToggleEditModeDone}
/>
);
})}
</TableBody>
</Table>
</TableContainer>
<TablePagination
rowsPerPageOptions={[5, 10, 25]}
component="div"
count={tasks.length}
rowsPerPage={rowsPerPage}
page={page}
onPageChange={handleChangePage}
onRowsPerPageChange={handleChangeRowsPerPage}
/>
</Paper>
<TaskModal
task={recievedTasks.find((task) => task.id === modal.id)}
open={modal.open}
handleClose={handleClose}
onChange={onChange}
user={user}
/>
</Box>
);
}
}
function descendingComparator(a, b, orderBy) {
if (b[orderBy] < a[orderBy]) {
return -1;
}
if (b[orderBy] > a[orderBy]) {
return 1;
}
return 0;
}
function getComparator(order, orderBy) {
return order === "desc"
? (a, b) => descendingComparator(a, b, orderBy)
: (a, b) => -descendingComparator(a, b, orderBy);
}
function stableSort(array, comparator) {
const stabilizedThis = array?.map((el, index) => [el, index]);
stabilizedThis.sort((a, b) => {
const order = comparator(a[0], b[0]);
if (order !== 0) {
return order;
}
return a[1] - b[1];
});
return stabilizedThis.map((el) => el[0]);
}
import * as React from "react";
import PropTypes from "prop-types";
import Box from "@mui/material/Box";
import TableCell from "@mui/material/TableCell";
import TableHead from "@mui/material/TableHead";
import TableRow from "@mui/material/TableRow";
import TableSortLabel from "@mui/material/TableSortLabel";
import { visuallyHidden } from "@mui/utils";
const headCells = [
{
id: "id",
numeric: true,
disablePadding: true,
label: "",
},
{
id: "priority",
numeric: false,
disablePadding: true,
label: "Приоритет",
},
{
id: "createdAt",
numeric: true,
disablePadding: false,
label: "Дата создания",
},
{
id: "title",
numeric: true,
disablePadding: false,
label: "Заголовок",
},
{
id: "projectName",
numeric: true,
disablePadding: false,
label: "Проект",
},
{
id: "executorDisplayName",
numeric: true,
disablePadding: false,
label: "Исполнитель",
},
{
id: "authorDisplayName",
numeric: true,
disablePadding: false,
label: "Автор",
},
{
id: "dateTimeStart",
numeric: true,
disablePadding: false,
label: "Дата и время выполнения",
},
{
id: "dateTimeDue",
numeric: true,
disablePadding: false,
label: "Дедлайн",
},
{
id: "accomplish",
numeric: true,
disablePadding: false,
label: "Статус",
},
{
id: "change",
numeric: false,
disablePadding: false,
label: "",
},
{
id: "delete",
numeric: false,
disablePadding: false,
label: "",
},
];
export default function UsersTasksHeader({ order, orderBy, rowCount, onRequestSort }) {
const createSortHandler = (property) => (event) => {
onRequestSort(event, property);
};
return (
<TableHead>
<TableRow>
{headCells.map((headCell) => (
<TableCell
key={headCell.id}
align={"center"}
padding={headCell.disablePadding ? "none" : "normal"}
sortDirection={orderBy === headCell.id ? order : false}
>
<TableSortLabel
active={orderBy === headCell.id}
direction={orderBy === headCell.id ? order : "asc"}
onClick={createSortHandler(headCell.id)}
>
{headCell.label}
{orderBy === headCell.id ? (
<Box component="span" sx={visuallyHidden}>
{order === "desc" ? "sorted descending" : "sorted ascending"}
</Box>
) : null}
</TableSortLabel>
</TableCell>
))}
</TableRow>
</TableHead>
);
}
UsersTasksHeader.propTypes = {
onRequestSort: PropTypes.func.isRequired,
order: PropTypes.oneOf(["asc", "desc"]).isRequired,
orderBy: PropTypes.string.isRequired,
rowCount: PropTypes.number.isRequired,
};
......@@ -53,7 +53,7 @@ export const fetchProjects = () => {
return async dispatch => {
dispatch(fetchProjectsRequest());
try {
const response = await axios.get("/projects");
const response = await axios.get("/projects/my");
dispatch(fetchProjectsSuccess(response.data));
} catch(e) {
dispatch(fetchProjectsError(e));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment