import { CSSProperties } from 'react'; import { EventFields, EventModel, SchedulerGroup, SchedulerResource, TimeScaleProps } from '../types/scheduler-types'; import { ProcessedEventsData, CellData } from '../types/internal-interface'; import { ResourceGroupingMetadata, ResourceLevel, TimelineResourceRowMeta } from './ResourceGroupingService'; export declare const ALL_DAY_EVENT_HEIGHT: number; export declare const EVENTS_GAP: number; export declare const ROW_HEIGHT: number; export declare const DEFAULT_TIMELINE_EVENT_HEIGHT: number; export declare const DEFAULT_SCROLLBAR_HEIGHT: number; export declare const HEADER_ROW_HEIGHT: number; export declare const SLOT_ROW_HEIGHT: number; export declare const BASE_COLUMN_WIDTH: number; export declare const EVENT_GAP: number; export declare const BLOCKINDICATOR_WIDTH: number; /** @private */ export declare class EventService { /** * Filters events that fall within the given render dates range * * @param {EventModel[]} events - The events to filter * @param {Date[]} renderDates - The dates being rendered * @returns {EventModel[]} - Filtered events that intersect with render dates */ static filterEventsByDateRange(events: EventModel[], renderDates: Date[]): EventModel[]; /** * Finds a non-conflicting position for an event * * @param {Date[]} renderDates - The dates being rendered * @param {Date} startDate - The start date of the event * @param {Date} endDate - The end date of the event * @param {boolean} includeEndMidnight - Indicates to include event mid night end event. * @param {Map} occupiedPositions - Map of occupied positions * @returns {number} A non-conflicting position index */ static findNonConflictingPosition(renderDates: Date[], startDate: Date, endDate: Date, includeEndMidnight: boolean, occupiedPositions: Map): number; /** * Maps raw event data to EventModel objects based on field mappings * * @param {Record[]} events - Raw event data to process * @param {Record} [fields] - Field mapping configuration * @returns {EventModel[]} Array of EventModel objects with mapped properties */ static mapEventData(events: Record[], fields?: EventFields): EventModel[]; /** * Sorts events by start time and duration * * @param {ProcessedEventsData[]} events - Array of events to sort * @returns {ProcessedEventsData[]} Sorted array of events */ static sortEventsByStartTimeAndDuration(events: ProcessedEventsData[]): ProcessedEventsData[]; static calculateOverlappingEvents(events: ProcessedEventsData[]): ProcessedEventsData[][]; static identifyOverlapGroups(sortedEvents: ProcessedEventsData[]): ProcessedEventsData[][]; static convertOverlapGroupsToEventGroups(overlapGroups: ProcessedEventsData[][]): ProcessedEventsData[][]; /** * Prioritizes events based on all-day status, duration, and start time * * @param {ProcessedEventsData[]} events - Array of events * @returns {ProcessedEventsData[]} Sorted array of events */ static prioritizeEvents(events: ProcessedEventsData[]): ProcessedEventsData[]; static resolveOverlappingEvents(events: ProcessedEventsData[]): ProcessedEventsData[][]; /** * Groups events by each render date they span. * * @param {EventModel[]} events - Events to group. * @param {Date[]} renderDates - Render dates to check against. * @param {boolean} [excludeBlockEvents=true] - Whether to exclude block events. * @returns {Map} Events grouped by date key. */ static groupEventsByRenderDates(events: EventModel[], renderDates: Date[], excludeBlockEvents?: boolean): Map; /** * Filters out overlapping events, keeping only the highest priority event from each overlapping group. * Events are grouped by date first, then overlap resolution is applied within each date. * * @param {EventModel[]} events - Array of events to filter * @param {Date[]} renderDates - Array of render dates for date-based grouping * @returns {EventModel[]} - Filtered array containing only non-overlapping events (highest priority from each group within same date) * @private */ static filterNonOverlappingEvents(events: EventModel[], renderDates: Date[]): EventModel[]; /** * Checks if two events overlap in time * * @param {ProcessedEventsData} event1 - First event * @param {ProcessedEventsData} event2 - Second event * @returns {boolean} True if events overlap */ static eventsOverlap(event1: ProcessedEventsData, event2: ProcessedEventsData): boolean; /** * Checks if an event overlaps with any other events in the collection * * @param {EventModel} event - Event to check * @param {EventModel[]} allEvents - All events in the scheduler * @returns {boolean} True if event overlaps with any other event */ static checkEventOverlap(event: EventModel, allEvents: EventModel[]): boolean; /** * Checks if an event overlaps with any blocked events * * @param {EventModel | EventModel[]} eventData - Event(s) to check * @param {EventModel[]} allEvents - All events in the scheduler * @returns {boolean} True if event overlaps with a blocked event */ static isBlockRange(eventData: EventModel | EventModel[], allEvents?: EventModel[]): boolean; /** * Splits a multi-day event into daily segments * * @param {EventModel} event - The event to split * @param {Date[]} renderDates - The dates being rendered * @returns {ProcessedEventsData[]} Array of event segments */ static splitEventByDay(event: EventModel, renderDates: Date[]): ProcessedEventsData[]; /** * Processes events specifically for Agenda View to calculate segments. * Matches EJ2 AgendaBase.processAgendaEvents logic. * When `resourceLeaf` is provided (compact view active resource), events are * scoped to that leaf before segmentation, so per-date filtering downstream * is unnecessary. * * @param {EventModel[]} events - Events to process * @param {Date[]} dates - Current view dates * @param {SchedulerResource[]} [resources] - Resource configurations (field mappings) * @param {ResourceLevel} [resourceLeaf] - Active leaf (compact view) to scope events to * @returns {Map} Processed events grouped by date key */ static processAgendaEvents(events: EventModel[], dates: Date[], resources?: SchedulerResource[], resourceLeaf?: ResourceLevel): Map; /** * Checks if any date has more events than the allowed maximum * * @param {Date[]} renderDates - The dates being rendered * @param {Map} eventsByDate - Map of events by date * @param {number} maxEventsStack - Maximum events allowed per row. * @returns {boolean} True if any date has more events than allowed */ static isAlldayHasMoreEvents(renderDates: Date[], eventsByDate: Map, maxEventsStack?: number): boolean; /** * Checks if an event spans multiple days * * @param {EventModel} event - The event to check * @returns {boolean} True if the event spans multiple days */ static isMultiDayEvent(event: EventModel): boolean; /** * Gets accessibility label for an event * * @param {EventModel} event - The event * @returns {string} Accessibility label text */ static getAriaLabel(event: EventModel): string; /** * Generates a unique ID for an event * * @returns {string} A unique ID string */ static generateEventGuid(): string; static getEventClassNames(event: EventModel): string[]; static getEventsMap(renderDates: Date[], events: ProcessedEventsData[]): Map; /** * Gets the maximum number of events in any cell * * @param {Map} eventsByDate - Map of events by date * @param {Date[]} [renderDates] - Optional array of dates to consider * @returns {number} The maximum number of events in any cell */ static getMaxEventsInCell(eventsByDate: Map, renderDates?: Date[]): number; static processDayEvents(renderDates: Date[], eventsData: EventModel[], resources?: SchedulerResource[], groupingConfig?: SchedulerGroup, groupIndex?: number): ProcessedEventsData[]; private static getAbsoluteColumnIndex; /** * Calculates pixel position and size for a cloned month event using DOM measurements. * * @param {HTMLDivElement} schedulerRef - Reference to the Scheduler instance. * @param {ProcessedEventsData} eventInfo - Event metadata including rowIndex/columnIndex and dates. * @param {number} cellWidth - Width of a single date cell in pixels. * @param {boolean} isAllDaySource - Indicates all day row events. * @param {boolean} isRtl - Defines its RTL. * @param {boolean} isMonthView - Define current view is month view or not. * @param {HTMLElement} currentCell - Contains current target. * @param {ResourceGroupingMetadata} groupingConfig - Grouping configuration for resource grouping. * @returns {CSSProperties} Inline style object containing top, left, and width (in pixels). */ static cloneEventPosition(schedulerRef: HTMLDivElement, eventInfo: ProcessedEventsData, cellWidth: number, isAllDaySource: boolean, isRtl: boolean, isMonthView: boolean, currentCell?: HTMLElement, groupingConfig?: ResourceGroupingMetadata): CSSProperties; static splitEventByWeek(rowDates: Date[][], event: EventModel): ProcessedEventsData[]; private static applyResourceColorToSegment; static processCloneEvent(schedulerRef: HTMLDivElement, renderDates: Date[], event: EventModel, showWeekend: boolean, workDays: number[], cellWidth: number, isAllDaySource: boolean, isRtl: boolean, isMonthView: boolean, currentCell?: HTMLElement, resources?: SchedulerResource[], groupIndex?: number, groupingConfig?: ResourceGroupingMetadata, resourceColorField?: string): ProcessedEventsData[]; static processTimeSlotCloneEvent(schedulerRef: HTMLDivElement, renderDates: Date[], event: EventModel, timeScale: TimeScaleProps, startHour: string, endHour: string, cellWidth: number, isRtl?: boolean, cellHeight?: number, resources?: SchedulerResource[], groupIndex?: number, groupingConfig?: ResourceGroupingMetadata, resourceColorField?: string): ProcessedEventsData[]; /** * Returns an event from the given collection that matches the provided guid. * * @param {EventModel[]} events - Collection of events to search * @param {string} guid - The guid to match * @returns {EventModel | undefined} The matched event, if any */ static getEventByGuid(events: EventModel[], guid: string): EventModel | undefined; /** * Converts event times from UTC to display timezone for calendar rendering. * For events with timezone metadata, their startTime/endTime are converted * from UTC to the assigned timezone. All-day events bypass conversion. * * Priority order: * 1. Event-level timezone (startTimezone/endTimezone) - converted if present * 2. Scheduler-level timezone - used as fallback for events without event-level timezone * 3. No conversion if neither is present * * @param {EventModel[]} events - Events to convert for display * @param {string} [schedulerTimezone] - Optional scheduler-level timezone to apply to all events without event-level timezone * @param {boolean} [isReverse] - perform reverse conversion (remove timezone offsets / convert back to scheduler/UTC) * @returns {EventModel[]} Events with timezone-converted times for display */ static processTimeZone(events: EventModel[], schedulerTimezone?: string, isReverse?: boolean): EventModel[]; /** * Converts a single event time from scheduler timezone to event timezone (or vice versa) * Returns the original time if any parameter is missing. * * @param {Date} time - The date/time to convert * @param {string} tz - The source timezone (typically scheduler timezone) * @param {string} eventTz - The target event timezone * @returns {Date} Converted date or original/undefined */ static convertEventTime(time: Date, tz?: string, eventTz?: string): Date; /** * Gets the resource color for an event based on the resource configuration. * If the event doesn't have a resource field value, returns the first resource's color as default. * * @param {EventModel} event - The event to get the color for * @param {SchedulerResource[]} resources - Array of resource configurations * @param {string} [resourceColorField] - Optional name of the resource level to use for coloring * @param {(string | number)[]} [groupOrder] - Optional array representing the current resource group context * @returns {string | undefined} The color value from the resource, or undefined if no resources or no color field */ static getResourceColor(event: EventModel, resources?: SchedulerResource[], resourceColorField?: string, groupOrder?: (string | number)[]): string | undefined; /** * Finds a resource data item that matches the given resource field value. * * @param {SchedulerResource} resource - The resource configuration * @param {unknown} fieldValue - The value to match against the resource's idField * @returns {Record} The matching resource data item */ private static findResourceData; /** * Gets the color from the first resource data item (default resource). * * @param {SchedulerResource} resource - The resource configuration * @returns {string} The color value from the first resource */ private static getDefaultResourceColor; /** * Splits a single event into multiple events when it has resources configured with multiple: true. * Each split event gets a unique ID and GUID. Used during save operation to ensure proper event creation. * * @param {EventModel} event - The event to split * @param {SchedulerResource[]} resources - The resource configurations * @param {EventModel[]} [eventsData] - Optional array of existing events for ID generation * @param {boolean} groupEdit - Indicates whether group editing is enabled. * @returns {EventModel[]} Array of events, one per resource ID, each with unique ID and GUID */ static splitEventForMultipleResources(event: EventModel, resources?: SchedulerResource[], eventsData?: EventModel[], groupEdit?: boolean): EventModel[]; /** * Checks if an event matches a specific resource leaf (for resource grouping). * Validates that the event's resource field values align with the leaf resource's groupOrder chain. * * @param {EventModel} event - The event to check * @param {CellData} resourceLeaf - The leaf-level resource object with groupOrder and resourceData properties * @param {SchedulerResource[]} resources - Array of resource configurations (defines field mappings) * @returns {boolean} True if event belongs to this resource leaf * * @private */ static matchesResource(event: EventModel, resourceLeaf: CellData | ResourceLevel | TimelineResourceRowMeta, resources?: SchedulerResource[]): boolean; /** * Get smallest missing number from array (EJ2 algorithm). * Used for calculating event stack positions without gaps. * * @param {number[]} array - Array of occupied position indices * @returns {number} Smallest non-negative integer not in array * @private */ static getSmallestMissingNumber(array: number[]): number; /** * Calculates the content height for the timeline view based on the available scheduler height, * the calculated timeline height, and the horizontal scrollbar height (if present). * * When the scrollable container overflows horizontally, the default scrollbar height is * subtracted from the available scheduler height so the content fits within the viewport. * * @param {number} schedulerHeight - Available height within the scheduler container (excluding header). * @param {number} calculatedTimelineHeight - Height computed from event rows / max events stack. * @param {HTMLElement | null} scrollElement - The scrollable container element to inspect for horizontal overflow. * @param {number} defaultScrollbarHeight - The default scrollbar height to subtract when horizontal overflow is present. * @returns {number} The content height to apply to the timeline content section. */ static calculateTimelineContentHeight(schedulerHeight: number, calculatedTimelineHeight: number, scrollElement: HTMLElement | null, defaultScrollbarHeight: number): number; /** * Resolve event identity keys used by timeline positioning maps. * * @param {EventModel} event - Event to derive keys from * @returns {Object} Event identity keys * @private */ static getEventIdentityKeys(event: EventModel): { eventID: string; isAllDay: boolean; eventKey: string; }; static createEventStyle(positionPx: number, widthPx: number, topPx: number, isRtl: boolean, totalWidthPx?: number): CSSProperties; }