Commit 7f55d5c6 authored by Ermolaev Timur's avatar Ermolaev Timur

#149 Начал проектировку с самого начала, начал разделять дефолтную таблицу на компоненты

parent e5558375
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,
colSpan
}) => {
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
colSpan={colSpan}
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 { addTaskToUserTasksTable } from "../../store/actions/tasksActions";
import TaskModal from "./TaskModal/TaskModal";
export default function NewTaskForm({
projects,
currentProject,
setCurrentProject,
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?projects.find(project=>project.title==="Не определено"):null,
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((project) => project.id === value);
setCurrentProject(project)
const newTask = { ...task };
newTask.project = project;
setTask(newTask);
};
const onExecutorChange = (e, task) => {
const {value, name} = e.target.value;
let executorMember = null
const newTask = { ...task };
if( name==='executor' && value!==null) {
executorMember = currentProject.find((member) => member.user.id === value);
newTask.executor = executorMember?.user;
}
setTask(newTask);
};
const onDateChange = (id, value, property) => {
const newTask = {
...task,
[property]: moment.parseZone(value, "DD/MM/YYYY", true).format(),
};
setTask(newTask);
};
const handleAddTask = () => {
dispatch(addTaskToUserTasksTable(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"}
colSpan={headCell.colSpan}
>
{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
colSpan={3}
{...{
task,
name: "title",
value: task.title,
onModalOpen,
user: user,
placeholder: "Кликните для ввода информации по задаче"
}}
/>
<TableCell>
<BasicSelect
items={projects?.map((project) => ({
value: project?.id,
title: project?.title,
}))}
task={task}
onChange={onProjectChange}
name="project"
value={task.project?.id}
/>
</TableCell>
<TableCell>
<BasicSelect
items={currentProject?currentProject?.members.map((member) => ({
value: member?.user?.id,
title: member?.user?.displayName,
})):null}
task={task}
onChange={onExecutorChange}
name="executor"
value={task?.executor?.id}
defaultValue={user.id}
/>
</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: "title",
numeric: false,
disablePadding: false,
label: "Заголовок",
colSpan:3
},
{
id: "projectName",
numeric: true,
disablePadding: false,
label: "Проект",
},
{
id: "executorName",
numeric: false,
disablePadding: false,
label: "Исполнитель",
},
{
id: "dateTimeDeadLine",
numeric: true,
disablePadding: false,
label: "Дедлайн",
},
{
id: "add",
numeric: false,
disablePadding: false,
label: "",
},
];
import React,{useState} 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';
import { TaskStatuses } from "../../../helpers/TableTasksHelpers";
const weekDays = ["Вс","Пн","Вт","Ср","Чт","Пт","Сб" ];
const TableRowTask= ({
user,
task,
deleteHandle,
handleEditTask,
deleteDateTimeTask,
onChange,
onModalOpen,
// onProjectChange,
// onExecutorChange,
uniqueProjects,
// executors,
onDateChange,
onToggleEditMode,
onToggleEditModeDone,
})=>{
const [open, setOpen] = useState(false);
const [defaultExecutor, setDefaultExecutor] = useState(task.executor?.id)
const [executors, setExecutors]=useState([])
const [currentProject, setCurrentProject] = useState(null);
const [recievedTasks, setRecievedTasks] = useState([]);
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()];
}
const onProjectChange = (e, task) => {
e.preventDefault()
setDefaultExecutor(user)
const projectId = e.target.value;
const project = uniqueProjects.length>0 ?uniqueProjects.find((uniqueProject) => uniqueProject.id === projectId):null;
console.log('change project ', project)
setCurrentProject(project)
let executorList=[]
if(project?.members){
for (let member of project.members){
executorList.push(member.user)
}
}
setExecutors(executorList)
// const { id } = task;
// const newTasks = recievedTasks.map((task) => {
// if (task.id === id) {
// const updated = { ...task };
// updated.project = project;
// updated.projectName =project.title? project.title:null;
// return updated;
// }
task.project = project;
task.projectName=project.title? project.title:null;
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);
task.executor = executor;
task.executorName = executor.displayName;
return task;
};
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"
defaultValue={defaultExecutor?.id}
/>
</TableCell>
) : (
<CustomTableCell
{...{
task,
name: "executor",
value: task.executor?.displayName,
user:user
}}
/>
)}
<CustomTableCell
{...{
task,
name: "author",
value: task.author.displayName,
user:user
}}
/>
{task.isEditMode && task.author.id===user.id ? (
<TableCell>
<Tooltip title="Перейти в календарь">
<IconButton
onClick={(id) => { deleteHandle(task.id);}}
>
<CalendarMonthIcon />
</IconButton>
</Tooltip>
</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>
)}
{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: "создано" },
{ value: "done", title: "выполнено" },
{ value: "failed", title: "просрочено" },
{ value: "progress", title: "в работе" },
{ value: "cancelled", title: "отменено" },
]}
task={task}
onChange={onChange}
name="accomplish"
value={task.accomplish}
user={user}
/>
</TableCell>
) : (
<CustomTableCell
{...{
task,
name: "accomplish",
value: TaskStatuses[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%'}}
>
</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 UsersTaskToolBar({projects,onClose,projectIdListForTaskSelect,setProjectIdListForTaskSelect,formStatus,onClick}) {
let projectsFilter =
<></>
if (Array.isArray(projects)) {
projectsFilter=
<MultipleSelect
projects={projects}
onClose={onClose}
projectName={projectIdListForTaskSelect}
setProjectName={setProjectIdListForTaskSelect}
/>
}
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>
);
}
import { Table, TableBody, TableCell, TableContainer, TableRow} from "@mui/material";
import { memo } from "react";
import UsersTasksTableHead from "../UsersTasksTableHead/UsersTasksTableHead";
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]);
}
function descendingComparator(a, b, orderBy) {
if (b[orderBy] < a[orderBy]) {
return -1;
}
if (b[orderBy] > a[orderBy]) {
return 1;
}
return 0;
}
function UsersTasksTableContainer({order, orderBy, handleRequestSort, rows, page, rowsPerPage}) {
const emptyRows = page > 0 ? Math.max(0, (1 + page) * rowsPerPage - rows.length) : 0;
return (
<TableContainer>
<Table
sx={{ minWidth: 750 }}
aria-labelledby="tableTitle"
>
<UsersTasksTableHead
order={order}
orderBy={orderBy}
onRequestSort={handleRequestSort}
/>
<TableBody>
{stableSort(rows, getComparator(order, orderBy))
.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
.map((row, index) => {
return (
<TableRow
hover
tabIndex={-1}
key={row.name}
>
<TableCell
component="th"
scope="row"
padding="none"
>
{row.name}
</TableCell>
<TableCell align="right">{row.calories}</TableCell>
<TableCell align="right">{row.fat}</TableCell>
<TableCell align="right">{row.carbs}</TableCell>
<TableCell align="right">{row.protein}</TableCell>
</TableRow>
);
})}
{emptyRows > 0 && (
<TableRow>
<TableCell colSpan={6} />
</TableRow>
)}
</TableBody>
</Table>
</TableContainer>
);
}
export default memo(UsersTasksTableContainer)
\ No newline at end of file
import * as React from "react"; import { Box, TableCell, TableHead, TableRow, TableSortLabel } from "@mui/material";
import PropTypes from "prop-types"; import { visuallyHidden } from '@mui/utils';
import Box from "@mui/material/Box"; import { memo } from "react";
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 = [ const headCells = [
{ {
id: "id", id: 'name',
numeric: true,
disablePadding: true,
label: "",
},
{
id: "priority",
numeric: false, numeric: false,
disablePadding: true, disablePadding: true,
label: "Приоритет", label: 'Dessert (100g serving)',
},
{
id: "createdAt",
numeric: true,
disablePadding: false,
label: "Дата создания",
}, },
{ {
id: "title", id: 'calories',
numeric: true, numeric: true,
disablePadding: false, disablePadding: false,
label: "Заголовок", label: 'Calories',
}, },
{ {
id: "projectName", id: 'fat',
numeric: true, numeric: true,
disablePadding: false, disablePadding: false,
label: "Проект", label: 'Fat (g)',
}, },
{ {
id: "executorDisplayName", id: 'carbs',
numeric: true, numeric: true,
disablePadding: false, disablePadding: false,
label: "Исполнитель", label: 'Carbs (g)',
}, },
{ {
id: "authorDisplayName", id: 'protein',
numeric: true, numeric: true,
disablePadding: false, disablePadding: false,
label: "Автор", label: 'Protein (g)',
},
{
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 }) { function UsersTasksTableHead({ order, orderBy, onRequestSort }) {
const createSortHandler = (property) => (event) => { const createSortHandler = (property) => (event) => {
onRequestSort(event, property); onRequestSort(event, property);
}; };
...@@ -95,19 +46,19 @@ export default function UsersTasksHeader({ order, orderBy, rowCount, onRequestSo ...@@ -95,19 +46,19 @@ export default function UsersTasksHeader({ order, orderBy, rowCount, onRequestSo
{headCells.map((headCell) => ( {headCells.map((headCell) => (
<TableCell <TableCell
key={headCell.id} key={headCell.id}
align={"center"} align={headCell.numeric ? 'right' : 'left'}
padding={headCell.disablePadding ? "none" : "normal"} padding={headCell.disablePadding ? 'none' : 'normal'}
sortDirection={orderBy === headCell.id ? order : false} sortDirection={orderBy === headCell.id ? order : false}
> >
<TableSortLabel <TableSortLabel
active={orderBy === headCell.id} active={orderBy === headCell.id}
direction={orderBy === headCell.id ? order : "asc"} direction={orderBy === headCell.id ? order : 'asc'}
onClick={createSortHandler(headCell.id)} onClick={createSortHandler(headCell.id)}
> >
{headCell.label} {headCell.label}
{orderBy === headCell.id ? ( {orderBy === headCell.id ? (
<Box component="span" sx={visuallyHidden}> <Box component="span" sx={visuallyHidden}>
{order === "desc" ? "sorted descending" : "sorted ascending"} {order === 'desc' ? 'sorted descending' : 'sorted ascending'}
</Box> </Box>
) : null} ) : null}
</TableSortLabel> </TableSortLabel>
...@@ -118,9 +69,4 @@ export default function UsersTasksHeader({ order, orderBy, rowCount, onRequestSo ...@@ -118,9 +69,4 @@ export default function UsersTasksHeader({ order, orderBy, rowCount, onRequestSo
); );
} }
UsersTasksHeader.propTypes = { export default memo(UsersTasksTableHead)
onRequestSort: PropTypes.func.isRequired, \ No newline at end of file
order: PropTypes.oneOf(["asc", "desc"]).isRequired,
orderBy: PropTypes.string.isRequired,
rowCount: PropTypes.number.isRequired,
};
import { TablePagination } from "@mui/material";
import { memo } from "react";
function UsersTasksTablePagination({count, rowsPerPage, page, handleChangePage, handleChangeRowsPerPage}) {
return (
<TablePagination
rowsPerPageOptions={[5, 10, 25]}
component="div"
count={count}
rowsPerPage={rowsPerPage}
page={page}
onPageChange={handleChangePage}
onRowsPerPageChange={handleChangeRowsPerPage}
/>
);
}
export default memo(UsersTasksTablePagination)
\ No newline at end of file
import { Toolbar, Typography } from "@mui/material";
import { memo } from "react";
function UsersTasksTableToolbar() {
return (
<Toolbar>
<Typography
sx={{ flex: '1 1 100%' }}
variant="h6"
id="tableTitle"
component="div"
>
Nutrition
</Typography>
</Toolbar>
);
}
export default memo(UsersTasksTableToolbar)
\ No newline at end of file
import * as React from "react"; import * as React from 'react';
import { import Box from '@mui/material/Box';
Box, import Paper from '@mui/material/Paper';
Table, import UsersTasksTableToolbar from '../../components/UsersTasksCompoments/UsersTasksTableToolbar/UsersTasksTableToolbar';
TableBody, import UsersTasksTablePagination from '../../components/UsersTasksCompoments/UsersTasksTablePagination/UsersTasksTablePagination';
TableContainer, import UsersTasksTableContainer from '../../components/UsersTasksCompoments/UsersTasksTableContainer/UsersTasksTableContainer';
TablePagination,
Paper, function createData(name, calories, fat, carbs, protein) {
} from "@mui/material"; return {
import { useState, useEffect } from "react"; name,
import { useDispatch, useSelector } from "react-redux"; calories,
import TaskModal from "../../components/UsersTasksCompoments/TaskModal/TaskModal"; fat,
import moment from "moment"; carbs,
import UsersTaskToolBar from "../../components/UsersTasksCompoments/UsersTaskToolBar"; protein,
import { deleteTask, editTask, deleteDateTimeTask , fetchAllTasksByMembership} 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 projects = useSelector((state) => state.tasks.projects);
const user = useSelector((state) => state.users.user);
const [executors, setExecutors]=useState([])
// const [currentExecutor, setCurrentExecutor]= useState(task.executor.id?task.executor:'')
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(25);
const [modal, setModal] = useState({
open: false,
task: null,
});
useEffect(() => {
dispatch(fetchAllTasksByMembership());
if (tasks && tasks?.length > 0) {
setRecievedTasks(tasks);
}
}, [dispatch,
tasks?.length,
addTaskForm, setAddTaskForm]);
const handleRequestSort = ( property) => { const rows = [
const isAsc = orderBy === property && order === "asc"; createData('Cupcake', 305, 3.7, 67, 4.3),
setOrder(isAsc ? "desc" : "asc"); createData('Donut', 452, 25.0, 51, 4.9),
createData('Eclair', 262, 16.0, 24, 6.0),
createData('Frozen yoghurt', 159, 6.0, 24, 4.0),
createData('Gingerbread', 356, 16.0, 49, 3.9),
createData('Honeycomb', 408, 3.2, 87, 6.5),
createData('Ice cream sandwich', 237, 9.0, 37, 4.3),
createData('Jelly Bean', 375, 0.0, 94, 0.0),
createData('KitKat', 518, 26.0, 65, 7.0),
createData('Lollipop', 392, 0.2, 98, 0.0),
createData('Marshmallow', 318, 0, 81, 2.0),
createData('Nougat', 360, 19.0, 9, 37.0),
createData('Oreo', 437, 18.0, 63, 4.0),
];
export default function EnhancedTable() {
const [order, setOrder] = React.useState('asc');
const [orderBy, setOrderBy] = React.useState('calories');
const [page, setPage] = React.useState(0);
const [rowsPerPage, setRowsPerPage] = React.useState(5);
const handleRequestSort = (event, property) => {
const isAsc = orderBy === property && order === 'asc';
setOrder(isAsc ? 'desc' : 'asc');
setOrderBy(property); setOrderBy(property);
}; };
const handleChangePage = ( newPage) => { const handleChangePage = (event, newPage) => {
setPage(newPage); setPage(newPage);
}; };
...@@ -65,255 +52,24 @@ export default function UsersTasks() { ...@@ -65,255 +52,24 @@ export default function UsersTasks() {
setPage(0); setPage(0);
}; };
const onChange = (e, task) => { return (
const value = e.target.value; <Paper sx={{ width: '100%', mb: 2 }}>
const name = e.target.name; <UsersTasksTableToolbar />
const { id } = task; <UsersTasksTableContainer
const newTasks = recievedTasks.map((task) => { order={order}
if (task.id === id) { orderBy={orderBy}
return { ...task, [name]: value }; onRequestSort={handleRequestSort}
} rows={rows}
return task; page={page}
}); rowsPerPage={rowsPerPage}
setRecievedTasks(newTasks); />
}; <UsersTasksTablePagination
count={rows.length}
rowsPerPage={rowsPerPage}
const onDateChange = (id, value, property) => { page={page}
const newTasks = recievedTasks.map((task) => { handleChangePage={handleChangePage}
if (task.id === id) { handleChangeRowsPerPage={handleChangeRowsPerPage}
return { />
...task, </Paper>
[property]: moment.parseZone(value, "DD/MM/YY", true).format(), );
};
}
return task;
});
setRecievedTasks(newTasks);
};
const onProjectChange = (e, task) => {
const projectId = e.target.value;
const project = projects.length>0 ?projects.find((uniqueProject) => uniqueProject.id === projectId):null;
setCurrentProject(project)
let executorList=[]
if(project?.members){
for (let member of project.members){
executorList.push(member.user)
}
}
setExecutors(executorList)
const { id } = task;
const newTasks = recievedTasks.map((task) => {
if (task.id === id) {
const updated = { ...task };
updated.project = project;
updated.projectName =project.title? project.title:null;
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) {
console.log('toggledDone task ', task)
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 onModalOpen = (event, task) => {
event.stopPropagation();
setModal({ ...modal, open: true, id: task.id });
};
const handleClose = () => {
setModal({ ...modal, open: false, id: null });
};
// ++++++++фильтрация по проектам+++++++++++++++
const [projectIdListForTaskSelect, setProjectIdListForTaskSelect] = React.useState([]);
const [filterProjectTumbler, setFilterProjectTumbler] = React.useState(false);
const onClose=(projectIdListForTaskSelect)=>{
let tasksFilteredByProject = tasks
if (projectIdListForTaskSelect.length>0) {
tasksFilteredByProject = tasks.filter(task=>projectIdListForTaskSelect.includes(task.project?.id))
}
setRecievedTasks(tasksFilteredByProject)
setFilterProjectTumbler(true)
}
// if (
// tasks &&
// tasks?.length > 0 &&
// recievedTasks &&
// recievedTasks?.length > 0
// ) {
return (
<Box sx={{ width: "fullwidth" }}>
<Paper sx={{ width: "100%", mb: 2 }}>
<UsersTaskToolBar
onClick={() => setAddTaskForm(!addTaskForm)}
formStatus={addTaskForm}
projects={projects}
onClose={onClose}
projectIdListForTaskSelect={projectIdListForTaskSelect}
setProjectIdListForTaskSelect={setProjectIdListForTaskSelect}
/>
{addTaskForm ? (
<NewTaskForm
projects={projects}
setCurrentProject={setCurrentProject}
currentProject={currentProject}
setAddTaskForm={()=>setAddTaskForm(false)}
/>
) : null}
<TableContainer>
<Table sx={{ minWidth: 600 }} aria-labelledby="tableTitle" size='small'>
<UsersTasksHeader
order={order}
orderBy={orderBy}
onRequestSort={handleRequestSort}
rowCount={recievedTasks.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}
deleteDateTimeTask={deleteDateTimeTaskHandle}
onChange={onChange}
onModalOpen={onModalOpen}
onProjectChange={onProjectChange}
executors={executors}
onExecutorChange={onExecutorChange}
uniqueProjects={projects}
onDateChange={onDateChange}
onToggleEditMode={onToggleEditMode}
onToggleEditModeDone={onToggleEditModeDone}
/>
);
})}
</TableBody>
</Table>
</TableContainer>
<TablePagination
rowsPerPageOptions={[5, 10, 25]}
component="div"
count={recievedTasks.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]);
} }
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