簡體   English   中英

FullCalendar 重復事件

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM