Back to React Admin

The Scheduler Component

docs/Scheduler.md

5.14.618.3 KB
Original Source

<Scheduler>

This Enterprise Edition component, part of ra-scheduler, is a full-featured scheduler for managing tasks, assignments, events, scheduling constraints and dependencies, completion, recurring events, property booking, skill matrix, nested events, etc.

<video controls autoplay playsinline muted loop> <source src="https://react-admin-ee.marmelab.com/assets/ra-scheduler.mp4" type="video/mp4"/> Your browser does not support the video tag. </video>

It supports drag and drop, infinite scroll, zoom, custom layout and styling, collapsible columns, localization, grouping and filtering and export to pdf.

This packages integrates react-admin with Bryntum Scheduler, a modern and high-performance scheduling UI component. As it leverages react-admin's data provider, it is backend agnostic.

Test it live in the Enterprise Edition Storybook.

Usage

<Scheduler> is an all-in one component. Use it as the list prop of a react-admin <Resource>:

{% raw %}

tsx
// in ./src/App.tsx
import { Admin, Resource } from 'react-admin';
import { dataProvider } from './dataProvider';
import { EventList } from './events/EventList';

export const MyAdmin = () => (
    <Admin dataProvider={dataProvider}>
        <Resource name="events" list={EventList} />
    </Admin>
);

// in ./src/events/EventList.tsx
import { Scheduler } from '@react-admin/ra-scheduler';
import '@bryntum/core-thin/core.material.css';
import '@bryntum/grid-thin/grid.material.css';
import '@bryntum/scheduler-thin/scheduler.material.css';
import { endOfDay, startOfDay } from 'date-fns';

export const EventList = () => (
    <Scheduler
        columns={[{ text: 'Name', field: 'name', width: 130 }]}
        viewPreset="hourAndDay"
        startDate={startOfDay(new Date())}
        endDate={endOfDay(new Date())}
    />
);

{% endraw %}

<Scheduler> renders a Bryntum Scheduler and integrates it with the dataProvider and @react-admin/ra-form-layout dialogs.

It uses all the available horizontal and vertical space in the layout's content section.

Props

In addition to the props accepted by Bryntum Scheduler, <Scheduler> accepts the following props:

PropRequiredTypeDefaultDescription
actionsOptionalReactNodeA component displayed on top of the scheduler, usually to display a toolbar with action buttons
convertersOptionalobjectAn object containing converters from dataProvider records to Bryntum models and vice-versa
CreateDialogPropsOptionalobjectProps to pass to the <CreateDialog> used to create new events
EditDialogPropsOptionalobjectProps to pass to the <EditDialog> used to edit existing events
eventCreateOptionalReactNodeThe form used to create new events
eventEditOptionalReactNodeThe form used to edit existing events
mutationOptionsOptionalobjectThe mutation options sent when updating Events via drag/drop or resize and Resources via the inline editor
resourcesOptionalobject{ resources: "resources", events: "events" }The resources names to use for Events and Resources
queryOptionsOptionalobjectThe query options sent when fetching Events and Resources
sxOptionalobjectThe sx prop passed down to the wrapping <div> element
titleOptionalobjectThe title to display in the <AppBar>

actions

A component displayed on top of the scheduler, usually to display a toolbar with action buttons. By default, it renders a toolbar with navigation buttons to go to the previous or next day. You can provide your own actions by passing a component to the actions prop, for instance to use the provided navigation buttons for week or month navigation:

{% raw %}

tsx
// in ./src/events/EventList.tsx
import { Scheduler, SchedulerWeeksNavigationButtons } from '@react-admin/ra-scheduler';
import '@bryntum/core-thin/core.material.css';
import '@bryntum/grid-thin/grid.material.css';
import '@bryntum/scheduler-thin/scheduler.material.css';
import { startOfWeek } from 'date-fns';

const EventListActions = () => (
    <TopToolbar>
        <SchedulerWeeksNavigationButtons />
    </TopToolbar>
);

export const EventList = () => (
    <Scheduler
        columns={[{ text: 'Name', field: 'name', width: 130 }]}
        viewPreset="weekAndDay"
        startDate={startOfWeek(new Date())}
        actions={<EventListActions />}
    />
);

{% endraw %}

converters

An object that contains function converting dataProvider records to Bryntum models and vice-versa:

{% raw %}

tsx
// in ./src/events/EventList.tsx
import { Scheduler } from '@react-admin/ra-scheduler';
import '@bryntum/core-thin/core.material.css';
import '@bryntum/grid-thin/grid.material.css';
import '@bryntum/scheduler-thin/scheduler.material.css';
import { startOfDay } from 'date-fns';

export const EventList = () => (
    <Scheduler
        columns={[{ text: 'Name', field: 'name', width: 130 }]}
        viewPreset="hourAndDay"
        startDate={startOfDay(new Date())}
        converters={{
            toBryntumEvent: (record) => ({
                id: record.id,
                name: record.name,
                resourceId: record.resource_id,
                eventColor: record.color,
                startDate: new Date(record.start_at),
                endDate: new Date(record.end_at),
            }),
            toBryntumResource: (record) => ({
                id: record.id,
                name: record.name,
            }),
            toEvent: (model) => ({
                id: model.id,
                name: model.name,
                resource_id: model.resourceId,
                start_at: model.startDate,
                end_at: model.endDate,
                color: record.eventColor,
            }),
            toResource: (model) => ({
                id: model.id,
                name: model.name,
            }),
        }}
    />
);

{% endraw %}

CreateDialogProps

The props to pass to the <CreateDialog> used to create new events:

{% raw %}

tsx
// in ./src/events/EventList.tsx
import { Scheduler } from '@react-admin/ra-scheduler';
import '@bryntum/core-thin/core.material.css';
import '@bryntum/grid-thin/grid.material.css';
import '@bryntum/scheduler-thin/scheduler.material.css';
import { startOfDay } from 'date-fns';

export const EventList = () => {
    return (
        <Scheduler
            columns={[{ text: 'Name', field: 'name', width: 130 }]}
            viewPreset="hourAndDay"
            startDate={startOfDay(new Date())}
            CreateDialogProps={{
                title: "Create a new event"
            }}
        />
    );
};

{% endraw %}

EditDialogProps

The props to pass to the <EditDialog> used to create new events:

{% raw %}

tsx
// in ./src/events/EventList.tsx
import { Scheduler } from '@react-admin/ra-scheduler';
import '@bryntum/core-thin/core.material.css';
import '@bryntum/grid-thin/grid.material.css';
import '@bryntum/scheduler-thin/scheduler.material.css';
import { startOfDay } from 'date-fns';

export const EventList = () => {
    return (
        <Scheduler
            columns={[{ text: 'Name', field: 'name', width: 130 }]}
            viewPreset="hourAndDay"
            startDate={startOfDay(new Date())}
            EditDialogProps={{
                title: <EventEditTitle />
            }}
        />
    );
};

const EventEditTitle = () => {
    const record = useRecordContext();
    return record ? <span>Edit {record?.name}</span> : null;
};

{% endraw %}

eventCreate

<Scheduler> includes a default form for events creation and edition with the basic fields. You can provide a custom form component to create new events with the eventCreate prop:

{% raw %}

tsx
// in ./src/events/EventList.tsx
import { Scheduler } from '@react-admin/ra-scheduler';
import '@bryntum/core-thin/core.material.css';
import '@bryntum/grid-thin/grid.material.css';
import '@bryntum/scheduler-thin/scheduler.material.css';
import { startOfDay } from 'date-fns';
import {
    AutocompleteInput,
    DateTimeInput,
    ReferenceInput,
    required,
    SelectInput,
    SimpleForm,
    TextInput
} from 'react-admin';

export const EventList = () => (
    <Scheduler
        viewPreset="hourAndDay"
        startDate={startOfDay(new Date())}
        eventCreate={<CustomEventForm />}
    />
);

const CustomEventForm = () => (
    <SimpleForm>
        <TextInput source="name" validate={required()} />
        <ReferenceInput source="resourceId" reference="resources">
            <AutocompleteInput validate={required()} />
        </ReferenceInput>
        <DateTimeInput source="startDate" validate={required()} />
        <DateTimeInput source="endDate" validate={required()} />
        <SelectInput source="eventColor" choices={colors} />
    </SimpleForm>
);

const colors = ['red', 'blue', 'green', 'yellow', 'purple'];

{% endraw %}

eventEdit

<Scheduler> includes a default form for events creation and edition with the basic fields. You can provide a custom form component to edit existing events with the eventEdit prop:

{% raw %}

tsx
// in ./src/events/EventList.tsx
import { Scheduler } from '@react-admin/ra-scheduler';
import '@bryntum/core-thin/core.material.css';
import '@bryntum/grid-thin/grid.material.css';
import '@bryntum/scheduler-thin/scheduler.material.css';
import { startOfDay } from 'date-fns';
import {
    AutocompleteInput,
    DateTimeInput,
    ReferenceInput,
    required,
    SelectInput,
    SimpleForm,
    TextInput
} from 'react-admin';

export const EventList = () => (
    <Scheduler
        viewPreset="hourAndDay"
        startDate={startOfDay(new Date())}
        eventEdit={<CustomEventForm />}
    />
);

const CustomEventForm = () => (
    <SimpleForm>
        <TextInput source="name" validate={required()} />
        <ReferenceInput source="resourceId" reference="resources">
            <AutocompleteInput validate={required()} />
        </ReferenceInput>
        <DateTimeInput source="startDate" validate={required()} />
        <DateTimeInput source="endDate" validate={required()} />
        <SelectInput source="eventColor" choices={colors} />
    </SimpleForm>
);

const colors = ['red', 'blue', 'green', 'yellow', 'purple'];

{% endraw %}

mutationOptions

Bryntum Scheduler allows users to modify events by resizing or drag/dropping them and resources by double clicking them. If you need to pass additional data for those updates, use the mutationOptions prop:

{% raw %}

tsx
// in ./src/events/EventList.tsx
import { Scheduler } from '@react-admin/ra-scheduler';
import '@bryntum/core-thin/core.material.css';
import '@bryntum/grid-thin/grid.material.css';
import '@bryntum/scheduler-thin/scheduler.material.css';
import { startOfDay } from 'date-fns';

export const EventList = () => (
    <Scheduler
        viewPreset="hourAndDay"
        startDate={startOfDay(new Date())}
        mutationOptions={{ meta: { option: 'value' }}}
    />
);

{% endraw %}

resources

By default, <Scheduler> uses:

  • the resource from the current ResourceContext or "events" if no ResourceContext is available (for instance in a dashboard) as the default resource name for the scheduler Events
  • "resources" as the default resource name for the scheduler Resources

If you want to use another name, set the resources prop:

{% raw %}

tsx
// in ./src/events/EventList.tsx
import { Scheduler } from '@react-admin/ra-scheduler';
import '@bryntum/core-thin/core.material.css';
import '@bryntum/grid-thin/grid.material.css';
import '@bryntum/scheduler-thin/scheduler.material.css';
import { startOfDay } from 'date-fns';

export const EventList = () => (
    <Scheduler
        resources={{
            events: "tasks",
            resources: "employees"
        }}
        viewPreset="hourAndDay"
        startDate={startOfDay(new Date())}
    />
);

{% endraw %}

queryOptions

The query options when fetching Events or Resources:

{% raw %}

tsx
// in ./src/events/EventList.tsx
import { Scheduler } from '@react-admin/ra-scheduler';
import '@bryntum/core-thin/core.material.css';
import '@bryntum/grid-thin/grid.material.css';
import '@bryntum/scheduler-thin/scheduler.material.css';
import { startOfDay } from 'date-fns';

export const EventList = () => (
    <Scheduler
        viewPreset="hourAndDay"
        startDate={startOfDay(new Date())}
        queryOptions={{ meta: { option: 'value' }}}
    />
);

{% endraw %}

sx

The sx prop passed down to the wrapping <div> element:

{% raw %}

tsx
// in ./src/events/EventList.tsx
import { Scheduler } from '@react-admin/ra-scheduler';
import '@bryntum/core-thin/core.material.css';
import '@bryntum/grid-thin/grid.material.css';
import '@bryntum/scheduler-thin/scheduler.material.css';
import { startOfDay } from 'date-fns';

export const EventList = () => (
    <Scheduler
        viewPreset="hourAndDay"
        startDate={startOfDay(new Date())}
        sx={{
            '& .b-grid-header': {
                color: 'white',
                backgroundColor: 'rgba(0, 0, 0, 0.8)',
            },
            '& .b-sch-header-timeaxis-cell': {
                color: 'white',
            },
        }}
    />
);

{% endraw %}

title

The title to display in the <AppBar>:

{% raw %}

tsx
// in ./src/events/EventList.tsx
import { Scheduler } from '@react-admin/ra-scheduler';
import '@bryntum/core-thin/core.material.css';
import '@bryntum/grid-thin/grid.material.css';
import '@bryntum/scheduler-thin/scheduler.material.css';
import { startOfDay } from 'date-fns';

export const EventList = () => (
    <Scheduler
        viewPreset="hourAndDay"
        startDate={startOfDay(new Date())}
        title="Today planning"
    />
);

{% endraw %}

<SchedulerDaysNavigationButtons>

A component that displays navigation buttons to move through days in a <Scheduler> that displays data day by day.

{% raw %}

tsx
// in ./src/events/EventList.tsx
import { Scheduler, SchedulerDaysNavigationButtons } from '@react-admin/ra-scheduler';
import '@bryntum/core-thin/core.material.css';
import '@bryntum/grid-thin/grid.material.css';
import '@bryntum/scheduler-thin/scheduler.material.css';
import { startOfDay } from 'date-fns';

const EventListActions = () => (
    <TopToolbar>
        <SchedulerDaysNavigationButtons />
    </TopToolbar>
);

export const EventList = () => (
    <Scheduler
        columns={[{ text: 'Name', field: 'name', width: 130 }]}
        viewPreset="hourAndDay"
        startDate={startOfDay(new Date())}
        actions={<EventListActions />}
    />
);

{% endraw %}

<SchedulerWeeksNavigationButtons>

A component that displays navigation buttons to move through weeks in a <Scheduler> that displays data week by week.

{% raw %}

tsx
// in ./src/events/EventList.tsx
import { Scheduler, SchedulerWeeksNavigationButtons } from '@react-admin/ra-scheduler';
import '@bryntum/core-thin/core.material.css';
import '@bryntum/grid-thin/grid.material.css';
import '@bryntum/scheduler-thin/scheduler.material.css';
import { startOfWeek } from 'date-fns';

const EventListActions = () => (
    <TopToolbar>
        <SchedulerWeeksNavigationButtons />
    </TopToolbar>
);

export const EventList = () => (
    <Scheduler
        columns={[{ text: 'Name', field: 'name', width: 130 }]}
        viewPreset="weekAndDay"
        startDate={startOfWeek(new Date())}
        actions={<EventListActions />}
    />
);

{% endraw %}

<SchedulerMonthsNavigationButtons>

A component that displays navigation buttons to move through months in a <Scheduler> that displays data month by month.

{% raw %}

tsx
// in ./src/events/EventList.tsx
import { Scheduler, SchedulerMonthsNavigationButtons } from '@react-admin/ra-scheduler';
import '@bryntum/core-thin/core.material.css';
import '@bryntum/grid-thin/grid.material.css';
import '@bryntum/scheduler-thin/scheduler.material.css';
import { startOfMonth } from 'date-fns';

const EventListActions = () => (
    <TopToolbar>
        <SchedulerMonthsNavigationButtons />
    </TopToolbar>
);

export const EventList = () => (
    <Scheduler
        columns={[{ text: 'Name', field: 'name', width: 130 }]}
        viewPreset="monthAndYear"
        startDate={startOfMonth(new Date())}
        actions={<EventListActions />}
    />
);

{% endraw %}