Hello, so I need to drag appointments into my calendar, where each appointment has a preset recurrence.
I'm sending custom data to the editorTemplate and create a component RecurrenceEditorComponent where I set the recurrence rule to it's value.
Now the problem is that the on the event actionBegin, the returned reccurenceID, recurrenceRule and Exception come back as empty and the recurrence is NOT being set.
Here's the full code.
import * as React from "react";
import { ScheduleComponent, ResourcesDirective, ResourceDirective, ViewsDirective, ViewDirective, Inject, TimelineViews, Resize, DragAndDrop, TimelineMonth, Agenda, Day, Week, RecurrenceEditorComponent } from "@syncfusion/ej2-react-schedule";
import "../../assets/css/external-drag-drop.css";
import { extend, closest, remove, addClass } from "@syncfusion/ej2-base";
import { TreeViewComponent } from "@syncfusion/ej2-react-navigations";
import dataSource from "./datasource.json";
import { DateTimePickerComponent } from "@syncfusion/ej2-react-calendars";
import Loading from "../components/Loading.js";
import { useState } from "react";
import { useSelector } from "react-redux";
import { useEffect } from "react";
import { Avatar } from "@mui/material";
import DateTimePicker from "react-datetime-picker";
import { DropDownListComponent } from "@syncfusion/ej2-react-dropdowns";
function Calender() {
const [isLoading, setIsLoading] = useState(true);
const [teams, setTeams] = useState(undefined);
const [workOrders, setWorkOrders] = useState(undefined);
const teamsData = useSelector((state) => state.teamReducer.leader_teams.data);
const workOrdersData = useSelector((state) => state.workOrderReducer.workOrders.data);
let scheduleObj;
let treeObj;
let isTreeItemDropped = false;
let draggedItemId = "";
const allowDragAndDrops = true;
const [assignedData, setAssignedData] = useState(undefined);
useEffect(() => {
if (teamsData && workOrdersData && setAssignedData) {
let tempTeams = [];
teamsData.map((team) => {
// console.log("team.team");
// console.log(team.team);
tempTeams.push({
Id: team?.leader?.id,
TeamId: team?.id,
teamName: team?.team?.name,
leaderName: team?.leader?.name,
picture: team?.leader?.picture,
});
});
setTeams(tempTeams);
let tempWorkOrders = [];
workOrdersData.map((workOrder) => {
// console.log("workOrder");
// console.log(workOrder);
tempWorkOrders.push({
Id: workOrder.workOrder.id,
Task: workOrder.location.name + ", " + workOrder.service.name + ", " + workOrder.module.name,
CustomerEmail: workOrder.request.customer_email,
Details: workOrder.request_entity.description,
Repeat: workOrder.request_entity.schedule_frequency,
RecurrenceRule: "FREQ=DAILY;INTERVAL=3",
ConsultantID: '1'
});
});
let tempAssignWorkOrders = [];
workOrdersData.map((workOrder) => {
// console.log("workOrder");
// console.log(workOrder);
tempAssignWorkOrders.push({
Id: workOrder.workOrder.id,
Task: workOrder.location.name + ", " + workOrder.service.name + ", " + workOrder.module.name,
Name: workOrder.location.name + ", " + workOrder.service.name + ", " + workOrder.module.name,
CustomerEmail: workOrder.request.customer_email,
Details: workOrder.request_entity.description,
Repeat: workOrder.request_entity.schedule_frequency,
RecurrenceRule: "FREQ=DAILY;INTERVAL=4",
ConsultantID: 1,
"StartTime": "2022-12-20T03:30:00.000Z",
"EndTime": "2022-12-20T04:30:00.000Z",
"Description": "Health Checkup"
});
});
// "Id": 10,
// "Name": "David",
// "StartTime": "2022-12-20T03:30:00.000Z",
// "EndTime": "2022-12-20T04:30:00.000Z",
// "Description": "Health Checkup",
// "DepartmentID": 1,
// "ConsultantID": 1,
// "DepartmentName": "GENERAL"
setWorkOrders(tempAssignWorkOrders);
setAssignedData(extend([], tempAssignWorkOrders, null, true));
setIsLoading(false);
}
}, [teamsData, workOrdersData]);
function getTeamName(value) {
return value.resourceData.teamName;
}
function getTeamLeaderImage(value) {
if (value.resourceData.picture) {
return value.resourceData.picture;
}
}
function getTeamLeaderName(value) {
if (value.resourceData.leaderName) {
return value.resourceData.leaderName;
} else {
return "NO LEADER";
}
}
function resourceHeaderTemplate(props) {
return (
<div className="template-wrap">
<div className="specialist-category">
<Avatar className="specialist-image" src={getTeamLeaderImage(props)} />
<div className="specialist-name">{getTeamName(props)}</div>
<div className="specialist-designation">{getTeamLeaderName(props)}</div>
</div>
</div>
);
}
function treeTemplate(props) {
console.log("treeTemplate");
// console.log(props)
return (
<div id="waiting">
<div id="waitdetails">
<div id="waitlist">{props.Task}</div>
<div id="waitcategory">{props.CustomerEmail}</div>
</div>
</div>
);
}
function onItemDrag(event) {
console.log("onItemDrag");
if (scheduleObj.isAdaptive) {
let classElement = scheduleObj.element.querySelector(".e-device-hover");
if (classElement) {
classElement.classList.remove("e-device-hover");
}
if (event.event.target.classList.contains("e-work-cells")) {
addClass([event.event.target], "e-device-hover");
}
}
if (document.body.style.cursor === "not-allowed") {
document.body.style.cursor = "";
}
if (event.name === "nodeDragging") {
let dragElementIcon = document.querySelectorAll(".e-drag-item.treeview-external-drag .e-icon-expandable");
for (let i = 0; i < dragElementIcon.length; i++) {
dragElementIcon[i].style.display = "none";
}
}
}
function onActionBegin(event) {
console.log("event");
console.log(event);
if (event.requestType === "eventCreate" && isTreeItemDropped) {
let treeViewData = treeObj.fields.dataSource;
// console.log("treeViewData");
// console.log(treeViewData);
const filteredPeople = treeViewData.filter((item) => item.Id !== parseInt(draggedItemId, 10));
// console.log("filteredPeople");
// console.log(filteredPeople);
treeObj.fields.dataSource = filteredPeople;
let elements = document.querySelectorAll(".e-drag-item.treeview-external-drag");
// console.log("elements");
// console.log(elements);
for (let i = 0; i < elements.length; i++) {
remove(elements[i]);
}
}
}
const field = { text: "teamName", value: "Id" };
const editorTemplate = (props) => {
console.log("props");
console.log(props);
return props !== undefined ? (
<table className="custom-event-editor" style={{ width: "100%", cellpadding: "5", height: "600px" }}>
<tbody>
<tr>
<td className="e-textlabel">Title</td>
<td colSpan={4}>
<input disabled value={props.title} data-name="Title" id="title" className="e-field e-input" type="text" name="Title" style={{ width: "100%" }} />
</td>
</tr>
<tr>
<td className="e-textlabel">Customer Email</td>
<td colSpan={4}>
<input disabled value={props.customerEmail} data-name="customerEmail" id="customerEmail" className="e-field e-input" type="text" name="Customer Email" style={{ width: "100%" }} />
</td>
</tr>
<tr>
<td className="e-textlabel">Selected Team</td>
<td colSpan={4}>
<input disabled value={props.teamName} data-name="teamName" id="teamName" className="e-field e-input" type="text" name="Selected Team" style={{ width: "100%" }} />
</td>
</tr>
<tr>
<td className="e-textlabel">From</td>
<td colSpan={4}>
<DateTimePickerComponent fields={field} enabled={false} format="dd/MM/yy hh:mm a" id="StartTime" data-name="StartTime" value={new Date(props.startTime || props.StartTime)} className="e-field"></DateTimePickerComponent>
</td>
</tr>
<tr>
<td className="e-textlabel">To</td>
<td colSpan={4}>
<DateTimePickerComponent fields={field} format="dd/MM/yy hh:mm a" id="EndTime" data-name="EndTime" value={new Date(props.endTime || props.EndTime)} className="e-field"></DateTimePickerComponent>
</td>
</tr>
<tr>
<td className="e-textlabel">Schedule</td>
<td colSpan={4}>
<RecurrenceEditorComponent value={props.RecurrenceRule} ref={(recurrObject) => (recurrObject = { recurrObject })} frequencies={["daily"]} id="RecurrenceEditor"></RecurrenceEditorComponent>
</td>
</tr>
<tr>
<td className="e-textlabel">Details</td>
<td colSpan={4}>
<textarea value={props.details} data-name="Details" id="Details" className="e-field e-input" name="Details" rows={4} cols={50} style={{ width: "100%", height: "50px !important", resize: "vertical" }}></textarea>
</td>
</tr>
<tr>
<td className="e-textlabel">Consultant</td>
<td colSpan={4}>
<DropDownListComponent disabled={"true"} className="e-field" placeholder="Choose Consultant" data-name="ConsultantID" dataSource={teams} fields={field} value={props.ConsultantID} />
</td>
</tr>
<input hidden disabled value={props.workOrderId} data-name="workOrderId" id="workOrderId" className="e-field e-input" type="text" name="workOrderId" style={{ width: "100%" }} />
{/* <input hidden disabled value={props.RecurrenceRule} data-name="RecurrenceRule" id="RecurrenceRule" className="e-field" type="text" name="RecurrenceRule" style={{ width: "100%" }} /> */}
<input hidden disabled value={props.teamId} data-name="teamId" id="teamId" className="e-field e-input" type="text" name="teamId" style={{ width: "100%" }} />
</tbody>
</table>
) : (
<div></div>
);
};
function onTreeDragStop(event) {
let treeElement = closest(event.target, ".e-treeview");
let classElement = scheduleObj.element.querySelector(".e-device-hover");
if (classElement) {
classElement.classList.remove("e-device-hover");
}
if (!treeElement) {
event.cancel = true;
let scheduleElement = closest(event.target, ".e-content-wrap");
if (scheduleElement) {
let treeviewData = treeObj.fields.dataSource;
if (event.target.classList.contains("e-work-cells")) {
const filteredData = treeviewData.filter((item) => item.Id === parseInt(event.draggedNodeData.id, 10));
console.log("filteredData");
console.log(filteredData);
let cellData = scheduleObj.getCellDetails(event.target);
// console.log("cellData");
// console.log(cellData);
let resourceDetails = scheduleObj.getResourcesByIndex(cellData.groupIndex);
let eventData = {
title: filteredData[0].Task,
StartTime: cellData.startTime,
EndTime: cellData.endTime,
IsAllDay: false,
customerEmail: filteredData[0].CustomerEmail,
workOrderId: filteredData[0].Id,
teamId: resourceDetails.resourceData.Id,
teamName: resourceDetails.resourceData.teamName,
details: filteredData[0].Details,
repeatEvery: filteredData[0].Repeat,
ConsultantID: resourceDetails.resourceData.Id,
RecurrenceRule: filteredData[0].RecurrenceRule,
// RecurrenceEditor: "FREQ=DAILY;INTERVAL=" + filteredData[0].Repeat
};
scheduleObj.openEditor(eventData, "Add", true);
isTreeItemDropped = true;
draggedItemId = event.draggedNodeData.id;
}
}
}
}
return (
<Loading isLoading={isLoading}>
<div className="schedule-control-section">
<div className="col-lg-12 control-section">
<div className="control-wrapper drag-sample-wrapper">
<div className="schedule-container">
<div className="title-container">
<h1 className="title-text">Work Order Assignment</h1>
</div>
<ScheduleComponent
ref={(schedule) => (scheduleObj = schedule)}
cssClass="schedule-drag-drop"
width="100%"
height="650px"
selectedDate={new Date()}
currentView="Day"
resourceHeaderTemplate={resourceHeaderTemplate.bind(this)}
eventSettings={{
dataSource: assignedData,
fields: {
id: { title: "ID", name: "Id" },
subject: { title: "Task", name: "Task" },
startTime: { title: "From", name: "StartTime" },
endTime: { title: "To", name: "EndTime" },
description: { title: "Details", name: "Details" },
isAllDay: false,
RecurrenceRule: { title: "RecurrenceRule", name: "RecurrenceRule" },
},
timezone: false,
}}
editorTemplate={editorTemplate.bind(this)}
group={{ enableCompactView: true, resources: ["Consultants"] }}
actionBegin={onActionBegin.bind(this)}
drag={onItemDrag.bind(this)}
>
<ResourcesDirective>
<ResourceDirective field="ConsultantID" title="Consultant" name="Consultants" allowMultiple={false} dataSource={teams} textField="teamName" idField="Id" colorField="Color"></ResourceDirective>
</ResourcesDirective>
<ViewsDirective>
<ViewDirective option="TimelineMonth" />
<ViewDirective option="Week" />
<ViewDirective option="Day" />
</ViewsDirective>
<Inject services={[TimelineViews, TimelineMonth, Resize, DragAndDrop, Agenda, Week, Day]} />
</ScheduleComponent>
</div>
<div className="treeview-container">
<div className="title-container">
<h1 className="title-text">Waiting List</h1>
</div>
<TreeViewComponent ref={(tree) => (treeObj = tree)} cssClass="treeview-external-drag" dragArea=".drag-sample-wrapper" nodeTemplate={treeTemplate.bind(this)} fields={{ dataSource: workOrders, id: "Id", text: "Name" }} nodeDragStop={onTreeDragStop.bind(this)} nodeDragging={onItemDrag.bind(this)} allowDragAndDrop={allowDragAndDrops} />
</div>
</div>
</div>
</div>
</Loading>
);
}
export default Calender;