我正在研究React-big-calendar。我能够自定义eventWrapper。但是当我与DragAndDropCalendar一起使用时,它不能按预期工作。 View Calendar
//main.js
import React, { Component } from "react";
import { withStyles } from "@material-ui/core/styles";
import {
Grid,
Typography,
Fab,
List,
ListItem,
ListItemText,
IconButton,
Icon,
Box
} from "@material-ui/core";
import { Add, Delete, Edit, More } from "@material-ui/icons";
import BigCalendar from "./Calendar";
import SchedulingNavigation from "./SchedulingNavigation";
import ShiftEditor from "./ShiftEditor";
import OpenShiftForm from "./OpenShiftForm";
import CalendarToolbar from "./Toolbar";
import { shifts, employees } from "./events";
import styles from "./SchedulingCss";
class MyCalendar extends Component {
constructor(props) {
super(props);
this.state = {
events: [],
data: [],
openshiftdata: [],
curId: null,
open: false,
openShift: false,
value: 0,
shift: {
employee_id: "",
worksite: "",
position: "",
starttime: "",
endtime: "",
addbreak: "",
start: "",
end: ""
},
formats: ["week"],
selectedSlot: null,
employees: [],
view: "week"
};
}
componentDidMount() {
let events = shifts.shifts.map(item => {
return {
id: item.id,
title: "",
start: new Date(item.start_date_time),
end: new Date(item.end_date_time),
employee_id: item.status === "Assigned" && item.employee_id,
status: item.status,
allDay: item.status === "Open"
};
});
this.setState({ events, employees, curId: employees[0].id });
}
isSunOrSat = date =>
new Date(date).getDay() === 0 || new Date(date).getDay() === 6;
isTimeOff = date => {
let { data, curId, events } = this.state;
let evts = curId === null ? events : data[curId].timeoff;
for (let el of evts) {
el = typeof el === "object" ? el.start : el;
if (new Date(el).getDate() === date.getDate()) {
return true;
}
}
return false;
};
customDayPropGetter = date => {
if (this.isTimeOff(date)) {
return {
className: "special-day",
style: {
background: "#ffaaaa"
}
};
//return { className: "rbc-off-range-bg" };
} else {
return {};
}
};
handleSelect = date => {
//check for Saturday and Sunday's
// if (this.isTimeOff(date)) return false;
let { shift, openShift } = this.state;
openShift = true;
shift.start = date;
shift.end = date;
this.setState({ openShift, shift, selectedSlot: date });
};
handleClickOpen = () => {
this.setState({ open: true });
};
handleClose = () => {
this.setState({
open: false,
openShift: false
});
};
handleChange = (event, value) => {
this.setState({ value });
};
handleShiftChange = event => {
let { shift } = this.state;
shift[event.target.name] = event.target.value;
this.setState({ shift });
};
handleSelectEvent = () => {
let { curId } = this.state;
if (curId === null) {
this.setState({ openShift: true, open: false, curId: null });
} else {
//Add separate form for regular employee.
}
};
handleSelectSlot = ({ start }) => {
this.setState({ selectedSlot: start, openShift: true });
};
getDateTime = (date, time) => {
let newdate = new Date(date);
let newtime = time.split(":");
return [
newdate.getFullYear(),
newdate.getMonth(),
newdate.getDate(),
newtime[0],
newtime[1],
0
];
};
createEvent = () => {
let { events, shift } = this.state;
let event = {
id: Math.floor(Math.random() * 90676176),
title: `${shift.worksite} - ${shift.position}`,
start: new Date(...this.getDateTime(shift.start, shift.starttime)),
end: new Date(...this.getDateTime(shift.end, shift.endtime)),
employee_id: shift.employee_id,
status: shift.employee_id === "Open Shift" ? "Open" : "Assigned",
allDay: shift.employee_id === "Open Shift"
};
events.push(event);
shift = {
employee_id: "",
worksite: "",
position: "",
starttime: "",
endtime: "",
addbreak: "",
start: "",
end: ""
};
this.setState({ events, shift, open: false, openShift: false });
};
//function for toggling the day week and month
handleFormat = (event, formats) => this.setState({ formats });
getName = id => {
let employee = employees.filter(item => item.id === id);
if (employee.length > 0) return employee[0].display_name;
else return "Open Shift";
};
populateEvents = employee => {
this.setState({ curId: employee.id });
};
deleteEvent = event => {
let { events } = this.state;
events = events.filter(el => el.id != event.id);
this.setState({ events: events });
};
myEvent = ({ event }) => {
let { curId } = this.state;
let { eventBg, eventOpenShift } = this.props.classes;
return (
<Grid
container
spacing={3}
justify="space-around"
style={{ padding: 2, position: "relative" }}
>
<Grid
item
className={event.status === "Open" ? eventOpenShift : eventBg}
style={{ position: "relative" }}
xs
>
<Typography variant="subtitle2" style={{ padding: 2 }}>
{`${new Date(event.start).getHours()}AM-${new Date(
event.end
).getHours()}PM ${this.getName(event.employee_id)}`}
</Typography>
<span style={{ position: "absolute", bottom: 0, right: 0 }}>
<IconButton
aria-label="Delete"
onClick={() => this.deleteEvent(event)}
>
<Delete />
</IconButton>
<IconButton aria-label="Edit">
<Edit />
</IconButton>
</span>
</Grid>
</Grid>
);
};
myDateCellWrapper = ({ children, value }) => {
return (
<Grid container className={this.props.classes.root} justify="center">
<Grid item className={this.props.classes.test} xs={3} justify="center">
<Fab
size="small"
color="primary"
aria-label="Add"
className={this.props.classes.fab}
onClick={() => this.handleSelect(value)}
>
<Add />
</Fab>
</Grid>
</Grid>
);
};
myTimeGutterHeader = (...args) => {
return (
<Grid container justify="center">
<Grid item xs={6} justify="center">
<Typography variant="h6">Open Shift</Typography>
</Grid>
</Grid>
);
};
myToolbar = () => {
return <CalendarToolbar views={["month", "week"]} />;
};
EventAgenda = ({ event }) => {
return (
<span>
<em style={{ color: "magenta" }}>{event.title}</em>
<p>{event.desc}</p>
</span>
);
};
moveEvent = ({ event, start, end, isAllDay: droppedOnAllDaySlot }) => {
const { events } = this.state;
const idx = events.indexOf(event);
let allDay = event.allDay;
if (!event.allDay && droppedOnAllDaySlot) {
allDay = true;
} else if (event.allDay && !droppedOnAllDaySlot) {
allDay = false;
}
const updatedEvent = { ...event, start, end, allDay };
const nextEvents = [...events];
nextEvents.splice(idx, 1, updatedEvent);
this.setState({
events: nextEvents
});
// alert(`${event.title} was dropped onto ${updatedEvent.start}`)
};
onEventResize = (type, { event, start, end, allDay }) => {
this.setState(state => {
state.events[0].start = start;
state.events[0].end = end;
return { events: state.events };
});
};
render() {
const {
events,
data,
openShift,
selectedSlot,
employees,
curId,
view
} = this.state;
const { classes } = this.props;
return (
<div>
<Grid
container
justify="space-around"
spacing={6}
className={classes.grid}
>
<Grid item xs={9}>
<BigCalendar
events={events}
curId={view === "week" ? curId : null}
handleSelectEvent={this.handleSelectEvent}
handleSelectSlot={this.handleSelectSlot}
views={["month", "week"]}
view={view}
onView={view => this.setState({ view })}
myEvent={this.myEvent}
myDateCellWrapper={this.myDateCellWrapper}
myTimeGutterHeader={this.myTimeGutterHeader}
moveEvent={this.moveEvent}
onEventResize={this.onEventResize}
/>
</Grid>
</Grid>
</div>
);
}
}
export default withStyles(styles)(MyCalendar);
//Calendar.js
import React from "react";
import { Calendar, momentLocalizer, Views } from "react-big-calendar";
import moment from "moment";
import withDragAndDrop from "react-big-calendar/lib/addons/dragAndDrop";
import "react-big-calendar/lib/addons/dragAndDrop/styles.css";
import "react-big-calendar/lib/css/react-big-calendar.css";
const localizer = momentLocalizer(moment);
const DragAndDropCalendar = withDragAndDrop(Calendar);
const BigCalendar = ({
events,
curId,
views,
onView,
handleSelectEvent,
handleSelectSlot,
myEvent,
myDateCellWrapper,
myTimeGutterHeader,
myToolbar,
moveEvent,
onEventResize
}) => (
<DragAndDropCalendar
selectable
localizer={localizer}
events={events}
startAccessor="start"
endAccessor="end"
style={{ height: "90vh" }}
onEventDrop={moveEvent}
onEventResize={onEventResize}
resizable
components={{
eventWrapper: myEvent,
dateCellWrapper: myDateCellWrapper
}}
/>
);
export default BigCalendar;
//Css
const styles = theme => ({
iconHover: {
"&:hover": {
color: "red"
}
},
inline: {
display: "inline",
margin: theme.spacing.unit,
padding: 5
},
formControl: {
margin: theme.spacing.unit,
minWidth: 120
},
tr: {
padding: 15,
border: 1,
borderCollapse: "collapse"
},
typography: {
marginTop: 15,
padding: theme.spacing.unit
},
addbreak: {
marginTop: 10
},
root: {
minHeight: "100%",
flex: 1,
border: "1px solid #dcdcdc"
},
table: {
minWidth: 700
},
paper: {
paddingLeft: theme.spacing.unit * 2,
paddingRight: theme.spacing.unit * 2
},
togSelected: {
boxShadow: "none"
},
togBtn: {
paddingTop: "10px",
paddingBottom: "10px",
"&$togBtnSelected": {
color: theme.palette.common.white,
backgroundColor: theme.palette.primary.main,
"&:hover": {
backgroundColor: theme.palette.primary.main
}
},
alignSelf: "stretch",
height: "auto",
flexGrow: 1
},
grid: {
marginTop: theme.spacing.unit * 3
},
eventBg: {
color: "#474F6F",
backgroundColor: "#F2F4F5"
},
eventOpenShift: {
color: "white",
backgroundColor: "#D9425A"
},
fab: {
margin: theme.spacing.unit * 1,
zIndex: 99,
opacity: 0,
"&:hover": {
opacity: 1
}
},
test: {
flex: 1,
display: "flex",
flexDirection: "row",
margin: theme.spacing.unit * 1,
zIndex: 99,
opacity: 0,
"&:hover": {
opacity: 1
}
},
button: {
margin: theme.spacing.unit * 1
},
boardCell: {
position: "relative",
display: "block",
flexGrow: 1,
flexShrink: 1
},
boardSlot: {
position: "relative",
height: "3.1rem",
marginTop: 1
},
shifttile: {
position: "absolute",
color: "white",
width: "100%",
height: "100%",
zIndex: 100
},
shifttileInner: {
overflow: "hidden",
background: "#F2F4F5",
width: "100%",
height: "100%",
paddingLeft: "0.4rem",
paddingTop: "0.3rem"
},
shifttileInnerOpen: {
overflow: "hidden",
background: "#D9425A",
width: "100%",
height: "100%",
paddingLeft: "0.4rem",
paddingTop: "0.3rem"
},
shifttitle: {
display: "block",
overflow: "hidden",
color: "#37424D"
},
shifttileTime: {
overflow: "hidden",
color: "#37424D",
marginLeft: "0.2rem"
},
slotAction: {
minWidth: "2.65rem",
position: "absolute",
bottom: 0,
left: "50%"
}
});
export default styles;
所有已创建或无法拖放到不同时隙的openshift。在此处输入图片说明