@isma91/react-scheduler 4.0.5 → 4.0.7
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/package.json +6 -6
- package/package.json +9 -7
- package/.github/workflows/publish.yml +0 -29
- package/.github/workflows/tests.yml +0 -35
- package/.gitignore +0 -32
- package/.husky/pre-commit +0 -2
- package/.prettierignore +0 -1
- package/.prettierrc.json +0 -7
- package/.yarnrc.yml +0 -1
- package/eslint.config.js +0 -79
- package/index.html +0 -41
- package/isma91-react-scheduler-4.0.5.tgz +0 -0
- package/jest.config.ts +0 -194
- package/public/favicon.ico +0 -0
- package/public/logo192.png +0 -0
- package/public/logo512.png +0 -0
- package/public/manifest.json +0 -25
- package/public/robots.txt +0 -3
- package/scripts/post-pack.js +0 -34
- package/src/App.tsx +0 -25
- package/src/Page1.tsx +0 -67
- package/src/events.tsx +0 -227
- package/src/index.tsx +0 -21
- package/src/lib/SchedulerComponent.tsx +0 -78
- package/src/lib/__tests__/index.test.tsx +0 -24
- package/src/lib/components/common/Cell.tsx +0 -52
- package/src/lib/components/common/LocaleArrow.tsx +0 -38
- package/src/lib/components/common/ResourceHeader.tsx +0 -73
- package/src/lib/components/common/Tabs.tsx +0 -119
- package/src/lib/components/common/TodayTypo.tsx +0 -44
- package/src/lib/components/common/WithResources.tsx +0 -98
- package/src/lib/components/events/Actions.tsx +0 -65
- package/src/lib/components/events/AgendaEventsList.tsx +0 -126
- package/src/lib/components/events/CurrentTimeBar.tsx +0 -59
- package/src/lib/components/events/EmptyAgenda.tsx +0 -27
- package/src/lib/components/events/EventItem.tsx +0 -180
- package/src/lib/components/events/EventItemPopover.tsx +0 -179
- package/src/lib/components/events/MonthEvents.tsx +0 -141
- package/src/lib/components/events/TodayEvents.tsx +0 -99
- package/src/lib/components/hoc/DateProvider.tsx +0 -19
- package/src/lib/components/inputs/DatePicker.tsx +0 -95
- package/src/lib/components/inputs/Input.tsx +0 -113
- package/src/lib/components/inputs/SelectInput.tsx +0 -164
- package/src/lib/components/month/MonthTable.tsx +0 -207
- package/src/lib/components/nav/DayDateBtn.tsx +0 -77
- package/src/lib/components/nav/MonthDateBtn.tsx +0 -80
- package/src/lib/components/nav/Navigation.tsx +0 -201
- package/src/lib/components/nav/WeekDateBtn.tsx +0 -89
- package/src/lib/components/week/WeekTable.tsx +0 -229
- package/src/lib/helpers/constants.ts +0 -4
- package/src/lib/helpers/generals.tsx +0 -354
- package/src/lib/hooks/useArrowDisable.ts +0 -26
- package/src/lib/hooks/useCellAttributes.ts +0 -67
- package/src/lib/hooks/useDragAttributes.ts +0 -31
- package/src/lib/hooks/useEventPermissions.ts +0 -42
- package/src/lib/hooks/useStore.ts +0 -8
- package/src/lib/hooks/useSyncScroll.ts +0 -31
- package/src/lib/hooks/useWindowResize.ts +0 -37
- package/src/lib/index.tsx +0 -14
- package/src/lib/positionManger/context.ts +0 -14
- package/src/lib/positionManger/provider.tsx +0 -113
- package/src/lib/positionManger/usePosition.ts +0 -8
- package/src/lib/store/context.ts +0 -5
- package/src/lib/store/default.ts +0 -159
- package/src/lib/store/provider.tsx +0 -226
- package/src/lib/store/types.ts +0 -40
- package/src/lib/styles/styles.ts +0 -256
- package/src/lib/types.ts +0 -429
- package/src/lib/views/Day.tsx +0 -272
- package/src/lib/views/DayAgenda.tsx +0 -57
- package/src/lib/views/Editor.tsx +0 -258
- package/src/lib/views/Month.tsx +0 -82
- package/src/lib/views/MonthAgenda.tsx +0 -84
- package/src/lib/views/Week.tsx +0 -92
- package/src/lib/views/WeekAgenda.tsx +0 -81
- package/src/vite-env.d.ts +0 -3
- package/tsconfig.build.json +0 -5
- package/tsconfig.json +0 -27
- package/vite.config.js +0 -40
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import { useEffect, useState } from "react";
|
|
2
|
-
import { PositionManagerState, PositionContext } from "./context";
|
|
3
|
-
import useStore from "../hooks/useStore";
|
|
4
|
-
import { DefaultResource, FieldProps, ProcessedEvent, ResourceFields } from "../types";
|
|
5
|
-
import {
|
|
6
|
-
getResourcedEvents,
|
|
7
|
-
sortEventsByTheEarliest,
|
|
8
|
-
sortEventsByTheLengthest,
|
|
9
|
-
} from "../helpers/generals";
|
|
10
|
-
import { eachDayOfInterval, format } from "date-fns";
|
|
11
|
-
import { View } from "../components/nav/Navigation";
|
|
12
|
-
|
|
13
|
-
type Props = {
|
|
14
|
-
children: React.ReactNode;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
const setEventPositions = (events: ProcessedEvent[]) => {
|
|
18
|
-
const slots: PositionManagerState["renderedSlots"][string] = {};
|
|
19
|
-
let position = 0;
|
|
20
|
-
for (let i = 0; i < events.length; i++) {
|
|
21
|
-
const event = events[i];
|
|
22
|
-
const eventLength = eachDayOfInterval({ start: event.start, end: event.end });
|
|
23
|
-
for (let i = 0; i < eventLength.length; i++) {
|
|
24
|
-
const day = format(eventLength[i], "yyyy-MM-dd");
|
|
25
|
-
if (slots[day]) {
|
|
26
|
-
const positions = Object.values(slots[day]);
|
|
27
|
-
while (positions.includes(position)) {
|
|
28
|
-
position += 1;
|
|
29
|
-
}
|
|
30
|
-
slots[day][event.event_id] = position;
|
|
31
|
-
} else {
|
|
32
|
-
slots[day] = { [event.event_id]: position };
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// rest
|
|
37
|
-
position = 0;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
return slots;
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
const setEventPositionsWithResources = (
|
|
44
|
-
events: ProcessedEvent[],
|
|
45
|
-
resources: DefaultResource[],
|
|
46
|
-
rFields: ResourceFields,
|
|
47
|
-
fields: FieldProps[],
|
|
48
|
-
view: View
|
|
49
|
-
) => {
|
|
50
|
-
const sorted =
|
|
51
|
-
view === "month" ? sortEventsByTheLengthest(events) : sortEventsByTheEarliest(events);
|
|
52
|
-
const slots: PositionManagerState["renderedSlots"] = {};
|
|
53
|
-
|
|
54
|
-
if (resources.length) {
|
|
55
|
-
for (const resource of resources) {
|
|
56
|
-
const resourcedEvents = getResourcedEvents(sorted, resource, rFields, fields);
|
|
57
|
-
const positions = setEventPositions(resourcedEvents);
|
|
58
|
-
slots[resource[rFields.idField]] = positions;
|
|
59
|
-
}
|
|
60
|
-
} else {
|
|
61
|
-
slots.all = setEventPositions(sorted);
|
|
62
|
-
}
|
|
63
|
-
return slots;
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
export const PositionProvider = ({ children }: Props) => {
|
|
67
|
-
const { events, resources, resourceFields, fields, view } = useStore();
|
|
68
|
-
const [state, set] = useState<PositionManagerState>({
|
|
69
|
-
renderedSlots: setEventPositionsWithResources(events, resources, resourceFields, fields, view),
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
useEffect(() => {
|
|
73
|
-
set((prev) => ({
|
|
74
|
-
...prev,
|
|
75
|
-
renderedSlots: setEventPositionsWithResources(
|
|
76
|
-
events,
|
|
77
|
-
resources,
|
|
78
|
-
resourceFields,
|
|
79
|
-
fields,
|
|
80
|
-
view
|
|
81
|
-
),
|
|
82
|
-
}));
|
|
83
|
-
}, [events, fields, resourceFields, resources, view]);
|
|
84
|
-
|
|
85
|
-
const setRenderedSlot = (day: string, eventId: string, position: number, resourceId?: string) => {
|
|
86
|
-
set((prev) => ({
|
|
87
|
-
...prev,
|
|
88
|
-
renderedSlots: {
|
|
89
|
-
...prev.renderedSlots,
|
|
90
|
-
[resourceId || "all"]: {
|
|
91
|
-
...prev.renderedSlots?.[resourceId || "all"],
|
|
92
|
-
[day]: prev.renderedSlots?.[resourceId || "all"]?.[day]
|
|
93
|
-
? {
|
|
94
|
-
...prev.renderedSlots?.[resourceId || "all"]?.[day],
|
|
95
|
-
[eventId]: position,
|
|
96
|
-
}
|
|
97
|
-
: { [eventId]: position },
|
|
98
|
-
},
|
|
99
|
-
},
|
|
100
|
-
}));
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
return (
|
|
104
|
-
<PositionContext.Provider
|
|
105
|
-
value={{
|
|
106
|
-
...state,
|
|
107
|
-
setRenderedSlot,
|
|
108
|
-
}}
|
|
109
|
-
>
|
|
110
|
-
{children}
|
|
111
|
-
</PositionContext.Provider>
|
|
112
|
-
);
|
|
113
|
-
};
|
package/src/lib/store/context.ts
DELETED
package/src/lib/store/default.ts
DELETED
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
import { enUS } from "date-fns/locale";
|
|
2
|
-
import { SchedulerProps } from "../types";
|
|
3
|
-
import { getOneView, getTimeZonedDate } from "../helpers/generals";
|
|
4
|
-
|
|
5
|
-
const defaultMonth = {
|
|
6
|
-
weekDays: [0, 1, 2, 3, 4, 5, 6],
|
|
7
|
-
weekStartOn: 6,
|
|
8
|
-
startHour: 9,
|
|
9
|
-
endHour: 17,
|
|
10
|
-
navigation: true,
|
|
11
|
-
disableGoToDay: false,
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
const defaultWeek = {
|
|
15
|
-
weekDays: [0, 1, 2, 3, 4, 5, 6],
|
|
16
|
-
weekStartOn: 6,
|
|
17
|
-
startHour: 9,
|
|
18
|
-
endHour: 17,
|
|
19
|
-
step: 60,
|
|
20
|
-
navigation: true,
|
|
21
|
-
disableGoToDay: false,
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
const defaultDay = {
|
|
25
|
-
startHour: 9,
|
|
26
|
-
endHour: 17,
|
|
27
|
-
step: 60,
|
|
28
|
-
navigation: true,
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
const defaultResourceFields = {
|
|
32
|
-
idField: "assignee",
|
|
33
|
-
textField: "text",
|
|
34
|
-
subTextField: "subtext",
|
|
35
|
-
avatarField: "avatar",
|
|
36
|
-
colorField: "color",
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
const defaultTranslations = (trans: Partial<SchedulerProps["translations"]> = {}) => {
|
|
40
|
-
const { navigation, form, event, ...other } = trans;
|
|
41
|
-
|
|
42
|
-
return {
|
|
43
|
-
navigation: Object.assign(
|
|
44
|
-
{
|
|
45
|
-
month: "Month",
|
|
46
|
-
week: "Week",
|
|
47
|
-
day: "Day",
|
|
48
|
-
agenda: "Agenda",
|
|
49
|
-
today: "Today",
|
|
50
|
-
},
|
|
51
|
-
navigation
|
|
52
|
-
),
|
|
53
|
-
form: Object.assign(
|
|
54
|
-
{
|
|
55
|
-
addTitle: "Add Event",
|
|
56
|
-
editTitle: "Edit Event",
|
|
57
|
-
confirm: "Confirm",
|
|
58
|
-
delete: "Delete",
|
|
59
|
-
cancel: "Cancel",
|
|
60
|
-
},
|
|
61
|
-
form
|
|
62
|
-
),
|
|
63
|
-
event: Object.assign(
|
|
64
|
-
{
|
|
65
|
-
title: "Title",
|
|
66
|
-
start: "Start",
|
|
67
|
-
end: "End",
|
|
68
|
-
allDay: "All Day",
|
|
69
|
-
},
|
|
70
|
-
event
|
|
71
|
-
),
|
|
72
|
-
...Object.assign(
|
|
73
|
-
{ moreEvents: "More...", loading: "Loading...", noDataToDisplay: "No data to display" },
|
|
74
|
-
other
|
|
75
|
-
),
|
|
76
|
-
};
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
const defaultViews = (props: Partial<SchedulerProps>) => {
|
|
80
|
-
const { month, week, day } = props;
|
|
81
|
-
return {
|
|
82
|
-
month: month !== null ? Object.assign(defaultMonth, month) : null,
|
|
83
|
-
week: week !== null ? Object.assign(defaultWeek, week) : null,
|
|
84
|
-
day: day !== null ? Object.assign(defaultDay, day) : null,
|
|
85
|
-
};
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
export const defaultProps = (props: Partial<SchedulerProps>) => {
|
|
89
|
-
// We're pulling values out of props that we don't want to
|
|
90
|
-
// pass on, so there are 'unused' ones here.
|
|
91
|
-
const {
|
|
92
|
-
translations,
|
|
93
|
-
resourceFields,
|
|
94
|
-
view,
|
|
95
|
-
agenda,
|
|
96
|
-
selectedDate,
|
|
97
|
-
resourceViewMode,
|
|
98
|
-
direction,
|
|
99
|
-
dialogMaxWidth,
|
|
100
|
-
hourFormat,
|
|
101
|
-
...otherProps
|
|
102
|
-
} = props;
|
|
103
|
-
|
|
104
|
-
const views = defaultViews(props);
|
|
105
|
-
const defaultView = view || "week";
|
|
106
|
-
const initialView = views[defaultView] ? defaultView : getOneView(views);
|
|
107
|
-
return {
|
|
108
|
-
...views,
|
|
109
|
-
translations: defaultTranslations(translations),
|
|
110
|
-
resourceFields: Object.assign(defaultResourceFields, resourceFields),
|
|
111
|
-
view: initialView,
|
|
112
|
-
selectedDate: getTimeZonedDate(selectedDate || new Date(), props.timeZone),
|
|
113
|
-
height: 600,
|
|
114
|
-
navigation: true,
|
|
115
|
-
disableViewNavigator: false,
|
|
116
|
-
events: [],
|
|
117
|
-
fields: [],
|
|
118
|
-
loading: undefined,
|
|
119
|
-
customEditor: undefined,
|
|
120
|
-
onConfirm: undefined,
|
|
121
|
-
onDelete: undefined,
|
|
122
|
-
viewerExtraComponent: undefined,
|
|
123
|
-
resources: [],
|
|
124
|
-
resourceHeaderComponent: undefined,
|
|
125
|
-
resourceViewMode: resourceViewMode || "default",
|
|
126
|
-
direction: direction || "ltr",
|
|
127
|
-
dialogMaxWidth: dialogMaxWidth || "md",
|
|
128
|
-
locale: enUS,
|
|
129
|
-
deletable: true,
|
|
130
|
-
editable: true,
|
|
131
|
-
hourFormat: hourFormat || "12",
|
|
132
|
-
draggable: true,
|
|
133
|
-
agenda,
|
|
134
|
-
enableAgenda: typeof agenda === "undefined" || agenda,
|
|
135
|
-
showCurrentTimeBar: true,
|
|
136
|
-
forceInlineMultiDay: false,
|
|
137
|
-
...otherProps,
|
|
138
|
-
};
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
export const initialStore = {
|
|
142
|
-
...defaultProps({}),
|
|
143
|
-
setProps: () => {},
|
|
144
|
-
dialog: false,
|
|
145
|
-
selectedRange: undefined,
|
|
146
|
-
selectedEvent: undefined,
|
|
147
|
-
selectedResource: undefined,
|
|
148
|
-
handleState: () => {},
|
|
149
|
-
getViews: () => [],
|
|
150
|
-
toggleAgenda: () => {},
|
|
151
|
-
triggerDialog: () => {},
|
|
152
|
-
triggerLoading: () => {},
|
|
153
|
-
handleGotoDay: () => {},
|
|
154
|
-
confirmEvent: () => {},
|
|
155
|
-
setCurrentDragged: () => {},
|
|
156
|
-
onDrop: () => {},
|
|
157
|
-
_refetchToken: 0,
|
|
158
|
-
refetch: () => {},
|
|
159
|
-
};
|
|
@@ -1,226 +0,0 @@
|
|
|
1
|
-
import { DragEvent, useEffect, useState } from "react";
|
|
2
|
-
import { EventActions, ProcessedEvent, SchedulerProps } from "../types";
|
|
3
|
-
import { defaultProps, initialStore } from "./default";
|
|
4
|
-
import { StoreContext } from "./context";
|
|
5
|
-
import { SchedulerState, SelectedRange, Store } from "./types";
|
|
6
|
-
import { arraytizeFieldVal, getAvailableViews } from "../helpers/generals";
|
|
7
|
-
import { addMinutes, differenceInMinutes, isEqual } from "date-fns";
|
|
8
|
-
import { View } from "../components/nav/Navigation";
|
|
9
|
-
|
|
10
|
-
type Props = {
|
|
11
|
-
children: React.ReactNode;
|
|
12
|
-
initial: Partial<SchedulerProps>;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export const StoreProvider = ({ children, initial }: Props) => {
|
|
16
|
-
const [state, set] = useState<Store>({ ...initialStore, ...defaultProps(initial) });
|
|
17
|
-
|
|
18
|
-
useEffect(() => {
|
|
19
|
-
set((prev) => ({
|
|
20
|
-
...prev,
|
|
21
|
-
onEventDrop: initial.onEventDrop,
|
|
22
|
-
customEditor: initial.customEditor,
|
|
23
|
-
customHeaderContent: initial.customHeaderContent,
|
|
24
|
-
// Only sync events if NOT using getRemoteEvents
|
|
25
|
-
// Otherwise, let the internal state manage events
|
|
26
|
-
...(initial.getRemoteEvents ? {} : { events: initial.events || [] }),
|
|
27
|
-
}));
|
|
28
|
-
}, [
|
|
29
|
-
initial.onEventDrop,
|
|
30
|
-
initial.customEditor,
|
|
31
|
-
initial.events,
|
|
32
|
-
initial.customHeaderContent,
|
|
33
|
-
initial.getRemoteEvents,
|
|
34
|
-
]);
|
|
35
|
-
|
|
36
|
-
useEffect(() => {
|
|
37
|
-
if ("undefined" !== typeof initial.loading) {
|
|
38
|
-
set((prev) => ({ ...prev, loading: initial.loading }));
|
|
39
|
-
}
|
|
40
|
-
}, [initial.loading]);
|
|
41
|
-
|
|
42
|
-
const handleState = (value: SchedulerState[keyof SchedulerState], name: keyof SchedulerState) => {
|
|
43
|
-
set((prev) => ({ ...prev, [name]: value }));
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const getViews = () => {
|
|
47
|
-
return getAvailableViews(state);
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
const toggleAgenda = () => {
|
|
51
|
-
set((prev) => {
|
|
52
|
-
const newStatus = !prev.agenda;
|
|
53
|
-
|
|
54
|
-
if (state.onViewChange && typeof state.onViewChange === "function") {
|
|
55
|
-
state.onViewChange(state.view, newStatus);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return { ...prev, agenda: newStatus };
|
|
59
|
-
});
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
const triggerDialog = (status: boolean, selected?: SelectedRange | ProcessedEvent) => {
|
|
63
|
-
const isEvent = selected as ProcessedEvent;
|
|
64
|
-
|
|
65
|
-
set((prev) => ({
|
|
66
|
-
...prev,
|
|
67
|
-
dialog: status,
|
|
68
|
-
selectedRange: isEvent?.event_id
|
|
69
|
-
? undefined
|
|
70
|
-
: isEvent || {
|
|
71
|
-
start: new Date(),
|
|
72
|
-
end: new Date(Date.now() + 60 * 60 * 1000),
|
|
73
|
-
},
|
|
74
|
-
selectedEvent: isEvent?.event_id ? isEvent : undefined,
|
|
75
|
-
selectedResource: isEvent?.[state.resourceFields?.idField],
|
|
76
|
-
}));
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
const triggerLoading = (status: boolean) => {
|
|
80
|
-
// Trigger if not out-sourced by props
|
|
81
|
-
if (typeof initial.loading === "undefined") {
|
|
82
|
-
set((prev) => ({ ...prev, loading: status }));
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
const handleGotoDay = (day: Date) => {
|
|
87
|
-
const currentViews = getViews();
|
|
88
|
-
let view: View | undefined;
|
|
89
|
-
if (currentViews.includes("day")) {
|
|
90
|
-
view = "day";
|
|
91
|
-
set((prev) => ({ ...prev, view: "day", selectedDate: day }));
|
|
92
|
-
} else if (currentViews.includes("week")) {
|
|
93
|
-
view = "week";
|
|
94
|
-
set((prev) => ({ ...prev, view: "week", selectedDate: day }));
|
|
95
|
-
} else {
|
|
96
|
-
console.warn("No Day/Week views available");
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
if (!!view && state.onViewChange && typeof state.onViewChange === "function") {
|
|
100
|
-
state.onViewChange(view, state.agenda);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
if (!!view && state.onSelectedDateChange && typeof state.onSelectedDateChange === "function") {
|
|
104
|
-
state.onSelectedDateChange(day);
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
const confirmEvent = (event: ProcessedEvent | ProcessedEvent[], action: EventActions) => {
|
|
109
|
-
let updatedEvents: ProcessedEvent[];
|
|
110
|
-
if (action === "edit") {
|
|
111
|
-
if (Array.isArray(event)) {
|
|
112
|
-
updatedEvents = state.events.map((e) => {
|
|
113
|
-
const exist = event.find((ex) => ex.event_id === e.event_id);
|
|
114
|
-
return exist ? { ...e, ...exist } : e;
|
|
115
|
-
});
|
|
116
|
-
} else {
|
|
117
|
-
updatedEvents = state.events.map((e) =>
|
|
118
|
-
e.event_id === event.event_id ? { ...e, ...event } : e
|
|
119
|
-
);
|
|
120
|
-
}
|
|
121
|
-
} else {
|
|
122
|
-
updatedEvents = state.events.concat(event);
|
|
123
|
-
}
|
|
124
|
-
set((prev) => ({ ...prev, events: updatedEvents }));
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
const setCurrentDragged = (event?: ProcessedEvent) => {
|
|
128
|
-
set((prev) => ({ ...prev, currentDragged: event }));
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
const onDrop = async (
|
|
132
|
-
event: DragEvent<HTMLButtonElement>,
|
|
133
|
-
eventId: string,
|
|
134
|
-
startTime: Date,
|
|
135
|
-
resKey?: string,
|
|
136
|
-
resVal?: string | number
|
|
137
|
-
) => {
|
|
138
|
-
// Get dropped event
|
|
139
|
-
const droppedEvent = state.events.find((e) => {
|
|
140
|
-
if (typeof e.event_id === "number") {
|
|
141
|
-
return e.event_id === +eventId;
|
|
142
|
-
}
|
|
143
|
-
return e.event_id === eventId;
|
|
144
|
-
}) as ProcessedEvent;
|
|
145
|
-
|
|
146
|
-
// Check if has resource and if is multiple
|
|
147
|
-
const resField = state.fields.find((f) => f.name === resKey);
|
|
148
|
-
const isMultiple = !!resField?.config?.multiple;
|
|
149
|
-
let newResource = resVal as string | number | string[] | number[];
|
|
150
|
-
if (resField) {
|
|
151
|
-
const eResource = droppedEvent[resKey as string];
|
|
152
|
-
const currentRes = arraytizeFieldVal(resField, eResource, droppedEvent).value;
|
|
153
|
-
if (isMultiple) {
|
|
154
|
-
// if dropped on already owned resource
|
|
155
|
-
if (currentRes.includes(resVal)) {
|
|
156
|
-
// Omit if dropped on same time slot for multiple event
|
|
157
|
-
if (isEqual(droppedEvent.start, startTime)) {
|
|
158
|
-
return;
|
|
159
|
-
}
|
|
160
|
-
newResource = currentRes;
|
|
161
|
-
} else {
|
|
162
|
-
// if have multiple resource ? add other : move to other
|
|
163
|
-
newResource = currentRes.length > 1 ? [...currentRes, resVal] : [resVal];
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// Omit if dropped on same time slot for non multiple events
|
|
169
|
-
if (isEqual(droppedEvent.start, startTime)) {
|
|
170
|
-
if (!newResource || (!isMultiple && newResource === droppedEvent[resKey as string])) {
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// Update event time according to original duration & update resources/owners
|
|
176
|
-
const diff = differenceInMinutes(droppedEvent.end, droppedEvent.start);
|
|
177
|
-
const updatedEvent: ProcessedEvent = {
|
|
178
|
-
...droppedEvent,
|
|
179
|
-
start: startTime,
|
|
180
|
-
end: addMinutes(startTime, diff),
|
|
181
|
-
recurring: undefined,
|
|
182
|
-
[resKey as string]: newResource || "",
|
|
183
|
-
};
|
|
184
|
-
|
|
185
|
-
// Local
|
|
186
|
-
if (!state.onEventDrop || typeof state.onEventDrop !== "function") {
|
|
187
|
-
return confirmEvent(updatedEvent, "edit");
|
|
188
|
-
}
|
|
189
|
-
// Remote
|
|
190
|
-
try {
|
|
191
|
-
triggerLoading(true);
|
|
192
|
-
const _event = await state.onEventDrop(event, startTime, updatedEvent, droppedEvent);
|
|
193
|
-
if (_event) {
|
|
194
|
-
confirmEvent(_event, "edit");
|
|
195
|
-
}
|
|
196
|
-
} finally {
|
|
197
|
-
triggerLoading(false);
|
|
198
|
-
}
|
|
199
|
-
};
|
|
200
|
-
|
|
201
|
-
const refetch = () => {
|
|
202
|
-
if (initial.getRemoteEvents) {
|
|
203
|
-
set((prev) => ({ ...prev, _refetchToken: prev._refetchToken + 1 }));
|
|
204
|
-
}
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
return (
|
|
208
|
-
<StoreContext.Provider
|
|
209
|
-
value={{
|
|
210
|
-
...state,
|
|
211
|
-
handleState,
|
|
212
|
-
getViews,
|
|
213
|
-
toggleAgenda,
|
|
214
|
-
triggerDialog,
|
|
215
|
-
triggerLoading,
|
|
216
|
-
handleGotoDay,
|
|
217
|
-
confirmEvent,
|
|
218
|
-
setCurrentDragged,
|
|
219
|
-
onDrop,
|
|
220
|
-
refetch,
|
|
221
|
-
}}
|
|
222
|
-
>
|
|
223
|
-
{children}
|
|
224
|
-
</StoreContext.Provider>
|
|
225
|
-
);
|
|
226
|
-
};
|
package/src/lib/store/types.ts
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { DragEvent } from "react";
|
|
2
|
-
import { View } from "../components/nav/Navigation";
|
|
3
|
-
import { DefaultResource, EventActions, ProcessedEvent, SchedulerProps } from "../types";
|
|
4
|
-
|
|
5
|
-
export type SelectedRange = { start: Date; end: Date };
|
|
6
|
-
|
|
7
|
-
export interface SchedulerState extends SchedulerProps {
|
|
8
|
-
dialog: boolean;
|
|
9
|
-
selectedRange?: SelectedRange;
|
|
10
|
-
selectedEvent?: ProcessedEvent;
|
|
11
|
-
selectedResource?: DefaultResource["assignee"] | DefaultResource["assignee"][];
|
|
12
|
-
selectedTab?: DefaultResource["assignee"];
|
|
13
|
-
currentDragged?: ProcessedEvent;
|
|
14
|
-
enableAgenda?: boolean;
|
|
15
|
-
/** @internal */
|
|
16
|
-
_refetchToken: number;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export interface Store extends SchedulerState {
|
|
20
|
-
handleState(value: SchedulerState[keyof SchedulerState], name: keyof SchedulerState): void;
|
|
21
|
-
getViews(): View[];
|
|
22
|
-
toggleAgenda: () => void;
|
|
23
|
-
triggerDialog(status: boolean, event?: SelectedRange | ProcessedEvent): void;
|
|
24
|
-
triggerLoading(status: boolean): void;
|
|
25
|
-
handleGotoDay(day: Date): void;
|
|
26
|
-
confirmEvent(event: ProcessedEvent | ProcessedEvent[], action: EventActions): void;
|
|
27
|
-
setCurrentDragged(event?: ProcessedEvent): void;
|
|
28
|
-
onDrop(
|
|
29
|
-
event: DragEvent<HTMLButtonElement>,
|
|
30
|
-
eventId: string,
|
|
31
|
-
droppedStartTime: Date,
|
|
32
|
-
resourceKey?: string,
|
|
33
|
-
resourceVal?: string | number
|
|
34
|
-
): void;
|
|
35
|
-
/**
|
|
36
|
-
* Manually trigger a refetch of remote events.
|
|
37
|
-
* Only works when `getRemoteEvents` prop is provided.
|
|
38
|
-
*/
|
|
39
|
-
refetch(): void;
|
|
40
|
-
}
|