Calendar Component in CargoXplorer TMS
Introduction
The Calendar Component is a powerful and flexible element in CargoXplorer TMS used for displaying and managing calendar-based data. Built on top of FullCalendar.io, it provides comprehensive calendar functionality including event management, date selection, multiple view types, and interactive features essential for logistics and transportation management systems.
YAML Structure
component: calendar
props:
  calendarId: "{{ number calendarId }}"
  initialView: "dayGridMonth"
  height: 600
  options:
    headerToolbar:
      left: "prev,next today"
      center: "title"
      right: "dayGridMonth,timeGridWeek,timeGridDay"
    selectable: true
    editable: true
  events:
    onDateClick:
      - notification:
          message: "Date clicked: {{ event.dateStr }}"
    onEventClick:
      - navigate:
          to: "/orders/{{ event.event.extendedProps.orderId }}"
    onSelect:
      - setVariables:
          selectedStart: "{{ event.startStr }}"
          selectedEnd: "{{ event.endStr }}"
Attribute Description
- component: (string) Must be set to "calendar" to use this component type.
- props: (object) Contains the configuration properties for the calendar component.- calendarId: (number) Required - Unique integer identifier for the calendar instance. The system automatically loads all events associated with this calendar ID from the backend.
- initialView: (string) The initial view to display. Options include:- dayGridMonth- Month view with day grid (default)
- timeGridWeek- Week view with time slots
- timeGridDay- Day view with time slots
- listWeek- List view for the week
- listMonth- List view for the month
- multiMonthYear- Multi-month year view
 
- height: (number|string) Calendar height in pixels or "auto"
- aspectRatio: (number) Width-to-height ratio (default: 1.35)
- options: (object) FullCalendar configuration options- headerToolbar: (object) Toolbar configuration- left: (string) Left toolbar buttons
- center: (string) Center toolbar content
- right: (string) Right toolbar buttons
 
- footerToolbar: (object) Footer toolbar configuration
- selectable: (boolean) Allow date/time selection
- selectMirror: (boolean) Show selection preview
- editable: (boolean) Allow event editing
- droppable: (boolean) Allow dropping external elements
- weekends: (boolean) Display weekends (default: true)
- locale: (string) Language/locale setting
- timeZone: (string) Time zone setting
- nowIndicator: (boolean) Show current time indicator
- slotMinTime: (string) Earliest time slot (e.g., "06:00:00")
- slotMaxTime: (string) Latest time slot (e.g., "22:00:00")
- slotDuration: (string) Duration of each time slot (e.g., "00:30:00")
- eventDisplay: (string) How events are displayed ("auto", "block", "list-item")
- dayMaxEvents: (number|boolean) Maximum events per day before "+more" link
- moreLinkClick: (string) Action when clicking "+more" link
- events: (array) Static event data (optional - events are typically loaded via calendarId)
- eventSources: (array) Multiple event sources configuration using GraphQL queries (optional)
 
 
- events: (object) Event handlers for calendar interactions using Component Actions- onDateClick: (array) Actions to execute when a date/time is clicked
- onEventClick: (array) Actions to execute when an event is clicked
- onSelect: (array) Actions to execute when a date/time range is selected
- onUnselect: (array) Actions to execute when selection is cleared
- onEventDrop: (array) Actions to execute when an event is dragged/dropped
- onEventResize: (array) Actions to execute when an event is resized
- onEventChange: (array) Actions to execute when an event is modified
- onDatesSet: (array) Actions to execute when view/date range changes
- onLoading: (array) Actions to execute when loading state changes
 
Examples
Basic Calendar
component: calendar
props:
  calendarId: 1001
  initialView: "dayGridMonth"
  height: 500
Calendar with Static Events
component: calendar
props:
  calendarId: 1003
  initialView: "dayGridMonth"
  height: 500
  options:
    events:
      - id: "shipment-001"
        title: "Pickup - ABC Corp"
        start: "2024-01-15T09:00:00"
        end: "2024-01-15T10:00:00"
        color: "#ff6b6b"
        extendedProps:
          type: "pickup"
          orderId: "ORD-12345"
          customer: "ABC Corporation"
          location: "123 Main St, New York"
          driver: "John Smith"
      - id: "shipment-002"
        title: "Delivery - XYZ Ltd"
        start: "2024-01-15T14:00:00"
        end: "2024-01-15T15:30:00"
        color: "#4ecdc4"
        extendedProps:
          type: "delivery"
          orderId: "ORD-12346"
          customer: "XYZ Limited"
          location: "456 Oak Ave, Boston"
          driver: "Jane Doe"
      - id: "maintenance-001"
        title: "Truck Maintenance"
        start: "2024-01-16T08:00:00"
        end: "2024-01-16T12:00:00"
        color: "#ffa726"
        allDay: false
        extendedProps:
          type: "maintenance"
          vehicleId: "TRUCK-001"
          serviceType: "Regular Service"
          location: "Main Garage"
  events:
    onEventClick:
      - setActionsVariables:
          eventId: "{{ event.event.id }}"
          eventType: "{{ event.event.extendedProps.type }}"
      - if: "{{ eval eventType === 'pickup' || eventType === 'delivery' }}"
        then:
          - navigate:
              to: "/orders/{{ event.event.extendedProps.orderId }}"
        else:
          - navigate:
              to: "/maintenance/{{ event.event.extendedProps.vehicleId }}"
Calendar with Multiple Event Sources
component: calendar
props:
  calendarId: 1002
  initialView: "dayGridMonth"
  height: 600
  options:
    eventSources:
      - query:
          command: "query GetShipmentEvents($organizationId: ID!, $start: String!, $end: String!) { shipmentEvents(organizationId: $organizationId, start: $start, end: $end) { id title start end color extendedProps } }"
          variables:
            organizationId: "{{ organizationId }}"
            start: "{{ currentViewStart }}"
            end: "{{ currentViewEnd }}"
        color: "#3788d8"
        textColor: "white"
      - query:
          command: "query GetWarehouseEvents($warehouseId: ID!, $start: String!, $end: String!) { warehouseEvents(warehouseId: $warehouseId, start: $start, end: $end) { id title start end color extendedProps } }"
          variables:
            warehouseId: "{{ warehouseId }}"
            start: "{{ currentViewStart }}"
            end: "{{ currentViewEnd }}"
        color: "#ffa726"
        textColor: "white"
      - events: "{{ maintenance.schedule }}"
        color: "#e53e3e"
        textColor: "white"
      - events:
          - title: "Weekly Team Meeting"
            start: "2024-01-15T10:00:00"
            end: "2024-01-15T11:00:00"
            color: "#9c27b0"
            rrule: "FREQ=WEEKLY;BYDAY=MO"
            extendedProps:
              type: "meeting"
              location: "Conference Room A"
  events:
    onEventClick:
      - setActionsVariables:
          eventType: "{{ event.event.extendedProps.type }}"
          eventId: "{{ event.event.id }}"
      - navigate:
          to: "/events/{{ eventType }}/{{ eventId }}"
Advanced Shipment Calendar
component: calendar
props:
  calendarId: 1004
  initialView: "timeGridWeek"
  height: 600
  options:
    headerToolbar:
      left: "prev,next today"
      center: "title"
      right: "dayGridMonth,timeGridWeek,timeGridDay,listWeek"
    selectable: true
    selectMirror: true
    editable: true
    droppable: true
    weekends: true
    slotMinTime: "06:00:00"
    slotMaxTime: "22:00:00"
    slotDuration: "00:30:00"
    nowIndicator: true
    dayMaxEvents: 3
    moreLinkClick: "popover"
    locale: "en-US"
    timeZone: "America/New_York"
  events:
    onDateClick:
      - consoleLog:
          message: "Date clicked: {{ event.dateStr }}"
      - setVariables:
          selectedDate: "{{ event.dateStr }}"
    onEventClick:
      - setActionsVariables:
          orderId: "{{ event.event.extendedProps.orderId }}"
      - navigate:
          to: "/shipments/{{ orderId }}"
    onSelect:
      - setVariables:
          selectedStart: "{{ event.startStr }}"
          selectedEnd: "{{ event.endStr }}"
      - dialog:
          name: "createShipmentDialog"
          props:
            title: "Create New Shipment"
            startDate: "{{ selectedStart }}"
            endDate: "{{ selectedEnd }}"
    onEventDrop:
      - mutation:
          command: "mutation UpdateShipmentSchedule($id: ID!, $start: String!, $end: String!) { updateShipmentSchedule(id: $id, start: $start, end: $end) { id start end } }"
          variables:
            id: "{{ event.event.extendedProps.orderId }}"
            start: "{{ event.event.startStr }}"
            end: "{{ event.event.endStr }}"
          onSuccess:
            - notification:
                message: "Shipment schedule updated successfully"
          onError:
            - notification:
                message: "Failed to update shipment schedule"
                variant: "error"
    onEventResize:
      - mutation:
          command: "mutation UpdateShipmentDuration($id: ID!, $end: String!) { updateShipmentDuration(id: $id, end: $end) { id end } }"
          variables:
            id: "{{ event.event.extendedProps.orderId }}"
            end: "{{ event.event.endStr }}"
          onSuccess:
            - notification:
                message: "Shipment duration updated"
          onError:
            - notification:
                message: "Failed to update duration"
                variant: "error"
Delivery Schedule Calendar
component: calendar
props:
  calendarId: 1005
  initialView: "listWeek"
  height: "auto"
  options:
    headerToolbar:
      left: "prev,next"
      center: "title"
      right: "listWeek,listMonth"
  events:
    onEventClick:
      - setActionsVariables:
          orderId: "{{ event.event.extendedProps.orderId }}"
          eventType: "{{ event.event.extendedProps.type }}"
      - navigate:
          to: "/orders/{{ orderId }}"
    onDateClick:
      - setVariables:
          selectedDate: "{{ event.dateStr }}"
      - query:
          command: "query GetDeliveriesForDate($date: String!) { deliveriesForDate(date: $date) { id title customer status } }"
          variables:
            date: "{{ selectedDate }}"
          onSuccess:
            - setStore:
                dailyDeliveries: "{{ result.deliveriesForDate }}"
            - dialog:
                name: "dailyDeliveriesDialog"
                props:
                  title: "Deliveries for {{ selectedDate }}"
                  deliveries: "{{ dailyDeliveries }}"
Operations Calendar with Loading States
component: calendar
props:
  calendarId: 1006
  initialView: "dayGridMonth"
  height: 650
  options:
    headerToolbar:
      left: "prev,next today"
      center: "title"
      right: "dayGridMonth,timeGridWeek"
  events:
    onEventClick:
      - setActionsVariables:
          eventId: "{{ event.event.id }}"
          eventType: "{{ event.event.extendedProps.type }}"
      - if: "{{ eval eventType === 'shipment' }}"
        then:
          - navigate:
              to: "/shipments/{{ eventId }}"
        else:
          - if: "{{ eval eventType === 'warehouse' }}"
            then:
              - navigate:
                  to: "/warehouse/activities/{{ eventId }}"
            else:
              - navigate:
                  to: "/maintenance/{{ eventId }}"
    onLoading:
      - if: "{{ event.isLoading }}"
        then:
          - setVariables:
              calendarLoading: true
          - notification:
              message: "Loading calendar events..."
        else:
          - setVariables:
              calendarLoading: false
    onDatesSet:
      - setVariables:
          currentViewStart: "{{ event.startStr }}"
          currentViewEnd: "{{ event.endStr }}"
          currentView: "{{ event.view.type }}"
      - consoleLog:
          message: "Calendar view changed to {{ currentView }} ({{ currentViewStart }} - {{ currentViewEnd }})"
Resource-Based Vehicle Calendar
component: calendar
props:
  calendarId: 1007
  initialView: "resourceTimeGridDay"
  height: 700
  options:
    headerToolbar:
      left: "prev,next today"
      center: "title"
      right: "resourceTimeGridDay,resourceTimeGridWeek"
    resources:
      - id: "truck-01"
        title: "Truck 01 (ABC-123)"
        eventColor: "#3788d8"
      - id: "truck-02"
        title: "Truck 02 (DEF-456)"
        eventColor: "#ffa726"
      - id: "truck-03"
        title: "Truck 03 (GHI-789)"
        eventColor: "#4caf50"
    editable: true
    selectable: true
  events:
    onEventDrop:
      - setActionsVariables:
          assignmentId: "{{ event.event.id }}"
          newResourceId: "{{ event.newResource.id }}"
          newStart: "{{ event.event.startStr }}"
          newEnd: "{{ event.event.endStr }}"
      - mutation:
          command: "mutation UpdateVehicleAssignment($id: ID!, $vehicleId: String!, $start: String!, $end: String!) { updateVehicleAssignment(id: $id, vehicleId: $vehicleId, start: $start, end: $end) { id vehicleId start end } }"
          variables:
            id: "{{ assignmentId }}"
            vehicleId: "{{ newResourceId }}"
            start: "{{ newStart }}"
            end: "{{ newEnd }}"
          onSuccess:
            - notification:
                message: "Vehicle assignment updated successfully"
          onError:
            - notification:
                message: "Failed to update vehicle assignment"
                variant: "error"
            - refresh: "calendar"
    onSelect:
      - setActionsVariables:
          resourceId: "{{ event.resource.id }}"
          selectedStart: "{{ event.startStr }}"
          selectedEnd: "{{ event.endStr }}"
      - dialog:
          name: "createVehicleAssignmentDialog"
          props:
            title: "Create Vehicle Assignment"
            vehicleId: "{{ resourceId }}"
            startTime: "{{ selectedStart }}"
            endTime: "{{ selectedEnd }}"
          onClose:
            - if: "{{ result.success }}"
              then:
                - refresh: "calendar"
                - notification:
                    message: "New vehicle assignment created"
    onEventClick:
      - setActionsVariables:
          assignmentId: "{{ event.event.id }}"
      - navigate:
          to: "/vehicle-assignments/{{ assignmentId }}"
Advanced Usage
Custom Event Rendering
Basic Custom Event Layout
component: calendar
props:
  calendarId: 2001
  options:
    eventContent:
      component: layout
      props:
        type: "div"
        options:
          className: "custom-event"
        children:
          - component: text
            props:
              type: "strong"
              value: "{{ event.title }}"
          - component: text
            props:
              type: "div"
              value: "{{ event.extendedProps.customer || '' }}"
              options:
                className: "event-details"
Advanced Shipment Event Rendering
component: calendar
props:
  calendarId: 2002
  options:
    eventContent:
      component: layout
      props:
        type: "div"
        options:
          className: "shipment-event {{ event.extendedProps.status }}"
        children:
          - component: layout
            props:
              type: "div"
              options:
                className: "event-header"
              children:
                - component: badge
                  props:
                    text: "{{ event.extendedProps.type }}"
                    variant: "{{ eval event.extendedProps.type === 'pickup' ? 'warning' : 'success' }}"
                - component: text
                  props:
                    type: "span"
                    value: "{{ event.title }}"
                    options:
                      className: "event-title"
          - component: layout
            props:
              type: "div"
              options:
                className: "event-body"
              children:
                - component: text
                  props:
                    type: "div"
                    value: "📍 {{ event.extendedProps.location }}"
                    options:
                      className: "event-location"
                - component: text
                  props:
                    type: "div"
                    value: "🏢 {{ event.extendedProps.customer }}"
                    options:
                      className: "event-customer"
                - component: text
                  props:
                    type: "div"
                    value: "📦 {{ event.extendedProps.commodities }} items"
                    options:
                      className: "event-commodities"
Resource-Based Event Rendering
component: calendar
props:
  calendarId: 2003
  options:
    eventContent:
      component: layout
      props:
        type: "div"
        options:
          className: "vehicle-assignment-event"
        children:
          - component: layout
            props:
              type: "div"
              options:
                className: "assignment-header"
              children:
                - component: text
                  props:
                    type: "strong"
                    value: "{{ event.title }}"
                - component: badge
                  props:
                    text: "{{ event.extendedProps.priority }}"
                    variant: "{{ eval event.extendedProps.priority === 'high' ? 'danger' : event.extendedProps.priority === 'medium' ? 'warning' : 'info' }}"
          - component: layout
            props:
              type: "div"
              options:
                className: "assignment-details"
              children:
                - component: text
                  props:
                    type: "div"
                    value: "🚛 {{ event.extendedProps.vehicleType }}"
                - component: text
                  props:
                    type: "div"
                    value: "👤 {{ event.extendedProps.driverName }}"
                - component: text
                  props:
                    type: "div"
                    value: "📍 {{ event.extendedProps.route }}"
Conditional Event Rendering
component: calendar
props:
  calendarId: 2004
  options:
    eventContent:
      component: layout
      props:
        type: "div"
        options:
          className: "status-event {{ event.extendedProps.status }}"
        children:
          - component: text
            props:
              type: "div"
              value: "{{ event.title }}"
              options:
                className: "event-title"
          - component: layout
            if: "{{ eval event.extendedProps.status === 'delayed' }}"
            props:
              type: "div"
              options:
                className: "delay-warning"
              children:
                - component: text
                  props:
                    type: "span"
                    value: "⚠️ Delayed"
                    options:
                      className: "delay-text"
                - component: text
                  props:
                    type: "div"
                    value: "New ETA: {{ event.extendedProps.newEta }}"
          - component: layout
            if: "{{ eval event.extendedProps.status === 'completed' }}"
            props:
              type: "div"
              options:
                className: "completion-info"
              children:
                - component: text
                  props:
                    type: "span"
                    value: "✅ Completed"
                    options:
                      className: "completion-text"
### Dynamic Options Based on User Role
```yaml
component: calendar
props:
  calendarId: 2005
  options:
    editable: "{{ eval user.role === 'manager' }}"
    selectable: "{{ eval user.permissions.includes('schedule_create') }}"
Custom Rendering Benefits
Using component definitions for custom event rendering provides several advantages:
- Consistency: Maintains the same YAML-based component structure used throughout CargoXplorer
- Reusability: Custom rendering components can be reused across different calendars
- Maintainability: Easier to update and maintain without JavaScript knowledge
- Security: Avoids potential XSS vulnerabilities from raw HTML injection
- Type Safety: Leverages the existing component validation system
- Localization: Automatic support for multi-language text content
- Conditional Rendering: Built-in support for conditional display logic
Additional Custom Rendering Hooks
Custom Day Header Rendering
component: calendar
props:
  calendarId: 3001
  options:
    dayHeaderContent:
      component: layout
      props:
        type: "div"
        options:
          className: "custom-day-header"
        children:
          - component: text
            props:
              type: "div"
              value: "{{ date.format('ddd') }}"
              options:
                className: "day-name"
          - component: text
            props:
              type: "div"
              value: "{{ date.format('DD') }}"
              options:
                className: "day-number"
          - component: badge
            if: "{{ eval date.format('E') === '1' }}"
            props:
              text: "Week Start"
              variant: "info"
              size: "sm"
Custom Day Cell Rendering
component: calendar
props:
  calendarId: 3002
  options:
    dayCellContent:
      component: layout
      props:
        type: "div"
        options:
          className: "custom-day-cell {{ eval date.format('E') === '6' || date.format('E') === '7' ? 'weekend' : 'weekday' }}"
        children:
          - component: text
            props:
              type: "div"
              value: "{{ date.format('D') }}"
              options:
                className: "day-number"
          - component: layout
            if: "{{ eval date.isSame(moment(), 'day') }}"
            props:
              type: "div"
              options:
                className: "today-indicator"
              children:
                - component: text
                  props:
                    type: "span"
                    value: "Today"
                    options:
                      className: "today-text"
Custom "More" Link Rendering
component: calendar
props:
  calendarId: 3003
  options:
    moreLinkContent:
      component: button
      props:
        text: "+ {{ num }} more events"
        variant: "link"
        size: "sm"
        options:
          className: "more-events-link"
Standard Events and Handlers
Event Handler Parameters
All event handlers receive detailed information about the calendar interaction:
- onDateClick: { date, dateStr, allDay, dayEl, jsEvent, view }
- onEventClick: { event, el, jsEvent, view }
- onSelect: { start, end, startStr, endStr, allDay, jsEvent, view }
- onEventDrop: { event, delta, revert, jsEvent, view }
- onEventResize: { event, startDelta, endDelta, revert, jsEvent, view }
Common Event Handler Examples
# Date Click Handler - Log and set variables
onDateClick:
  - consoleLog:
      message: "Date clicked: {{ event.dateStr }}"
  - setVariables:
      selectedDate: "{{ event.dateStr }}"
      selectedAllDay: "{{ event.allDay }}"
# Event Click Handler - Navigate to order details
onEventClick:
  - setActionsVariables:
      orderId: "{{ event.event.extendedProps.orderId }}"
  - navigate:
      to: "/orders/{{ orderId }}"
# Date Selection Handler - Open creation modal
onSelect:
  - setVariables:
      newEventStart: "{{ event.startStr }}"
      newEventEnd: "{{ event.endStr }}"
      isAllDay: "{{ event.allDay }}"
  - dialog:
      name: "createEventModal"
      props:
        title: "Create New Event"
        startDate: "{{ newEventStart }}"
        endDate: "{{ newEventEnd }}"
        allDay: "{{ isAllDay }}"
# Event Drop Handler - Update schedule in database
onEventDrop:
  - setActionsVariables:
      orderId: "{{ event.event.extendedProps.orderId }}"
      newStart: "{{ event.event.startStr }}"
      newEnd: "{{ event.event.endStr }}"
  - mutation:
      command: "mutation UpdateOrderSchedule($id: ID!, $start: String!, $end: String!) { updateOrderSchedule(id: $id, scheduledStart: $start, scheduledEnd: $end) { id scheduledStart scheduledEnd } }"
      variables:
        id: "{{ orderId }}"
        start: "{{ newStart }}"
        end: "{{ newEnd }}"
      onSuccess:
        - notification:
            message: "Schedule updated successfully"
        - refresh: "calendar"
      onError:
        - notification:
            message: "Failed to update schedule"
            variant: "error"
        - refresh: "calendar"
# Loading State Handler - Show/hide loading indicator
onLoading:
  - if: "{{ event.isLoading }}"
    then:
      - setVariables:
          isCalendarLoading: true
    else:
      - setVariables:
          isCalendarLoading: false
Best Practices
- 
Performance Optimization: - Use lazyFetching: truefor large datasets
- Implement server-side pagination for events
- Set appropriate dayMaxEventsto avoid overcrowding
 
- Use 
- 
User Experience: - Provide clear visual feedback for different event types using colors
- Use meaningful event titles and descriptions
- Implement proper loading states
 
- 
Data Management: - Use calendarIdconsistently across related components
- Implement proper error handling for event sources
- Cache frequently accessed calendar data
 
- Use 
- 
Accessibility: - Ensure keyboard navigation works properly
- Provide alt text for custom event content
- Use sufficient color contrast for events
 
- 
Mobile Responsiveness: - Test calendar behavior on mobile devices
- Consider using different views for mobile (e.g., listWeek)
- Ensure touch interactions work properly
 
- 
Localization: - Set appropriate localeandtimeZonebased on user preferences
- Localize button text and date formats
- Consider different calendar systems for international users
 
- Set appropriate 
Integration with CargoXplorer TMS
Event Loading Strategies
The calendar component supports multiple approaches for loading events:
1. Automatic Loading via CalendarId (Recommended)
Events are automatically loaded from the backend using the calendarId parameter:
component: calendar
props:
  calendarId: 5001
  # Events are automatically fetched based on calendar ID
Benefits:
- Centralized Management: Events managed in the backend calendar system
- Real-time Updates: Automatic synchronization with backend changes
- Filtering: Server-side filtering based on view and date range
- Caching: Optimal performance through intelligent caching
- Business Hours: Automatically loaded from calendar configuration
2. Static Event Configuration
Define events directly in the component configuration:
component: calendar
props:
  calendarId: 5002
  options:
    events:
      - title: "Meeting"
        start: "2024-01-15T10:00:00"
        # ... event properties
Use Cases:
- Development/Testing: Quick prototyping and testing
- Static Schedules: Fixed recurring events that don't change
- Demo Purposes: Sample data for demonstrations
3. Multiple Event Sources with Queries
Combine events from various sources using GraphQL queries (see Variables for query syntax):
component: calendar
props:
  calendarId: 5003
  options:
    eventSources:
      - query: # Shipment events query
          command: "query GetShipmentEvents($organizationId: ID!, $start: String!, $end: String!) { shipmentEvents(organizationId: $organizationId, start: $start, end: $end) { id title start end color extendedProps } }"
          variables:
            organizationId: "{{ organizationId }}"
            start: "{{ currentViewStart }}"
            end: "{{ currentViewEnd }}"
        color: "#3788d8"
        textColor: "white"
      - query: # Warehouse events query
          command: "query GetWarehouseEvents($warehouseId: ID!, $dateRange: DateRangeInput!) { warehouseEvents(warehouseId: $warehouseId, dateRange: $dateRange) { id title start end extendedProps } }"
          variables:
            warehouseId: "{{ number warehouseId }}"
            dateRange:
              start: "{{ currentViewStart }}"
              end: "{{ currentViewEnd }}"
        color: "#ffa726"
        textColor: "white"
      - events: "{{ staticEvents }}" # Variable data
        color: "#e53e3e"
      - events: [] # Inline events
Query Features:
- Variable Interpolation: Use {{ variable }}syntax from Variables documentation
- Type Casting: Use {{ number value }}for integer parameters
- Date Formatting: Use {{ format date 'YYYY-MM-DD' }}for date parameters
- Dynamic Variables: Calendar automatically provides currentViewStartandcurrentViewEnd
Use Cases:
- Data Integration: Combining data from multiple GraphQL endpoints
- Mixed Sources: Query data + static events + variable data
- Conditional Loading: Different queries based on user permissions or selections
- Real-time Data: GraphQL subscriptions for live event updates
4. Dynamic Event Loading
Load events from variables or computed data:
component: calendar
props:
  calendarId: 5004
  options:
    events: "{{ userSchedule.events }}"
    # or
    eventSources:
      - events: "{{ eval filterEventsByRole(allEvents, user.role) }}"
        color: "#3788d8"
      - events: "{{ personalTasks }}"
        color: "#ffa726"
Use Cases:
- Role-based Filtering: Different events based on user permissions
- Computed Events: Events calculated from other data
- Variable Data: Events stored in application variables
- Conditional Loading: Events based on user selections or filters
Event Persistence and Updates
CalendarId-based Events (Backend Managed)
- Persistence: Events are stored in the backend calendar system
- Updates: Changes via drag/drop, resize, or actions are automatically saved
- Real-time: Multiple users see updates immediately
- Validation: Server-side validation and business rules apply
Static/Manual Events (Component Managed)
- Persistence: Events exist only in the component configuration
- Updates: Changes are local to the current session
- Refresh: Events reset to original configuration on page reload
- Use Case: Temporary events, demos, or read-only displays
Hybrid Approach
component: calendar
props:
  calendarId: 6001 # Loads persistent events
  options:
    eventSources:
      - events: "{{ temporaryEvents }}" # Session-based events
        editable: false # Read-only overlay events
        color: "#cccccc"
        display: "background" # Background events
Automatic Data Loading
The calendar component automatically loads all calendar-related data from the backend using the calendarId parameter. The system handles:
- Event Fetching: Events are automatically retrieved based on the calendar ID
- Business Hours: Business hours are loaded from the calendar configuration
- Calendar Settings: Time zones, working days, and display preferences are loaded automatically
- Real-time Updates: Changes to calendar events and settings are reflected in real-time
- Filtering: Events are filtered based on the current view and date range
- Caching: Frequently accessed calendar data is cached for optimal performance
Calendar ID Guidelines
Important: Calendar IDs must always be integers in CargoXplorer TMS:
# Correct - Integer calendar IDs
calendarId: 1001                    # Direct integer
calendarId: "{{ number calendarId }}" # Variable with type casting
# Incorrect - String calendar IDs
calendarId: "shipment-calendar"     # ❌ String not allowed
calendarId: "{{ calendarId }}"      # ❌ Without number casting
Recommended ID Patterns:
- 1000-1999: Organization-level calendars
- 2000-2999: Department-specific calendars
- 3000-3999: User-specific calendars
- 4000-4999: Vehicle/equipment calendars
- 5000+: Custom application calendars
Event Object Structure
All calendar events follow a standardized structure regardless of loading method:
# Basic Event Structure
- id: "unique-event-id" # Unique identifier
  title: "Event Title" # Display title
  start: "2024-01-15T09:00:00" # Start date/time (ISO format)
  end: "2024-01-15T10:00:00" # End date/time (optional)
  allDay: false # All-day event flag
  color: "#ff6b6b" # Event background color
  textColor: "#ffffff" # Text color
  borderColor: "#ff6b6b" # Border color
  classNames: ["custom-class"] # CSS classes
  display: "auto" # Display mode: auto, block, list-item, background
  # Extended Properties (TMS-specific data)
  extendedProps:
    type: "pickup" # Event type
    orderId: "ORD-12345" # Related order ID
    customer: "ABC Corporation" # Customer name
    location: "123 Main St, New York" # Location
    driver: "John Smith" # Assigned driver
    vehicleId: "TRUCK-001" # Vehicle identifier
    status: "scheduled" # Current status
    priority: "high" # Priority level
    commodities: 5 # Number of items
    weight: "2500kg" # Total weight
    notes: "Special handling required" # Additional notes
  # Recurring Events (optional)
  rrule: "FREQ=WEEKLY;BYDAY=MO" # Recurrence rule
  duration: "01:00:00" # Duration for recurring events
Event Types for TMS Operations
- Pickups: Origin collection events
- Color: #ff6b6b(Red variants)
- Extended props: orderId,customer,pickupLocation,driver
 
- Color: 
- Deliveries: Destination delivery events
- Color: #4ecdc4(Teal variants)
- Extended props: orderId,customer,deliveryLocation,driver
 
- Color: 
- Transit: In-transit milestones
- Color: #3788d8(Blue variants)
- Extended props: orderId,checkpoint,vehicleId,eta
 
- Color: 
- Warehouse: Storage and handling operations
- Color: #ffa726(Orange variants)
- Extended props: warehouseId,operation,commodities,zone
 
- Color: 
- Maintenance: Vehicle and equipment servicing
- Color: #e53e3e(Dark red variants)
- Extended props: vehicleId,serviceType,mechanicId,location
 
- Color: 
- Customs: Clearance and inspection events
- Color: #9c27b0(Purple variants)
- Extended props: orderId,customsOffice,documentType,inspector
 
- Color: