Commit 98c5286f authored by Ermolaev Timur's avatar Ermolaev Timur

#100 Перенес логику в недельный календарь, придаю коду более приятный вид

parent 7843e98f
import { Grid } from "@mui/material";
const CalendarRow = ({children, week}) => {
const CalendarRow = ({ children, week }) => {
return <>
<Grid
container
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}
</Grid>
......
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 CalendarTask from "../CalendarTask/CalendarTask";
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(()=>{
return hoursInDay.map((hour)=>parseInt(hour.split(':')[0]))},
[hoursInDay])
const hours = useMemo(() => {
return getHoursInDayNumbers(hoursInDay)
}, [hoursInDay])
const availableTasks = useMemo(() => {
return getAvailableTasks(tasks, year, month, day.dayNumber)
......@@ -29,9 +30,9 @@ const CalendarRowDay = ({xs, hoursInDay, createTaskInCellHandler, currentTask, h
item
xs={10.8}
align='center'
sx={{position: 'relative'}}
sx={{ position: 'relative' }}
>
{hoursInDay.map((hour, i)=>{
{hoursInDay.map((hour, i) => {
return (
<CalendarStandartCell
linesInDay={linesInDay}
......@@ -48,21 +49,21 @@ const CalendarRowDay = ({xs, hoursInDay, createTaskInCellHandler, currentTask, h
</CalendarStandartCell>
)
})}
<Grid sx={{position: 'absolute', top: '0'}} container item xs={12}>
{linesInDay?.map((line, i)=>{
<Grid sx={{ position: 'absolute', top: '0' }} container item xs={12}>
{linesInDay?.map((line, i) => {
const boxes = getBoxesInLine(line, hoursInDay, sortedTasks)
return(
<Grid key={i} container sx={{height: '35px', backgroundColor: 'rgb(0,0,0,0)', marginBottom: '5px'}}>
{boxes.map((box, index)=>{
return (
<Grid key={i} container sx={{ height: '35px', backgroundColor: 'rgb(0,0,0,0)', marginBottom: '5px' }}>
{boxes.map((box, index) => {
if (box.task) {
return (<Grid
item xs={box.xs}
key={box.task.id}
sx={{height: '35px', marginBottom: '5px'}}
sx={{ height: '35px', marginBottom: '5px' }}
>
<CalendarTask
dragTaskHandler={dragTaskHandler}
setCurrentLine={()=>{setCurrentLine(day.dayNumber)}}
setCurrentLine={() => { setCurrentLine(day.dayNumber) }}
currentTask={currentTask}
currentLine={currentLine}
hour={parseInt(hours[index])}
......@@ -93,10 +94,10 @@ const CalendarRowDay = ({xs, hoursInDay, createTaskInCellHandler, currentTask, h
})}
</Grid>
<Grid container sx={{height: '35px', backgroundColor: 'rgb(0,0,0,0)', marginBottom: '5px', position: 'absolute', bottom: '0'}}>
{hoursInDay.map((hour, i)=>{
<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
return (<EmptyBox
key={i}
modal={modal}
dayNumber={day.dayNumber}
......@@ -115,8 +116,8 @@ const CalendarRowDay = ({xs, hoursInDay, createTaskInCellHandler, currentTask, h
</>
};
export default memo(CalendarRowDay, (prevProps, nextProps)=>{
if(!prevProps.modal) return false
if(nextProps.modal) return true
export default memo(CalendarRowDay, (prevProps, nextProps) => {
if (!prevProps.modal) return false
if (nextProps.modal) return true
});
import { Grid} from "@mui/material";
import React, { memo, useEffect, useState} from "react";
import { Grid } from "@mui/material";
import React, { memo, useEffect, useState } from "react";
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)
useEffect(()=>{
if(!modal) {
useEffect(() => {
if (!modal) {
setIsThisCell(false);
}
}, [modal])
......@@ -30,10 +30,10 @@ const EmptyBox = ({hourNumber, handleOpen, dayNumber, xs, dragTaskHandler, modal
dragTaskHandler(dayNumber, hourNumber)
}
return(<Grid
onDragOver={(e)=>{dragOverHandler(e)}}
onDrop={(e)=>{dropHandler(e)}}
onClick={(e)=>{onClickHandler(e, dayNumber, hourNumber)}}
return (<Grid
onDragOver={(e) => { dragOverHandler(e) }}
onDrop={(e) => { dropHandler(e) }}
onClick={(e) => { onClickHandler(e, dayNumber, hourNumber) }}
className='test_empty_box'
item xs={xs} sx={{
height: '40px',
......@@ -42,11 +42,11 @@ const EmptyBox = ({hourNumber, handleOpen, dayNumber, xs, dragTaskHandler, modal
cursor: copyTask ? 'pointer' : 'default'
}}>
{isThisCell ?
<DefaultTask/> : ' '}
<DefaultTask /> : ' '}
</Grid>)
};
export default memo(EmptyBox, (prevProps, nextProps)=>{
if(!prevProps.modal) return false
if(nextProps.modal) return true
export default memo(EmptyBox, (prevProps, nextProps) => {
if (!prevProps.modal) return false
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) => {
if (line) {
let xs = 12/hoursInDay.length
......
import { Grid } from "@mui/material";
import { memo } from "react";
const CalendarSmallCell = ({children, xs, week}) => {
const CalendarSmallCell = ({ children, xs, week }) => {
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}
</Grid>
</>
......
import { Grid} from "@mui/material";
import { Grid } from "@mui/material";
import { memo, useEffect, useState } from "react";
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 cellClass = {
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',
borderBottom: week ?'1px solid black' : null,
borderBottom: week ? '1px solid black' : null,
}
useEffect(()=>{
if(!modal) {
useEffect(() => {
if (!modal) {
setIsThisCell(false);
}
}, [modal])
......@@ -41,19 +41,19 @@ const CalendarStandartCell = ({children, xs, hours, dayNumber, createTaskInCell
<Grid
item xs={xs}
sx={cellClass}
onClick={(e)=>{onClickHandler(e)}}
onDragOver={(e)=>{dragOverHandler(e)}}
onDrop={(e)=>{dropHandler(e)}}
onClick={(e) => { onClickHandler(e) }}
onDragOver={(e) => { dragOverHandler(e) }}
onDrop={(e) => { dropHandler(e) }}
>
{children}
{isThisCell ?
<DefaultTask/> : null}
<DefaultTask /> : null}
</Grid>
</>
};
export default memo(CalendarStandartCell, (prevProps, nextProps)=>{
if(!prevProps.modal) return false
if(nextProps.modal) return true
});
\ No newline at end of file
export default memo(CalendarStandartCell, (prevProps, nextProps) => {
if (!prevProps.modal) return false
if (nextProps.modal) return true
});
\ No newline at end of file
import { Grid} from "@mui/material";
import React, { memo, useEffect, useState} from "react";
import { Grid } from "@mui/material";
import React, { memo, useEffect, useState } from "react";
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('')
useEffect(() => {
......@@ -17,7 +17,7 @@ const CalendarTask = ({setCurrentTask, handleOpen, task, line, setCurrentLine, s
const onClickTaskHandler = (e, task) => {
e.stopPropagation();
setCurrentTask((prevState)=>{
setCurrentTask((prevState) => {
return {
...task,
infoForCell: {
......@@ -43,16 +43,16 @@ const CalendarTask = ({setCurrentTask, handleOpen, task, line, setCurrentLine, s
return (<>
<Grid
draggable={true}
onDragLeave={(e)=>{dragLeaveHandler(e)}}
onDragStart={(e)=>{dragStartHandler(e, line, task)}}
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'}}
onClick={(e)=>{onClickTaskHandler(e, task)}}
onDragLeave={(e) => { dragLeaveHandler(e) }}
onDragStart={(e) => { dragStartHandler(e, line, task) }}
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' }}
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}
</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>
......
......@@ -17,7 +17,7 @@ const DefaultTaskStyles = {
zIndex: '5'
}
const DefaultTask = ({}) => {
const DefaultTask = ({ }) => {
return (<>
<Box
......
import { Box, FormControlLabel, Switch} from "@mui/material";
import { Box, FormControlLabel, Switch } from "@mui/material";
import { useState } from "react";
import CalendarRow from "./CalendarRow/CalendarRow";
import CalendarSmallCell from "./CalendarSmallCell/CalendarSmallCell";
......@@ -8,12 +8,12 @@ import MonthCalendarModalContent from "../MonthCalendarModalContent/MonthCalenda
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 [modal, setModal] = useState({open:false, y: 0, x: 0,});
const [modal, setModal] = useState({ open: false, y: 0, x: 0, });
const handleOpen = (e) => {
setModal( {
setModal({
open: true,
yClickСordinates: e.clientY,
xClickСordinates: e.clientX,
......@@ -25,23 +25,23 @@ function MonthCalendarBody({month, year, tasks, createTaskInCellHandler, current
};
const handleClose = () => {
setModal({...modal, open: false})
setModal({ ...modal, open: false })
setCurrentTask({})
};
return (
<Box style={{marginBottom: '30px'}}>
<div style={{position: 'sticky', top: '0px', zIndex: '10', backgroundColor: 'lightgrey'}}>
<Box style={{ marginBottom: '30px' }}>
<div style={{ position: 'sticky', top: '0px', zIndex: '10', backgroundColor: 'lightgrey' }}>
<CalendarRow
>
<CalendarSmallCell xs={1.2}>
<FormControlLabel
control={<Switch color="primary" checked={hourFormat} onChange={()=>{setHourFormat(()=>!hourFormat)}}/>}
control={<Switch color="primary" checked={hourFormat} onChange={() => { setHourFormat(() => !hourFormat) }} />}
label="1 час"
labelPlacement="end"
/>
</CalendarSmallCell>
{hoursInDay?.map((hours, i)=>{
{hoursInDay?.map((hours, i) => {
return (
<CalendarStandartCell key={i} xs={cellSizes.standarCell}>
{hours}
......@@ -50,7 +50,7 @@ function MonthCalendarBody({month, year, tasks, createTaskInCellHandler, current
})}
</CalendarRow>
</div>
{daysInMonth?.map((day, i)=>{
{daysInMonth?.map((day, i) => {
return (
<CalendarRow
key={i}
......@@ -83,7 +83,7 @@ function MonthCalendarBody({month, year, tasks, createTaskInCellHandler, current
})}
<ModalTask
modal={modal}
handleClose={()=>{handleClose()}}
handleClose={() => { handleClose() }}
>
<MonthCalendarModalContent
title={currentTask.title}
......@@ -91,9 +91,9 @@ function MonthCalendarBody({month, year, tasks, createTaskInCellHandler, current
priority={currentTask.priority}
startHour={currentTask.infoForCell?.startHour}
endHour={currentTask.infoForCell?.endHour}
onChangeCurrentTaskHandler={(e)=>{ onChangeCurrentTaskHandler(e)}}
sendNewTaskHandler={()=>{sendNewTaskHandler(); handleClose()}}
deleteTaskHandler={()=>{deleteTaskHandler(currentTask.id); handleClose()}}
onChangeCurrentTaskHandler={(e) => { onChangeCurrentTaskHandler(e) }}
sendNewTaskHandler={() => { sendNewTaskHandler(); handleClose() }}
deleteTaskHandler={() => { deleteTaskHandler(currentTask.id); handleClose() }}
/>
</ModalTask>
</Box>
......
......@@ -3,7 +3,7 @@ import { Box, Typography } from '@mui/material';
import { memo } from 'react';
import ArrowDecrementButton from '../../../UI/ArrowDecrementButton/ArrowDecrementButton';
import ArrowIncrementButton from '../../../UI/ArrowIncrementButton/ArrowIncrementButton';
function MonthAndYearInfo({currentMonthString, year, incrementMonth, decrementMonth}) {
function MonthAndYearInfo({ currentMonthString, year, incrementMonth, decrementMonth }) {
return (
<>
......@@ -35,7 +35,7 @@ function MonthAndYearInfo({currentMonthString, year, incrementMonth, decrementMo
onClick={incrementMonth}
/>
</Box>
</> );
</>);
}
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 MonthAndYearInfo from './MonthAndYearInfo/MonthAndYearInfo';
import СustomSelect from '../../UI/СustomSelect/СustomSelect'
const workers = [{value: '', text: '--выберите сотрудника--'}, {value: 'Василий', text: 'Василий'}, {value: 'Никита', text: 'Никита'}]
const types = [{value: 'Месяц', text: 'Месяц'}, {value: 'Неделя', text: 'Неделя'}]
const workers = [{ value: '', text: '--выберите сотрудника--' }, { 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 (
<>
......@@ -22,15 +22,15 @@ function MonthCalendarHeader({ currentMonthString, decrementMonth, incrementMont
/>
<СustomSelect
value={worker}
onChange={(e)=>{onChangeWorkerHandler(e)}}
onChange={(e) => { onChangeWorkerHandler(e) }}
label={'Сотрудник'}
id={'worker'}
items={workers}
/>
<div style={{marginLeft: '20px'}}>
<div style={{ marginLeft: '20px' }}>
<СustomSelect
value={calendarType}
onChange={(e)=>{onChangeCalendarTypeHandler(e)}}
onChange={(e) => { onChangeCalendarTypeHandler(e) }}
label={'Календарь'}
id={'calendar-type'}
items={types}
......
......@@ -2,19 +2,19 @@ import { Button, TextField } from "@mui/material";
import { memo } from "react";
import CustomSelect from '../../UI/СustomSelect/СustomSelect'
const priorities = [{value: null, text: '--Приоритет--'}, {value: 'A', text: 'A'}, {value: 'B', text: 'B'}, {value: 'C', text: 'C'}]
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 (<>
<TextField
id="task-description-title"
value={title}
label="Название"
variant="outlined"
sx={{marginBottom: '30px'}}
sx={{ marginBottom: '30px' }}
name='title'
onChange={(e)=>{onChangeCurrentTaskHandler(e)}}
onChange={(e) => { onChangeCurrentTaskHandler(e) }}
/>
<TextField
id="task-description"
......@@ -23,28 +23,28 @@ function MonthCalendarModalContent({title, onChangeCurrentTaskHandler, descripti
value={description}
label="Описание"
variant="outlined"
sx={{marginBottom: '30px'}}
sx={{ marginBottom: '30px' }}
name='description'
onChange={(e)=>{onChangeCurrentTaskHandler(e)}}
onChange={(e) => { onChangeCurrentTaskHandler(e) }}
/>
<CustomSelect
defaultValue={null}
value={priority}
name={'priority'}
variant={'outlined'}
onChange={(e)=>{onChangeCurrentTaskHandler(e)}}
onChange={(e) => { onChangeCurrentTaskHandler(e) }}
label={'Приоритет'}
id={'priority-type'}
items={priorities}
/>
<div style={{display: 'flex', gap: '20px', margin: '20px 0'}}>
<div style={{ display: 'flex', gap: '20px', margin: '20px 0' }}>
<TextField
id="task-startHour"
value={startHour}
label="От"
variant="outlined"
name='startHour'
onChange={(e)=>{onChangeCurrentTaskHandler(e)}}
onChange={(e) => { onChangeCurrentTaskHandler(e) }}
/>
<TextField
id="task-endHour"
......@@ -52,11 +52,11 @@ function MonthCalendarModalContent({title, onChangeCurrentTaskHandler, descripti
label="До"
variant="outlined"
name='endHour'
onChange={(e)=>{onChangeCurrentTaskHandler(e)}}
onChange={(e) => { onChangeCurrentTaskHandler(e) }}
/>
</div>
<div style={{display: 'flex', gap: '20px', margin: '10px 0'}}>
<Button id='test_button_save_task'onClick={sendNewTaskHandler}>Сохранить</Button>
<div style={{ display: 'flex', gap: '20px', margin: '10px 0' }}>
<Button id='test_button_save_task' onClick={sendNewTaskHandler}>Сохранить</Button>
<Button onClick={deleteTaskHandler}>Удалить</Button>
</div>
</>);
......
import { Grid } from "@mui/material";
import CalendarRow from "../../../MonthCalendar/MonthCalendarBody/CalendarRow/CalendarRow";
import { useMemo } from "react";
import { getHoursInDayNumbers, getAvailableTasks, getLinesInDay, getSortedTasks } from "../../../../helpers/CalendarHelpers";
import CalendarStandartCell from "../../../MonthCalendar/MonthCalendarBody/CalendarStandartCell.js/CalendarStandartCell";
function CalendarRowDayWeek({ week, hoursInDay }) {
function CalendarRowDayWeek({hoursInDay, tasks, month, year, day, hourFormat}) {
const hours = useMemo(()=>{
return getHoursInDayNumbers(hoursInDay)
}, [hoursInDay])
const availableTasks = useMemo(() => {
return getAvailableTasks(tasks, year, month, day)
}, [tasks, month, year, day])
const sortedTasks = useMemo(() => {
return getSortedTasks(availableTasks)
}, [availableTasks])
const linesInDay = useMemo(() => {
return getLinesInDay(availableTasks, sortedTasks, hoursInDay, hours, hourFormat)
}, [availableTasks, hourFormat, hours, hoursInDay, sortedTasks])
console.log(linesInDay)
return (<>
{hoursInDay?.map((hour, i) => {
return (
......
......@@ -6,7 +6,7 @@ import CalendarStandartCell from "../../MonthCalendar/MonthCalendarBody/Calendar
import CalendarRowDayWeek from "./CalendarRowDayWeek/CalendarRowDayWeek";
import { getCurrentWeekDayString } from "./Helpers";
function WeekCalendarBody({ week, hoursInDay, hourFormat, setHourFormat, }) {
function WeekCalendarBody({ week, hoursInDay, hourFormat, setHourFormat, date, tasks }) {
return (
<>
......@@ -50,6 +50,11 @@ function WeekCalendarBody({ week, hoursInDay, hourFormat, setHourFormat, }) {
<Grid item key={i} xs={12 / week.length}>
<CalendarRowDayWeek
hoursInDay={hoursInDay}
tasks={tasks}
month={date.month}
year={date.year}
day={weekDay}
hourFormat={hourFormat}
/>
</Grid>
)
......
......@@ -3,7 +3,7 @@ import { useDispatch, useSelector } from 'react-redux';
import MonthCalendarBody from '../../components/MonthCalendar/MonthCalendarBody/MonthCalendarBody';
import MonthCalendarHeader from '../../components/MonthCalendar/MonthCalendarHeader/MonthCalendarHeader';
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() {
const dispatch = useDispatch();
......@@ -11,14 +11,14 @@ function MonthCalendar() {
const user = useSelector(state => state.users?.user);
const [hourFormat, setHourFormat] = useState(false);
const [dateNow, setDateNow] = useState({month: '', year: ''})
const [dateNow, setDateNow] = useState({ month: '', year: '' })
const [worker, setWorker] = 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 [cellSizes, setCellSizes] = useState({})
useEffect(()=>{
useEffect(() => {
setDateNow({
month: new Date().getMonth(),
year: new Date().getFullYear(),
......@@ -27,17 +27,17 @@ function MonthCalendar() {
}, [dispatch])
const hoursInDay = useMemo(()=>{
const hoursInDay = useMemo(() => {
let arr
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 {
arr = ['8:00', '10:00', '12:00', '14:00', '16:00', '18:00', '20:00', '22:00']
}
const cells = arr.length
const xs = 10.8/cells
setCellSizes(()=>{
return {smallCell: 0.6, standarCell: xs, dayCell: 12/cells}
const xs = 10.8 / cells
setCellSizes(() => {
return { smallCell: 0.6, standarCell: xs, dayCell: 12 / cells }
})
return arr
}, [hourFormat])
......@@ -59,24 +59,24 @@ function MonthCalendar() {
}, []);
const incrementMonth = useCallback(() => {
setDateNow((prevState)=>{
if (prevState.month + 1 === 12 ) {
return { month: 0, year: prevState.year + 1}
setDateNow((prevState) => {
if (prevState.month + 1 === 12) {
return { month: 0, year: prevState.year + 1 }
}
return {...prevState, month: prevState.month + 1}
return { ...prevState, month: prevState.month + 1 }
})
}, [])
const decrementMonth = useCallback(() => {
setDateNow((prevState)=>{
setDateNow((prevState) => {
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 {name, value} = e.target;
const { name, value } = e.target;
if (name === 'startHour' || name === 'endHour') {
setCurrentTask((prevState) => {
return {
......@@ -111,8 +111,8 @@ function MonthCalendar() {
hourDue = hour + 2
}
const newTask = {
title:"Задача",
description:"описание",
title: "Задача",
description: "описание",
priority: null,
dateTimeStart: dateToISOLikeButLocal(new Date(dateNow.year, dateNow.month, dayNumber, hour, 0)),
dateTimeDue: dateToISOLikeButLocal(new Date(dateNow.year, dateNow.month, dayNumber, hourDue, 59)),
......
import moment from 'moment';
import { useEffect, useState, useMemo, useCallback } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import WeekCalendarBody from '../../components/WeekCalendar/WeekCalendarBody/WeekCalendarBody';
import WeekCalendarHeader from '../../components/WeekCalendar/WeekCalendarHeader/WeekCalendarHeader'
import { getWeekInfoString, getWeekFromCurrentDate } from '../../helpers/CalendarHelpers';
import { fetchCalendarTasks } from '../../store/actions/tasksActions';
function WeekCalendar() {
const dispatch = useDispatch();
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);
......@@ -15,6 +19,7 @@ function WeekCalendar() {
const month = new Date().getMonth()
const currentDay = moment().date()
setDate({ year: year, month: month, currentDay: currentDay })
dispatch(fetchCalendarTasks())
}, [])
const hoursInDay = useMemo(() => {
......@@ -57,6 +62,8 @@ function WeekCalendar() {
weekInfo={weekInfo}
/>
<WeekCalendarBody
tasks={calendarTasks}
date={date}
week={week}
hourFormat={hourFormat}
setHourFormat={setHourFormat}
......
......@@ -6,8 +6,8 @@ export const getDaysInMonth = (dateNow) => {
const daysInMonthNumber = new Date(dateNow.year, dateNow.month + 1, 0).getDate()
for (let i = 1; i <= daysInMonthNumber; i++) {
const dayOfWeekNumber = new Date(dateNow.year, dateNow.month, i).getDay()
const getDayOfWeekString = ["ВС","ПН","ВТ","СР","ЧТ","ПТ","СБ"][dayOfWeekNumber]
newDaysInMonth.push({dayNumber: i, dayOfWeek: getDayOfWeekString})
const getDayOfWeekString = ["ВС", "ПН", "ВТ", "СР", "ЧТ", "ПТ", "СБ"][dayOfWeekNumber]
newDaysInMonth.push({ dayNumber: i, dayOfWeek: getDayOfWeekString })
}
return newDaysInMonth
} else {
......@@ -17,7 +17,7 @@ export const getDaysInMonth = (dateNow) => {
export const getCurrentMonthString = (month) => {
if (month <= 11 && month >= 0) {
return ["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь", "Декабрь"][month];
return ["Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь"][month];
} else {
return null
}
......@@ -39,7 +39,7 @@ export const getWeekFromCurrentDate = (year, month, curDay) => {
const week = [0, 0, 0, 0, 0, 0, 0]
const currentDayWeek = moment(new Date(year, month, curDay)).isoWeekday()
for (let i = 1; i <= 7; i++) {
if (currentDayWeek > i ) {
if (currentDayWeek > i) {
const day = moment(new Date(year, month, curDay - i)).date()
const dayWeek = moment(new Date(year, month, curDay - i)).isoWeekday()
week[dayWeek - 1] = day
......@@ -73,3 +73,114 @@ export const getWeekInfoString = (week, date) => {
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
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