Hi,
I am working on the Scheduler component, which displays events for resources on a resource timeline view (day, week, month). I get the events from the server using react-query and then pass them to the eventSettings as the dataSource.
Everything works well until I start using a custom resource header template or date header template. When I use these templates, the events do not appear until I change dates. Does anyone know why? Here is my Scheduler component:
import * as React from "react"
import {
ScheduleComponent,
Inject,
ViewsDirective,
ViewDirective,
EventSettingsModel,
ResourcesDirective,
TimelineMonth,
ResourceDirective,
TimelineViews,
ActionEventArgs,
} from "@syncfusion/ej2-react-schedule"
import { useEffect, useRef, useState } from "react"
import { SchedulerModel } from "components/scheduler-2/schedulerModel"
import { useSchedulerEvent, useSchedulerResource } from "components/scheduler/06_services/schedulerService"
import { endOfDay, startOfDay } from "date-fns"
import { runInAction } from "mobx"
import { observer } from "mobx-react"
import { Internationalization } from "@syncfusion/ej2-base"
const Scheduler = () => {
const [events, setEvents] = useState<Object[]>([])
const [model] = useState(() => new SchedulerModel())
const scheduleRef = useRef<ScheduleComponent>(null)
const { data: resources } = useSchedulerResource()
const { data: schedulerEvents } = useSchedulerEvent(model.getEventQueryInput())
const instance = new Internationalization()
useEffect(() => {
if (schedulerEvents) {
const typedEvents = schedulerEvents.map((m, idx) => {
return {
Id: idx + 1,
Subject: m.jobMetadata?.jobNumber,
StartTime: new Date(m.startDateTimeUtc),
EndTime: new Date(m.endDateTimeUtc),
ResourceId: m.resourceReferences,
Color: m.jobMetadata?.stateColor,
}
})
setEvents(typedEvents)
}
}, [schedulerEvents])
//To get the start and end dates of current view and current Date range
const onActionComplete = (args: ActionEventArgs) => {
if (args.requestType === "viewNavigate" || args.requestType === "dateNavigate") {
if (scheduleRef.current) {
const currentViewDates = scheduleRef.current.getCurrentViewDates()
const startDate = startOfDay(currentViewDates[0])
const endDate = endOfDay(currentViewDates[currentViewDates.length - 1])
runInAction(() => {
model.startDate.date = startDate
model.endDate.date = endDate
})
}
}
}
const resourceHeaderTemplate = (props: any) => {
return (
<div className="template-wrap flex items-center">
<div>
<img className="inline-block h-8 w-8 rounded-full" src={props.resourceData.profileImageUrl} alt="" />
</div>
<div className="ml-3">
<p className="text-sm font-medium text-gray-700 group-hover:text-gray-900">{props.resourceData.fullName}</p>
</div>
</div>
)
}
const eventTemplate = (props: any) => {
return (
<div
className="absolute inset-0 flex flex-col h-full rounded-lg p-2 text-xs leading-5"
style={{
background: props.Color + 30,
}}
>
<p className="order-1 font-semibold" style={{ color: props.Color }}>
{props.Subject}
</p>
</div>
)
}
const getDateHeaderText = (value: Date) => {
return instance.formatDate(value, { skeleton: "Ed" })
}
const dateHeaderTemplate = (props: any) => {
return <div className="text-center">{getDateHeaderText(props.date)}</div>
}
const eventSettings: EventSettingsModel = {
dataSource: events,
template: eventTemplate,
ignoreWhitespace: true,
}
const group = { allowGroupEdit: true, resources: ["Resources"] }
return (
<ScheduleComponent
id="scheduler"
ref={scheduleRef}
width="100%"
height="100%"
currentView="TimelineDay"
eventSettings={eventSettings}
group={group}
actionComplete={onActionComplete}
resourceHeaderTemplate={resourceHeaderTemplate}
cssClass="schedule-cell-dimension"
allowMultiCellSelection={true}
>
<ViewsDirective>
<ViewDirective option="TimelineDay" displayName="Day" />
<ViewDirective option="TimelineWeek" displayName="Week" />
<ViewDirective option="TimelineMonth" displayName="Month" />
</ViewsDirective>
<ResourcesDirective>
<ResourceDirective
field="ResourceId"
title="Resource"
name="Resources"
allowMultiple={true}
dataSource={resources}
textField="fullName"
idField="resourceReference"
></ResourceDirective>
</ResourcesDirective>
<Inject services={[TimelineViews, TimelineMonth]} />
</ScheduleComponent>
)
}
export default observer(Scheduler)
Hi Harmeet,
We require more additional details to check your reported problem at our end to validate your reported query. Could you please share the below details to proceed further?
Regards,
Swathi Ravi
Sure here are the code snippets:
function useSchedulerResource() {
return useQuery(keys.schedulerResourceQuery, fetchSchedulerResources, {
select: (data: Response<SchedulerResources>) => data.data.data.schedulerResources,
})
}
function fetchSchedulerResources() {
return graphQLClient.fetch(query.schedulerResourceQuery, null, true, common.peopleApiUrl, keys.schedulerResourceQuery)
}
function useSchedulerEvent(input: SchedulerEventQueryInput) {
return useQuery([keys.schedulerEventQuery, input], () => fetchSchedulerEvents(input), {
select: (data: Response<SchedulerEvents>) => data.data.data.schedulerEvents,
})
}
function fetchSchedulerEvents(input: SchedulerEventQueryInput) {
return graphQLClient.fetch(query.schedulerEventQuery, input, true, common.calendarApiUrl, keys.schedulerEventQuery)
}
export class SchedulerModel {
startDate: DatePickerObservable
endDate: DatePickerObservable
constructor() {
makeObservable(this, {})
this.startDate = new DatePickerObservable(startOfDay(new Date()))
this.endDate = new DatePickerObservable(endOfDay(new Date()))
}
getEventQueryInput() {
const input: SchedulerEventQueryInput = {
resourceReference: "",
clientReference: "",
categoryReferences: [],
stateReferences: [],
startDateTimeUtc: this.startDate.getUtcDateTime(),
endDateTimeUtc: this.endDate.getUtcDateTime(),
}
return input
}
}
Harmeet,
Based on the code snippets you shared, it appears that you might be fetching data remotely for your Schedule component. We created a sample with remote data and verified that it functions correctly as expected. If you are still experiencing the same issue despite using the provided sample, please provide the following information so that we can further assist you:
Sample: https://stackblitz.com/edit/react-ww3nih?file=index.js
Hi,
Sorry for the late reply. I have discovered that the useEffect setting events was causing the problem. I have updated the useSchedulerEvent hook, which now returns the typed events for the scheduler, so I'm no longer using useEffect for it. Thanks for your help as well.
function useSchedulerEvent(input: SchedulerEventQueryInput) {
return useQuery([keys.schedulerEventQuery, input], () => fetchSchedulerEvents(input), {
select: (data: Response<SchedulerEvents>) => {
return data.data.data.schedulerEvents.map((m, idx) => {
return {
Id: idx + 1,
Subject: m.jobMetadata?.jobNumber,
StartTime: new Date(m.startDateTimeUtc),
EndTime: new Date(m.endDateTimeUtc),
ResourceId: m.resourceReferences,
Color: m.jobMetadata?.stateColor,
ExtendedProps: m,
}
})
},
})
}
Hi Harmeet,
We are happy that you found the root cause of the issue and resolved the issue. Let us know if you need any further assistance.
Regards,
Ravikumar Venkatesan