Skip to content

Latest commit

 

History

History
551 lines (448 loc) · 13.1 KB

File metadata and controls

551 lines (448 loc) · 13.1 KB
title Plugin Calendar

import { InteractiveDemo } from '@/app/components/InteractiveDemo'; import { PluginLoader } from '@/app/components/PluginLoader';

Calendar view components for ObjectUI - includes both ObjectQL-integrated and standalone calendar components.

Installation

npm install @object-ui/plugin-calendar

<PluginLoader plugins={['calendar']}>

Overview

The @object-ui/plugin-calendar plugin provides two calendar components:

  1. ObjectCalendar (object-calendar): For ObjectQL data sources - displays database records as calendar events
  2. CalendarView (calendar-view): Standalone calendar component for displaying pre-loaded event data

Both components support month, week, and day views with full event management capabilities.

Drag-and-Drop Rescheduling

Month view

  • Move an event — grab any cell of the event pill and drop it on another day. The grabbed-day → drop-day distance is the day delta applied to both startDateField and endDateField, so dragging a multi-day span from any of its days behaves intuitively.
  • Resize an event — grab the small right-edge handle on the last day of a multi-day pill and drop it on a different day to extend or shrink the end date. The start date is preserved; drops earlier than the start are ignored.

Week / Day view (time grid)

Week and day views render a classic Google Calendar-style vertical time grid. All gestures use pointer events and snap to slotMinutes (default 30):

  • Move an event — drag the event body vertically to change its start time (and end, by the same delta). In week view, drag horizontally to also change the day.
  • Resize start — drag the top edge of an event to adjust only the start time. Refuses to cross the existing end.
  • Resize end — drag the bottom edge to adjust only the end time. Refuses to cross the existing start.
  • Drag-to-create — click-drag on an empty area of the time grid to open the quick-create dialog with start/end pre-filled to the dragged time range.

Pass slotMinutes={15} to change the snap granularity, or onTimeRangeSelect={(start, end) => …} to override the drag-to-create default.

When ObjectCalendar is bound to an object (i.e. it has objectName and a dataSource), the new dates are persisted automatically via dataSource.update() — local state is updated optimistically and rolled back on failure. To intercept (e.g. for a confirm dialog) pass an onEventDrop prop; supplying your own handler disables the default persistence.

<ObjectCalendar
  schema={{ type: 'object-calendar', objectName: 'campaign' }}
  // optional — omit to get default backend persistence
  onEventDrop={(record, newStart, newEnd) => {
    if (confirm(`Move ${record.name}?`)) save({ id: record.id, start_date: newStart, end_date: newEnd });
  }}
/>

Click-to-Create

Clicking the empty area of any day cell (month view) or click-dragging in the week/day time grid opens a quick-create dialog pre-filled with the selected date/range. Type a title and press Enter (or click Create) to persist a new record via dataSource.create(objectName, payload). The new record is inserted optimistically into the calendar so it appears immediately.

The payload includes the configured titleField, startDateField, optional endDateField (set to the clicked day), plus auto-defaults for any other required fields not provided by the user (first picklist option for select/status, false for booleans, 0 for numerics, or the field's declared defaultValue). This ensures the create succeeds against NOT NULL columns without forcing the user through the full form.

To override (e.g. open your own multi-field create form), pass onDateClick:

<ObjectCalendar
  schema={{ type: 'object-calendar', objectName: 'campaign' }}
  onDateClick={(day) => navigate(`/campaign/new?start=${day.toISOString()}`)}
/>

CalendarView Component

Full-featured standalone calendar with month, week, and day views for displaying events and scheduling.

Interactive Examples

Month View

Week View

CalendarView Usage

import '@object-ui/plugin-calendar'

const schema = {
  type: 'calendar-view',
  view: 'month',
  data: [
    {
      id: 1,
      title: 'Team Meeting',
      start: '2024-01-15T10:00:00',
      end: '2024-01-15T11:00:00',
      color: '#3b82f6'
    }
  ]
}

CalendarView Schema API

{
  type: 'calendar-view',
  view?: 'month' | 'week' | 'day',
  data?: Array<CalendarEventData>,
  titleField?: string,
  startDateField?: string,
  endDateField?: string,
  allDayField?: string,
  colorField?: string,
  colorMapping?: Record<string, string>,
  currentDate?: string,
  allowCreate?: boolean,
  onEventClick?: (event: any) => void,
  onDateClick?: (date: Date) => void,
  onViewChange?: (view: string) => void,
  onNavigate?: (date: Date) => void,
  className?: string
}

ObjectCalendar Component

Calendar component designed for use with ObjectQL data sources.

ObjectCalendar Component

Calendar component designed for use with ObjectQL data sources.

Features

  • ObjectQL Integration: Works seamlessly with object/api/value data providers
  • Automatic Field Mapping: Maps database fields to calendar events
  • Multiple View Modes: Month, week, and day calendar views
  • Date Filtering: Automatically filters records by date range
  • Event Interaction: Click handling for events and dates
  • Color Coding: Support for event color customization

ObjectCalendar Usage

Basic Usage with ObjectQL

import '@object-ui/plugin-calendar'

const schema = {
  type: 'object-calendar',
  objectName: 'events',  // Your ObjectQL object
  calendar: {
    startDateField: 'startDate',
    endDateField: 'endDate',
    titleField: 'title',
    colorField: 'category'
  }
}

With Static Data

const schema = {
  type: 'object-calendar',
  staticData: [
    {
      id: 1,
      title: 'Team Meeting',
      startDate: '2024-01-15T10:00:00',
      endDate: '2024-01-15T11:00:00',
      category: 'meeting'
    },
    {
      id: 2,
      title: 'Project Deadline',
      startDate: '2024-01-20',
      category: 'deadline'
    }
  ],
  calendar: {
    startDateField: 'startDate',
    endDateField: 'endDate',
    titleField: 'title',
    colorField: 'category'
  }
}

Schema API

{
  type: 'object-calendar',
  objectName?: string,              // ObjectQL object name
  staticData?: Array<any>,          // Static data array
  data?: ViewData,                  // Advanced data configuration
  calendar?: CalendarConfig,        // Calendar-specific configuration
  onEventClick?: (record: any) => void,
  onDateClick?: (date: Date) => void,
  className?: string
}

CalendarConfig

{
  startDateField: string,     // Field containing event start date
  endDateField?: string,      // Field containing event end date
  titleField: string,         // Field to use as event title
  colorField?: string,        // Field for color coding
  descriptionField?: string   // Field for event description
}

Configuration

Field Mapping

Map your database fields to calendar properties:

{
  type: 'object-calendar',
  objectName: 'tasks',
  calendar: {
    titleField: 'taskName',      // Database field for title
    startDateField: 'dueDate',   // Database field for start
    endDateField: 'completedAt', // Database field for end
    colorField: 'priority'       // Database field for color
  }
}

Data Providers

Object Provider (Database)

{
  type: 'object-calendar',
  objectName: 'appointments',
  calendar: {
    startDateField: 'scheduledAt',
    titleField: 'subject'
  }
}

Value Provider (Static)

{
  type: 'object-calendar',
  staticData: [
    { id: 1, title: 'Event 1', date: '2024-01-15' },
    { id: 2, title: 'Event 2', date: '2024-01-20' }
  ],
  calendar: {
    startDateField: 'date',
    titleField: 'title'
  }
}

API Provider

{
  type: 'object-calendar',
  data: {
    provider: 'api',
    endpoint: '/api/events',
    method: 'GET'
  },
  calendar: {
    startDateField: 'startTime',
    endDateField: 'endTime',
    titleField: 'eventName'
  }
}

Comparison: CalendarView vs ObjectCalendar

Feature CalendarView ObjectCalendar
Schema Type calendar-view object-calendar
Data Source Static arrays ObjectQL (database)
Use Case Pre-loaded event data Dynamic data from backend
Field Mapping Standard field names Configurable field names
Data Loading Manual via props Automatic via ObjectQL
Best For Static schedules Database-driven apps

When to use CalendarView:

  • You have static or pre-loaded event data
  • You're not using ObjectQL
  • You need a simple, standalone calendar

When to use ObjectCalendar:

  • You're using ObjectQL for data management
  • Events come from a database or API
  • You need automatic data fetching and filtering

Event Handling

Event Click

{
  type: 'object-calendar',
  objectName: 'events',
  calendar: {
    startDateField: 'start',
    titleField: 'title'
  },
  onEventClick: (record) => {
    console.log('Event clicked:', record);
    // Open event details
    // Navigate to event page
  }
}

Date Click

{
  type: 'object-calendar',
  objectName: 'events',
  calendar: {
    startDateField: 'start',
    titleField: 'title'
  },
  onDateClick: (date) => {
    console.log('Date clicked:', date);
    // Create new event on this date
  }
}

Examples

Appointment Scheduler

const appointmentCalendar = {
  type: 'object-calendar',
  objectName: 'appointments',
  calendar: {
    startDateField: 'appointmentDate',
    endDateField: 'appointmentEnd',
    titleField: 'patientName',
    descriptionField: 'notes',
    colorField: 'appointmentType'
  },
  onEventClick: (appointment) => {
    // Show appointment details
  }
}

Event Management

const eventCalendar = {
  type: 'object-calendar',
  objectName: 'events',
  calendar: {
    startDateField: 'eventStart',
    endDateField: 'eventEnd',
    titleField: 'eventTitle',
    colorField: 'eventCategory'
  },
  onEventClick: (event) => {
    // Navigate to event details
  },
  onDateClick: (date) => {
    // Create new event
  }
}

Task Deadlines

const taskCalendar = {
  type: 'object-calendar',
  objectName: 'tasks',
  calendar: {
    startDateField: 'dueDate',
    titleField: 'taskTitle',
    colorField: 'priority'
  },
  onEventClick: (task) => {
    // Open task details
  }
}

Direct Component Usage

You can also import and use the components directly in React:

import { CalendarView, ObjectCalendar } from '@object-ui/plugin-calendar';

// CalendarView - Standalone calendar
function MyCalendar() {
  const events = [
    {
      id: 1,
      title: 'Meeting',
      start: new Date('2024-01-15T10:00:00'),
      end: new Date('2024-01-15T11:00:00'),
      color: '#3b82f6'
    }
  ];

  return (
    <CalendarView
      events={events}
      view="month"
      onEventClick={(event) => console.log(event)}
    />
  );
}

// ObjectCalendar - ObjectQL-integrated
function MyObjectCalendar({ dataSource }) {
  const schema = {
    objectName: 'events',
    calendar: {
      startDateField: 'startDate',
      titleField: 'title'
    }
  };

  return (
    <ObjectCalendar
      schema={schema}
      dataSource={dataSource}
      onEventClick={(record) => console.log(record)}
    />
  );
}

TypeScript Support

import type { 
  CalendarViewSchema, 
  CalendarEvent,
  ObjectGridSchema,
  CalendarConfig 
} from '@object-ui/types'

// CalendarView types
const events: CalendarEvent[] = [
  {
    id: 1,
    title: 'Meeting',
    start: new Date('2024-01-15T10:00:00'),
    end: new Date('2024-01-15T11:00:00'),
    color: '#3b82f6'
  }
]

const calendarViewSchema: CalendarViewSchema = {
  type: 'calendar-view',
  view: 'month',
  data: events
}

// ObjectCalendar types
const calendarConfig: CalendarConfig = {
  startDateField: 'startDate',
  endDateField: 'endDate',
  titleField: 'title',
  colorField: 'category'
}

const objectCalendarSchema: ObjectGridSchema = {
  type: 'object-calendar',
  objectName: 'events',
  calendar: calendarConfig
}

Migration from @object-ui/plugin-calendar-view

The @object-ui/plugin-calendar-view package has been merged into this package. If you were using it:

Before

npm install @object-ui/plugin-calendar-view
import '@object-ui/plugin-calendar-view'
import { CalendarView } from '@object-ui/plugin-calendar-view'

After

npm install @object-ui/plugin-calendar
import '@object-ui/plugin-calendar'
import { CalendarView } from '@object-ui/plugin-calendar'

All functionality remains the same - just update your imports and package dependencies.

Related Documentation