'use client' import React, {useCallback, useContext, useEffect, useMemo, useRef, useState} from "react"; import {Calendar, dayjsLocalizer, Event, SlotInfo, View} from 'react-big-calendar' // https://day.js.org/docs/zh-CN/get-set/get-set import dayjs, {Dayjs} from 'dayjs' import 'react-big-calendar/lib/css/react-big-calendar.css' import 'react-big-calendar/lib/sass/styles.scss' import 'react-big-calendar/lib/addons/dragAndDrop/styles.scss' import '@/ui/task/calendar/index.modules.css' import {commonUpdate, getTaskTreeResult, OPERATION_BUTTON_TYPE} from "@/lib/task/project/data"; import {useSearchParams} from "next/dist/client/components/navigation"; import {DetailModelForm} from "@/ui/task/project/DetailModelForm"; import {SearchObject} from "@/lib/definitions"; import LocalContext from "@/ui/LocalContent"; import withDragAndDrop, {EventInteractionArgs} from "react-big-calendar/lib/addons/dragAndDrop"; import {TaskEvent} from "@/lib/task/calendar/data"; import {number} from "prop-types"; /** * https://github.com/jquense/react-big-calendar?tab=readme-ov-file * @constructor */ const localizer = dayjsLocalizer(dayjs) const DragAndDropCalendar = withDragAndDrop(Calendar) const CalShow: React.FC = () => { dayjs.locale('zh-cn') const [view, setView] = useState('month'); const [date, setDate] = useState(new Date()); const clickRef = useRef(null) // 展示在页面的任务,默认获取当前月的信息。 const [events, setEvents] = useState([]); const [open, setOpen] = useState(false); const [description, setDescription] = useState(''); const [operationId, setOperationId] = useState(-1); const [itemId, setItemId] = useState(-1); const [expectedStartTime, setExpectedStartTime] = useState(); const [expectedEndTime, setExpectedEndTime] = useState(); let state: string = useContext(LocalContext).taskState const handleViewChange = (newView: View) => { setView(newView); }; var pid = useSearchParams().get('pid'); function clearClickTimeout(){ clickRef && typeof clickRef.current=== 'number' &&!isNaN(clickRef.current) && isFinite(clickRef.current)&&window.clearTimeout(clickRef.current) } const handleNavigate = (newDate: Date) => { console.log('handleNavigate', newDate) setDate(newDate); const searchList: SearchObject[] = [] if (pid != null) { searchList.push({name: "pid", value: pid, operateType: "="}, { name: 'TREE', value: "false", operateType: "TREE" }); } searchList.push({name: "expectedStartTime", value: dayjs(newDate).startOf('month'), operateType: ">="}) searchList.push({name: 'expectedStartTime', value: dayjs(newDate).endOf('month'), operateType: "<="}) loadData(searchList); }; useEffect(() => { const searchListE = [] if (pid != null) { searchListE.push({name: "pid", value: pid, operateType: "="}, { name: 'TREE', value: "false", operateType: "TREE" }); } if (view === 'month') { searchListE.push({name: 'expectedStartTime', value: dayjs(date).startOf('month'), operateType: ">="}) searchListE.push({name: 'expectedStartTime', value: dayjs(date).endOf('month'), operateType: "<="}) } else { searchListE.push({name: 'expectedStartTime', value: dayjs(date).startOf('week'), operateType: ">="}) searchListE.push({name: 'expectedStartTime', value: dayjs(date).endOf('week'), operateType: "<="}) } loadData(searchListE); /** * What Is This? * This is to prevent a memory leak, in the off chance that you * teardown your interface prior to the timed method being called. */ return () => { clearClickTimeout() } }, [useContext(LocalContext)]); const message = { week: '周', work_week: '工作周', day: '天', month: '月', previous: '前', next: '后', today: '当下', agenda: '日程' } const loadData = (searchList: SearchObject[]) => { if (state.length > 0) { searchList.push({name: 'state', value: state, operateType: "IN"}) } searchList.push({name: 'expectedEndTime', value: dayjs(date).endOf('month'), operateType: "NOT NULL"}) let request = JSON.stringify({ pageSize: 9999, pageNumber: 1, data: searchList }) getTaskTreeResult(request).then(responseD => { if (responseD.status.success) { let result:TaskEvent[] =responseD.data.content.map(taskState => { return { start: dayjs(taskState.expectedStartTime).toDate(), end: dayjs(taskState.expectedEndTime).toDate(), title: taskState.name, resource: taskState.id, id:taskState.id, state:taskState.state, priority:taskState.priority } }); console.log('responseD.data.content:',result) setEvents(result) } }) } const reloadData = () => { setOpen(false) handleNavigate(expectedStartTime ? expectedStartTime.toDate() : date) } const handleSelectSlot = useCallback( ({start, end}: SlotInfo) => { setExpectedEndTime(dayjs(end)) setExpectedStartTime(dayjs(start)) setOperationId(OPERATION_BUTTON_TYPE.ADD) setDescription("添加任务") setOpen(true); }, [setEvents] ) const handleSelectEvent = useCallback( (event: Event, e: React.SyntheticEvent) => { clearClickTimeout() clickRef.current = window.setTimeout(()=> { // window.alert(event.title); console.log(event) setOperationId(OPERATION_BUTTON_TYPE.DETAIL) setDescription("任务详情") setItemId(event.resource) setOpen(true); },250) }, [] ) const {defaultDate, scrollToTime} = useMemo( () => ({ defaultDate: new Date(2015, 3, 12), scrollToTime: new Date(1970, 1, 1, 6), }), [] ) const doubleClick = (event: TaskEvent, e: React.SyntheticEvent) => { clearClickTimeout() clickRef.current = window.setTimeout(()=>{ // 数据落库 commonUpdate({ updateColumnList: [{ name: '任务状态', code: 'state', value: 7 }], conditionColumnList: [{ name: 'id', code: 'id', operateType: '=', value: event.resource }] }) setEvents((prev: TaskEvent[]) => { const existing: TaskEvent | undefined = prev.find((ev: TaskEvent) => ev.resource === event.resource); const filtered: TaskEvent[] | undefined = prev.filter((ev: TaskEvent) => ev.resource !== event.resource); if (existing !== undefined) { return [...filtered, {...existing, state:7}]; } if (filtered !== undefined) { return [...filtered]; } return []; }) },250) } const moveEvent = useCallback( ({event, start, end, isAllDay: droppedOnAllDaySlot = false}: EventInteractionArgs) => { const {allDay} = event if (!allDay && droppedOnAllDaySlot) { event.allDay = true } // 数据落库 commonUpdate({ updateColumnList: [{ name: '期望开始时间', code: 'expectedStartTime', value: start }, { name: '期望结束时间', code: 'expectedEndTime', value: end }], conditionColumnList: [{ name: 'id', code: 'id', operateType: '=', value: event.resource }] }) setEvents((prev: TaskEvent[]) => { const existing: TaskEvent | undefined = prev.find((ev: TaskEvent) => ev.resource === event.resource); const filtered: TaskEvent[] | undefined = prev.filter((ev: TaskEvent) => ev.resource !== event.resource); if (start instanceof Date && end instanceof Date && existing !== undefined) { return [...filtered, {...existing, start, end, allDay}]; } if (filtered !== undefined) { return [...filtered]; } return []; }) }, [setEvents] ) const eventPropGetter = useCallback( (event:TaskEvent) => ({ ...(event.state===7 ? { className: 'completeTask' } : event.priority===3?{ className: 'importantUrgentTask' }: event.priority===2?{ className: 'importantNotUrgentTask' }: event.priority===1?{ className: 'notImportantUrgentTask' }: { className: 'notImportantNotUrgentTask' }), }), [setEvents] ) return
{open&&}
} export default CalShow;