UNPKG

react-weekly-table

Version:

React weekly scheduler <br/> By default build time ranges for a week, supports up to 31 days <br/> Can work with different timezones, data always return to UTC+0

132 lines (131 loc) 4.78 kB
import { jsx as _jsx } from "react/jsx-runtime"; import { createContext, useCallback, useContext, useState, } from 'react'; import { HOUR_24, TIME, } from '../common'; import { useCells } from './CellsProvider'; import { useTimeBlock } from './TimeBlockProvider'; const CustomTimeContext = createContext({}); /** * Custom time provider context hook * @returns [CustomTimeProps]{@link CustomTimeProps} */ export const useCustomTime = () => useContext(CustomTimeContext); /** * Custom time provider, used for setting time with second precision */ const CustomTimeProvider = ({ children }) => { const { millisPerPixel } = useCells(); const { blocks, setBlocks } = useTimeBlock(); /** * Ms time state */ const [time, setTime] = useState({}); /** * Timers relative coordinates */ const [position, setPosition] = useState(); /** * Editing state * If active, other operations with timeblocks will be ignored */ const [isEditing, setEditing] = useState(false); /** * Prime timeblock state */ const [oldBlock, setOldBlock] = useState(); /** * Error state with description */ const [isError, setError] = useState(undefined); /** * Timers visible time */ const [displayTime, setDisplayTime] = useState({ startTime: '00:00:00', endTime: '00:00:00', }); /** * Extracting timeblock properties and saving it */ const handleObject = useCallback((block) => { setOldBlock(block); setPosition({ top: block.height > 20 ? block.height + block.top + 5 : block.top + 25, left: block.left, }); setTime({ startTime: block.startTime, endTime: block.endTime, }); setDisplayTime({ startTime: new Date(block.startTime).toISOString().substr(11, 8), endTime: new Date(block.endTime).toISOString().substr(11, 8), }); }, []); /** * Timers data extraction */ const handleTime = useCallback((newTime, type) => { if (newTime === undefined || newTime === null) { setError('Time is null'); return; } if (isNaN(newTime)) { newTime = 0; } setError(undefined); if (type === TIME.START) { setTime(Object.assign(Object.assign({}, time), { startTime: newTime })); setDisplayTime(Object.assign(Object.assign({}, displayTime), { startTime: new Date(newTime).toISOString().substr(11, 8) })); } else { setTime(Object.assign(Object.assign({}, time), { endTime: newTime === 0 ? HOUR_24 : newTime })); setDisplayTime(Object.assign(Object.assign({}, displayTime), { endTime: new Date(newTime).toISOString().substr(11, 8) })); } }, [displayTime, time]); /** * Timers data reset */ const resetTime = useCallback(() => { if (!oldBlock) return; setTime({ startTime: oldBlock.startTime, endTime: oldBlock.endTime, }); setDisplayTime({ startTime: new Date(oldBlock.startTime).toISOString().substr(11, 8), endTime: new Date(oldBlock.endTime).toISOString().substr(11, 8), }); setError(undefined); }, [oldBlock]); /** * Updating time to timeblock */ const updateBlock = useCallback(() => { if (!oldBlock) return true; const filteredBlocks = blocks.filter((b) => b.id !== oldBlock.id); if (time.endTime - time.startTime < 1000 * 60) { setError('Range < 1 min'); return true; } const topY = -(oldBlock.startTime - time.startTime) / millisPerPixel; const botY = -(oldBlock.endTime - time.endTime) / millisPerPixel; const newBlock = Object.assign(Object.assign({}, oldBlock), { startTime: time.startTime, endTime: time.endTime, realStartTime: time.startTime, realEndTime: time.endTime, top: oldBlock.top + topY, height: oldBlock.height + botY - topY }); setBlocks(filteredBlocks.concat(newBlock)); return false; //eslint-disable-next-line }, [blocks, millisPerPixel, oldBlock, time.endTime, time.startTime]); return (_jsx(CustomTimeContext.Provider, Object.assign({ value: { isEditing, resetTime, setEditing, handleTime, updateBlock, position, handleObject, displayTime, isError, } }, { children: children }))); }; export default CustomTimeProvider;