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 slotstimeGridDay
- Day view with time slotslistWeek
- List view for the weeklistMonth
- List view for the monthmultiMonthYear
- 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 optionsheaderToolbar
: (object) Toolbar configurationleft
: (string) Left toolbar buttonscenter
: (string) Center toolbar contentright
: (string) Right toolbar buttons
footerToolbar
: (object) Footer toolbar configurationselectable
: (boolean) Allow date/time selectionselectMirror
: (boolean) Show selection previeweditable
: (boolean) Allow event editingdroppable
: (boolean) Allow dropping external elementsweekends
: (boolean) Display weekends (default: true)locale
: (string) Language/locale settingtimeZone
: (string) Time zone settingnowIndicator
: (boolean) Show current time indicatorslotMinTime
: (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" linkmoreLinkClick
: (string) Action when clicking "+more" linkevents
: (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 ActionsonDateClick
: (array) Actions to execute when a date/time is clickedonEventClick
: (array) Actions to execute when an event is clickedonSelect
: (array) Actions to execute when a date/time range is selectedonUnselect
: (array) Actions to execute when selection is clearedonEventDrop
: (array) Actions to execute when an event is dragged/droppedonEventResize
: (array) Actions to execute when an event is resizedonEventChange
: (array) Actions to execute when an event is modifiedonDatesSet
: (array) Actions to execute when view/date range changesonLoading
: (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: true
for large datasets - Implement server-side pagination for events
- Set appropriate
dayMaxEvents
to 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
calendarId
consistently 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
locale
andtimeZone
based 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
currentViewStart
andcurrentViewEnd
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: