157 lines
6.0 KiB
TypeScript
157 lines
6.0 KiB
TypeScript
'use client'
|
|
import React, {useCallback, useContext, useEffect, useMemo} 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 {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";
|
|
|
|
/**
|
|
* https://github.com/jquense/react-big-calendar?tab=readme-ov-file
|
|
* @constructor
|
|
*/
|
|
const localizer = dayjsLocalizer(dayjs)
|
|
const CalShow: React.FC = () => {
|
|
dayjs.locale('zh-cn')
|
|
const [view, setView] = React.useState<View>('month');
|
|
const [date, setDate] = React.useState<Date>(new Date());
|
|
// 展示在页面的任务,默认获取当前月的信息。
|
|
const [events, setEvents] = React.useState<Event[]>([]);
|
|
const [open, setOpen] = React.useState(false);
|
|
const [description, setDescription] = React.useState('');
|
|
const [operationId, setOperationId] = React.useState(-1);
|
|
const [itemId,setItemId] = React.useState(-1);
|
|
const [expectedStartTime,setExpectedStartTime] = React.useState<Dayjs>();
|
|
const [expectedEndTime,setExpectedEndTime] = React.useState<Dayjs>();
|
|
let state:string=useContext(LocalContext).taskState
|
|
const handleViewChange = (newView: View) => {
|
|
setView(newView);
|
|
};
|
|
var pid = useSearchParams().get('pid');
|
|
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);
|
|
}, [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) {
|
|
setEvents(responseD.data.content.map(taskState => {
|
|
return {
|
|
start: dayjs(taskState.expectedStartTime).toDate(),
|
|
end: dayjs(taskState.expectedEndTime).toDate(),
|
|
title: taskState.name,
|
|
resource:taskState.id
|
|
}
|
|
}))
|
|
}
|
|
})
|
|
}
|
|
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<HTMLElement>) => {
|
|
// window.alert(event.title);
|
|
console.log(event)
|
|
setOperationId(OPERATION_BUTTON_TYPE.DETAIL)
|
|
setDescription("任务详情")
|
|
setItemId(event.resource)
|
|
setOpen(true);
|
|
},
|
|
[]
|
|
)
|
|
const {defaultDate, scrollToTime} = useMemo(
|
|
() => ({
|
|
defaultDate: new Date(2015, 3, 12),
|
|
scrollToTime: new Date(1970, 1, 1, 6),
|
|
}),
|
|
[]
|
|
)
|
|
return <div className="App" style={{height: '90vh'}}>
|
|
<DetailModelForm operationId={operationId} description={description} open={open} haveButton={false} itemId={itemId}
|
|
reloadData={reloadData} expectedStartTime={expectedStartTime} expectedEndTime={expectedEndTime}/>
|
|
<Calendar
|
|
localizer={localizer}
|
|
events={events}
|
|
view={view}
|
|
onView={handleViewChange}
|
|
// onRangeChange={rangeChange}
|
|
date={date}
|
|
onNavigate={handleNavigate}
|
|
messages={message}
|
|
// 点击任务
|
|
onSelectEvent={handleSelectEvent}
|
|
// 点击空白处添加任务
|
|
onSelectSlot={handleSelectSlot}
|
|
selectable
|
|
scrollToTime={scrollToTime}
|
|
/>
|
|
</div>
|
|
}
|
|
export default CalShow;
|