Commit 8f1aa7fe authored by Ermolaev Timur's avatar Ermolaev Timur

Merge branch 'task-100-feature/create_logic_for_tasks' into 'development'

Task 100 feature/create logic for tasks

See merge request !74
parents 6b73c9c8 a43800ac
import {Button} from "@mui/material"; import { Button } from "@mui/material";
import {NavLink} from "react-router-dom"; import { NavLink } from "react-router-dom";
import { superuserMenuButtons } from "../../../constants"; import { superuserMenuButtons } from "../../../constants";
import ProfileBlock from "../ProfileBlock/ProfileBlock"; import ProfileBlock from "../ProfileBlock/ProfileBlock";
const AdminMenu = () => { const AdminMenu = () => {
return <> return <>
{superuserMenuButtons.map((button, i)=>{ {superuserMenuButtons.map((button, i) => {
return( return (
<Button <Button
key={i} key={i}
component={NavLink} component={NavLink}
...@@ -19,7 +19,7 @@ const AdminMenu = () => { ...@@ -19,7 +19,7 @@ const AdminMenu = () => {
</Button> </Button>
) )
})} })}
<ProfileBlock/> <ProfileBlock />
</> </>
}; };
......
import {Button} from "@mui/material"; import { Button } from "@mui/material";
import {NavLink} from "react-router-dom"; import { NavLink } from "react-router-dom";
import { anonymoysMenuButtons } from "../../../constants"; import { anonymoysMenuButtons } from "../../../constants";
const AnonymousMenu = () => { const AnonymousMenu = () => {
return <> return <>
{anonymoysMenuButtons.map((button, i)=>{ {anonymoysMenuButtons.map((button, i) => {
return( return (
<Button <Button
key={i} key={i}
component={NavLink} component={NavLink}
......
import {Button} from "@mui/material"; import { Button } from "@mui/material";
import {NavLink} from "react-router-dom"; import { NavLink } from "react-router-dom";
import { workerMenuButtons } from "../../../constants"; import { workerMenuButtons } from "../../../constants";
import ProfileBlock from "../ProfileBlock/ProfileBlock"; import ProfileBlock from "../ProfileBlock/ProfileBlock";
const WorkerMenu = () => { const WorkerMenu = () => {
return <> return <>
{workerMenuButtons.map((button, i)=>{ {workerMenuButtons.map((button, i) => {
return( return (
<Button <Button
key={i} key={i}
component={NavLink} component={NavLink}
...@@ -19,8 +19,8 @@ const WorkerMenu = () => { ...@@ -19,8 +19,8 @@ const WorkerMenu = () => {
</Button> </Button>
) )
})} })}
<ProfileBlock/> <ProfileBlock />
</> </>
}; };
......
import { Grid } from "@mui/material"; import { Grid } from "@mui/material";
const CalendarRow = ({children, week}) => { const CalendarRow = ({ children, week }) => {
return <> return <>
<Grid <Grid
container container
align='center' align='center'
sx={{borderBottom: week ? null : '1px solid black', borderLeft: '1px solid black'}} sx={{ borderBottom: week ? null : '1px solid black', borderLeft: '1px solid black' }}
> >
{children} {children}
</Grid> </Grid>
</> </>
}; };
export default CalendarRow; export default CalendarRow;
......
import { Grid } from "@mui/material"; import { Grid } from "@mui/material";
import { memo, useMemo} from "react"; import { memo, useMemo } from "react";
import { getHoursInDayNumbers, getAvailableTasks, getLinesInDay, getSortedTasks } from "../../../../helpers/CalendarHelpers";
import CalendarStandartCell from "../CalendarStandartCell.js/CalendarStandartCell"; import CalendarStandartCell from "../CalendarStandartCell.js/CalendarStandartCell";
import CalendarTask from "../CalendarTask/CalendarTask"; import CalendarTask from "../CalendarTask/CalendarTask";
import EmptyBox from "./EmptyBox/EmptyBox"; import EmptyBox from "./EmptyBox/EmptyBox";
import { getAvailableTasks, getBoxesInLine, getLinesInDay, getSortedTasks } from "./Helpers"; import { getBoxesInLine } from "./Helpers";
const CalendarRowDay = ({xs, hoursInDay, createTaskInCellHandler, currentTask, handleOpen, modal, setCurrentTask, year, month, tasks, day, hourFormat, setCurrentLine, currentLine, dragTaskHandler, createCopyTask, setCopyTask, copyTask}) => { const CalendarRowDay = ({ xs, hoursInDay, createTaskInCellHandler, currentTask, handleOpen, modal, setCurrentTask, year, month, tasks, day, hourFormat, setCurrentLine, currentLine, dragTaskHandler, createCopyTask, setCopyTask, copyTask }) => {
const hours = useMemo(()=>{ const hours = useMemo(() => {
return hoursInDay.map((hour)=>parseInt(hour.split(':')[0]))}, return getHoursInDayNumbers(hoursInDay)
[hoursInDay]) }, [hoursInDay])
const availableTasks = useMemo(() => { const availableTasks = useMemo(() => {
return getAvailableTasks(tasks, year, month, day.dayNumber) return getAvailableTasks(tasks, year, month, day.dayNumber)
...@@ -24,99 +25,99 @@ const CalendarRowDay = ({xs, hoursInDay, createTaskInCellHandler, currentTask, h ...@@ -24,99 +25,99 @@ const CalendarRowDay = ({xs, hoursInDay, createTaskInCellHandler, currentTask, h
}, [availableTasks, hourFormat, hours, hoursInDay, sortedTasks]) }, [availableTasks, hourFormat, hours, hoursInDay, sortedTasks])
return <> return <>
<Grid <Grid
container container
item item
xs={10.8} xs={10.8}
align='center' align='center'
sx={{position: 'relative'}} sx={{ position: 'relative' }}
> >
{hoursInDay.map((hour, i)=>{ {hoursInDay.map((hour, i) => {
return ( return (
<CalendarStandartCell <CalendarStandartCell
linesInDay={linesInDay} linesInDay={linesInDay}
key={i} key={i}
item xs={xs} item xs={xs}
createTaskInCellHandler={createTaskInCellHandler} createTaskInCellHandler={createTaskInCellHandler}
hours={hour} hours={hour}
dragTaskHandler={dragTaskHandler} dragTaskHandler={dragTaskHandler}
dayNumber={day.dayNumber} dayNumber={day.dayNumber}
currentTask={currentTask} currentTask={currentTask}
handleOpen={handleOpen} handleOpen={handleOpen}
modal={modal} modal={modal}
> >
</CalendarStandartCell> </CalendarStandartCell>
) )
})} })}
<Grid sx={{position: 'absolute', top: '0'}} container item xs={12}> <Grid sx={{ position: 'absolute', top: '0' }} container item xs={12}>
{linesInDay?.map((line, i)=>{ {linesInDay?.map((line, i) => {
const boxes = getBoxesInLine(line, hoursInDay, sortedTasks) const boxes = getBoxesInLine(line, hoursInDay, sortedTasks)
return( return (
<Grid key={i} container sx={{height: '35px', backgroundColor: 'rgb(0,0,0,0)', marginBottom: '5px'}}> <Grid key={i} container sx={{ height: '35px', backgroundColor: 'rgb(0,0,0,0)', marginBottom: '5px' }}>
{boxes.map((box, index)=>{ {boxes.map((box, index) => {
if (box.task) { if (box.task) {
return (<Grid return (<Grid
item xs={box.xs} item xs={box.xs}
key={box.task.id} key={box.task.id}
sx={{height: '35px', marginBottom: '5px'}} sx={{ height: '35px', marginBottom: '5px' }}
> >
<CalendarTask <CalendarTask
dragTaskHandler={dragTaskHandler}
setCurrentLine={()=>{setCurrentLine(day.dayNumber)}}
currentTask={currentTask}
currentLine={currentLine}
hour={parseInt(hours[index])}
line={day.dayNumber}
task={box.task}
setCurrentTask={setCurrentTask}
handleOpen={handleOpen}
setCopyTask={setCopyTask}
/>
</Grid>)
} else {
return (<EmptyBox
key={index}
modal={modal}
dayNumber={day.dayNumber}
hourNumber={box.hour}
handleOpen={handleOpen}
dragTaskHandler={dragTaskHandler} dragTaskHandler={dragTaskHandler}
createCopyTask={createCopyTask} setCurrentLine={() => { setCurrentLine(day.dayNumber) }}
copyTask={copyTask} currentTask={currentTask}
createTaskInCellHandler={createTaskInCellHandler} currentLine={currentLine}
xs={box.xs} hour={parseInt(hours[index])}
> line={day.dayNumber}
</EmptyBox>) task={box.task}
} setCurrentTask={setCurrentTask}
})} handleOpen={handleOpen}
</Grid>) setCopyTask={setCopyTask}
})} />
</Grid> </Grid>)
} else {
<Grid container sx={{height: '35px', backgroundColor: 'rgb(0,0,0,0)', marginBottom: '5px', position: 'absolute', bottom: '0'}}> return (<EmptyBox
{hoursInDay.map((hour, i)=>{ key={index}
const hourNumber = parseInt(hour) modal={modal}
return(<EmptyBox dayNumber={day.dayNumber}
key={i} hourNumber={box.hour}
modal={modal} handleOpen={handleOpen}
dayNumber={day.dayNumber} dragTaskHandler={dragTaskHandler}
hourNumber={hourNumber} createCopyTask={createCopyTask}
handleOpen={handleOpen} copyTask={copyTask}
dragTaskHandler={dragTaskHandler} createTaskInCellHandler={createTaskInCellHandler}
createCopyTask={createCopyTask} xs={box.xs}
copyTask={copyTask}
createTaskInCellHandler={createTaskInCellHandler}
xs={xs}
> >
</EmptyBox>) </EmptyBox>)
}
})} })}
</Grid> </Grid>)
</Grid> })}
</> </Grid>
<Grid container sx={{ height: '35px', backgroundColor: 'rgb(0,0,0,0)', marginBottom: '5px', position: 'absolute', bottom: '0' }}>
{hoursInDay.map((hour, i) => {
const hourNumber = parseInt(hour)
return (<EmptyBox
key={i}
modal={modal}
dayNumber={day.dayNumber}
hourNumber={hourNumber}
handleOpen={handleOpen}
dragTaskHandler={dragTaskHandler}
createCopyTask={createCopyTask}
copyTask={copyTask}
createTaskInCellHandler={createTaskInCellHandler}
xs={xs}
>
</EmptyBox>)
})}
</Grid>
</Grid>
</>
}; };
export default memo(CalendarRowDay, (prevProps, nextProps)=>{ export default memo(CalendarRowDay, (prevProps, nextProps) => {
if(!prevProps.modal) return false if (!prevProps.modal) return false
if(nextProps.modal) return true if (nextProps.modal) return true
}); });
import { Grid} from "@mui/material"; import { Grid } from "@mui/material";
import React, { memo, useEffect, useState} from "react"; import React, { memo, useEffect, useState } from "react";
import DefaultTask from "../../DefaultTask/DefaultTask"; import DefaultTask from "../../DefaultTask/DefaultTask";
const EmptyBox = ({hourNumber, handleOpen, dayNumber, xs, dragTaskHandler, modal, createTaskInCellHandler, copyTask, createCopyTask}) => { const EmptyBox = ({ hourNumber, handleOpen, dayNumber, xs, dragTaskHandler, modal, createTaskInCellHandler, copyTask, createCopyTask }) => {
const [isThisCell, setIsThisCell] = useState(false) const [isThisCell, setIsThisCell] = useState(false)
useEffect(()=>{ useEffect(() => {
if(!modal) { if (!modal) {
setIsThisCell(false); setIsThisCell(false);
} }
}, [modal]) }, [modal])
const onClickHandler = (e, dayNumber, hour) => { const onClickHandler = (e, dayNumber, hour) => {
...@@ -19,7 +19,7 @@ const EmptyBox = ({hourNumber, handleOpen, dayNumber, xs, dragTaskHandler, modal ...@@ -19,7 +19,7 @@ const EmptyBox = ({hourNumber, handleOpen, dayNumber, xs, dragTaskHandler, modal
setIsThisCell(true); setIsThisCell(true);
handleOpen(e) handleOpen(e)
} }
} }
const dragOverHandler = (e) => { const dragOverHandler = (e) => {
e.preventDefault(); e.preventDefault();
} }
...@@ -30,23 +30,23 @@ const EmptyBox = ({hourNumber, handleOpen, dayNumber, xs, dragTaskHandler, modal ...@@ -30,23 +30,23 @@ const EmptyBox = ({hourNumber, handleOpen, dayNumber, xs, dragTaskHandler, modal
dragTaskHandler(dayNumber, hourNumber) dragTaskHandler(dayNumber, hourNumber)
} }
return(<Grid return (<Grid
onDragOver={(e)=>{dragOverHandler(e)}} onDragOver={(e) => { dragOverHandler(e) }}
onDrop={(e)=>{dropHandler(e)}} onDrop={(e) => { dropHandler(e) }}
onClick={(e)=>{onClickHandler(e, dayNumber, hourNumber)}} onClick={(e) => { onClickHandler(e, dayNumber, hourNumber) }}
className='test_empty_box' className='test_empty_box'
item xs={xs} sx={{ item xs={xs} sx={{
height: '40px', height: '40px',
backgroundColor: 'rgb(0,0,0,0)', backgroundColor: 'rgb(0,0,0,0)',
zIndex: '6', zIndex: '6',
cursor: copyTask ? 'pointer' : 'default' cursor: copyTask ? 'pointer' : 'default'
}}> }}>
{isThisCell ? {isThisCell ?
<DefaultTask/> : ' '} <DefaultTask /> : ' '}
</Grid>) </Grid>)
}; };
export default memo(EmptyBox, (prevProps, nextProps)=>{ export default memo(EmptyBox, (prevProps, nextProps) => {
if(!prevProps.modal) return false if (!prevProps.modal) return false
if(nextProps.modal) return true if (nextProps.modal) return true
}); });
\ No newline at end of file
const taskIsAvailableInCell = (task, hour, hourDiffEnd, hourDiff, hourFormat) => {
if (((task.infoForCell.endHour <= hour || task.infoForCell.startHour <= hour) && (task.infoForCell.endHour > hour))
|| (!hourFormat && task.infoForCell.startHour >= hour && task.infoForCell.endHour < hour + hourDiff)
|| (!hourFormat && task.infoForCell.startHour === hour + hourDiffEnd && task.infoForCell.endHour > hour)
|| (task.infoForCell.endMinute <= 59 && task.infoForCell.endHour === hour)) {
return true
} else {
return false
}
}
const lastPlaceInLineForTask = (task, hour, hourDiffEnd, hourFormat) => {
if ((task.infoForCell.endMinute === 59 && task.infoForCell.endHour === hour + hourDiffEnd) || (!hourFormat && task.infoForCell.endMinute === 59 && task.infoForCell.endHour === hour)) {
return true
} else {
return false
}
}
export const getLinesInDay = (availableTasks, sortedTasks, hoursInDay, hours, hourFormat) => {
let hourDiff
let hourDiffEnd
const lines = []
if (hourFormat) {
hourDiff = 1
hourDiffEnd = 0
} else {
hourDiff = 2
hourDiffEnd = 1
}
if (availableTasks.length) {
lines.push(hoursInDay.map((hour)=>parseInt(hour.split(':')[0])))
for (let k = 0; k < sortedTasks.length; k++) {
let skipLine = false
for (let j = 0; j < lines.length; j++) {
const line = lines[j]
const task = sortedTasks[k]
if (skipLine) {
skipLine = false
break;
}
for (let i = 0; i < line.length; i++) {
const hour = hours[i]
let havePlace = true
if (taskIsAvailableInCell(task, hour, hourDiffEnd, hourDiff, hourFormat)) {
if (!isNaN(line[i])) {
for (let a = 0; a < hours.length; a++) {
const hour = hours[a]
if (lastPlaceInLineForTask(task, hour, hourDiffEnd, hourFormat)) {
if (isNaN(line[a])) {
havePlace = false
break;
}
}
}
if (!havePlace) {
if (j + 1 === lines.length) {
lines.push(hoursInDay.map((hour)=>parseInt(hour.split(':')[0])))
}
havePlace = true
break;
}
line[i] += `-${k}`
if (lastPlaceInLineForTask(task, hour, hourDiffEnd, hourFormat)) {
skipLine = true
break;
}
} else {
if (j + 1 === lines.length) {
lines.push(hoursInDay.map((hour)=>parseInt(hour.split(':')[0])))
}
break;
}
}
}
}
}
}
return lines
}
export const getSortedTasks = (availableTasks) => {
if (availableTasks.length) {
const newSortedArr = [...availableTasks].sort(function(a,b){
const durattionFirstDate = a.infoForCell.endHour - a.infoForCell.startHour
const durattionSecondDate = b.infoForCell.endHour - b.infoForCell.startHour
return durattionSecondDate - durattionFirstDate;
})
return newSortedArr
}
}
export const getAvailableTasks = (tasks, year, month, dayNumber) => {
const tasksInDay = tasks.filter((task)=> {
if (year === task.infoForCell.startYear) {
if (month + 1 === task.infoForCell.startMonth) {
if (dayNumber === task.infoForCell.startDay) {
return task
} else {return false}
} else {return false}
} else {return false}
})
return tasksInDay
}
export const getBoxesInLine = (line, hoursInDay, sortedTasks) => { export const getBoxesInLine = (line, hoursInDay, sortedTasks) => {
if (line) { if (line) {
let xs = 12/hoursInDay.length let xs = 12/hoursInDay.length
......
import { Grid } from "@mui/material"; import { Grid } from "@mui/material";
import { memo } from "react"; import { memo } from "react";
const CalendarSmallCell = ({children, xs, week}) => { const CalendarSmallCell = ({ children, xs, week }) => {
return <> return <>
<Grid align='center' item xs={xs} sx={{borderRight: week ? null : '1px solid black', height: week ? '40px' : null, borderBottom: week ? '1px solid black' : null,}}> <Grid align='center' item xs={xs} sx={{ borderRight: week ? null : '1px solid black', height: week ? '40px' : null, borderBottom: week ? '1px solid black' : null, }}>
{children} {children}
</Grid> </Grid>
</> </>
}; };
export default memo(CalendarSmallCell); export default memo(CalendarSmallCell);
\ No newline at end of file
import { Grid} from "@mui/material"; import { Grid } from "@mui/material";
import { memo, useEffect, useState } from "react"; import { memo, useEffect, useState } from "react";
import DefaultTask from "../DefaultTask/DefaultTask"; import DefaultTask from "../DefaultTask/DefaultTask";
const CalendarStandartCell = ({children, xs, hours, dayNumber, createTaskInCellHandler, handleOpen, modal, dragTaskHandler, linesInDay, week}) => { const CalendarStandartCell = ({ children, xs, hours, dayNumber, createTaskInCellHandler, handleOpen, modal, dragTaskHandler, linesInDay, week }) => {
const [isThisCell, setIsThisCell] = useState(false) const [isThisCell, setIsThisCell] = useState(false)
const cellClass = { const cellClass = {
position: 'relative', position: 'relative',
height: linesInDay?.length ? `${40*linesInDay.length+35}px` : `${40}px`, height: linesInDay?.length ? `${40 * linesInDay.length + 35}px` : `${40}px`,
borderRight: '1px solid black', borderRight: '1px solid black',
borderBottom: week ?'1px solid black' : null, borderBottom: week ? '1px solid black' : null,
} }
useEffect(()=>{ useEffect(() => {
if(!modal) { if (!modal) {
setIsThisCell(false); setIsThisCell(false);
} }
}, [modal]) }, [modal])
const dragOverHandler = (e) => { const dragOverHandler = (e) => {
e.preventDefault(); e.preventDefault();
} }
const dropHandler = (e) => { const dropHandler = (e) => {
e.stopPropagation() e.stopPropagation()
e.preventDefault(); e.preventDefault();
...@@ -31,29 +31,29 @@ const CalendarStandartCell = ({children, xs, hours, dayNumber, createTaskInCell ...@@ -31,29 +31,29 @@ const CalendarStandartCell = ({children, xs, hours, dayNumber, createTaskInCell
} }
const onClickHandler = (e) => { const onClickHandler = (e) => {
if (linesInDay?.length) { if (linesInDay?.length) {
createTaskInCellHandler(dayNumber, hours); createTaskInCellHandler(dayNumber, hours);
setIsThisCell(true); setIsThisCell(true);
handleOpen(e) handleOpen(e)
} }
} }
return <> return <>
<Grid <Grid
item xs={xs} item xs={xs}
sx={cellClass} sx={cellClass}
onClick={(e)=>{onClickHandler(e)}} onClick={(e) => { onClickHandler(e) }}
onDragOver={(e)=>{dragOverHandler(e)}} onDragOver={(e) => { dragOverHandler(e) }}
onDrop={(e)=>{dropHandler(e)}} onDrop={(e) => { dropHandler(e) }}
> >
{children} {children}
{isThisCell ? {isThisCell ?
<DefaultTask/> : null} <DefaultTask /> : null}
</Grid> </Grid>
</> </>
}; };
export default memo(CalendarStandartCell, (prevProps, nextProps)=>{ export default memo(CalendarStandartCell, (prevProps, nextProps) => {
if(!prevProps.modal) return false if (!prevProps.modal) return false
if(nextProps.modal) return true if (nextProps.modal) return true
}); });
\ No newline at end of file \ No newline at end of file
import { Grid} from "@mui/material"; import { Grid } from "@mui/material";
import React, { memo, useEffect, useState} from "react"; import React, { memo, useEffect, useState } from "react";
import ContentCopyIcon from '@mui/icons-material/ContentCopy'; import ContentCopyIcon from '@mui/icons-material/ContentCopy';
const CalendarTask = ({setCurrentTask, handleOpen, task, line, setCurrentLine, setCopyTask}) => { const CalendarTask = ({ setCurrentTask, handleOpen, task, line, setCurrentLine, setCopyTask }) => {
const [color, setColor] = useState('') const [color, setColor] = useState('')
useEffect(() => { useEffect(() => {
...@@ -16,46 +16,46 @@ const CalendarTask = ({setCurrentTask, handleOpen, task, line, setCurrentLine, s ...@@ -16,46 +16,46 @@ const CalendarTask = ({setCurrentTask, handleOpen, task, line, setCurrentLine, s
}, [task]) }, [task])
const onClickTaskHandler = (e, task) => { const onClickTaskHandler = (e, task) => {
e.stopPropagation(); e.stopPropagation();
setCurrentTask((prevState)=>{ setCurrentTask((prevState) => {
return { return {
...task, ...task,
infoForCell: { infoForCell: {
...task.infoForCell, ...task.infoForCell,
endHour: task.infoForCell.endHour + 1 endHour: task.infoForCell.endHour + 1
} }
} }
}); });
handleOpen(e) handleOpen(e)
} }
const dragLeaveHandler = (e) => { const dragLeaveHandler = (e) => {
e.target.style.boxShadow = 'none' e.target.style.boxShadow = 'none'
} }
const dragStartHandler = (e, line, task) => { const dragStartHandler = (e, line, task) => {
setCurrentLine() setCurrentLine()
setCurrentTask(task); setCurrentTask(task);
} }
const dragEndHandler = (e) => { const dragEndHandler = (e) => {
e.target.style.boxShadow = 'none' e.target.style.boxShadow = 'none'
} }
return (<> return (<>
<Grid <Grid
draggable={true} draggable={true}
onDragLeave={(e)=>{dragLeaveHandler(e)}} onDragLeave={(e) => { dragLeaveHandler(e) }}
onDragStart={(e)=>{dragStartHandler(e, line, task)}} onDragStart={(e) => { dragStartHandler(e, line, task) }}
onDragEnd={(e)=>{dragEndHandler(e)}} onDragEnd={(e) => { dragEndHandler(e) }}
sx={{ position: 'relative', height: '30px', backgroundColor: color, borderRadius: '10px', margin: '5px 10px', display: 'flex', alignItems: 'center', zIndex: '5', justifyContent: 'space-between', padding: '0 15px'}} sx={{ position: 'relative', height: '30px', backgroundColor: color, borderRadius: '10px', margin: '5px 10px', display: 'flex', alignItems: 'center', zIndex: '5', justifyContent: 'space-between', padding: '0 15px' }}
onClick={(e)=>{onClickTaskHandler(e, task)}} onClick={(e) => { onClickTaskHandler(e, task) }}
> >
<span style={{maxWidth: '60%', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis'}}> <span style={{ maxWidth: '60%', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
{task.title} {task.title}
</span> </span>
<ContentCopyIcon sx={{width: '20px', cursor: 'pointer'}} onClick={(e)=>{e.stopPropagation(); setCopyTask(task)}}> <ContentCopyIcon sx={{ width: '20px', cursor: 'pointer' }} onClick={(e) => { e.stopPropagation(); setCopyTask(task) }}>
</ContentCopyIcon> </ContentCopyIcon>
</Grid> </Grid>
</>) </>)
}; };
......
...@@ -2,27 +2,27 @@ import { Box } from "@mui/material"; ...@@ -2,27 +2,27 @@ import { Box } from "@mui/material";
import { memo } from "react"; import { memo } from "react";
const DefaultTaskStyles = { const DefaultTaskStyles = {
position: 'relative', position: 'relative',
height: '30px', height: '30px',
backgroundColor: 'lightgreen', backgroundColor: 'lightgreen',
whiteSpace: 'nowrap', whiteSpace: 'nowrap',
overflow: 'hidden', overflow: 'hidden',
textOverflow: 'ellipsis', textOverflow: 'ellipsis',
borderRadius: '10px', borderRadius: '10px',
margin: '5px 10px', margin: '5px 10px',
display: 'flex', display: 'flex',
justifyContent: 'flex-start', justifyContent: 'flex-start',
alignItems: 'center', alignItems: 'center',
paddingLeft: '5px', paddingLeft: '5px',
zIndex: '5' zIndex: '5'
} }
const DefaultTask = ({}) => { const DefaultTask = ({ }) => {
return (<> return (<>
<Box <Box
sx={DefaultTaskStyles} sx={DefaultTaskStyles}
> >
<span> <span>
Задача Задача
</span> </span>
......
import { Box, FormControlLabel, Switch} from "@mui/material"; import { Box, FormControlLabel, Switch } from "@mui/material";
import { useState } from "react"; import { useState } from "react";
import CalendarRow from "./CalendarRow/CalendarRow"; import CalendarRow from "./CalendarRow/CalendarRow";
import CalendarSmallCell from "./CalendarSmallCell/CalendarSmallCell"; import CalendarSmallCell from "./CalendarSmallCell/CalendarSmallCell";
...@@ -8,15 +8,15 @@ import MonthCalendarModalContent from "../MonthCalendarModalContent/MonthCalenda ...@@ -8,15 +8,15 @@ import MonthCalendarModalContent from "../MonthCalendarModalContent/MonthCalenda
import CalendarRowDay from "./CalendarRowDay/CalendarRowDay"; import CalendarRowDay from "./CalendarRowDay/CalendarRowDay";
function MonthCalendarBody({month, year, tasks, createTaskInCellHandler, currentTask, setCurrentTask, hourFormat, setHourFormat, onChangeCurrentTaskHandler, sendNewTaskHandler, deleteTaskHandler, cellSizes, hoursInDay, daysInMonth, dragTaskHandler, createCopyTask, setCopyTask, copyTask}) { function MonthCalendarBody({ month, year, tasks, createTaskInCellHandler, currentTask, setCurrentTask, hourFormat, setHourFormat, onChangeCurrentTaskHandler, sendNewTaskHandler, deleteTaskHandler, cellSizes, hoursInDay, daysInMonth, dragTaskHandler, createCopyTask, setCopyTask, copyTask }) {
const [currentLine, setCurrentLine] = useState('') const [currentLine, setCurrentLine] = useState('')
const [modal, setModal] = useState({open:false, y: 0, x: 0,}); const [modal, setModal] = useState({ open: false, y: 0, x: 0, });
const handleOpen = (e) => { const handleOpen = (e) => {
setModal( { setModal({
open: true, open: true,
yClickСordinates: e.clientY, yClickСordinates: e.clientY,
xClickСordinates: e.clientX, xClickСordinates: e.clientX,
yDivClick: e.nativeEvent.offsetY, yDivClick: e.nativeEvent.offsetY,
xDivClick: e.nativeEvent.offsetX, xDivClick: e.nativeEvent.offsetX,
yDiv: e.target.offsetHeight, yDiv: e.target.offsetHeight,
...@@ -25,77 +25,77 @@ function MonthCalendarBody({month, year, tasks, createTaskInCellHandler, current ...@@ -25,77 +25,77 @@ function MonthCalendarBody({month, year, tasks, createTaskInCellHandler, current
}; };
const handleClose = () => { const handleClose = () => {
setModal({...modal, open: false}) setModal({ ...modal, open: false })
setCurrentTask({}) setCurrentTask({})
}; };
return ( return (
<Box style={{marginBottom: '30px'}}> <Box style={{ marginBottom: '30px' }}>
<div style={{position: 'sticky', top: '0px', zIndex: '10', backgroundColor: 'lightgrey'}}> <div style={{ position: 'sticky', top: '0px', zIndex: '10', backgroundColor: 'lightgrey' }}>
<CalendarRow <CalendarRow
> >
<CalendarSmallCell xs={1.2}> <CalendarSmallCell xs={1.2}>
<FormControlLabel <FormControlLabel
control={<Switch color="primary" checked={hourFormat} onChange={()=>{setHourFormat(()=>!hourFormat)}}/>} control={<Switch color="primary" checked={hourFormat} onChange={() => { setHourFormat(() => !hourFormat) }} />}
label="1 час" label="1 час"
labelPlacement="end" labelPlacement="end"
/> />
</CalendarSmallCell> </CalendarSmallCell>
{hoursInDay?.map((hours, i)=>{ {hoursInDay?.map((hours, i) => {
return ( return (
<CalendarStandartCell key={i} xs={cellSizes.standarCell}> <CalendarStandartCell key={i} xs={cellSizes.standarCell}>
{hours} {hours}
</CalendarStandartCell> </CalendarStandartCell>
) )
})} })}
</CalendarRow> </CalendarRow>
</div> </div>
{daysInMonth?.map((day, i)=>{ {daysInMonth?.map((day, i) => {
return ( return (
<CalendarRow <CalendarRow
key={i} key={i}
>
<CalendarSmallCell xs={cellSizes.smallCell}>{day.dayNumber}</CalendarSmallCell>
<CalendarSmallCell xs={cellSizes.smallCell}>{day.dayOfWeek}</CalendarSmallCell>
<CalendarRowDay
dragTaskHandler={dragTaskHandler}
xs={cellSizes.dayCell}
createTaskInCellHandler={createTaskInCellHandler}
hoursInDay={hoursInDay}
currentTask={currentTask}
handleOpen={handleOpen}
currentLine={currentLine}
setCurrentLine={setCurrentLine}
modal={modal.open}
setCurrentTask={setCurrentTask}
year={year}
month={month}
tasks={tasks}
day={day}
hourFormat={hourFormat}
createCopyTask={createCopyTask}
copyTask={copyTask}
setCopyTask={setCopyTask}
> >
<CalendarSmallCell xs={cellSizes.smallCell}>{day.dayNumber}</CalendarSmallCell> </CalendarRowDay>
<CalendarSmallCell xs={cellSizes.smallCell}>{day.dayOfWeek}</CalendarSmallCell>
<CalendarRowDay
dragTaskHandler={dragTaskHandler}
xs={cellSizes.dayCell}
createTaskInCellHandler={createTaskInCellHandler}
hoursInDay={hoursInDay}
currentTask={currentTask}
handleOpen={handleOpen}
currentLine={currentLine}
setCurrentLine={setCurrentLine}
modal={modal.open}
setCurrentTask={setCurrentTask}
year={year}
month={month}
tasks={tasks}
day={day}
hourFormat={hourFormat}
createCopyTask={createCopyTask}
copyTask={copyTask}
setCopyTask={setCopyTask}
>
</CalendarRowDay>
</CalendarRow> </CalendarRow>
) )
})} })}
<ModalTask <ModalTask
modal={modal} modal={modal}
handleClose={()=>{handleClose()}} handleClose={() => { handleClose() }}
> >
<MonthCalendarModalContent <MonthCalendarModalContent
title={currentTask.title} title={currentTask.title}
description={currentTask.description} description={currentTask.description}
priority={currentTask.priority} priority={currentTask.priority}
startHour={currentTask.infoForCell?.startHour} startHour={currentTask.infoForCell?.startHour}
endHour={currentTask.infoForCell?.endHour} endHour={currentTask.infoForCell?.endHour}
onChangeCurrentTaskHandler={(e)=>{ onChangeCurrentTaskHandler(e)}} onChangeCurrentTaskHandler={(e) => { onChangeCurrentTaskHandler(e) }}
sendNewTaskHandler={()=>{sendNewTaskHandler(); handleClose()}} sendNewTaskHandler={() => { sendNewTaskHandler(); handleClose() }}
deleteTaskHandler={()=>{deleteTaskHandler(currentTask.id); handleClose()}} deleteTaskHandler={() => { deleteTaskHandler(currentTask.id); handleClose() }}
/> />
</ModalTask> </ModalTask>
</Box> </Box>
); );
} }
......
...@@ -3,39 +3,39 @@ import { Box, Typography } from '@mui/material'; ...@@ -3,39 +3,39 @@ import { Box, Typography } from '@mui/material';
import { memo } from 'react'; import { memo } from 'react';
import ArrowDecrementButton from '../../../UI/ArrowDecrementButton/ArrowDecrementButton'; import ArrowDecrementButton from '../../../UI/ArrowDecrementButton/ArrowDecrementButton';
import ArrowIncrementButton from '../../../UI/ArrowIncrementButton/ArrowIncrementButton'; import ArrowIncrementButton from '../../../UI/ArrowIncrementButton/ArrowIncrementButton';
function MonthAndYearInfo({currentMonthString, year, incrementMonth, decrementMonth}) { function MonthAndYearInfo({ currentMonthString, year, incrementMonth, decrementMonth }) {
return ( return (
<> <>
<Box <Box
sx={{ sx={{
flexGrow: 1, flexGrow: 1,
display: 'flex', display: 'flex',
alignItems: 'center', alignItems: 'center',
gap: '10px' gap: '10px'
}} }}
id='test_month_info' id='test_month_info'
> >
<ArrowDecrementButton <ArrowDecrementButton
onClick={decrementMonth} onClick={decrementMonth}
/> />
<Box sx={{ flexBasis: '150px' }}> <Box sx={{ flexBasis: '150px' }}>
<Typography <Typography
variant="h6" variant="h6"
sx={{ sx={{
display: 'flex', display: 'flex',
justifyContent: 'center', justifyContent: 'center',
}} }}
> >
{currentMonthString} {currentMonthString}
</Typography> </Typography>
<Typography align='center'>{year}</Typography> <Typography align='center'>{year}</Typography>
</Box> </Box>
<ArrowIncrementButton <ArrowIncrementButton
onClick={incrementMonth} onClick={incrementMonth}
/> />
</Box> </Box>
</> ); </>);
} }
export default memo(MonthAndYearInfo); export default memo(MonthAndYearInfo);
\ No newline at end of file
import { AppBar, Toolbar} from '@mui/material'; import { AppBar, Toolbar } from '@mui/material';
import { Box } from '@mui/system'; import { Box } from '@mui/system';
import MonthAndYearInfo from './MonthAndYearInfo/MonthAndYearInfo'; import MonthAndYearInfo from './MonthAndYearInfo/MonthAndYearInfo';
import СustomSelect from '../../UI/СustomSelect/СustomSelect' import СustomSelect from '../../UI/СustomSelect/СustomSelect'
const workers = [{value: '', text: '--выберите сотрудника--'}, {value: 'Василий', text: 'Василий'}, {value: 'Никита', text: 'Никита'}] const workers = [{ value: '', text: '--выберите сотрудника--' }, { value: 'Василий', text: 'Василий' }, { value: 'Никита', text: 'Никита' }]
const types = [{value: 'Месяц', text: 'Месяц'}, {value: 'Неделя', text: 'Неделя'}] const types = [{ value: 'Месяц', text: 'Месяц' }, { value: 'Неделя', text: 'Неделя' }]
function MonthCalendarHeader({ currentMonthString, decrementMonth, incrementMonth, calendarType, onChangeWorkerHandler, onChangeCalendarTypeHandler, worker, year }) {
function MonthCalendarHeader({ currentMonthString, decrementMonth, incrementMonth, calendarType, onChangeWorkerHandler, onChangeCalendarTypeHandler, worker, year}) {
return ( return (
<> <>
<Box sx={{ flexGrow: 1 }}> <Box sx={{ flexGrow: 1 }}>
<AppBar position="static"> <AppBar position="static">
<Toolbar> <Toolbar>
<MonthAndYearInfo <MonthAndYearInfo
currentMonthString={currentMonthString} currentMonthString={currentMonthString}
decrementMonth={decrementMonth} decrementMonth={decrementMonth}
incrementMonth={incrementMonth} incrementMonth={incrementMonth}
year={year} year={year}
/> />
<СustomSelect <СustomSelect
value={worker} value={worker}
onChange={(e)=>{onChangeWorkerHandler(e)}} onChange={(e) => { onChangeWorkerHandler(e) }}
label={'Сотрудник'} label={'Сотрудник'}
id={'worker'} id={'worker'}
items={workers} items={workers}
/> />
<div style={{marginLeft: '20px'}}> <div style={{ marginLeft: '20px' }}>
<СustomSelect <СustomSelect
value={calendarType} value={calendarType}
onChange={(e)=>{onChangeCalendarTypeHandler(e)}} onChange={(e) => { onChangeCalendarTypeHandler(e) }}
label={'Календарь'} label={'Календарь'}
id={'calendar-type'} id={'calendar-type'}
items={types} items={types}
/> />
</div> </div>
</Toolbar> </Toolbar>
</AppBar> </AppBar>
</Box> </Box>
</> </>
); );
} }
......
import { Button, TextField } from "@mui/material"; import { Button, TextField } from "@mui/material";
import { memo } from "react"; import { memo } from "react";
import { priorities } from "../../../constants";
import CustomSelect from '../../UI/СustomSelect/СustomSelect' import CustomSelect from '../../UI/СustomSelect/СustomSelect'
const priorities = [{value: null, text: '--Приоритет--'}, {value: 'A', text: 'A'}, {value: 'B', text: 'B'}, {value: 'C', text: 'C'}]
function MonthCalendarModalContent({ title, onChangeCurrentTaskHandler, description, priority, sendNewTaskHandler, deleteTaskHandler, startHour, endHour }) {
function MonthCalendarModalContent({title, onChangeCurrentTaskHandler, description, priority, sendNewTaskHandler, deleteTaskHandler, startHour, endHour}) {
return (<> return (<>
<TextField <TextField
id="task-description-title" id="task-description-title"
value={title} value={title}
label="Название" label="Название"
variant="outlined" variant="outlined"
sx={{marginBottom: '30px'}} sx={{ marginBottom: '30px' }}
name='title' name='title'
onChange={(e)=>{onChangeCurrentTaskHandler(e)}} onChange={(e) => { onChangeCurrentTaskHandler(e) }}
/> />
<TextField <TextField
id="task-description" id="task-description"
multiline multiline
rows={4} rows={4}
value={description} value={description}
label="Описание" label="Описание"
variant="outlined" variant="outlined"
sx={{marginBottom: '30px'}} sx={{ marginBottom: '30px' }}
name='description' name='description'
onChange={(e)=>{onChangeCurrentTaskHandler(e)}} onChange={(e) => { onChangeCurrentTaskHandler(e) }}
/> />
<CustomSelect <CustomSelect
defaultValue={null} defaultValue={null}
value={priority} value={priority}
name={'priority'} name={'priority'}
variant={'outlined'} variant={'outlined'}
onChange={(e)=>{onChangeCurrentTaskHandler(e)}} onChange={(e) => { onChangeCurrentTaskHandler(e) }}
label={'Приоритет'} label={'Приоритет'}
id={'priority-type'} id={'priority-type'}
items={priorities} items={priorities}
/> />
<div style={{display: 'flex', gap: '20px', margin: '20px 0'}}> <div style={{ display: 'flex', gap: '20px', margin: '20px 0' }}>
<TextField <TextField
id="task-startHour" id="task-startHour"
value={startHour} value={startHour}
label="От" label="От"
variant="outlined" variant="outlined"
name='startHour' name='startHour'
onChange={(e)=>{onChangeCurrentTaskHandler(e)}} onChange={(e) => { onChangeCurrentTaskHandler(e) }}
/> />
<TextField <TextField
id="task-endHour" id="task-endHour"
value={endHour} value={endHour}
label="До" label="До"
variant="outlined" variant="outlined"
name='endHour' name='endHour'
onChange={(e)=>{onChangeCurrentTaskHandler(e)}} onChange={(e) => { onChangeCurrentTaskHandler(e) }}
/> />
</div> </div>
<div style={{display: 'flex', gap: '20px', margin: '10px 0'}}> <div style={{ display: 'flex', gap: '20px', margin: '10px 0' }}>
<Button id='test_button_save_task'onClick={sendNewTaskHandler}>Сохранить</Button> <Button id='test_button_save_task' onClick={sendNewTaskHandler}>Сохранить</Button>
<Button onClick={deleteTaskHandler}>Удалить</Button> <Button onClick={deleteTaskHandler}>Удалить</Button>
</div> </div>
</>); </>);
......
import {AppBar, Box, Toolbar, Typography} from "@mui/material"; import { AppBar, Box, Toolbar, Typography } from "@mui/material";
import {NavLink} from "react-router-dom"; import { NavLink } from "react-router-dom";
import {useSelector} from "react-redux"; import { useSelector } from "react-redux";
import HasAccess from "../HasAccess/HasAccess"; import HasAccess from "../HasAccess/HasAccess";
import AnonymousMenu from "../../Menus/AnonymousMenu/AnonymousMenu"; import AnonymousMenu from "../../Menus/AnonymousMenu/AnonymousMenu";
import WorkerMenu from "../../Menus/WorkerMenu/WorkerMenu"; import WorkerMenu from "../../Menus/WorkerMenu/WorkerMenu";
...@@ -10,24 +10,24 @@ const AppToolbar = () => { ...@@ -10,24 +10,24 @@ const AppToolbar = () => {
const user = useSelector(state => state.users.user); const user = useSelector(state => state.users.user);
return <Box sx={{ flexGrow: 1, mb: "40px" }}> return <Box sx={{ flexGrow: 1, mb: "40px" }}>
<AppBar position="static"> <AppBar position="static">
<Toolbar> <Toolbar>
<Typography <Typography
variant="h4" variant="h4"
component="div" component="div"
sx={{ flexGrow: 1 }}> sx={{ flexGrow: 1 }}>
<NavLink to='/' style={{textDecoration: 'none', color: 'inherit'}}>Task Manager</NavLink> <NavLink to='/' style={{ textDecoration: 'none', color: 'inherit' }}>Task Manager</NavLink>
</Typography> </Typography>
<HasAccess allowed={!user}> <HasAccess allowed={!user}>
<AnonymousMenu/> <AnonymousMenu />
</HasAccess> </HasAccess>
<HasAccess roles={['user']}> <HasAccess roles={['user']}>
<WorkerMenu/> <WorkerMenu />
</HasAccess> </HasAccess>
<HasAccess roles={['superuser']}> <HasAccess roles={['superuser']}>
<AdminMenu/> <AdminMenu />
</HasAccess> </HasAccess>
</Toolbar> </Toolbar>
</AppBar> </AppBar>
......
import { FormControl, InputLabel, MenuItem, Select} from '@mui/material'; import { FormControl, InputLabel, MenuItem, Select } from '@mui/material';
import { memo } from 'react'; import { memo } from 'react';
function СustomSelect({value, onChange, label, variant='standard', items, id, defaultValue, name}) { function СustomSelect({ value, onChange, label, variant = 'standard', items, id, defaultValue, name }) {
return ( return (
<> <>
<FormControl variant={variant} sx={{ m: 0, minWidth: 120 }}> <FormControl variant={variant} sx={{ m: 0, minWidth: 120 }}>
<InputLabel id={`${id}-select-label`}>{label}</InputLabel> <InputLabel id={`${id}-select-label`}>{label}</InputLabel>
<Select <Select
labelId={`${id}-select-label`} labelId={`${id}-select-label`}
...@@ -16,7 +16,7 @@ function СustomSelect({value, onChange, label, variant='standard', items, id, ...@@ -16,7 +16,7 @@ function СustomSelect({value, onChange, label, variant='standard', items, id,
name={name} name={name}
defaultValue={defaultValue} defaultValue={defaultValue}
> >
{items.map((item, i)=>{ {items.map((item, i) => {
return ( return (
<MenuItem <MenuItem
key={i} key={i}
...@@ -26,11 +26,11 @@ function СustomSelect({value, onChange, label, variant='standard', items, id, ...@@ -26,11 +26,11 @@ function СustomSelect({value, onChange, label, variant='standard', items, id,
})} })}
</Select> </Select>
</FormControl> </FormControl>
</> ); </>);
} }
export default memo(СustomSelect, (prevProps, nextProps)=>{ export default memo(СustomSelect, (prevProps, nextProps) => {
if(prevProps.value !== nextProps.value) { if (prevProps.value !== nextProps.value) {
return false return false
} else { } else {
return true return true
......
import { Grid } from "@mui/material"; import { useMemo } from "react";
import CalendarRow from "../../../MonthCalendar/MonthCalendarBody/CalendarRow/CalendarRow"; import { getHoursInDayNumbers, getAvailableTasks, getLinesInDay, getSortedTasks } from "../../../../helpers/CalendarHelpers";
import CalendarStandartCell from "../../../MonthCalendar/MonthCalendarBody/CalendarStandartCell.js/CalendarStandartCell"; import CalendarStandartCell from "../../../MonthCalendar/MonthCalendarBody/CalendarStandartCell.js/CalendarStandartCell";
function CalendarRowDayWeek({week, hoursInDay}) { function CalendarRowDayWeek({ hoursInDay, tasks, month, year, day, hourFormat }) {
return ( <> const hours = useMemo(() => {
<Grid item xs={11.005}> return getHoursInDayNumbers(hoursInDay)
<CalendarRow week={true}> }, [hoursInDay])
{week?.map((weekDay, i)=>{
return ( const availableTasks = useMemo(() => {
<Grid item key={i} xs={12/week.length}> return getAvailableTasks(tasks, year, month, day)
{hoursInDay?.map((hour, i)=>{ }, [tasks, month, year, day])
return (
<CalendarStandartCell key={i} week={true}> const sortedTasks = useMemo(() => {
return getSortedTasks(availableTasks)
</CalendarStandartCell>) }, [availableTasks])
})}
</Grid>) const linesInDay = useMemo(() => {
})} return getLinesInDay(availableTasks, sortedTasks, hoursInDay, hours, hourFormat)
</CalendarRow> }, [availableTasks, hourFormat, hours, hoursInDay, sortedTasks])
</Grid>
</> ); return (<>
{hoursInDay?.map((hour, i) => {
return (
<CalendarStandartCell key={i} week={true}>
</CalendarStandartCell>)
})}
</>);
} }
export default CalendarRowDayWeek; export default CalendarRowDayWeek;
\ No newline at end of file
export const getCurrentWeekDayString = (dayNumber) => { export const getCurrentWeekDayString = (dayNumber) => {
if (dayNumber <= 6 && dayNumber >= 0) { if (dayNumber <= 6 && dayNumber >= 0) {
return ["ПН","ВТ","СР","ЧТ","ПТ","СБ","ВС"][dayNumber]; return ["ПН", "ВТ", "СР", "ЧТ", "ПТ", "СБ", "ВС"][dayNumber];
} else { } else {
return null return null
} }
......
...@@ -6,36 +6,36 @@ import CalendarStandartCell from "../../MonthCalendar/MonthCalendarBody/Calendar ...@@ -6,36 +6,36 @@ import CalendarStandartCell from "../../MonthCalendar/MonthCalendarBody/Calendar
import CalendarRowDayWeek from "./CalendarRowDayWeek/CalendarRowDayWeek"; import CalendarRowDayWeek from "./CalendarRowDayWeek/CalendarRowDayWeek";
import { getCurrentWeekDayString } from "./Helpers"; import { getCurrentWeekDayString } from "./Helpers";
function WeekCalendarBody({week, hoursInDay, hourFormat, setHourFormat,}) { function WeekCalendarBody({ week, hoursInDay, hourFormat, setHourFormat, date, tasks }) {
return ( return (
<> <>
<Box style={{marginBottom: '30px'}}> <Box style={{ marginBottom: '30px' }}>
<Box style={{position: 'sticky', top: '0px', zIndex: '10', backgroundColor: 'lightgrey'}}> <Box style={{ position: 'sticky', top: '0px', zIndex: '10', backgroundColor: 'lightgrey' }}>
<CalendarRow <CalendarRow
> >
<CalendarSmallCell xs={1}> <CalendarSmallCell xs={1}>
<FormControlLabel <FormControlLabel
control={<Switch color="primary" checked={hourFormat} onChange={()=>{setHourFormat(()=>!hourFormat)}}/>} control={<Switch color="primary" checked={hourFormat} onChange={() => { setHourFormat(() => !hourFormat) }} />}
label="1 час" label="1 час"
labelPlacement="end" labelPlacement="end"
/> />
</CalendarSmallCell> </CalendarSmallCell>
{week?.map((weekDay, i)=>{ {week?.map((weekDay, i) => {
return ( return (
<CalendarStandartCell key={i} xs={11/week.length}> <CalendarStandartCell key={i} xs={11 / week.length}>
<span style={{display: 'block', fontWeight: "600"}}>{weekDay}</span> <span style={{ display: 'block', fontWeight: "600" }}>{weekDay}</span>
<span style={{marginBottom: '10px'}}>{getCurrentWeekDayString(i)}</span> <span style={{ marginBottom: '10px' }}>{getCurrentWeekDayString(i)}</span>
</CalendarStandartCell> </CalendarStandartCell>
) )
})} })}
</CalendarRow> </CalendarRow>
</Box> </Box>
<Grid container> <Grid container>
<CalendarRow week={true}> <CalendarRow week={true}>
<Grid item xs={0.995} flexDirection='column'> <Grid item xs={0.995} flexDirection='column'>
{hoursInDay?.map((hour, i)=>{ {hoursInDay?.map((hour, i) => {
return ( return (
<CalendarSmallCell key={i} week={true}> <CalendarSmallCell key={i} week={true}>
{hour} {hour}
...@@ -43,14 +43,28 @@ function WeekCalendarBody({week, hoursInDay, hourFormat, setHourFormat,}) { ...@@ -43,14 +43,28 @@ function WeekCalendarBody({week, hoursInDay, hourFormat, setHourFormat,}) {
})} })}
</Grid> </Grid>
<CalendarRowDayWeek <Grid item xs={11.005}>
week={week} <CalendarRow week={true}>
hoursInDay={hoursInDay} {week?.map((weekDay, i) => {
/> return (
<Grid item key={i} xs={12 / week.length}>
<CalendarRowDayWeek
hoursInDay={hoursInDay}
tasks={tasks}
month={date.month}
year={date.year}
day={weekDay}
hourFormat={hourFormat}
/>
</Grid>
)
})}
</CalendarRow>
</Grid>
</CalendarRow> </CalendarRow>
</Grid> </Grid>
</Box> </Box>
</> </>
); );
} }
......
import { AppBar, Toolbar} from '@mui/material'; import { AppBar, Toolbar } from '@mui/material';
import { Box } from '@mui/system'; import { Box } from '@mui/system';
import WeekCalendarHeaderInfo from './WeekCalendarHeaderInfo/WeekCalendarHeaderInfo'; import WeekCalendarHeaderInfo from './WeekCalendarHeaderInfo/WeekCalendarHeaderInfo';
function WeekCalendarHeader({decrementWeek, incrementWeek, weekInfo}) { function WeekCalendarHeader({ decrementWeek, incrementWeek, weekInfo }) {
return ( return (
<> <>
<Box sx={{ flexGrow: 1 }}> <Box sx={{ flexGrow: 1 }}>
<AppBar position="static"> <AppBar position="static">
<Toolbar> <Toolbar>
<WeekCalendarHeaderInfo <WeekCalendarHeaderInfo
decrementWeek={decrementWeek} decrementWeek={decrementWeek}
incrementWeek={incrementWeek} incrementWeek={incrementWeek}
weekInfo={weekInfo} weekInfo={weekInfo}
/> />
</Toolbar> </Toolbar>
</AppBar> </AppBar>
</Box> </Box>
</> </>
); );
} }
......
import ArrowDecrementButton from '../../../UI/ArrowDecrementButton/ArrowDecrementButton'; import ArrowDecrementButton from '../../../UI/ArrowDecrementButton/ArrowDecrementButton';
import ArrowIncrementButton from '../../../UI/ArrowIncrementButton/ArrowIncrementButton'; import ArrowIncrementButton from '../../../UI/ArrowIncrementButton/ArrowIncrementButton';
import { Box } from '@mui/system'; import { Box } from '@mui/system';
import {Typography} from '@mui/material'; import { Typography } from '@mui/material';
function WeekCalendarHeaderInfo({decrementWeek, incrementWeek, weekInfo}) { function WeekCalendarHeaderInfo({ decrementWeek, incrementWeek, weekInfo }) {
return ( return (
<> <>
<Box sx={{width: '40%', marginBottom: '15px'}}> <Box sx={{ width: '40%', marginBottom: '15px' }}>
<h2>Цель недели: Наладить режим сна</h2> <h2>Цель недели: Наладить режим сна</h2>
<Box sx={{display: 'flex', alignItems: 'center'}}> <Box sx={{ display: 'flex', alignItems: 'center' }}>
<ArrowDecrementButton <ArrowDecrementButton
onClick={()=>{decrementWeek()}} onClick={() => { decrementWeek() }}
/> />
<Typography <Typography
variant="h6" variant="h6"
sx={{ sx={{
flexBasis: '250px', flexBasis: '250px',
display: 'flex', display: 'flex',
justifyContent: 'center', justifyContent: 'center',
}} }}
> >
{weekInfo} {weekInfo}
</Typography> </Typography>
<ArrowIncrementButton <ArrowIncrementButton
onClick={()=>{incrementWeek()}} onClick={() => { incrementWeek() }}
/> />
</Box>
</Box> </Box>
</Box>
</> </>
); );
} }
......
...@@ -3,21 +3,28 @@ export const uploadsUrl = `${apiUrl}/uploads`; ...@@ -3,21 +3,28 @@ export const uploadsUrl = `${apiUrl}/uploads`;
export const workerMenuButtons = [ export const workerMenuButtons = [
{text: 'Проекты', path: '/projects'}, { text: 'Проекты', path: '/projects' },
{text: 'Неделя', path: '/week'}, { text: 'Неделя', path: '/week' },
{text: 'Месяц', path: '/month'}, { text: 'Месяц', path: '/month' },
{text: 'Мои задачи', path: '/my-tasks'} { text: 'Мои задачи', path: '/my-tasks' }
] ]
export const superuserMenuButtons = [ export const superuserMenuButtons = [
{text: 'Проекты', path: '/projects'}, { text: 'Проекты', path: '/projects' },
{text: 'Неделя', path: '/week'}, { text: 'Неделя', path: '/week' },
{text: 'Месяц', path: '/month'}, { text: 'Месяц', path: '/month' },
{text: 'Мои задачи', path: '/my-tasks'}, { text: 'Мои задачи', path: '/my-tasks' },
{text: 'Задачи Сотрудников', path: '/workers-tasks'}, { text: 'Задачи Сотрудников', path: '/workers-tasks' },
{text: 'Создать Сотрудника', path: '/sign-up'} { text: 'Создать Сотрудника', path: '/sign-up' }
] ]
export const anonymoysMenuButtons = [ export const anonymoysMenuButtons = [
{text: 'Вход', path: '/sign-in'}, { text: 'Вход', path: '/sign-in' },
]
export const priorities = [
{ value: null, text: '--Приоритет--' },
{ value: 'A', text: 'A' },
{ value: 'B', text: 'B' },
{ value: 'C', text: 'C' }
] ]
\ No newline at end of file
import { useEffect, useCallback, useState, useMemo } from 'react'; import { useEffect, useCallback, useState, useMemo } from 'react';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import MonthCalendarBody from '../../components/MonthCalendar/MonthCalendarBody/MonthCalendarBody'; import MonthCalendarBody from '../../components/MonthCalendar/MonthCalendarBody/MonthCalendarBody';
import MonthCalendarHeader from '../../components/MonthCalendar/MonthCalendarHeader/MonthCalendarHeader'; import MonthCalendarHeader from '../../components/MonthCalendar/MonthCalendarHeader/MonthCalendarHeader';
import { dateToISOLikeButLocal, getCurrentMonthString, getDaysInMonth } from '../../helpers/CalendarHelpers'; import { dateToISOLikeButLocal, getCurrentMonthString, getDaysInMonth } from '../../helpers/CalendarHelpers';
import { addCalendarTask, addCopyCalendarTask, deleteCalendarTask, editCalendarTask, fetchCalendarTasks} from '../../store/actions/tasksActions'; import { addCalendarTask, addCopyCalendarTask, deleteCalendarTask, editCalendarTask, fetchCalendarTasks } from '../../store/actions/tasksActions';
function MonthCalendar() { function MonthCalendar() {
const dispatch = useDispatch(); const dispatch = useDispatch();
...@@ -11,14 +11,14 @@ function MonthCalendar() { ...@@ -11,14 +11,14 @@ function MonthCalendar() {
const user = useSelector(state => state.users?.user); const user = useSelector(state => state.users?.user);
const [hourFormat, setHourFormat] = useState(false); const [hourFormat, setHourFormat] = useState(false);
const [dateNow, setDateNow] = useState({month: '', year: ''}) const [dateNow, setDateNow] = useState({ month: '', year: '' })
const [worker, setWorker] = useState(''); const [worker, setWorker] = useState('');
const [calendarType, setCalendarType] = useState('Месяц'); const [calendarType, setCalendarType] = useState('Месяц');
const [currentTask, setCurrentTask] = useState({title: '', description: '', priority: null, infoForCell: {startHour: null, endHour: null}}) const [currentTask, setCurrentTask] = useState({ title: '', description: '', priority: null, infoForCell: { startHour: null, endHour: null } })
const [copyTask, setCopyTask] = useState(null) const [copyTask, setCopyTask] = useState(null)
const [cellSizes, setCellSizes] = useState({}) const [cellSizes, setCellSizes] = useState({})
useEffect(()=>{ useEffect(() => {
setDateNow({ setDateNow({
month: new Date().getMonth(), month: new Date().getMonth(),
year: new Date().getFullYear(), year: new Date().getFullYear(),
...@@ -27,17 +27,17 @@ function MonthCalendar() { ...@@ -27,17 +27,17 @@ function MonthCalendar() {
}, [dispatch]) }, [dispatch])
const hoursInDay = useMemo(()=>{ const hoursInDay = useMemo(() => {
let arr let arr
if (hourFormat) { if (hourFormat) {
arr = ['8:00', '9:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00', '19:00', '20:00','21:00','22:00'] arr = ['8:00', '9:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00', '19:00', '20:00', '21:00', '22:00']
} else { } else {
arr = ['8:00', '10:00', '12:00', '14:00', '16:00', '18:00', '20:00', '22:00'] arr = ['8:00', '10:00', '12:00', '14:00', '16:00', '18:00', '20:00', '22:00']
} }
const cells = arr.length const cells = arr.length
const xs = 10.8/cells const xs = 10.8 / cells
setCellSizes(()=>{ setCellSizes(() => {
return {smallCell: 0.6, standarCell: xs, dayCell: 12/cells} return { smallCell: 0.6, standarCell: xs, dayCell: 12 / cells }
}) })
return arr return arr
}, [hourFormat]) }, [hourFormat])
...@@ -59,39 +59,39 @@ function MonthCalendar() { ...@@ -59,39 +59,39 @@ function MonthCalendar() {
}, []); }, []);
const incrementMonth = useCallback(() => { const incrementMonth = useCallback(() => {
setDateNow((prevState)=>{ setDateNow((prevState) => {
if (prevState.month + 1 === 12 ) { if (prevState.month + 1 === 12) {
return { month: 0, year: prevState.year + 1} return { month: 0, year: prevState.year + 1 }
} }
return {...prevState, month: prevState.month + 1} return { ...prevState, month: prevState.month + 1 }
}) })
}, []) }, [])
const decrementMonth = useCallback(() => { const decrementMonth = useCallback(() => {
setDateNow((prevState)=>{ setDateNow((prevState) => {
if (prevState.month - 1 === -1) { if (prevState.month - 1 === -1) {
return { month: 11, year: prevState.year - 1} return { month: 11, year: prevState.year - 1 }
} }
return {...prevState, month: prevState.month - 1} return { ...prevState, month: prevState.month - 1 }
}) })
}, []) }, [])
const onChangeCurrentTaskHandler = useCallback((e) => { const onChangeCurrentTaskHandler = useCallback((e) => {
const {name, value} = e.target; const { name, value } = e.target;
if (name === 'startHour' || name === 'endHour') { if (name === 'startHour' || name === 'endHour') {
setCurrentTask((prevState) => { setCurrentTask((prevState) => {
return { return {
...prevState, ...prevState,
infoForCell: { infoForCell: {
...prevState.infoForCell, ...prevState.infoForCell,
[name]: parseInt(value) [name]: parseInt(value)
} }
} }
}); });
} else { } else {
setCurrentTask((prevState) => { setCurrentTask((prevState) => {
return { return {
...prevState, ...prevState,
[name]: value [name]: value
} }
}); });
} }
...@@ -111,8 +111,8 @@ function MonthCalendar() { ...@@ -111,8 +111,8 @@ function MonthCalendar() {
hourDue = hour + 2 hourDue = hour + 2
} }
const newTask = { const newTask = {
title:"Задача", title: "Задача",
description:"описание", description: "описание",
priority: null, priority: null,
dateTimeStart: dateToISOLikeButLocal(new Date(dateNow.year, dateNow.month, dayNumber, hour, 0)), dateTimeStart: dateToISOLikeButLocal(new Date(dateNow.year, dateNow.month, dayNumber, hour, 0)),
dateTimeDue: dateToISOLikeButLocal(new Date(dateNow.year, dateNow.month, dayNumber, hourDue, 59)), dateTimeDue: dateToISOLikeButLocal(new Date(dateNow.year, dateNow.month, dayNumber, hourDue, 59)),
...@@ -124,7 +124,7 @@ function MonthCalendar() { ...@@ -124,7 +124,7 @@ function MonthCalendar() {
} }
setCurrentTask((newTask)) setCurrentTask((newTask))
} }
const dragTaskHandler = async (dayNumber, hour) => { const dragTaskHandler = async (dayNumber, hour) => {
const hourDiff = currentTask.infoForCell.endHour - currentTask.infoForCell.startHour const hourDiff = currentTask.infoForCell.endHour - currentTask.infoForCell.startHour
const lastHour = hoursInDay[hoursInDay.length - 1].split(':')[0] const lastHour = hoursInDay[hoursInDay.length - 1].split(':')[0]
...@@ -206,7 +206,7 @@ function MonthCalendar() { ...@@ -206,7 +206,7 @@ function MonthCalendar() {
<> <>
<MonthCalendarHeader <MonthCalendarHeader
year={dateNow.year} year={dateNow.year}
currentMonthString={currentMonthString} currentMonthString={currentMonthString}
decrementMonth={decrementMonth} decrementMonth={decrementMonth}
incrementMonth={incrementMonth} incrementMonth={incrementMonth}
onChangeCalendarTypeHandler={onChangeCalendarTypeHandler} onChangeCalendarTypeHandler={onChangeCalendarTypeHandler}
...@@ -220,7 +220,7 @@ function MonthCalendar() { ...@@ -220,7 +220,7 @@ function MonthCalendar() {
tasks={calendarTasks} tasks={calendarTasks}
createTaskInCellHandler={createTaskInCellHandler} createTaskInCellHandler={createTaskInCellHandler}
setCurrentTask={setCurrentTask} setCurrentTask={setCurrentTask}
hourFormat={hourFormat} hourFormat={hourFormat}
setHourFormat={setHourFormat} setHourFormat={setHourFormat}
currentTask={currentTask} currentTask={currentTask}
onChangeCurrentTaskHandler={onChangeCurrentTaskHandler} onChangeCurrentTaskHandler={onChangeCurrentTaskHandler}
......
import moment from 'moment'; import moment from 'moment';
import { useEffect, useState, useMemo, useCallback } from 'react'; import { useEffect, useState, useMemo, useCallback } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import WeekCalendarBody from '../../components/WeekCalendar/WeekCalendarBody/WeekCalendarBody'; import WeekCalendarBody from '../../components/WeekCalendar/WeekCalendarBody/WeekCalendarBody';
import WeekCalendarHeader from '../../components/WeekCalendar/WeekCalendarHeader/WeekCalendarHeader' import WeekCalendarHeader from '../../components/WeekCalendar/WeekCalendarHeader/WeekCalendarHeader'
import { getWeekInfoString, getWeekFromCurrentDate } from '../../helpers/CalendarHelpers'; import { getWeekInfoString, getWeekFromCurrentDate } from '../../helpers/CalendarHelpers';
import { fetchCalendarTasks } from '../../store/actions/tasksActions';
function WeekCalendar() { function WeekCalendar() {
const dispatch = useDispatch();
const [date, setDate] = useState({year: '', month: '', currentDay: ''}) const { calendarTasks } = useSelector(state => state.tasks);
const user = useSelector(state => state.users?.user);
const [date, setDate] = useState({ year: '', month: '', currentDay: '' })
const [hourFormat, setHourFormat] = useState(false); const [hourFormat, setHourFormat] = useState(false);
useEffect(()=>{ useEffect(() => {
const year = new Date().getFullYear() const year = new Date().getFullYear()
const month = new Date().getMonth() const month = new Date().getMonth()
const currentDay = moment().date() const currentDay = moment().date()
setDate({year: year, month: month, currentDay: currentDay}) setDate({ year: year, month: month, currentDay: currentDay })
dispatch(fetchCalendarTasks())
}, []) }, [])
const hoursInDay = useMemo(()=>{ const hoursInDay = useMemo(() => {
let arr let arr
if (hourFormat) { if (hourFormat) {
arr = ['8:00', '9:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00', '19:00', '20:00','21:00','22:00'] arr = ['8:00', '9:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00', '19:00', '20:00', '21:00', '22:00']
} else { } else {
arr = ['8:00', '10:00', '12:00', '14:00', '16:00', '18:00', '20:00', '22:00'] arr = ['8:00', '10:00', '12:00', '14:00', '16:00', '18:00', '20:00', '22:00']
} }
return arr return arr
}, [hourFormat]) }, [hourFormat])
const week = useMemo(()=>{ const week = useMemo(() => {
return getWeekFromCurrentDate(date.year, date.month, date.currentDay) return getWeekFromCurrentDate(date.year, date.month, date.currentDay)
}, [date]) }, [date])
const incrementWeek = useCallback(() => { const incrementWeek = useCallback(() => {
setDate((prevState)=>{ setDate((prevState) => {
const newDate = new Date(prevState.year, prevState.month, prevState.currentDay + 7) const newDate = new Date(prevState.year, prevState.month, prevState.currentDay + 7)
return {year: newDate.getFullYear(), month: newDate.getMonth(), currentDay: moment(newDate).date()} return { year: newDate.getFullYear(), month: newDate.getMonth(), currentDay: moment(newDate).date() }
}) })
}, []) }, [])
const decrementWeek = useCallback(() => { const decrementWeek = useCallback(() => {
setDate((prevState)=>{ setDate((prevState) => {
const newDate = new Date(prevState.year, prevState.month, prevState.currentDay - 7) const newDate = new Date(prevState.year, prevState.month, prevState.currentDay - 7)
return {year: newDate.getFullYear(), month: newDate.getMonth(), currentDay: moment(newDate).date()} return { year: newDate.getFullYear(), month: newDate.getMonth(), currentDay: moment(newDate).date() }
}) })
}, []) }, [])
const weekInfo = useMemo(()=>{ const weekInfo = useMemo(() => {
return getWeekInfoString(week, date) return getWeekInfoString(week, date)
}, [date, week]) }, [date, week])
return ( return (
<> <>
<WeekCalendarHeader <WeekCalendarHeader
...@@ -57,6 +62,8 @@ function WeekCalendar() { ...@@ -57,6 +62,8 @@ function WeekCalendar() {
weekInfo={weekInfo} weekInfo={weekInfo}
/> />
<WeekCalendarBody <WeekCalendarBody
tasks={calendarTasks}
date={date}
week={week} week={week}
hourFormat={hourFormat} hourFormat={hourFormat}
setHourFormat={setHourFormat} setHourFormat={setHourFormat}
......
...@@ -6,8 +6,8 @@ export const getDaysInMonth = (dateNow) => { ...@@ -6,8 +6,8 @@ export const getDaysInMonth = (dateNow) => {
const daysInMonthNumber = new Date(dateNow.year, dateNow.month + 1, 0).getDate() const daysInMonthNumber = new Date(dateNow.year, dateNow.month + 1, 0).getDate()
for (let i = 1; i <= daysInMonthNumber; i++) { for (let i = 1; i <= daysInMonthNumber; i++) {
const dayOfWeekNumber = new Date(dateNow.year, dateNow.month, i).getDay() const dayOfWeekNumber = new Date(dateNow.year, dateNow.month, i).getDay()
const getDayOfWeekString = ["ВС","ПН","ВТ","СР","ЧТ","ПТ","СБ"][dayOfWeekNumber] const getDayOfWeekString = ["ВС", "ПН", "ВТ", "СР", "ЧТ", "ПТ", "СБ"][dayOfWeekNumber]
newDaysInMonth.push({dayNumber: i, dayOfWeek: getDayOfWeekString}) newDaysInMonth.push({ dayNumber: i, dayOfWeek: getDayOfWeekString })
} }
return newDaysInMonth return newDaysInMonth
} else { } else {
...@@ -17,7 +17,7 @@ export const getDaysInMonth = (dateNow) => { ...@@ -17,7 +17,7 @@ export const getDaysInMonth = (dateNow) => {
export const getCurrentMonthString = (month) => { export const getCurrentMonthString = (month) => {
if (month <= 11 && month >= 0) { if (month <= 11 && month >= 0) {
return ["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь", "Декабрь"][month]; return ["Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь"][month];
} else { } else {
return null return null
} }
...@@ -26,7 +26,7 @@ export const getCurrentMonthString = (month) => { ...@@ -26,7 +26,7 @@ export const getCurrentMonthString = (month) => {
export const dateToISOLikeButLocal = (date) => { export const dateToISOLikeButLocal = (date) => {
if (date instanceof Date && !isNaN(date)) { if (date instanceof Date && !isNaN(date)) {
const offsetMs = date.getTimezoneOffset() * 60 * 1000; const offsetMs = date.getTimezoneOffset() * 60 * 1000;
const msLocal = date.getTime() - offsetMs; const msLocal = date.getTime() - offsetMs;
const dateLocal = new Date(msLocal); const dateLocal = new Date(msLocal);
const iso = dateLocal.toISOString(); const iso = dateLocal.toISOString();
return iso; return iso;
...@@ -37,39 +37,150 @@ export const dateToISOLikeButLocal = (date) => { ...@@ -37,39 +37,150 @@ export const dateToISOLikeButLocal = (date) => {
export const getWeekFromCurrentDate = (year, month, curDay) => { export const getWeekFromCurrentDate = (year, month, curDay) => {
const week = [0, 0, 0, 0, 0, 0, 0] const week = [0, 0, 0, 0, 0, 0, 0]
const currentDayWeek = moment(new Date(year, month, curDay)).isoWeekday() const currentDayWeek = moment(new Date(year, month, curDay)).isoWeekday()
for (let i = 1; i <= 7; i++) { for (let i = 1; i <= 7; i++) {
if (currentDayWeek > i ) { if (currentDayWeek > i) {
const day = moment(new Date(year, month, curDay - i)).date() const day = moment(new Date(year, month, curDay - i)).date()
const dayWeek = moment(new Date(year, month, curDay - i)).isoWeekday() const dayWeek = moment(new Date(year, month, curDay - i)).isoWeekday()
week[dayWeek - 1] = day week[dayWeek - 1] = day
} else if (currentDayWeek === i) { } else if (currentDayWeek === i) {
const day = moment(new Date(year, month, curDay)).date() const day = moment(new Date(year, month, curDay)).date()
const dayWeek = moment(new Date(year, month, curDay)).isoWeekday() const dayWeek = moment(new Date(year, month, curDay)).isoWeekday()
week[dayWeek - 1] = day week[dayWeek - 1] = day
} else { } else {
const day = moment(new Date(year, month, curDay + i - moment(new Date(year, month, curDay)).isoWeekday())).date() const day = moment(new Date(year, month, curDay + i - moment(new Date(year, month, curDay)).isoWeekday())).date()
const dayWeek = i - moment(new Date(year, month, curDay)).isoWeekday() + moment(new Date(year, month, curDay)).isoWeekday() const dayWeek = i - moment(new Date(year, month, curDay)).isoWeekday() + moment(new Date(year, month, curDay)).isoWeekday()
week[dayWeek - 1] = day week[dayWeek - 1] = day
}
} }
return week }
return week
} }
export const getWeekInfoString = (week, date) => { export const getWeekInfoString = (week, date) => {
if (week[0] > week[6]) { if (week[0] > week[6]) {
if (date.currentDay < week[0]) { if (date.currentDay < week[0]) {
if (date.month === 0) { if (date.month === 0) {
return getCurrentMonthString(11) + ' - ' + getCurrentMonthString(0) + ' ' + date.year return getCurrentMonthString(11) + ' - ' + getCurrentMonthString(0) + ' ' + date.year
} }
return getCurrentMonthString(date.month - 1) + ' - ' + getCurrentMonthString(date.month) + ' ' + date.year return getCurrentMonthString(date.month - 1) + ' - ' + getCurrentMonthString(date.month) + ' ' + date.year
} else { } else {
if (date.month === 11) { if (date.month === 11) {
return getCurrentMonthString(date.month) + ' - ' + getCurrentMonthString(0) + ' ' + date.year return getCurrentMonthString(date.month) + ' - ' + getCurrentMonthString(0) + ' ' + date.year
} }
return getCurrentMonthString(date.month) + ' - ' + getCurrentMonthString(date.month + 1) + ' ' + date.year return getCurrentMonthString(date.month) + ' - ' + getCurrentMonthString(date.month + 1) + ' ' + date.year
} }
} else { } else {
return getCurrentMonthString(date.month) + ' ' + date.year return getCurrentMonthString(date.month) + ' ' + date.year
} }
}
export const getHoursInDayNumbers = (hoursInDay) => {
return hoursInDay.map((hour) => parseInt(hour.split(':')[0]))
}
const taskIsAvailableInCell = (task, hour, hourDiffEnd, hourDiff, hourFormat) => {
if (((task.infoForCell.endHour <= hour || task.infoForCell.startHour <= hour) && (task.infoForCell.endHour > hour))
|| (!hourFormat && task.infoForCell.startHour >= hour && task.infoForCell.endHour < hour + hourDiff)
|| (!hourFormat && task.infoForCell.startHour === hour + hourDiffEnd && task.infoForCell.endHour > hour)
|| (task.infoForCell.endMinute <= 59 && task.infoForCell.endHour === hour)) {
return true
} else {
return false
}
}
const lastPlaceInLineForTask = (task, hour, hourDiffEnd, hourFormat) => {
if ((task.infoForCell.endMinute === 59 && task.infoForCell.endHour === hour + hourDiffEnd) || (!hourFormat && task.infoForCell.endMinute === 59 && task.infoForCell.endHour === hour)) {
return true
} else {
return false
}
}
export const getLinesInDay = (availableTasks, sortedTasks, hoursInDay, hours, hourFormat) => {
let hourDiff
let hourDiffEnd
const lines = []
if (hourFormat) {
hourDiff = 1
hourDiffEnd = 0
} else {
hourDiff = 2
hourDiffEnd = 1
}
if (availableTasks.length) {
lines.push(hoursInDay.map((hour)=>parseInt(hour.split(':')[0])))
for (let k = 0; k < sortedTasks.length; k++) {
let skipLine = false
for (let j = 0; j < lines.length; j++) {
const line = lines[j]
const task = sortedTasks[k]
if (skipLine) {
skipLine = false
break;
}
for (let i = 0; i < line.length; i++) {
const hour = hours[i]
let havePlace = true
if (taskIsAvailableInCell(task, hour, hourDiffEnd, hourDiff, hourFormat)) {
if (!isNaN(line[i])) {
for (let a = 0; a < hours.length; a++) {
const hour = hours[a]
if (lastPlaceInLineForTask(task, hour, hourDiffEnd, hourFormat)) {
if (isNaN(line[a])) {
havePlace = false
break;
}
}
}
if (!havePlace) {
if (j + 1 === lines.length) {
lines.push(hoursInDay.map((hour)=>parseInt(hour.split(':')[0])))
}
havePlace = true
break;
}
line[i] += `-${k}`
if (lastPlaceInLineForTask(task, hour, hourDiffEnd, hourFormat)) {
skipLine = true
break;
}
} else {
if (j + 1 === lines.length) {
lines.push(hoursInDay.map((hour)=>parseInt(hour.split(':')[0])))
}
break;
}
}
}
}
}
}
return lines
}
export const getSortedTasks = (availableTasks) => {
if (availableTasks.length) {
const newSortedArr = [...availableTasks].sort(function(a,b){
const durattionFirstDate = a.infoForCell.endHour - a.infoForCell.startHour
const durattionSecondDate = b.infoForCell.endHour - b.infoForCell.startHour
return durattionSecondDate - durattionFirstDate;
})
return newSortedArr
}
}
export const getAvailableTasks = (tasks, year, month, dayNumber) => {
const tasksInDay = tasks.filter((task)=> {
if (year === task.infoForCell.startYear) {
if (month + 1 === task.infoForCell.startMonth) {
if (dayNumber === task.infoForCell.startDay) {
return task
} else {return false}
} else {return false}
} else {return false}
})
return tasksInDay
} }
\ No newline at end of file
import {getDaysInMonth, getCurrentMonthString, dateToISOLikeButLocal} from '../helpers/CalendarHelpers'; import {getDaysInMonth, getCurrentMonthString, dateToISOLikeButLocal, getAvailableTasks, getSortedTasks} from '../helpers/CalendarHelpers';
import {getAvailableTasks, getSortedTasks} from '../components/MonthCalendar/MonthCalendarBody/CalendarRowDay/Helpers'
describe('Получение дней в феврале 2022', () => { describe('Получение дней в феврале 2022', () => {
test('Всего дней', () => { test('Всего дней', () => {
......
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