Getting Started
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
Section titled “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
Section titled “Minimal TypeScript setup”If the grid already exists in your app, set the same properties directly:
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
Section titled “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
Section titled “Core concepts”eventsare the scheduled blocks. Each event needs anid,startDateTime, andendDateTime. Addtitle,resourceId,resourceIds, orassignmentIdswhen the event needs a label or belongs to a person, room, machine, team, or other capacity.resourcesare the schedulable rows in resource planning. A resource can be a person, room, vehicle, machine, location, team, department, or parent group.viewsdecide how time is shown. Useday,week, ormonthfor calendar-style time grids, andresourceTimelinewhen each resource needs its own row across a visible date or time range.projectionis 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
eventSchedulerEventswith the next event array, and persists changes to local state or a backend.
Data ownership
Section titled “Data ownership”Use the scheduler props as the public data boundary:
- Events: Every event needs
id,startDateTime, andendDateTime.title,resourceId,resourceIds,status, andtypeare 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, andmetadatafeed 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
resourceIdandresourceIdsduring projection. - Availability: Use dated
working,blocked,holiday, andbreakwindows 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
Section titled “Main props”eventScheduler: MainEventSchedulerConfig. 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 directresourceIdfields.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.sourceandcolumns: 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
Section titled “Basic setup”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
Section titled “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:
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
Section titled “Where to start”- Choose the view. Use
weekfor a shift-style calendar, orresourceTimelinewhen each resource needs a row. - Define the visible range with
weekStartDate,dateRange,visibleDays,slotMinutes, andtimeRange. - Provide
eventSchedulerResourceswhen events need to be placed against staff, rooms, equipment, teams, or other capacity. - Provide
eventSchedulerEventswith ISO datetime strings and stable ids. - Add
calendarsfor recurring working rules andeventSchedulerAvailabilityfor dated working windows, breaks, holidays, or blocked time. - Enable editing only when the host app handles emitted changes. Start with
editable: falsefor read-only schedules, then turn onallowCreate,allowMove,allowResize, andallowDeleteas your persistence flow is ready. - Add conflict rules, templates, remote data, custom labels, or renderers after the basic schedule renders.
Handling edits
Section titled “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.
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:
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:
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
Section titled “Next guides”- Vertical vs Horizontal Time helps choose between calendar-style and resource-timeline scheduling.
- Timeline Views explains day, week, month, and resource timeline configuration.
- Week View is a practical recipe for shift-style vertical week calendars.
- Editing and Interaction covers create, move, resize, delete, editors, selection, clipboard, keyboard shortcuts, permissions, and validation.
- Conflicts covers overlap, availability, locked-change, duration, capacity, prevention events, and assignment checks.
- Event Scheduler Calendars covers working days, holidays, and resource-specific operating hours.
- Scheduling Rules explains how calendars, availability, visual non-working time, and conflict policies work together.
- Remote Data covers loading ranges, optimistic mutations, rollback, and load-more flows.
- Customization groups labels, event rendering, layout/cells, slots/hours, conflicts/states, context menus, styling, interaction, and editor hooks.
- 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.