具有自定义组件的DragAndDrop无法正常运行

时间:2019-07-16 18:32:14

标签: reactjs react-big-calendar

我正在研究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。在此处输入图片说明

enter image description here

0 个答案:

没有答案