@isma91/react-scheduler 4.0.0
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/.github/workflows/publish.yml +29 -0
- package/.github/workflows/tests.yml +35 -0
- package/.gitignore +32 -0
- package/.husky/pre-commit +2 -0
- package/.prettierignore +1 -0
- package/.prettierrc.json +7 -0
- package/.yarnrc.yml +1 -0
- package/LICENSE +24 -0
- package/README.md +172 -0
- package/dist/LICENSE +24 -0
- package/dist/README.md +172 -0
- package/dist/SchedulerComponent.d.ts +3 -0
- package/dist/components/common/Cell.d.ts +13 -0
- package/dist/components/common/LocaleArrow.d.ts +8 -0
- package/dist/components/common/ResourceHeader.d.ts +6 -0
- package/dist/components/common/Tabs.d.ts +16 -0
- package/dist/components/common/TodayTypo.d.ts +8 -0
- package/dist/components/common/WithResources.d.ts +6 -0
- package/dist/components/events/Actions.d.ts +8 -0
- package/dist/components/events/AgendaEventsList.d.ts +7 -0
- package/dist/components/events/CurrentTimeBar.d.ts +11 -0
- package/dist/components/events/EmptyAgenda.d.ts +2 -0
- package/dist/components/events/EventItem.d.ts +10 -0
- package/dist/components/events/EventItemPopover.d.ts +9 -0
- package/dist/components/events/MonthEvents.d.ts +13 -0
- package/dist/components/events/TodayEvents.d.ts +16 -0
- package/dist/components/hoc/DateProvider.d.ts +5 -0
- package/dist/components/inputs/DatePicker.d.ts +14 -0
- package/dist/components/inputs/Input.d.ts +19 -0
- package/dist/components/inputs/SelectInput.d.ts +22 -0
- package/dist/components/month/MonthTable.d.ts +8 -0
- package/dist/components/nav/DayDateBtn.d.ts +6 -0
- package/dist/components/nav/MonthDateBtn.d.ts +6 -0
- package/dist/components/nav/Navigation.d.ts +3 -0
- package/dist/components/nav/WeekDateBtn.d.ts +8 -0
- package/dist/components/week/WeekTable.d.ts +11 -0
- package/dist/helpers/constants.d.ts +4 -0
- package/dist/helpers/generals.d.ts +78 -0
- package/dist/hooks/useArrowDisable.d.ts +5 -0
- package/dist/hooks/useCellAttributes.d.ts +18 -0
- package/dist/hooks/useDragAttributes.d.ts +10 -0
- package/dist/hooks/useEventPermissions.d.ts +7 -0
- package/dist/hooks/useStore.d.ts +2 -0
- package/dist/hooks/useSyncScroll.d.ts +8 -0
- package/dist/hooks/useWindowResize.d.ts +4 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +2853 -0
- package/dist/package.json +65 -0
- package/dist/positionManger/context.d.ts +14 -0
- package/dist/positionManger/provider.d.ts +5 -0
- package/dist/positionManger/usePosition.d.ts +4 -0
- package/dist/store/context.d.ts +2 -0
- package/dist/store/default.d.ts +245 -0
- package/dist/store/provider.d.ts +7 -0
- package/dist/store/types.d.ts +27 -0
- package/dist/styles/styles.d.ts +30 -0
- package/dist/types.d.ts +372 -0
- package/dist/views/Day.d.ts +2 -0
- package/dist/views/DayAgenda.d.ts +7 -0
- package/dist/views/Editor.d.ts +11 -0
- package/dist/views/Month.d.ts +2 -0
- package/dist/views/MonthAgenda.d.ts +7 -0
- package/dist/views/Week.d.ts +2 -0
- package/dist/views/WeekAgenda.d.ts +8 -0
- package/eslint.config.js +79 -0
- package/index.html +41 -0
- package/jest.config.ts +194 -0
- package/package.json +137 -0
- package/public/favicon.ico +0 -0
- package/public/logo192.png +0 -0
- package/public/logo512.png +0 -0
- package/public/manifest.json +25 -0
- package/public/robots.txt +3 -0
- package/scripts/post-pack.js +34 -0
- package/src/App.tsx +25 -0
- package/src/Page1.tsx +67 -0
- package/src/events.tsx +227 -0
- package/src/index.tsx +21 -0
- package/src/lib/SchedulerComponent.tsx +78 -0
- package/src/lib/__tests__/index.test.tsx +24 -0
- package/src/lib/components/common/Cell.tsx +52 -0
- package/src/lib/components/common/LocaleArrow.tsx +38 -0
- package/src/lib/components/common/ResourceHeader.tsx +73 -0
- package/src/lib/components/common/Tabs.tsx +119 -0
- package/src/lib/components/common/TodayTypo.tsx +44 -0
- package/src/lib/components/common/WithResources.tsx +98 -0
- package/src/lib/components/events/Actions.tsx +65 -0
- package/src/lib/components/events/AgendaEventsList.tsx +115 -0
- package/src/lib/components/events/CurrentTimeBar.tsx +59 -0
- package/src/lib/components/events/EmptyAgenda.tsx +27 -0
- package/src/lib/components/events/EventItem.tsx +180 -0
- package/src/lib/components/events/EventItemPopover.tsx +179 -0
- package/src/lib/components/events/MonthEvents.tsx +141 -0
- package/src/lib/components/events/TodayEvents.tsx +99 -0
- package/src/lib/components/hoc/DateProvider.tsx +19 -0
- package/src/lib/components/inputs/DatePicker.tsx +95 -0
- package/src/lib/components/inputs/Input.tsx +113 -0
- package/src/lib/components/inputs/SelectInput.tsx +164 -0
- package/src/lib/components/month/MonthTable.tsx +207 -0
- package/src/lib/components/nav/DayDateBtn.tsx +77 -0
- package/src/lib/components/nav/MonthDateBtn.tsx +80 -0
- package/src/lib/components/nav/Navigation.tsx +201 -0
- package/src/lib/components/nav/WeekDateBtn.tsx +89 -0
- package/src/lib/components/week/WeekTable.tsx +229 -0
- package/src/lib/helpers/constants.ts +4 -0
- package/src/lib/helpers/generals.tsx +354 -0
- package/src/lib/hooks/useArrowDisable.ts +26 -0
- package/src/lib/hooks/useCellAttributes.ts +67 -0
- package/src/lib/hooks/useDragAttributes.ts +31 -0
- package/src/lib/hooks/useEventPermissions.ts +42 -0
- package/src/lib/hooks/useStore.ts +8 -0
- package/src/lib/hooks/useSyncScroll.ts +31 -0
- package/src/lib/hooks/useWindowResize.ts +37 -0
- package/src/lib/index.tsx +14 -0
- package/src/lib/positionManger/context.ts +14 -0
- package/src/lib/positionManger/provider.tsx +113 -0
- package/src/lib/positionManger/usePosition.ts +8 -0
- package/src/lib/store/context.ts +5 -0
- package/src/lib/store/default.ts +157 -0
- package/src/lib/store/provider.tsx +211 -0
- package/src/lib/store/types.ts +33 -0
- package/src/lib/styles/styles.ts +256 -0
- package/src/lib/types.ts +423 -0
- package/src/lib/views/Day.tsx +265 -0
- package/src/lib/views/DayAgenda.tsx +57 -0
- package/src/lib/views/Editor.tsx +258 -0
- package/src/lib/views/Month.tsx +82 -0
- package/src/lib/views/MonthAgenda.tsx +84 -0
- package/src/lib/views/Week.tsx +92 -0
- package/src/lib/views/WeekAgenda.tsx +81 -0
- package/src/vite-env.d.ts +3 -0
- package/tsconfig.build.json +5 -0
- package/tsconfig.json +27 -0
- package/vite.config.js +40 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { Fragment, useState } from "react";
|
|
2
|
+
import {
|
|
3
|
+
Button,
|
|
4
|
+
useTheme,
|
|
5
|
+
useMediaQuery,
|
|
6
|
+
Popover,
|
|
7
|
+
MenuList,
|
|
8
|
+
MenuItem,
|
|
9
|
+
IconButton,
|
|
10
|
+
} from "@mui/material";
|
|
11
|
+
import { WeekDateBtn } from "./WeekDateBtn";
|
|
12
|
+
import { DayDateBtn } from "./DayDateBtn";
|
|
13
|
+
import { MonthDateBtn } from "./MonthDateBtn";
|
|
14
|
+
import MoreVertIcon from "@mui/icons-material/MoreVert";
|
|
15
|
+
import ViewAgendaIcon from "@mui/icons-material/ViewAgenda";
|
|
16
|
+
import useStore from "../../hooks/useStore";
|
|
17
|
+
import { NavigationDiv } from "../../styles/styles";
|
|
18
|
+
import { getTimeZonedDate } from "../../helpers/generals";
|
|
19
|
+
|
|
20
|
+
export type View = "month" | "week" | "day";
|
|
21
|
+
|
|
22
|
+
const Navigation = () => {
|
|
23
|
+
const {
|
|
24
|
+
selectedDate,
|
|
25
|
+
view,
|
|
26
|
+
week,
|
|
27
|
+
handleState,
|
|
28
|
+
getViews,
|
|
29
|
+
translations,
|
|
30
|
+
navigation,
|
|
31
|
+
day,
|
|
32
|
+
month,
|
|
33
|
+
disableViewNavigator,
|
|
34
|
+
onSelectedDateChange,
|
|
35
|
+
onViewChange,
|
|
36
|
+
stickyNavigation,
|
|
37
|
+
timeZone,
|
|
38
|
+
agenda,
|
|
39
|
+
toggleAgenda,
|
|
40
|
+
enableAgenda,
|
|
41
|
+
customHeaderContent,
|
|
42
|
+
stickyNavigationOffset,
|
|
43
|
+
} = useStore();
|
|
44
|
+
const [anchorEl, setAnchorEl] = useState<Element | null>(null);
|
|
45
|
+
const theme = useTheme();
|
|
46
|
+
const isDesktop = useMediaQuery(theme.breakpoints.up("sm"));
|
|
47
|
+
const views = getViews();
|
|
48
|
+
|
|
49
|
+
const toggleMoreMenu = (el?: Element) => {
|
|
50
|
+
setAnchorEl(el || null);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const handleSelectedDateChange = (date: Date) => {
|
|
54
|
+
handleState(date, "selectedDate");
|
|
55
|
+
|
|
56
|
+
if (onSelectedDateChange && typeof onSelectedDateChange === "function") {
|
|
57
|
+
onSelectedDateChange(date);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const handleChangeView = (view: View) => {
|
|
62
|
+
handleState(view, "view");
|
|
63
|
+
if (onViewChange && typeof onViewChange === "function") {
|
|
64
|
+
onViewChange(view, agenda);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const renderDateSelector = () => {
|
|
69
|
+
switch (view) {
|
|
70
|
+
case "month":
|
|
71
|
+
return (
|
|
72
|
+
month?.navigation && (
|
|
73
|
+
<MonthDateBtn selectedDate={selectedDate} onChange={handleSelectedDateChange} />
|
|
74
|
+
)
|
|
75
|
+
);
|
|
76
|
+
case "week":
|
|
77
|
+
return (
|
|
78
|
+
week?.navigation && (
|
|
79
|
+
<WeekDateBtn
|
|
80
|
+
selectedDate={selectedDate}
|
|
81
|
+
onChange={handleSelectedDateChange}
|
|
82
|
+
weekProps={week!}
|
|
83
|
+
/>
|
|
84
|
+
)
|
|
85
|
+
);
|
|
86
|
+
case "day":
|
|
87
|
+
return (
|
|
88
|
+
day?.navigation && (
|
|
89
|
+
<DayDateBtn selectedDate={selectedDate} onChange={handleSelectedDateChange} />
|
|
90
|
+
)
|
|
91
|
+
);
|
|
92
|
+
default:
|
|
93
|
+
return "";
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
if (!navigation && disableViewNavigator) return null;
|
|
98
|
+
|
|
99
|
+
return (
|
|
100
|
+
<NavigationDiv sticky={stickyNavigation ? "1" : "0"} offset={stickyNavigationOffset}>
|
|
101
|
+
<div data-testid="date-navigator">{navigation && renderDateSelector()}</div>
|
|
102
|
+
|
|
103
|
+
{customHeaderContent && (
|
|
104
|
+
<div className="rs__custom_header_content">{customHeaderContent()}</div>
|
|
105
|
+
)}
|
|
106
|
+
|
|
107
|
+
<div
|
|
108
|
+
className="rs__view_navigator"
|
|
109
|
+
data-testid="view-navigator"
|
|
110
|
+
style={{
|
|
111
|
+
visibility: disableViewNavigator ? "hidden" : "visible",
|
|
112
|
+
}}
|
|
113
|
+
>
|
|
114
|
+
<Button
|
|
115
|
+
onClick={() => handleSelectedDateChange(getTimeZonedDate(new Date(), timeZone))}
|
|
116
|
+
aria-label={translations.navigation.today}
|
|
117
|
+
>
|
|
118
|
+
{translations.navigation.today}
|
|
119
|
+
</Button>
|
|
120
|
+
{enableAgenda &&
|
|
121
|
+
(isDesktop ? (
|
|
122
|
+
<Button
|
|
123
|
+
color={agenda ? "primary" : "inherit"}
|
|
124
|
+
onClick={toggleAgenda}
|
|
125
|
+
aria-label={translations.navigation.agenda}
|
|
126
|
+
>
|
|
127
|
+
{translations.navigation.agenda}
|
|
128
|
+
</Button>
|
|
129
|
+
) : (
|
|
130
|
+
<IconButton
|
|
131
|
+
color={agenda ? "primary" : "default"}
|
|
132
|
+
style={{ padding: 5 }}
|
|
133
|
+
onClick={toggleAgenda}
|
|
134
|
+
>
|
|
135
|
+
<ViewAgendaIcon />
|
|
136
|
+
</IconButton>
|
|
137
|
+
))}
|
|
138
|
+
|
|
139
|
+
{views.length > 1 &&
|
|
140
|
+
(isDesktop ? (
|
|
141
|
+
views.map((v) => (
|
|
142
|
+
<Button
|
|
143
|
+
key={v}
|
|
144
|
+
color={v === view ? "primary" : "inherit"}
|
|
145
|
+
onClick={() => handleChangeView(v)}
|
|
146
|
+
onDragOver={(e) => {
|
|
147
|
+
e.preventDefault();
|
|
148
|
+
handleChangeView(v);
|
|
149
|
+
}}
|
|
150
|
+
>
|
|
151
|
+
{translations.navigation[v]}
|
|
152
|
+
</Button>
|
|
153
|
+
))
|
|
154
|
+
) : (
|
|
155
|
+
<Fragment>
|
|
156
|
+
<IconButton
|
|
157
|
+
style={{ padding: 5 }}
|
|
158
|
+
onClick={(e) => {
|
|
159
|
+
toggleMoreMenu(e.currentTarget);
|
|
160
|
+
}}
|
|
161
|
+
>
|
|
162
|
+
<MoreVertIcon />
|
|
163
|
+
</IconButton>
|
|
164
|
+
<Popover
|
|
165
|
+
open={Boolean(anchorEl)}
|
|
166
|
+
anchorEl={anchorEl}
|
|
167
|
+
onClose={() => {
|
|
168
|
+
toggleMoreMenu();
|
|
169
|
+
}}
|
|
170
|
+
anchorOrigin={{
|
|
171
|
+
vertical: "center",
|
|
172
|
+
horizontal: "center",
|
|
173
|
+
}}
|
|
174
|
+
transformOrigin={{
|
|
175
|
+
vertical: "top",
|
|
176
|
+
horizontal: "center",
|
|
177
|
+
}}
|
|
178
|
+
>
|
|
179
|
+
<MenuList autoFocusItem={!!anchorEl} disablePadding>
|
|
180
|
+
{views.map((v) => (
|
|
181
|
+
<MenuItem
|
|
182
|
+
key={v}
|
|
183
|
+
selected={v === view}
|
|
184
|
+
onClick={() => {
|
|
185
|
+
toggleMoreMenu();
|
|
186
|
+
handleChangeView(v);
|
|
187
|
+
}}
|
|
188
|
+
>
|
|
189
|
+
{translations.navigation[v]}
|
|
190
|
+
</MenuItem>
|
|
191
|
+
))}
|
|
192
|
+
</MenuList>
|
|
193
|
+
</Popover>
|
|
194
|
+
</Fragment>
|
|
195
|
+
))}
|
|
196
|
+
</div>
|
|
197
|
+
</NavigationDiv>
|
|
198
|
+
);
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
export { Navigation };
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
import DateProvider from "../hoc/DateProvider";
|
|
3
|
+
import { Button, Popover } from "@mui/material";
|
|
4
|
+
import { endOfWeek, format, startOfWeek, addDays } from "date-fns";
|
|
5
|
+
import { LocaleArrow } from "../common/LocaleArrow";
|
|
6
|
+
import { DateCalendar } from "@mui/x-date-pickers";
|
|
7
|
+
import useStore from "../../hooks/useStore";
|
|
8
|
+
import useArrowDisable from "../../hooks/useArrowDisable";
|
|
9
|
+
import { WeekProps } from "../../types";
|
|
10
|
+
|
|
11
|
+
interface WeekDateBtnProps {
|
|
12
|
+
selectedDate: Date;
|
|
13
|
+
onChange(value: Date): void;
|
|
14
|
+
weekProps: WeekProps;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const WeekDateBtn = ({ selectedDate, onChange, weekProps }: WeekDateBtnProps) => {
|
|
18
|
+
const { locale, navigationPickerProps } = useStore();
|
|
19
|
+
const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);
|
|
20
|
+
const { weekStartOn } = weekProps;
|
|
21
|
+
const weekStart = startOfWeek(selectedDate, { weekStartsOn: weekStartOn });
|
|
22
|
+
const weekEnd = endOfWeek(selectedDate, { weekStartsOn: weekStartOn });
|
|
23
|
+
const { prevDisabled, nextDisabled } = useArrowDisable();
|
|
24
|
+
|
|
25
|
+
const handleOpen = (event: React.MouseEvent<HTMLButtonElement>) => {
|
|
26
|
+
setAnchorEl(event.currentTarget);
|
|
27
|
+
};
|
|
28
|
+
const handleClose = () => {
|
|
29
|
+
setAnchorEl(null);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const handleChange = (e: Date | null) => {
|
|
33
|
+
onChange(e || new Date());
|
|
34
|
+
handleClose();
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const handlePrev = () => {
|
|
38
|
+
const ladtDayPrevWeek = addDays(weekStart, -1);
|
|
39
|
+
onChange(ladtDayPrevWeek);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const handleNext = () => {
|
|
43
|
+
const firstDayNextWeek = addDays(weekEnd, 1);
|
|
44
|
+
onChange(firstDayNextWeek);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<>
|
|
49
|
+
<LocaleArrow
|
|
50
|
+
type="prev"
|
|
51
|
+
onClick={handlePrev}
|
|
52
|
+
disabled={prevDisabled}
|
|
53
|
+
aria-label="previous week"
|
|
54
|
+
/>
|
|
55
|
+
<Button style={{ padding: 4 }} onClick={handleOpen} aria-label="selected week">
|
|
56
|
+
{`${format(weekStart, "dd", { locale })} - ${format(weekEnd, "dd MMM yyyy", {
|
|
57
|
+
locale,
|
|
58
|
+
})}`}
|
|
59
|
+
</Button>
|
|
60
|
+
<Popover
|
|
61
|
+
open={Boolean(anchorEl)}
|
|
62
|
+
anchorEl={anchorEl}
|
|
63
|
+
onClose={handleClose}
|
|
64
|
+
anchorOrigin={{
|
|
65
|
+
vertical: "bottom",
|
|
66
|
+
horizontal: "left",
|
|
67
|
+
}}
|
|
68
|
+
>
|
|
69
|
+
<DateProvider>
|
|
70
|
+
<DateCalendar
|
|
71
|
+
{...navigationPickerProps}
|
|
72
|
+
openTo="day"
|
|
73
|
+
views={["month", "day"]}
|
|
74
|
+
value={selectedDate}
|
|
75
|
+
onChange={handleChange}
|
|
76
|
+
/>
|
|
77
|
+
</DateProvider>
|
|
78
|
+
</Popover>
|
|
79
|
+
<LocaleArrow
|
|
80
|
+
type="next"
|
|
81
|
+
onClick={handleNext}
|
|
82
|
+
disabled={nextDisabled}
|
|
83
|
+
aria-label="next week"
|
|
84
|
+
/>
|
|
85
|
+
</>
|
|
86
|
+
);
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export { WeekDateBtn };
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { Fragment, useMemo } from "react";
|
|
2
|
+
import useStore from "../../hooks/useStore";
|
|
3
|
+
import { TableGrid } from "../../styles/styles";
|
|
4
|
+
import {
|
|
5
|
+
differenceInDaysOmitTime,
|
|
6
|
+
filterMultiDaySlot,
|
|
7
|
+
filterTodayEvents,
|
|
8
|
+
getHourFormat,
|
|
9
|
+
} from "../../helpers/generals";
|
|
10
|
+
import { MULTI_DAY_EVENT_HEIGHT } from "../../helpers/constants";
|
|
11
|
+
import { DefaultResource, ProcessedEvent } from "../../types";
|
|
12
|
+
import useSyncScroll from "../../hooks/useSyncScroll";
|
|
13
|
+
import {
|
|
14
|
+
addMinutes,
|
|
15
|
+
endOfDay,
|
|
16
|
+
format,
|
|
17
|
+
isAfter,
|
|
18
|
+
isBefore,
|
|
19
|
+
isSameDay,
|
|
20
|
+
isToday,
|
|
21
|
+
startOfDay,
|
|
22
|
+
} from "date-fns";
|
|
23
|
+
import TodayTypo from "../common/TodayTypo";
|
|
24
|
+
import usePosition from "../../positionManger/usePosition";
|
|
25
|
+
import EventItem from "../events/EventItem";
|
|
26
|
+
import { Typography } from "@mui/material";
|
|
27
|
+
import TodayEvents from "../events/TodayEvents";
|
|
28
|
+
import Cell from "../common/Cell";
|
|
29
|
+
|
|
30
|
+
type Props = {
|
|
31
|
+
daysList: Date[];
|
|
32
|
+
hours: Date[];
|
|
33
|
+
cellHeight: number;
|
|
34
|
+
minutesHeight: number;
|
|
35
|
+
resource?: DefaultResource;
|
|
36
|
+
resourcedEvents: ProcessedEvent[];
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const WeekTable = ({
|
|
40
|
+
daysList,
|
|
41
|
+
hours,
|
|
42
|
+
cellHeight,
|
|
43
|
+
minutesHeight,
|
|
44
|
+
resourcedEvents,
|
|
45
|
+
resource,
|
|
46
|
+
}: Props) => {
|
|
47
|
+
const {
|
|
48
|
+
week,
|
|
49
|
+
events,
|
|
50
|
+
handleGotoDay,
|
|
51
|
+
resources,
|
|
52
|
+
resourceFields,
|
|
53
|
+
resourceViewMode,
|
|
54
|
+
direction,
|
|
55
|
+
locale,
|
|
56
|
+
hourFormat,
|
|
57
|
+
timeZone,
|
|
58
|
+
stickyNavigation,
|
|
59
|
+
stickyNavigationOffset,
|
|
60
|
+
stickyNavigationHeight,
|
|
61
|
+
currentTime,
|
|
62
|
+
showCurrentTimeBar,
|
|
63
|
+
currentTimeBarColor,
|
|
64
|
+
forceInlineMultiDay,
|
|
65
|
+
} = useStore();
|
|
66
|
+
const { startHour, endHour, step, cellRenderer, disableGoToDay, headRenderer, hourRenderer } =
|
|
67
|
+
week!;
|
|
68
|
+
const { renderedSlots } = usePosition();
|
|
69
|
+
const { headersRef, bodyRef } = useSyncScroll();
|
|
70
|
+
const MULTI_SPACE = MULTI_DAY_EVENT_HEIGHT;
|
|
71
|
+
const weekStart = startOfDay(daysList[0]);
|
|
72
|
+
const weekEnd = endOfDay(daysList[daysList.length - 1]);
|
|
73
|
+
const hFormat = getHourFormat(hourFormat);
|
|
74
|
+
|
|
75
|
+
// Equalizing multi-day section height except in resource/tabs mode
|
|
76
|
+
const headerHeight = useMemo(() => {
|
|
77
|
+
const shouldEqualize = resources.length && resourceViewMode === "default";
|
|
78
|
+
const allWeekMulti = filterMultiDaySlot(
|
|
79
|
+
shouldEqualize ? events : resourcedEvents,
|
|
80
|
+
daysList,
|
|
81
|
+
timeZone,
|
|
82
|
+
true,
|
|
83
|
+
forceInlineMultiDay
|
|
84
|
+
);
|
|
85
|
+
return MULTI_SPACE * allWeekMulti.length + 45;
|
|
86
|
+
}, [
|
|
87
|
+
MULTI_SPACE,
|
|
88
|
+
daysList,
|
|
89
|
+
events,
|
|
90
|
+
resourceViewMode,
|
|
91
|
+
resourcedEvents,
|
|
92
|
+
resources.length,
|
|
93
|
+
timeZone,
|
|
94
|
+
]);
|
|
95
|
+
|
|
96
|
+
const renderMultiDayEvents = (
|
|
97
|
+
events: ProcessedEvent[],
|
|
98
|
+
today: Date,
|
|
99
|
+
resource?: DefaultResource
|
|
100
|
+
) => {
|
|
101
|
+
const isFirstDayInWeek = isSameDay(weekStart, today);
|
|
102
|
+
const allWeekMulti = filterMultiDaySlot(
|
|
103
|
+
events,
|
|
104
|
+
daysList,
|
|
105
|
+
timeZone,
|
|
106
|
+
undefined,
|
|
107
|
+
forceInlineMultiDay
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
const multiDays = allWeekMulti
|
|
111
|
+
.filter((e) => (isBefore(e.start, weekStart) ? isFirstDayInWeek : isSameDay(e.start, today)))
|
|
112
|
+
.sort((a, b) => b.end.getTime() - a.end.getTime());
|
|
113
|
+
return multiDays.map((event) => {
|
|
114
|
+
const hasPrev = isBefore(startOfDay(event.start), weekStart);
|
|
115
|
+
const hasNext = isAfter(endOfDay(event.end), weekEnd);
|
|
116
|
+
const eventLength =
|
|
117
|
+
differenceInDaysOmitTime(hasPrev ? weekStart : event.start, hasNext ? weekEnd : event.end) +
|
|
118
|
+
1;
|
|
119
|
+
|
|
120
|
+
const day = format(today, "yyyy-MM-dd");
|
|
121
|
+
const resourceId = resource ? resource[resourceFields.idField] : "all";
|
|
122
|
+
const rendered = renderedSlots?.[resourceId]?.[day];
|
|
123
|
+
const position = rendered?.[event.event_id] || 0;
|
|
124
|
+
|
|
125
|
+
return (
|
|
126
|
+
<div
|
|
127
|
+
key={event.event_id}
|
|
128
|
+
className="rs__multi_day"
|
|
129
|
+
style={{
|
|
130
|
+
top: position * MULTI_SPACE + 45,
|
|
131
|
+
width: `${99.9 * eventLength}%`,
|
|
132
|
+
overflowX: "hidden",
|
|
133
|
+
}}
|
|
134
|
+
>
|
|
135
|
+
<EventItem event={event} hasPrev={hasPrev} hasNext={hasNext} multiday />
|
|
136
|
+
</div>
|
|
137
|
+
);
|
|
138
|
+
});
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
return (
|
|
142
|
+
<>
|
|
143
|
+
{/* Header days */}
|
|
144
|
+
<TableGrid
|
|
145
|
+
days={daysList.length}
|
|
146
|
+
ref={headersRef}
|
|
147
|
+
sticky="1"
|
|
148
|
+
stickyNavigation={stickyNavigation}
|
|
149
|
+
stickyOffset={stickyNavigationOffset}
|
|
150
|
+
stickyHeight={stickyNavigationHeight}
|
|
151
|
+
>
|
|
152
|
+
<span className="rs__cell rs__time"></span>
|
|
153
|
+
{daysList.map((date, i) => (
|
|
154
|
+
<span
|
|
155
|
+
key={i}
|
|
156
|
+
className={`rs__cell rs__header ${isToday(date) ? "rs__today_cell" : ""}`}
|
|
157
|
+
style={{ height: headerHeight }}
|
|
158
|
+
>
|
|
159
|
+
{typeof headRenderer === "function" ? (
|
|
160
|
+
<div>{headRenderer({ day: date, events: resourcedEvents, resource })}</div>
|
|
161
|
+
) : (
|
|
162
|
+
<TodayTypo
|
|
163
|
+
date={date}
|
|
164
|
+
onClick={!disableGoToDay ? handleGotoDay : undefined}
|
|
165
|
+
locale={locale}
|
|
166
|
+
/>
|
|
167
|
+
)}
|
|
168
|
+
{renderMultiDayEvents(resourcedEvents, date, resource)}
|
|
169
|
+
</span>
|
|
170
|
+
))}
|
|
171
|
+
</TableGrid>
|
|
172
|
+
{/* Time Cells */}
|
|
173
|
+
<TableGrid days={daysList.length} ref={bodyRef}>
|
|
174
|
+
{hours.map((h, i) => (
|
|
175
|
+
<Fragment key={i}>
|
|
176
|
+
<span style={{ height: cellHeight }} className="rs__cell rs__header rs__time">
|
|
177
|
+
{typeof hourRenderer === "function" ? (
|
|
178
|
+
<div>{hourRenderer(format(h, hFormat, { locale }))}</div>
|
|
179
|
+
) : (
|
|
180
|
+
<Typography variant="caption">{format(h, hFormat, { locale })}</Typography>
|
|
181
|
+
)}
|
|
182
|
+
</span>
|
|
183
|
+
{daysList.map((date, ii) => {
|
|
184
|
+
const start = new Date(`${format(date, "yyyy/MM/dd")} ${format(h, hFormat)}`);
|
|
185
|
+
const end = addMinutes(start, step);
|
|
186
|
+
const field = resourceFields.idField;
|
|
187
|
+
return (
|
|
188
|
+
<span key={ii} className={`rs__cell ${isToday(date) ? "rs__today_cell" : ""}`}>
|
|
189
|
+
{/* Events of each day - run once on the top hour column */}
|
|
190
|
+
{i === 0 && (
|
|
191
|
+
<TodayEvents
|
|
192
|
+
todayEvents={filterTodayEvents(
|
|
193
|
+
resourcedEvents,
|
|
194
|
+
date,
|
|
195
|
+
timeZone,
|
|
196
|
+
forceInlineMultiDay
|
|
197
|
+
)}
|
|
198
|
+
today={date}
|
|
199
|
+
minuteHeight={minutesHeight}
|
|
200
|
+
startHour={startHour}
|
|
201
|
+
endHour={endHour}
|
|
202
|
+
step={step}
|
|
203
|
+
direction={direction}
|
|
204
|
+
timeZone={timeZone}
|
|
205
|
+
currentTime={currentTime}
|
|
206
|
+
showCurrentTimeBar={showCurrentTimeBar}
|
|
207
|
+
currentTimeBarColor={currentTimeBarColor}
|
|
208
|
+
/>
|
|
209
|
+
)}
|
|
210
|
+
<Cell
|
|
211
|
+
start={start}
|
|
212
|
+
end={end}
|
|
213
|
+
day={date}
|
|
214
|
+
height={cellHeight}
|
|
215
|
+
resourceKey={field}
|
|
216
|
+
resourceVal={resource ? resource[field] : null}
|
|
217
|
+
cellRenderer={cellRenderer}
|
|
218
|
+
/>
|
|
219
|
+
</span>
|
|
220
|
+
);
|
|
221
|
+
})}
|
|
222
|
+
</Fragment>
|
|
223
|
+
))}
|
|
224
|
+
</TableGrid>
|
|
225
|
+
</>
|
|
226
|
+
);
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
export default WeekTable;
|