ra-scheduler

react-admin ≥ 5.8.3

A full-featured scheduler component for managing tasks, assignments, events, scheduling constraints and dependencies, completion, recurring events, property booking, skill matrix, nested events, etc.

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.

Installation

You will need a valid Bryntum Scheduler License and a valid React-Admin Enterprise Edition License to use this package.

Configure your package manager to use the Bryntum NPM repository by following these instructions: Using Bryntum NPM repository and packages

Next, install the @react-admin/ra-scheduler repository:

npm install --save @react-admin/ra-scheduler
# or
yarn add @react-admin/ra-scheduler

Translations

In order to have correct labels on the navigation buttons, you have to set up the internationalization with the provided translations or your own. Check out the Internationalization section below for detailed steps.

Data Provider Setup

The Scheduler lets you manage Events. Events must be resources with at least an id, a name, a startDate, an endDate and a resourceId (the resource assigned to this event, for instance a person). Here is a typical event:

{
    id: 123,
    title: 'Package delivery',
    startDate: '2020-10-20T08:00:00.000Z',
    endDate: '2020-10-20T09:30:00.000Z',
    resourceId: 456
},

That means that in order to be able to use ra-scheduler, your dataProvider must return event-like objects for at least one resource. In case your event records don't exactly match this format, ra-scheduler allows to specify a function to convert records to Events.

Events can have many more fields, e.g. for recurrent events, groups, colors, etc. Check the Event model on the Bryntum documentation.

In addition, the scheduler queries a list of events in a time interval. Your dataProvider must support getList() queries with an interval filter. By default, the interval filter looks like the following:

{
    // lower time boundary
    startDate: '2020-10-01T00:00:00.000Z',
    // upper time boundary
    endDate: '2020-12-31T23:59:59.000Z'
}

As explained above, events are assigned a Resource, for instance a person. Resources must be a React Admin resource with at least an id. Here is a typical resource representing an employee:

{
    id: 456,
    name: 'Jane Doe',
},

Resources can have many more fields, e.g. for groups, colors, etc. Check the Resource model on the Bryntum documentation.

Once your data provider can query events and resources, you're ready to use the <Scheduler> component.

Usage

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

// 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())}
    />
);
// 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())}
    />
);

<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.

<Scheduler>

A component that displays events in a timeline. It uses Bryntum Scheduler under the hood.

Props

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

Prop Required Type Default Description
actions Optional ReactNode A component displayed on top of the scheduler, usually to display a toolbar with action buttons
converters Optional object An object containing converters from dataProvider records to Bryntum models and vice-versa
CreateDialogProps Optional object Props to pass to the <CreateDialog> used to create new events
EditDialogProps Optional object Props to pass to the <EditDialog> used to edit existing events
eventCreate Optional ReactNode The form used to create new events
eventEdit Optional ReactNode The form used to edit existing events
eventName Optional string The name of the resource for Events
mutationOptions Optional object The mutation options sent when updating Events via drag/drop or resize and Resources via the inline editor
resourcesName Optional string 'resources' The name of the resource for Resources
queryOptions Optional object The query options sent when fetching Events and Resources
sx Optional object The sx prop passed down to the wrapping <div> element
title Optional object The 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:

// 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 />}
    />
);
// 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 />}
    />
);

converters

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

// 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: RaRecord) => ({
                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: RaRecord) => ({
                id: record.id,
                name: record.name,
            }),
            toEvent?: (model: EventModel) => ({
                id: model.id,
                name: model.name,
                resource_id: model.resourceId,
                start_at: model.startDate,
                end_at: model.endDate,
                color: record.eventColor,
            }),
            toResource?: (model: ResourceModel) => ({
                id: model.id,
                name: model.name,
            }),
        }}
    />
);
// 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,
            }),
        }}
    />
);

CreateDialogProps

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

// 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"
            }}
        />
    );
};
// 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",
            }}
        />
    );
};

EditDialogProps

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

// 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;
};
// 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;
};

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:

// 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'];
// 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"];

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:

// 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'];
// 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"];

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:

// 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' }}}
    />
);
// 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" } }}
    />
);

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:

// 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())}
    />
);
// 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())}
    />
);

queryOptions

The query options when fetching Events or Resources:

// 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' }}}
    />
);
// 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" } }}
    />
);

sx

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

// 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',
            },
        }}
    />
);
// 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",
            },
        }}
    />
);

title

The title to display in the <AppBar>:

// 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"
    />
);
// 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" />
);

<SchedulerDaysNavigationButtons>

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

// 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 />}
    />
);
// 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 />}
    />
);

<SchedulerWeeksNavigationButtons>

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

// 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 />}
    />
);
// 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 />}
    />
);

<SchedulerMonthsNavigationButtons>

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

// 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 />}
    />
);
// 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 />}
    />
);

Internationalization

ra-scheduler provides translations for English (raSchedulerLanguageEnglish) and French (raSchedulerLanguageFrench).

You should merge these translations with the other interface messages before passing them to your i18nProvider:

import { mergeTranslations } from 'react-admin';
import polyglotI18nProvider from 'ra-i18n-polyglot';
import englishMessages from 'ra-language-english';
import frenchMessages from 'ra-language-french';
import {
    raSchedulerLanguageEnglish,
    raSchedulerLanguageFrench,
} from '@react-admin/ra-scheduler';

const i18nProvider = polyglotI18nProvider(locale =>
    locale === 'en'
        ? mergeTranslations(englishMessages, raSchedulerLanguageEnglish)
        : mergeTranslations(frenchMessages, raSchedulerLanguageFrench)
);
import { mergeTranslations } from "react-admin";
import polyglotI18nProvider from "ra-i18n-polyglot";
import englishMessages from "ra-language-english";
import frenchMessages from "ra-language-french";
import { raSchedulerLanguageEnglish, raSchedulerLanguageFrench } from "@react-admin/ra-scheduler";

const i18nProvider = polyglotI18nProvider((locale) =>
    locale === "en"
        ? mergeTranslations(englishMessages, raSchedulerLanguageEnglish)
        : mergeTranslations(frenchMessages, raSchedulerLanguageFrench)
);

CHANGELOG

v1.0.0

2025-06-11

  • Initial release