[英]FullCalendar duplication events
我是一個有遺留項目的大三學生(
我們有一個包含 fullCalendar 組件的頁面。 里面有很多事件監聽器。 如果我們在 eventDragStart 上更改任何 state,我們會在將事件拖動到 eventChange 的另一個位置時得到一個重復的 animation 事件。 如果我們擺脫在 eventDragStart 上更改任何 state,那么一切都可以。 在重新加載頁面后的第一種情況下,我們有正確的事件位置。 我怎樣才能擺脫這種重復?
import './Schedule.css';
import SmartSelect from '../../Root/Components/SmartSelect';
import PeopleList from '../Containers/PeopleList';
import SessionModal from '../Containers/SessionModal';
import FunkFullCalendar from '../../Root/Components/FunkFullCalendar';
import moment from 'moment-timezone';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { ISO_DATE_WITHOUT_TIME } from '../../constants';
import BinModal from '../Containers/BinModal';
import localizer from '../../localizer';
import { useDispatch, useSelector } from 'react-redux';
import { useHistory } from 'react-router-dom';
import { setInterval, loadSessions, changeTime } from '../Actions/ScheduleActions';
import { openSessionById, openNewSession } from '../Actions/SessionModalActions';
import { datesToKey, extractName } from '../../helpers';
const Schedule = () => {
const dispatch = useDispatch();
const history = useHistory();
const [showBin, setShowBin] = useState(false);
{/* <> ... </> */}
const room = useSelector((state) => state.schedule.selectedRoom);
const startDate = useSelector(
(state) =>
state.schedule.calendarStartDate &&
moment(state.schedule.calendarStartDate).tz(selectedStudio?.timeZoneName)?.format(ISO_DATE_WITHOUT_TIME)
);
const endDate = useSelector(
(state) =>
state.schedule.calendarEndDate &&
moment(state.schedule.calendarEndDate).tz(selectedStudio?.timeZoneName)?.format(ISO_DATE_WITHOUT_TIME)
);
let key = datesToKey(startDate, endDate);
const _sessions = useSelector((state) => state.schedule.sessions[key] || []);
const persons = useSelector((state) => state.schedule?.actors);
const sessions = _sessions?.map((session) => {
let title = session.actorIds
?.map((w) => {
let personName = persons.find((person) => person.id === w);
if (!personName) return '';
return extractName(personName);
})
.join('; ');
return {
title: title,
start: moment(session.start).tz(selectedStudio?.timeZoneName).format(),
end: moment(session.end).tz(selectedStudio?.timeZoneName).format(),
id: session.id,
};
});
const changeInterval = (startDate, endDate) => {
dispatch(loadSessions(room, startDate, endDate));
dispatch(setInterval(startDate, endDate));
if (room) {
history.push('/schedule/' + room + '/week/' + moment(startDate).tz(timeZone).format(ISO_DATE_WITHOUT_TIME));
}
};
const openSession = (id) => {
dispatch(openSessionById(id));
};
const changeSessionTime = (sessionId, start, due) => {
dispatch(changeTime(sessionId, start, due));
};
const createSession = (startDate, actorId) => {
dispatch(openNewSession(startDate, actorId));
};
const handleDragStart = () => setShowBin(true);
const handleDragEnd = () => setShowBin(false);
return (
<div className="sch-container">
<div className="tpl-header">
{/* <> ... </> */}
</div>
<div className="sch-calendar-layout">
<div className="sch-calendar-container">
<FunkFullCalendar
next={() => {
let newStartDate = moment(startDate).tz(timeZone, true).startOf('week').add(1, 'week');
let newEndDate = moment(newStartDate).endOf('week');
changeInterval(newStartDate.toISOString(), newEndDate.toISOString());
}}
prev={() => {
let newStartDate = moment(startDate).tz(timeZone, true).subtract(1, 'week');
let newEndDate = moment(newStartDate).endOf('week');
changeInterval(newStartDate.toISOString(), newEndDate.toISOString());
}}
today={() => {
let startDate = moment().tz(timeZone, true).startOf('week');
let endDate = moment().tz(timeZone, true).endOf('week');
changeInterval(startDate.toISOString(), endDate.toISOString());
}}
timeGridWeek={() => {
setView('timeGridWeek');
}}
allDaySlot={false}
defaultView={'timeGridWeek'}
view={view}
events={sessions}
eventDragStart={handleDragStart}
eventDragStop={handleDragEnd}
dateClick={(evt) => {
let correctedDate = moment(evt.date).utc().tz(timeZone, true);
createSession(correctedDate);
}}
drop={(evt) => {
let correctedDate = moment(evt.date).utc().tz(timeZone, true);
createSession(correctedDate, evt.draggedEl.dataset.actorid);
}}
eventClick={(evt) => {
openSession(evt.event.id);
}}
eventChange={(evt) => {
let correctedStart = moment(evt.event.start).utc().tz(timeZone, true);
let correctedEnd = moment(evt.event.end).utc().tz(timeZone, true);
changeSessionTime(evt.event.id, correctedStart, correctedEnd);
}}
startDate={startDate}
endDate={endDate}
eventTimeFormat={{
hour: '2-digit',
minute: '2-digit',
meridiem: false,
hour12: false,
}}
dateFormat={dateFormat}
timeZone={timeZone}
timeZoneParam={timeZone}
timeZoneOffsetName={timeZoneOffset}
language={language}
/>
</div>
{showBin ? (
<div className="sch-actors-list trash-panel">
{localizer.getString('interface:dragHeretoCancelSession', language)}
</div>
) : (
<div className="sch-actors-list">
{/* <> ... </> */}
</div>
)}
</div>
</div>
);
};
export default Schedule;
這是日歷組件
import { useEffect, useState, useRef, useCallback } from 'react';
import FullCalendar from '@fullcalendar/react';
import dayGridPlugin from '@fullcalendar/daygrid';
import timeGridWeek from '@fullcalendar/timegrid';
// import momentPlugin from '@fullcalendar/moment'
import interactionPlugin from '@fullcalendar/interaction';
import './FullCalendarWraper.css';
import moment from 'moment-timezone';
import { ISO_DATE_WITHOUT_TIME } from '../../constants';
import { useSelector } from 'react-redux';
const FunkFullCalendar = (props) => {
const calendar = useRef();
const calendarRef = useRef();
const sessions = useSelector((state) => state.schedule.sessions);
const findEvents = useCallback(
(events, sessions, status, color, drop) => {
const result = [];
let filteredSessions = Object.values(sessions)
.flat()
.filter((session) => session.status === status);
filteredSessions.map((session) => {
events.forEach((event) => {
if (event.id === session.id) {
result.push(event);
}
});
});
return result.flat().map((x) => ({ ...x, color: color, droppable: drop }));
},
[sessions, props.events]
);
calendarRef.current = findEvents(props.events, sessions, 'Scheduled', '#3788D8', true).concat(
findEvents(props.events, sessions, 'Completed', '#c0a65e', false)
);
const startDate = moment(props.startDate).isValid() ? props.startDate : moment().startOf('week').toISOString();
const [calendarState, setCalendarState] = useState({
view: 'timeGridWeek',
startDate: startDate,
timeZone: props.timeZone,
events: [],
language: props.language,
});
useEffect(() => {
let unsubscribe = false;
if (!unsubscribe) {
setCalendarDate(props.startDate);
}
return () => {
unsubscribe = true;
};
}, []);
const setCalendarDate = (date) => {
if (calendar.current) {
let newDate = moment(date).isValid ? moment(date) : moment();
let localDate = moment(newDate.format(ISO_DATE_WITHOUT_TIME)).utc(true);
calendar?.current?.getApi().gotoDate(localDate.toISOString());
}
};
if (props?.startDate !== calendarState.startDate || props.timeZone !== calendarState.timeZone) {
if (props.startDate) {
setCalendarState({ ...calendarState, startDate: props.startDate, timeZone: props.timeZone });
setCalendarDate(props.startDate);
}
}
return (
<div className="fcw-container">
<div className="fcw-inline-buttons">
{/* <>...</> */}
</div>
<div className="fcw-calendar-parent">
<FullCalendar
height="100%"
initialView={props.defaultView}
firstDay={1}
headerToolbar={false}
plugins={[dayGridPlugin, timeGridWeek, interactionPlugin]}
eventTextColor="white"
droppable
editable
events={calendarRef.current}
ref={calendar}
allDaySlot={false}
eventTimeFormat={props.eventTimeFormat}
locale={props.dateFormat}
timeZone={props.timeZone}
timeZoneParam={props.timeZone}
eventDragStart={props.eventDragStart}
eventDragStop={props.eventDragStop}
dateClick={(d) => {
props.dateClick(d);
}}
drop={(evt) => {
if (props.drop) props.drop(evt);
}}
eventClick={(evt) => {
props.eventClick(evt);
}}
eventChange={(e) => {
props.eventChange(e);
}}
/>
</div>
</div>
);
};
export default FunkFullCalendar;
更改時間 function
export function changeTime(sessionId, startDate, dueDate) {
return async function (dispatch, getState) {
let diff = moment(dueDate).diff(moment(startDate));
let duration = moment.duration(diff);
let deltaDays = duration.days();
let deltaHours = duration.hours();
let deltaMinutes = duration.minutes();
const state = getState();
// const sessions = ;
const selectedSession = Object.values(state.schedule.sessions)
.flat()
.find((session) => session.id === sessionId);
if (selectedSession.status === 'Completed') {
dispatch(createNotification('change_time_error', 'notification:cantRescheduleCompletedSession', 'ERROR', 5000));
} else {
if (deltaDays > 0 || deltaHours > 6 || (deltaHours === 6 && deltaMinutes > 0)) {
dueDate = moment(startDate).add(6, 'hours');
}
try {
let result = await post(Connections.backend + SESSIONS_URL + '/' + sessionId + '/reschedule', {
start: startDate.toISOString(),
end: dueDate.toISOString(),
});
} catch (e) {
dispatch(createNotification('change_time_error', e.message, 'ERROR', 5000));
} finally {
dispatch(
loadSessions(state.schedule.selectedRoom, state.schedule.calendarStartDate, state.schedule.calendarEndDate)
);
}
}
};
}```
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.