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
JavaScript
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;