# Getting Started
URL: https://pro.rv-grid.com/guides/event-scheduler/introduction/
Source: src/content/docs/guides/event-scheduler/introduction/index.mdx
Description: Set up RevoGrid Enterprise Event Scheduler for staff scheduling, shift planning, room booking, equipment planning, and team calendars.
`EventSchedulerPlugin` turns RevoGrid Enterprise into a commercial scheduler for events on time grids. Use it for staff rosters, employee shifts, room reservations, machine plans, field crews, support queues, and sprint capacity.

The scheduler supports calendar and resource timeline views, editable event blocks, resources, assignments, calendars, availability, conflicts, grouping, templates, recurrence helpers, remote data, custom renderers, and export helpers.

Create an empty grid and provide scheduler data through side-channel props. The scheduler owns the generated grid projection; your app owns persistence.

## Minimal Astro setup

The only required event fields are `id`, `startDateTime`, and `endDateTime`. Add `title`, `resourceId`, `status`, `type`, `metadata`, and resources when your product needs labels, capacity rows, filtering, styling, or persistence fields.

## Minimal TypeScript setup

If the grid already exists in your app, set the same properties directly:

```ts
import { EventSchedulerPlugin } from '@revolist/revogrid-enterprise';

grid.plugins = [EventSchedulerPlugin];

grid.eventScheduler = {
  view: 'week',
  weekStartDate: '2026-06-08',
  slotMinutes: 60,
  timeRange: { start: '08:00', end: '18:00' },
};

grid.eventSchedulerEvents = [
  {
    id: 'booking-1',
    startDateTime: '2026-06-08T09:00:00.000Z',
    endDateTime: '2026-06-08T12:00:00.000Z',
  },
];
```

## What Event Scheduler does

Event Scheduler uses RevoGrid as the rendering and interaction surface for time-based planning. Instead of building ordinary data rows and columns yourself, you give the grid scheduler configuration, events, resources, and optional planning datasets. The plugin projects that data into timeline columns, resource rows, event blocks, drag handles, conflict indicators, non-working time, and editor interactions.

Use it when the main question is "who or what is booked, when, and against which capacity?" Common use cases include:

- staff and employee shift scheduling
- room, desk, vehicle, or equipment booking
- machine and production line planning
- field crew, support queue, and service dispatch calendars
- sprint, delivery, or team-capacity calendars

## Core concepts

- `events` are the scheduled blocks. Each event needs an `id`, `startDateTime`, and `endDateTime`. Add `title`, `resourceId`, `resourceIds`, or `assignmentIds` when the event needs a label or belongs to a person, room, machine, team, or other capacity.
- `resources` are the schedulable rows in resource planning. A resource can be a person, room, vehicle, machine, location, team, department, or parent group.
- `views` decide how time is shown. Use `day`, `week`, or `month` for calendar-style time grids, and `resourceTimeline` when each resource needs its own row across a visible date or time range.
- `projection` is the derived scheduler model. The plugin combines config, events, resources, assignments, availability, templates, coverage requirements, and filters into visible rows, columns, event lanes, conflict markers, group summaries, and overlays.
- Your app owns the data. The grid renders the schedule and emits mutation events. Your app listens to those events, replaces `eventSchedulerEvents` with the next event array, and persists changes to local state or a backend.

## Data ownership

Use the scheduler props as the public data boundary:

- **Events**: Every event needs `id`, `startDateTime`, and `endDateTime`. `title`, `resourceId`, `resourceIds`, `status`, and `type` are optional. Use resource fields for resource timelines or leave them out for unassigned demand.
- **Resources**: Use resources for people, rooms, vehicles, machines, teams, locations, or parent groups. `calendarId`, `capacity`, `group`, `role`, and `metadata` feed calendars, grouping, coverage, utilization, and filters.
- **Assignments**: Use assignments when your system stores event-to-resource links separately from the event record. They are merged with `resourceId` and `resourceIds` during projection.
- **Availability**: Use dated `working`, `blocked`, `holiday`, and `break` windows for operational exceptions such as PTO, maintenance, temporary opening hours, or one-off closures.
- **Templates and coverage**: Use templates for repeated event creation and coverage requirements for required capacity/headcount checks.

`locked` and `readonly` events or resources reject normal edit flows. `color`, `className`, `status`, `type`, `category`, and `metadata` let products style, classify, filter, or persist scheduler records without replacing the scheduler model.

## Main props

- **`eventScheduler`**: Main `EventSchedulerConfig`. Controls the active view, visible date range, slot size, visible hours, editing permissions, event layout, conflicts, calendars, filters, labels, formatters, templates, remote loading, and customization hooks.
- **`eventSchedulerEvents`**: The event blocks to render. Events contain stable ids and start/end datetimes, plus optional titles, status/type metadata, and resource or assignment links.
- **`eventSchedulerResources`**: The schedulable resources shown in resource-timeline flows. Use it for people, rooms, machines, teams, locations, vehicles, or parent groups.
- **`eventSchedulerAssignments`**: Optional assignment link data when events and resources are connected by a separate system table instead of direct `resourceId` fields.
- **`eventSchedulerAvailability`**: Optional working, blocked, holiday, or break windows for resource-specific availability and outside-availability conflict checks.
- **`eventSchedulerTemplates`**: Optional reusable event templates for quick creation and recurrence helpers.
- **`eventSchedulerCoverageRequirements`**: Optional staffing or capacity requirements used by coverage summaries and gap highlighting.
- **`source` and `columns`**: Usually empty for scheduler pages. The scheduler projection owns the visual rows and columns, so host data should be passed through scheduler props.

## Basic setup

```ts
import {
  EventSchedulerPlugin,
  type EventSchedulerConfig,
  type EventSchedulerEventEntity,
  type EventSchedulerResourceEntity,
} from '@revolist/revogrid-enterprise';

const resources: EventSchedulerResourceEntity[] = [
  { id: 'room-a', name: 'Room A', role: 'Room', group: 'Conference' },
  { id: 'room-b', name: 'Room B', role: 'Room', group: 'Conference' },
];

const events: EventSchedulerEventEntity[] = [
  {
    id: 'booking-1',
    startDateTime: '2026-06-08T09:00:00.000Z',
    endDateTime: '2026-06-08T12:00:00.000Z',
    title: 'Customer workshop',
    resourceId: 'room-a',
    status: 'confirmed',
    type: 'booking',
  },
];

const eventScheduler: EventSchedulerConfig = {
  view: 'resourceTimeline',
  weekStartDate: '2026-06-08',
  dateRange: { start: '2026-06-08', end: '2026-06-08' },
  slotMinutes: 60,
  timeRange: { start: '08:00', end: '18:00' },
  editable: true,
  allowCreate: true,
  allowMove: true,
  allowResize: true,
  conflicts: { enabled: true, policy: 'mark', scope: 'same-resource' },
};

grid.plugins = [EventSchedulerPlugin];
grid.eventScheduler = eventScheduler;
grid.eventSchedulerResources = resources;
grid.eventSchedulerEvents = events;
grid.source = [];
grid.columns = [];
```

For framework wrappers, bind `eventScheduler`, `eventSchedulerResources`, and `eventSchedulerEvents` as grid properties.

## Blocking overlap and conflicts

Existing data can still render with conflict markers so users can review and fix it. To block future overlapping create, move, resize, and edit actions for the same resource, keep the scheduler in mark mode and promote only `overlap` to an error:

```ts
grid.eventScheduler = {
  ...grid.eventScheduler,
  conflicts: {
    enabled: true,
    policy: 'mark',
    scope: 'same-resource',
    rules: { overlap: 'error' },
  },
};
```

Error conflicts render with the built-in red conflict state. The same conflict result is used by the mutation pipeline, so an overlap introduced by create, move, resize, or edit is rejected before local events are committed.

## Where to start

1. Choose the view. Use `week` for a shift-style calendar, or `resourceTimeline` when each resource needs a row.
2. Define the visible range with `weekStartDate`, `dateRange`, `visibleDays`, `slotMinutes`, and `timeRange`.
3. Provide `eventSchedulerResources` when events need to be placed against staff, rooms, equipment, teams, or other capacity.
4. Provide `eventSchedulerEvents` with ISO datetime strings and stable ids.
5. Add `calendars` for recurring working rules and `eventSchedulerAvailability` for dated working windows, breaks, holidays, or blocked time.
6. Enable editing only when the host app handles emitted changes. Start with `editable: false` for read-only schedules, then turn on `allowCreate`, `allowMove`, `allowResize`, and `allowDelete` as your persistence flow is ready.
7. Add conflict rules, templates, remote data, custom labels, or renderers after the basic schedule renders.

## Handling edits

The scheduler emits a cancelable before-change event before it commits local event changes. This follows the RevoGrid event pattern: call `preventDefault()` on the before event to cancel the mutation.

```ts
grid.addEventListener('event-scheduler-before-event-change', (event) => {
  if (event.detail.event?.locked) {
    event.preventDefault();
  }
});
```

`event-scheduler-event-created`, `event-scheduler-event-changed`, and `event-scheduler-event-deleted` fire after the mutation succeeds. Use them for persistence and state sync, not cancellation. In local-state examples, update `eventSchedulerEvents` from the emitted `detail.events` array:

```ts
const syncEvents = (event: Event) => {
  grid.eventSchedulerEvents = [
    ...(event as CustomEvent<{ events: readonly EventSchedulerEventEntity[] }>).detail.events,
  ];
};

grid.addEventListener('event-scheduler-event-created', syncEvents);
grid.addEventListener('event-scheduler-event-changed', syncEvents);
grid.addEventListener('event-scheduler-event-deleted', syncEvents);
```

If your toolbar owns the current range or active view, also handle navigation and view requests:

```ts
grid.addEventListener('event-scheduler-navigate-request', (event) => {
  const { action } = (event as CustomEvent<{ action: 'previous' | 'next' | 'today' }>).detail;
  // Update weekStartDate/dateRange in grid.eventScheduler here.
});

grid.addEventListener('event-scheduler-view-request', (event) => {
  const { view } = (event as CustomEvent<{ view: EventSchedulerConfig['view'] }>).detail;
  // Update grid.eventScheduler.view here.
});
```

For remote products, use the same ownership model: the scheduler can optimistically emit changes, but your app or `remote` hooks decide when backend mutations are committed, rejected, or rolled back.

## Next guides

- [Vertical vs Horizontal Time](./vertical-vs-horizontal/) helps choose between calendar-style and resource-timeline scheduling.
- [Timeline Views](../timeline-views/) explains day, week, month, and resource timeline configuration.
- [Week View](../week-view/) is a practical recipe for shift-style vertical week calendars.
- [Editing and Interaction](../event-editing/) covers create, move, resize, delete, editors, selection, clipboard, keyboard shortcuts, permissions, and validation.
- [Conflicts](../scheduling-rules/conflicts/) covers overlap, availability, locked-change, duration, capacity, prevention events, and assignment checks.
- [Event Scheduler Calendars](../scheduling-rules/calendars/) covers working days, holidays, and resource-specific operating hours.
- [Scheduling Rules](../scheduling-rules/) explains how calendars, availability, visual non-working time, and conflict policies work together.
- [Remote Data](../remote-data/) covers loading ranges, optimistic mutations, rollback, and load-more flows.
- [Customization](../customization/) groups labels, event rendering, layout/cells, slots/hours, conflicts/states, context menus, styling, interaction, and editor hooks.
- [Examples](../examples/) collects small product-neutral examples for setup, event templates, day headers, slots, current-time markers, context menus, availability, read-only mode, cancelable selection state, and custom themes.

Start with the Event Staff Scheduler demo for the full business story, or the Employee Shift Planner demo for a focused week-view shift workflow.
