react-weekly-planning 1.0.39 → 1.0.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/AddTask/index.js +16 -0
- package/dist/components/CalendarForWeek.js +30 -0
- package/dist/components/CalendarForday.js +22 -0
- package/dist/components/DayContainer/index.js +15 -0
- package/dist/components/GroupContainer/index.js +15 -0
- package/dist/components/GroupsHeadContainer/index.js +8 -0
- package/dist/components/SumHoursContainer/index.js +15 -0
- package/dist/components/SumHoursHead/index.js +8 -0
- package/dist/components/TaskContainer/TaskVirtual.js +18 -0
- package/dist/components/TaskContainer/index.js +36 -0
- package/dist/components/TaskList/index.js +4 -0
- package/dist/components/VirtualGroupRow.js +64 -0
- package/dist/components/VirtualGroupRowDay.js +49 -0
- package/dist/components/index.js +70 -0
- package/dist/contexts/CalendarContext.js +8 -0
- package/dist/contexts/CalendarTaskContext.js +32 -0
- package/dist/definitions/index.js +1 -0
- package/dist/hooks/useCalendarDateState.js +19 -0
- package/dist/hooks/useCalendarTask.js +191 -0
- package/dist/hooks/useContainerScroll.js +14 -0
- package/dist/hooks/useData.js +7 -0
- package/dist/hooks/useGridContainer.js +24 -0
- package/dist/hooks/useIntersectionObserver.js +19 -0
- package/dist/hooks/useMainContainerItemContent.js +16 -0
- package/dist/hooks/useWindowsSize.js +19 -0
- package/dist/index.js +19 -0
- package/dist/lib/slyles.js +21 -0
- package/dist/lib/utils.js +657 -0
- package/dist/types/components/AddTask/index.d.ts +3 -0
- package/dist/types/components/CalendarForWeek.d.ts +3 -0
- package/dist/types/components/CalendarForday.d.ts +5 -0
- package/dist/types/components/DayContainer/index.d.ts +3 -0
- package/dist/types/components/GroupContainer/index.d.ts +3 -0
- package/dist/types/components/GroupsHeadContainer/index.d.ts +3 -0
- package/dist/types/components/SumHoursContainer/index.d.ts +3 -0
- package/dist/types/components/SumHoursHead/index.d.ts +3 -0
- package/dist/types/components/TaskContainer/TaskVirtual.d.ts +4 -0
- package/dist/types/components/TaskContainer/index.d.ts +3 -0
- package/dist/types/components/TaskList/index.d.ts +5 -0
- package/dist/types/components/VirtualGroupRow.d.ts +18 -0
- package/dist/types/components/VirtualGroupRowDay.d.ts +19 -0
- package/dist/types/components/index.d.ts +65 -0
- package/dist/types/contexts/CalendarContext.d.ts +7 -0
- package/dist/types/contexts/CalendarTaskContext.d.ts +23 -0
- package/dist/types/definitions/index.d.ts +417 -0
- package/dist/types/hooks/useCalendarDateState.d.ts +6 -0
- package/dist/types/hooks/useCalendarTask.d.ts +16 -0
- package/dist/types/hooks/useContainerScroll.d.ts +3 -0
- package/dist/types/hooks/useData.d.ts +4 -0
- package/dist/types/hooks/useGridContainer.d.ts +5 -0
- package/dist/types/hooks/useIntersectionObserver.d.ts +5 -0
- package/dist/types/hooks/useMainContainerItemContent.d.ts +4 -0
- package/dist/types/hooks/useWindowsSize.d.ts +4 -0
- package/dist/types/index.d.ts +16 -0
- package/dist/types/lib/slyles.d.ts +4 -0
- package/dist/types/lib/utils.d.ts +90 -0
- package/package.json +1 -1
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
const AddTask = ({ currentGroup, handleAddTask, addTaskRender, dayInfo, addTaskStyle, addTaskClassName, }) => {
|
|
3
|
+
if (addTaskRender) {
|
|
4
|
+
return (_jsx(_Fragment, { children: addTaskRender({
|
|
5
|
+
currentGroup,
|
|
6
|
+
dayInfo,
|
|
7
|
+
}) }));
|
|
8
|
+
}
|
|
9
|
+
const handleClick = () => {
|
|
10
|
+
if (!handleAddTask)
|
|
11
|
+
return;
|
|
12
|
+
handleAddTask(currentGroup, dayInfo);
|
|
13
|
+
};
|
|
14
|
+
return (_jsx("div", { onClick: handleClick, style: addTaskStyle, className: `addPlanStyle ${addTaskClassName}`, children: "+" }));
|
|
15
|
+
};
|
|
16
|
+
export default AddTask;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import GroupsHeadContainer from "./GroupsHeadContainer";
|
|
3
|
+
import { theadTrStyle } from "../lib/slyles";
|
|
4
|
+
import DayContainer from "./DayContainer";
|
|
5
|
+
import { getHash, updateOffsetWithDateCalendar, } from "../lib/utils";
|
|
6
|
+
import { memo, useMemo } from "react";
|
|
7
|
+
import useCalendarDateState from "../hooks/useCalendarDateState";
|
|
8
|
+
import { useCalendarTaskContext } from "../contexts/CalendarTaskContext";
|
|
9
|
+
import VirtualGroupRow from "./VirtualGroupRow";
|
|
10
|
+
const CalendarForWeek = (props) => {
|
|
11
|
+
var _a;
|
|
12
|
+
const { getTasks, isValidTask, addTask, deleteTask, getTask, hashScope, tasks } = useCalendarTaskContext();
|
|
13
|
+
const { dailyHours, weekDays } = useCalendarDateState(props.date, props.weekOffset, props.timeZone);
|
|
14
|
+
const memoizedHeader = useMemo(() => (_jsx("div", { className: "planningCalendarHeader", children: _jsxs("div", { className: `planningCalendarRow ${props.rowsClassName}`, style: Object.assign(Object.assign({}, theadTrStyle), props.rowsStyle), children: [_jsx("div", { className: `dayTh ${props.groupsColsClassName}`, style: Object.assign({}, props.groupsColsStyle), children: _jsx(GroupsHeadContainer, { className: `${props.groupHeadContainerClassName}`, style: props.groupHeadContainerStyle, groupsHeadRender: props.groupsHeadRender }) }), weekDays.map((day, i) => (_jsx("div", { className: `dayCol ${props.daysColsClassName}`, style: Object.assign({}, props.daysColsStyle), children: _jsx(DayContainer, { style: props.dayStyle, className: props.dayClassName, dayIndex: i, dayRender: props.dayRender, day: day.day, dayOfTheMonth: day.dayOfTheMonth, dayMonth: day.dayMonth, dayYear: day.dayYear }) }, i)))] }, "header") })), [weekDays, props.rowsClassName, props.rowsStyle, props.groupsColsClassName, props.groupsColsStyle, props.groupHeadContainerClassName, props.groupHeadContainerStyle, props.groupsHeadRender, props.daysColsClassName, props.daysColsStyle, props.dayStyle, props.dayClassName, props.dayRender]);
|
|
15
|
+
const offset = useMemo(() => updateOffsetWithDateCalendar(props.date), [props.date]);
|
|
16
|
+
return (_jsx("div", { className: "calendarForWeek", style: { position: "relative" }, children: _jsxs("div", { className: `planningCalendar ${props.className}`, style: Object.assign({}, props.style), children: [memoizedHeader, _jsx("div", { className: "planningCalendarBody", children: (_a = props.groups) === null || _a === void 0 ? void 0 : _a.map((group, i) => {
|
|
17
|
+
var _a;
|
|
18
|
+
const scope = hashScope || "week";
|
|
19
|
+
const groupHash = getHash(offset, group.id);
|
|
20
|
+
const sumHoursByGroupsCount = ((_a = tasks.buckets[groupHash[scope]]) === null || _a === void 0 ? void 0 : _a.sumOfTaskDuration) || 0;
|
|
21
|
+
return (_jsx(VirtualGroupRow, { group: group, i: i, props: props, getTasks: getTasks, isValidTask: isValidTask, addTask: addTask, deleteTask: deleteTask, getTask: getTask, dailyHours: dailyHours, hashScope: scope, tasks: tasks, sumHoursByGroupsCount: sumHoursByGroupsCount }, `${group.id}-${i}`));
|
|
22
|
+
}) })] }) }));
|
|
23
|
+
};
|
|
24
|
+
export default memo(CalendarForWeek, (prevProps, nextProps) => {
|
|
25
|
+
var _a, _b;
|
|
26
|
+
return (((_a = prevProps.date) === null || _a === void 0 ? void 0 : _a.getTime()) === ((_b = nextProps.date) === null || _b === void 0 ? void 0 : _b.getTime()) &&
|
|
27
|
+
prevProps.weekOffset === nextProps.weekOffset &&
|
|
28
|
+
prevProps.groups === nextProps.groups &&
|
|
29
|
+
prevProps.className === nextProps.className);
|
|
30
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import "./style.css";
|
|
3
|
+
import { memo, useMemo } from "react";
|
|
4
|
+
import useCalendarDateState from "../hooks/useCalendarDateState";
|
|
5
|
+
import VirtualGroupRowDay from "./VirtualGroupRowDay";
|
|
6
|
+
import DayContainer from "./DayContainer";
|
|
7
|
+
import { useCalendarTaskContext } from "../contexts/CalendarTaskContext";
|
|
8
|
+
function CalendarForDay(props) {
|
|
9
|
+
const { dailyHours, weekDays } = useCalendarDateState(props.date, props.weekOffset, props.timeZone);
|
|
10
|
+
const { getTasks, isValidTask, addTask, deleteTask, updateTask, getTask, hashScope, tasks } = useCalendarTaskContext();
|
|
11
|
+
const currentDay = weekDays[props.dayOffset || 0];
|
|
12
|
+
const memoizedHeader = useMemo(() => (currentDay ? (_jsx(DayContainer, { style: props.dayStyle, className: props.dayClassName, dayIndex: props.dayOffset || 0, dayRender: props.dayRender, day: currentDay.day, dayOfTheMonth: currentDay.dayOfTheMonth, dayMonth: currentDay.dayMonth, dayYear: currentDay.dayYear })) : null), [currentDay, props.dayStyle, props.dayClassName, props.dayOffset, props.dayRender]);
|
|
13
|
+
return (_jsxs("div", { className: `CalendarTableForDay ${props.className}`, style: Object.assign({ position: "relative" }, props.style), children: [memoizedHeader, _jsx("div", { className: `CalendarTableForDayTasksContainer`, children: props.groups.map((group, i) => (_jsx(VirtualGroupRowDay, { group: group, i: i, props: props, getTasks: getTasks, isValidTask: isValidTask, addTask: addTask, deleteTask: deleteTask, updateTask: updateTask, getTask: getTask, dailyHours: dailyHours, dayOffset: props.dayOffset || 0, hashScope: hashScope || "day", tasks: tasks }, `${group.id}-${i}`))) })] }));
|
|
14
|
+
}
|
|
15
|
+
export default memo(CalendarForDay, (prevProps, nextProps) => {
|
|
16
|
+
var _a, _b;
|
|
17
|
+
return (((_a = prevProps.date) === null || _a === void 0 ? void 0 : _a.getTime()) === ((_b = nextProps.date) === null || _b === void 0 ? void 0 : _b.getTime()) &&
|
|
18
|
+
prevProps.weekOffset === nextProps.weekOffset &&
|
|
19
|
+
prevProps.dayOffset === nextProps.dayOffset &&
|
|
20
|
+
prevProps.groups === nextProps.groups &&
|
|
21
|
+
prevProps.className === nextProps.className);
|
|
22
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { memo } from "react";
|
|
3
|
+
const DayContainer = ({ dayIndex, dayOfTheMonth, day, dayMonth, dayYear, dayRender, className, style, }) => {
|
|
4
|
+
if (dayRender) {
|
|
5
|
+
return (_jsx(_Fragment, { children: dayRender({
|
|
6
|
+
dayIndex,
|
|
7
|
+
day,
|
|
8
|
+
dayOfTheMonth,
|
|
9
|
+
dayMonth,
|
|
10
|
+
dayYear,
|
|
11
|
+
}) }));
|
|
12
|
+
}
|
|
13
|
+
return (_jsx("div", { className: `${className}`, style: style, children: `${day}. ${dayOfTheMonth}` }));
|
|
14
|
+
};
|
|
15
|
+
export default memo(DayContainer);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { memo } from "react";
|
|
3
|
+
import { groupContainerStyle } from "../../lib/slyles";
|
|
4
|
+
const GroupContainer = ({ className, style, groupRender, currentGroup, handleClickGroup, }) => {
|
|
5
|
+
if (groupRender) {
|
|
6
|
+
return _jsx(_Fragment, { children: groupRender({ currentGroup }) });
|
|
7
|
+
}
|
|
8
|
+
const handleClick = () => {
|
|
9
|
+
if (!handleClickGroup)
|
|
10
|
+
return;
|
|
11
|
+
handleClickGroup(currentGroup);
|
|
12
|
+
};
|
|
13
|
+
return (_jsxs("div", { onClick: handleClick, className: `${className}`, style: Object.assign(Object.assign({}, groupContainerStyle), style), children: [currentGroup.imageUrl && (_jsx("img", { width: 30, height: 30, src: currentGroup.imageUrl, alt: "groupimg" })), _jsx("label", { children: currentGroup.label && currentGroup.label })] }));
|
|
14
|
+
};
|
|
15
|
+
export default memo(GroupContainer);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
const GroupsHeadContainer = ({ groupsHeadRender, style, className, }) => {
|
|
3
|
+
if (groupsHeadRender) {
|
|
4
|
+
return _jsx(_Fragment, { children: groupsHeadRender() });
|
|
5
|
+
}
|
|
6
|
+
return (_jsx("div", { className: `${className}`, style: style, children: "WeeklyCalendar" }));
|
|
7
|
+
};
|
|
8
|
+
export default GroupsHeadContainer;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { memo } from "react";
|
|
3
|
+
import { totalLabel } from "../../lib/utils";
|
|
4
|
+
const SumHoursContainer = ({ groupId, weekOffset, calendarDate, sumHoursByGroups, sumHoursRender, className, style, }) => {
|
|
5
|
+
if (sumHoursRender) {
|
|
6
|
+
return (_jsx(_Fragment, { children: sumHoursRender({
|
|
7
|
+
groupId,
|
|
8
|
+
weekOffset,
|
|
9
|
+
calendarDate,
|
|
10
|
+
sumHoursByGroups,
|
|
11
|
+
}) }));
|
|
12
|
+
}
|
|
13
|
+
return (_jsx("div", { style: Object.assign({ textAlign: "right", marginRight: "5px" }, style), className: `${className}`, children: totalLabel(sumHoursByGroups) }));
|
|
14
|
+
};
|
|
15
|
+
export default memo(SumHoursContainer);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
const SumHoursHead = ({ sumHoursHeadRender, className, style, }) => {
|
|
3
|
+
if (sumHoursHeadRender) {
|
|
4
|
+
return _jsx(_Fragment, { children: sumHoursHeadRender() });
|
|
5
|
+
}
|
|
6
|
+
return (_jsx("div", { className: `${className}`, style: Object.assign({ textAlign: "right", marginRight: "5px" }, style), children: "Hours" }));
|
|
7
|
+
};
|
|
8
|
+
export default SumHoursHead;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React, { useRef } from "react";
|
|
3
|
+
import { useIntersectionObserver } from "../../hooks/useIntersectionObserver";
|
|
4
|
+
import TaskContainer from ".";
|
|
5
|
+
const TaskVirtual = (props) => {
|
|
6
|
+
const ref = useRef(null);
|
|
7
|
+
const entry = useIntersectionObserver(ref, {
|
|
8
|
+
rootMargin: "200px", // Margin to pre-render tasks before they appear
|
|
9
|
+
threshold: 0,
|
|
10
|
+
});
|
|
11
|
+
const isVisible = !!(entry === null || entry === void 0 ? void 0 : entry.isIntersecting);
|
|
12
|
+
return (_jsx("div", { ref: ref, style: {
|
|
13
|
+
minHeight: isVisible ? "auto" : "40px",
|
|
14
|
+
width: "100%",
|
|
15
|
+
marginBottom: "4px"
|
|
16
|
+
}, children: isVisible ? (_jsx(TaskContainer, Object.assign({}, props))) : (_jsx("div", { style: { height: "60px", backgroundColor: "rgba(200, 200, 200, 0.1)", borderRadius: "4px" } })) }));
|
|
17
|
+
};
|
|
18
|
+
export default React.memo(TaskVirtual);
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { memo } from "react";
|
|
3
|
+
import { millisecondsToDate } from "../../lib/utils";
|
|
4
|
+
const TaskContainer = ({ handleDragTask, taskRender, handleDragTaskEnd, style, className, currentTask, handleClickTask, }) => {
|
|
5
|
+
const handleDragStart = (event) => {
|
|
6
|
+
if (!handleDragTask)
|
|
7
|
+
return;
|
|
8
|
+
event.dataTransfer.effectAllowed = "move";
|
|
9
|
+
event.dataTransfer.setData("text/plain", currentTask.id);
|
|
10
|
+
window.sessionStorage.setItem("calendardragtaskId", currentTask.id);
|
|
11
|
+
window.sessionStorage.setItem("calendardragtaskStart", `${currentTask.taskStart}`);
|
|
12
|
+
window.sessionStorage.setItem("calendardragtaskEnd", `${currentTask.taskEnd}`);
|
|
13
|
+
window.sessionStorage.setItem("calendardragdayIndex", `${currentTask.dayIndex}`);
|
|
14
|
+
window.sessionStorage.setItem("calendardraghash", `${currentTask.hash}`);
|
|
15
|
+
handleDragTask(event, currentTask);
|
|
16
|
+
};
|
|
17
|
+
const handleDragEnd = (event) => {
|
|
18
|
+
if (!handleDragTaskEnd)
|
|
19
|
+
return;
|
|
20
|
+
handleDragTaskEnd(event);
|
|
21
|
+
};
|
|
22
|
+
const handleClick = () => {
|
|
23
|
+
if (!handleClickTask)
|
|
24
|
+
return;
|
|
25
|
+
handleClickTask(currentTask);
|
|
26
|
+
};
|
|
27
|
+
if (taskRender) {
|
|
28
|
+
return (_jsx("div", { onClick: handleClick, id: currentTask.id, className: `taskContainer ${className}`, style: Object.assign({}, style), draggable: true, onDragStart: handleDragStart, onDragEnd: handleDragEnd, children: taskRender({
|
|
29
|
+
currentTask,
|
|
30
|
+
}) }));
|
|
31
|
+
}
|
|
32
|
+
return (_jsxs("div", { onClick: handleClick, id: currentTask.id, className: `taskContainer ${className}`, style: Object.assign({}, style), draggable: true, onDragStart: handleDragStart, onDragEnd: handleDragEnd, children: [_jsx("p", { className: "tasklabel", children: currentTask.task && currentTask.task }), _jsx("p", { className: "taskhour", children: currentTask.taskStart &&
|
|
33
|
+
currentTask.taskEnd &&
|
|
34
|
+
`${millisecondsToDate(currentTask.taskStart).formattedDate} - ${millisecondsToDate(currentTask.taskEnd).formattedDate}` })] }));
|
|
35
|
+
};
|
|
36
|
+
export default memo(TaskContainer);
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import TaskContainer from "../TaskContainer";
|
|
3
|
+
const TaskList = ({ tasks }) => (_jsx("div", { style: { height: 300, width: "100%" }, children: _jsx("div", { style: { display: "flex", flexDirection: "column" }, children: tasks.map(task => _jsx(TaskContainer, { currentTask: task }, task.id)) }) }));
|
|
4
|
+
export default TaskList;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { memo, useRef, useMemo } from "react";
|
|
3
|
+
import { v4 as uuidv4 } from "uuid";
|
|
4
|
+
import { useIntersectionObserver } from "../hooks/useIntersectionObserver";
|
|
5
|
+
import GroupContainer from "./GroupContainer";
|
|
6
|
+
import TaskVirtual from "./TaskContainer/TaskVirtual";
|
|
7
|
+
import AddTask from "./AddTask";
|
|
8
|
+
import { getHash, getSessionStorageRecordForDragAndDrop, getUnqueId, updateOffsetWithDateCalendar, } from "../lib/utils";
|
|
9
|
+
import { groupTdStyle } from "../lib/slyles";
|
|
10
|
+
const VirtualGroupRow = ({ group, i, props, getTasks, isValidTask, addTask, deleteTask, getTask, dailyHours, hashScope, tasks, sumHoursByGroupsCount }) => {
|
|
11
|
+
const ref = useRef(null);
|
|
12
|
+
const entry = useIntersectionObserver(ref, {
|
|
13
|
+
rootMargin: "600px",
|
|
14
|
+
threshold: 0,
|
|
15
|
+
});
|
|
16
|
+
const isVisible = !!(entry === null || entry === void 0 ? void 0 : entry.isIntersecting);
|
|
17
|
+
const offset = useMemo(() => updateOffsetWithDateCalendar(props.date), [props.date]);
|
|
18
|
+
const cellData = useMemo(() => {
|
|
19
|
+
if (!isVisible)
|
|
20
|
+
return [];
|
|
21
|
+
return dailyHours.map((_, positionDay) => {
|
|
22
|
+
const hash = getHash(offset, group.id, positionDay);
|
|
23
|
+
const cellTasks = getTasks(hash[hashScope]);
|
|
24
|
+
return {
|
|
25
|
+
hash: hash[hashScope],
|
|
26
|
+
tasks: cellTasks,
|
|
27
|
+
positionDay
|
|
28
|
+
};
|
|
29
|
+
});
|
|
30
|
+
}, [isVisible, offset, group.id, dailyHours, hashScope, getTasks, isValidTask, tasks]);
|
|
31
|
+
return (_jsx("div", { ref: ref, className: `planningCalendarRow ${props.rowsClassName}`, style: Object.assign(Object.assign({}, props.rowsStyle), { minHeight: isVisible ? "auto" : "60px" }), children: isVisible ? (_jsxs(_Fragment, { children: [_jsx("div", { className: `groupCol ${props.groupsColsClassName}`, style: Object.assign(Object.assign({}, groupTdStyle), props.groupsColsStyle), children: _jsx(GroupContainer, { style: props.groupContainerStyle, className: props.groupContainerClassName, groupRender: props.groupRender, currentGroup: group, handleClickGroup: props.handleClickGroup }) }, group.id), cellData.map((cell) => {
|
|
32
|
+
return (_jsx("div", { onDragOver: (e) => e.preventDefault(), onDrop: (event) => {
|
|
33
|
+
const dropInfo = getSessionStorageRecordForDragAndDrop(cell.tasks, cell.positionDay, group.id, getTask, cell.hash);
|
|
34
|
+
if (!dropInfo)
|
|
35
|
+
return;
|
|
36
|
+
if (props.drop === "copy") {
|
|
37
|
+
addTask(Object.assign(Object.assign({}, dropInfo.newTask), { id: uuidv4() }));
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
deleteTask(dropInfo.newTask.draghash, dropInfo.newTask.id);
|
|
41
|
+
addTask(Object.assign(Object.assign({}, dropInfo.newTask), { id: getUnqueId() }));
|
|
42
|
+
}, id: `col-${group.id}day-i`, className: `dayCol ${props.dayColsClassName}`, style: props.dayColsStyle, children: _jsxs("div", { style: {
|
|
43
|
+
display: "flex",
|
|
44
|
+
width: "100%",
|
|
45
|
+
height: "100%",
|
|
46
|
+
flexDirection: "column",
|
|
47
|
+
padding: "5px",
|
|
48
|
+
}, children: [cell.tasks.map((task) => {
|
|
49
|
+
if (task.dayIndex === cell.positionDay &&
|
|
50
|
+
task.groupId === group.id && isValidTask(task)) {
|
|
51
|
+
return (_jsx(TaskVirtual, { handleDragTask: props.handleDragTask, taskRender: props.taskRender, handleDragTaskEnd: props.handleDragTaskEnd, style: props.taskContainerStyle, className: `${props.taskContainerClassName}`, currentTask: task, handleClickTask: props.handleClickTask }, `${task.id} task`));
|
|
52
|
+
}
|
|
53
|
+
else
|
|
54
|
+
return null;
|
|
55
|
+
}), _jsx(AddTask, { addTaskStyle: props.addTaskStyle, addTaskClassName: props.addTaskClassName, currentGroup: group, dayInfo: dailyHours[cell.positionDay], addTaskRender: props.addTaskRender, handleAddTask: props.handleAddTask })] }) }, `col-${group.id}day-i${cell.positionDay}`));
|
|
56
|
+
})] })) : (_jsx("div", { style: { height: "60px", width: "100%" } })) }));
|
|
57
|
+
};
|
|
58
|
+
export default memo(VirtualGroupRow, (prev, next) => {
|
|
59
|
+
return (prev.group.id === next.group.id &&
|
|
60
|
+
prev.i === next.i &&
|
|
61
|
+
prev.tasks === next.tasks &&
|
|
62
|
+
prev.props.date.getTime() === next.props.date.getTime() &&
|
|
63
|
+
prev.sumHoursByGroupsCount === next.sumHoursByGroupsCount);
|
|
64
|
+
});
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { memo, useRef, useMemo } from "react";
|
|
3
|
+
import { useIntersectionObserver } from "../hooks/useIntersectionObserver";
|
|
4
|
+
import GroupContainer from "./GroupContainer";
|
|
5
|
+
import TaskVirtual from "./TaskContainer/TaskVirtual";
|
|
6
|
+
import AddTask from "./AddTask";
|
|
7
|
+
import { getHash, getSessionStorageRecordForDragAndDrop, getUnqueId, updateOffsetWithDateCalendar, } from "../lib/utils";
|
|
8
|
+
const VirtualGroupRowDay = ({ group, i, props, getTasks, isValidTask, addTask, deleteTask, updateTask, getTask, dailyHours, dayOffset, hashScope, tasks, }) => {
|
|
9
|
+
const ref = useRef(null);
|
|
10
|
+
const entry = useIntersectionObserver(ref, {
|
|
11
|
+
rootMargin: "600px",
|
|
12
|
+
threshold: 0,
|
|
13
|
+
});
|
|
14
|
+
const isVisible = !!(entry === null || entry === void 0 ? void 0 : entry.isIntersecting);
|
|
15
|
+
const offset = useMemo(() => updateOffsetWithDateCalendar(props.date), [props.date]);
|
|
16
|
+
const currentDailyHours = dailyHours[dayOffset];
|
|
17
|
+
const hash = useMemo(() => getHash(offset, group.id, dayOffset), [offset, group.id, dayOffset]);
|
|
18
|
+
const cellTasks = useMemo(() => getTasks(hash[hashScope]), [getTasks, hash, hashScope, tasks]);
|
|
19
|
+
const handleDragOver = (event) => {
|
|
20
|
+
event.preventDefault();
|
|
21
|
+
};
|
|
22
|
+
return (_jsx("div", { ref: ref, style: Object.assign({ width: "100%", height: "auto", padding: "5px", borderBottom: "1.5px solid #0f52737e", borderRight: "0.74px solid rgba(198, 219, 225, 0.68)", borderLeft: "0.74px solid rgba(198, 219, 225, 0.68)", minHeight: isVisible ? "auto" : "60px" }, props.rowsStyle), className: `CalendarTableForDayRow ${props.rowsClassName}`, children: isVisible ? (_jsxs(_Fragment, { children: [_jsx("div", { style: Object.assign({ width: "auto", height: "auto" }, props.groupsColsStyle), className: props.groupsColsClassName, children: _jsx(GroupContainer, { style: props.groupContainerStyle, className: props.groupContainerClassName, groupRender: props.groupRender, currentGroup: group, handleClickGroup: props.handleClickGroup }) }), _jsxs("div", { className: "CalendarTableForDayGroupTasks", onDragOver: handleDragOver, onDrop: (event) => {
|
|
23
|
+
if (!cellTasks)
|
|
24
|
+
return;
|
|
25
|
+
const dropInfo = getSessionStorageRecordForDragAndDrop(cellTasks, currentDailyHours.positionDay, group.id, getTask, hash[hashScope]);
|
|
26
|
+
if (!dropInfo)
|
|
27
|
+
return;
|
|
28
|
+
if (props.drop === "copy") {
|
|
29
|
+
addTask(Object.assign(Object.assign({}, dropInfo.newTask), { id: getUnqueId() }));
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
updateTask(hash[hashScope], dropInfo.newTask.id, dropInfo.newTask);
|
|
33
|
+
}, children: [cellTasks.map((task) => {
|
|
34
|
+
if (task.dayIndex === dayOffset &&
|
|
35
|
+
task.groupId === group.id &&
|
|
36
|
+
isValidTask(task)) {
|
|
37
|
+
return (_jsx(TaskVirtual, { handleDragTask: props.handleDragTask, taskRender: props.taskRender, handleDragTaskEnd: props.handleDragTaskEnd, style: props.taskContainerStyle, className: `${props.taskContainerClassName}`, currentTask: task, handleClickTask: props.handleClickTask }, `${task.id} task`));
|
|
38
|
+
}
|
|
39
|
+
else
|
|
40
|
+
return null;
|
|
41
|
+
}), _jsx(AddTask, { addTaskStyle: props.addTaskStyle, addTaskClassName: props.addTaskClassName, currentGroup: group, dayInfo: currentDailyHours, addTaskRender: props.addTaskRender, handleAddTask: props.handleAddTask })] })] })) : (_jsx("div", { style: { height: "60px", width: "100%" } })) }));
|
|
42
|
+
};
|
|
43
|
+
export default memo(VirtualGroupRowDay, (prev, next) => {
|
|
44
|
+
return (prev.group.id === next.group.id &&
|
|
45
|
+
prev.i === next.i &&
|
|
46
|
+
prev.tasks === next.tasks &&
|
|
47
|
+
prev.props.date.getTime() === next.props.date.getTime() &&
|
|
48
|
+
prev.dayOffset === next.dayOffset);
|
|
49
|
+
});
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import "./style.css";
|
|
3
|
+
import CalendarForWeek from "./CalendarForWeek";
|
|
4
|
+
import CalendarForDay from "./CalendarForday";
|
|
5
|
+
import CalendarTaskContextProvider from "../contexts/CalendarTaskContext";
|
|
6
|
+
/**
|
|
7
|
+
* Calendar component to display tasks and groups in a weekly view.
|
|
8
|
+
*
|
|
9
|
+
* @param {CalendarPropsType} props - The props for the Calendar component.
|
|
10
|
+
* @param {number} [props.weekOffset] - Offset for the week (e.g., -7 for last week, 0 for current week, 7 for next week).
|
|
11
|
+
* @param {GroupFeildsType[]} props.groups - Array of group data to be displayed in the calendar.
|
|
12
|
+
* @param {string} [props.className] - Additional class names for the calendar component.
|
|
13
|
+
* @param {React.CSSProperties} [props.style] - Additional styles for the calendar component.
|
|
14
|
+
* @param {Date} props.date - The current date to display in the calendar.
|
|
15
|
+
* @param {(currentGroup: { currentGroup: GroupFeildsType }) => React.ReactNode} [props.groupRender] - Custom render function for a group.
|
|
16
|
+
* @param {({ dayIndex, day, dayOfTheMonth, dayMonth, dayYear }: { dayIndex: number; day: string; dayOfTheMonth: number; dayMonth: string; dayYear: number }) => React.ReactNode} [props.dayRender] - Custom render function for a day.
|
|
17
|
+
* @param {(currentTask: { currentTask: TaskFeildsType }) => React.ReactNode} [props.taskRender] - Custom render function for a task.
|
|
18
|
+
* @param {React.CSSProperties} [props.rowsStyle] - Additional styles for the rows.
|
|
19
|
+
* @param {string} [props.rowsClassName] - Additional class names for the rows.
|
|
20
|
+
* @param {React.CSSProperties} [props.groupsColsStyle] - Additional styles for the group columns.
|
|
21
|
+
* @param {string} [props.groupsColsClassName] - Additional class names for the group columns.
|
|
22
|
+
* @param {React.CSSProperties} [props.daysColsStyle] - Additional styles for the day columns.
|
|
23
|
+
* @param {string} [props.daysColsClassName] - Additional class names for the day columns.
|
|
24
|
+
* @param {string} [props.addTaskClassName] - Additional class names for the add-task button.
|
|
25
|
+
* @param {React.CSSProperties} [props.addTaskStyle] - Additional styles for the add-task button.
|
|
26
|
+
* @param {string} [props.groupContainerClassName] - Additional class names for the group containers.
|
|
27
|
+
* @param {React.CSSProperties} [props.groupContainerStyle] - Additional styles for the group containers.
|
|
28
|
+
* @param {string} [props.dayClassName] - Additional class names for the day elements.
|
|
29
|
+
* @param {React.CSSProperties} [props.dayStyle] - Additional styles for the day elements.
|
|
30
|
+
* @param {React.CSSProperties} [props.taskContainerStyle] - Additional styles for the task container.
|
|
31
|
+
* @param {string} [props.taskContainerClassName] - Additional class names for the task container.
|
|
32
|
+
* @param {React.CSSProperties} [props.groupHeadContainerStyle] - Additional styles for the group header container.
|
|
33
|
+
* @param {string} [props.groupHeadContainerClassName] - Additional class names for the group header container.
|
|
34
|
+
* @param {React.CSSProperties} [props.sumHoursContainerStyle] - Additional styles for the sum-of-hours container.
|
|
35
|
+
* @param {string} [props.sumHoursContainerClassName] - Additional class names for the sum-of-hours container.
|
|
36
|
+
* @param {React.CSSProperties} [props.sumHoursHeadStyle] - Additional styles for the sum-of-hours header.
|
|
37
|
+
* @param {string} [props.sumHoursHeadClassName] - Additional class names for the sum-of-hours header.
|
|
38
|
+
* @param {(currentGroup: GroupFeildsType, dayInfo: dayInfoType) => void} [props.handleAddTask] - Handler function for adding a new task.
|
|
39
|
+
* @param {({ currentGroup, dayInfo }: { currentGroup: GroupFeildsType; dayInfo: dayInfoType }) => React.ReactNode} [props.addTaskRender] - Custom render function for adding a task.
|
|
40
|
+
* @param {TasksType} props.tasks - Array of tasks to be displayed in the calendar.
|
|
41
|
+
* @param {(event: React.DragEvent<HTMLDivElement>, currentTask: TaskFeildsType) => void} [props.handleDragTask] - Handler function for dragging a task.
|
|
42
|
+
* @param {(event: React.DragEvent<HTMLDivElement>, taskStart: number, taskEnd: number, taskDate: Date, groupId: string, dayIndex: number, newTask: TaskFeildsType, newTasks: TasksType) => void} [props.handleDropTask] - Handler function for dropping a task.
|
|
43
|
+
* @param {(event: React.DragEvent<HTMLDivElement>) => void} [props.handleDragTaskEnd] - Handler function for ending the drag of a task.
|
|
44
|
+
* @param {() => React.ReactNode} [props.groupsHeadRender] - Custom render function for the groups header.
|
|
45
|
+
* @param {({
|
|
46
|
+
* groupId,
|
|
47
|
+
* tasks,
|
|
48
|
+
* weekOffset,
|
|
49
|
+
* calendarDate,
|
|
50
|
+
* sumHoursByGroups
|
|
51
|
+
* }: {
|
|
52
|
+
* groupId: string;
|
|
53
|
+
* tasks: TasksType;
|
|
54
|
+
* weekOffset: number;
|
|
55
|
+
* calendarDate: Date;
|
|
56
|
+
* sumHoursByGroups: number;
|
|
57
|
+
* }) => React.ReactNode} [props.sumHoursRender] - Custom render function for the sum of hours.
|
|
58
|
+
* @param {() => React.ReactNode} [props.sumHoursHeadRender] - Custom render function for the sum-of-hours header.
|
|
59
|
+
* @param {(currentTask: TaskFeildsType) => void} [props.handleClickTask] - Handler function for clicking a task.
|
|
60
|
+
* @param {(currentGroup: GroupFeildsType) => void} [props.handleClickGroup] - Handler function for clicking a group.
|
|
61
|
+
* @param {0|1|2|3|4|5|6} [props.dayOffset] - Offset index for the day column (0 = first day of week, …, 6 = last day).
|
|
62
|
+
* @param {React.CSSProperties} [props.dayColsStyle] - Additional styles for the day columns.
|
|
63
|
+
* @param {string} [props.dayColsClassName] - Additional class names for the day columns.
|
|
64
|
+
* @param {React.CSSProperties} [props.hoursColsStyle] - Additional styles for the hours columns.
|
|
65
|
+
* @param {string} [props.hoursColsClassName] - Additional class names for the hours columns.
|
|
66
|
+
*/
|
|
67
|
+
const Calendar = (props) => {
|
|
68
|
+
return (_jsx(CalendarTaskContextProvider, { hashScope: "week", children: props.scope === "day" ? _jsx(CalendarForDay, Object.assign({}, props)) : _jsx(CalendarForWeek, Object.assign({}, props)) }));
|
|
69
|
+
};
|
|
70
|
+
export default Calendar;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useContext } from "react";
|
|
3
|
+
const CalendarContext = createContext({});
|
|
4
|
+
const CalendarContextProvider = ({ children, }) => {
|
|
5
|
+
return (_jsx(CalendarContext.Provider, { value: {}, children: children }));
|
|
6
|
+
};
|
|
7
|
+
export const useCalendarContext = () => useContext(CalendarContext);
|
|
8
|
+
export default CalendarContextProvider;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useContext } from "react";
|
|
3
|
+
import { useCalendarTask } from "../hooks/useCalendarTask";
|
|
4
|
+
const CalendarTaskContext = createContext({
|
|
5
|
+
tasks: { buckets: {}, dataLength: 0, taskCache: {} },
|
|
6
|
+
addTask: () => { },
|
|
7
|
+
getTasks: () => [],
|
|
8
|
+
updateTask: () => { },
|
|
9
|
+
deleteTask: () => { },
|
|
10
|
+
cleanExpiredTasks: () => { },
|
|
11
|
+
cleanExpiredTasksByHash: () => { },
|
|
12
|
+
isValidTask: () => false,
|
|
13
|
+
getTask: () => undefined,
|
|
14
|
+
hashScope: "week"
|
|
15
|
+
});
|
|
16
|
+
const CalendarTaskContextProvider = ({ children, hashScope }) => {
|
|
17
|
+
const { tasks, addTask, getTasks, updateTask, deleteTask, cleanExpiredTasks, cleanExpiredTasksByHash, isValidTask, getTask } = useCalendarTask(hashScope || "week");
|
|
18
|
+
return (_jsx(CalendarTaskContext.Provider, { value: {
|
|
19
|
+
tasks,
|
|
20
|
+
addTask,
|
|
21
|
+
getTasks,
|
|
22
|
+
updateTask,
|
|
23
|
+
deleteTask,
|
|
24
|
+
cleanExpiredTasks,
|
|
25
|
+
cleanExpiredTasksByHash,
|
|
26
|
+
isValidTask,
|
|
27
|
+
getTask,
|
|
28
|
+
hashScope
|
|
29
|
+
}, children: children }));
|
|
30
|
+
};
|
|
31
|
+
export const useCalendarTaskContext = () => useContext(CalendarTaskContext);
|
|
32
|
+
export default CalendarTaskContextProvider;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import { calculateWeekDifference, getDateObjectInTimeZone, getDayHourly, getWeekDays, } from "../lib/utils";
|
|
3
|
+
function useCalendarDateState(date, weekOffset, timeZone) {
|
|
4
|
+
const [calendarDateState, setCalendarDateState] = useState({ dailyHours: [], weekDays: [] });
|
|
5
|
+
useEffect(() => {
|
|
6
|
+
const weekOffsetByDate = timeZone
|
|
7
|
+
? calculateWeekDifference(getDateObjectInTimeZone(timeZone), timeZone)
|
|
8
|
+
: calculateWeekDifference(date, timeZone);
|
|
9
|
+
const weekDays = getWeekDays(weekOffsetByDate || weekOffset || 0, timeZone);
|
|
10
|
+
const dailyHours = getDayHourly(weekOffsetByDate || weekOffset || 0, timeZone);
|
|
11
|
+
const calData = {
|
|
12
|
+
dailyHours: dailyHours,
|
|
13
|
+
weekDays,
|
|
14
|
+
};
|
|
15
|
+
setCalendarDateState(calData);
|
|
16
|
+
}, [date, weekOffset]);
|
|
17
|
+
return Object.assign({}, calendarDateState);
|
|
18
|
+
}
|
|
19
|
+
export default useCalendarDateState;
|