UNPKG

@progress/kendo-angular-scheduler

Version:

Kendo UI Scheduler Angular - Outlook or Google-style angular scheduler calendar. Full-featured and customizable embedded scheduling from the creator developers trust for professional UI components.

163 lines (162 loc) 6.37 kB
/**----------------------------------------------------------------------------------------- * Copyright © 2025 Progress Software Corporation. All rights reserved. * Licensed under commercial license. See LICENSE.md in the project root for more information *-------------------------------------------------------------------------------------------*/ import { ChangeDetectorRef, Directive, Input } from '@angular/core'; import { OCCURRENCE_ID } from './common/constants'; import { SchedulerComponent } from './scheduler.component'; import { parseRule, expand } from '@progress/kendo-recurrence'; import { toUTCDateTime } from './views/utils'; import { ZonedDate } from '@progress/kendo-date-math'; import { LocalDataChangesService } from './editing/local-data-changes.service'; import { clone, setField, getField } from './common/util'; import { IntlService } from '@progress/kendo-angular-intl'; import * as i0 from "@angular/core"; import * as i1 from "./scheduler.component"; import * as i2 from "@progress/kendo-angular-intl"; import * as i3 from "./editing/local-data-changes.service"; // TODO // Extract as public method const occurrences = (item, fields, range, timezone, weekStart) => { const rrule = parseRule({ recurrenceRule: getField(item, fields.recurrenceRule), weekStart: weekStart }); if (!rrule.start) { const start = getField(item, fields.start); rrule.start = ZonedDate.fromLocalDate(start, timezone); } if (!rrule.end) { const end = getField(item, fields.end); rrule.end = ZonedDate.fromLocalDate(end, timezone); } const exceptions = getField(item, fields.recurrenceExceptions); if (exceptions) { rrule.exceptionDates = exceptions .map(exDate => ZonedDate.fromLocalDate(exDate, timezone)); // TODO: Merge exceptions from recurrence rule with event.recurrenceException } const utcRangeStart = toUTCDateTime(range.start); const utcRangeEnd = toUTCDateTime(range.end); const series = expand(rrule, { rangeStart: ZonedDate.fromUTCDate(utcRangeStart, timezone), rangeEnd: ZonedDate.fromUTCDate(utcRangeEnd, timezone) }); if (!series.events.length) { return []; } const expanded = series.events.map(occ => { const event = clone(item); setField(event, fields.id, OCCURRENCE_ID); setField(event, fields.recurrenceId, getField(item, fields.id)); setField(event, fields.start, occ.start.toLocalDate()); setField(event, fields.end, occ.end.toLocalDate()); return event; }); return [item, ...expanded]; }; /** * A directive that processes Scheduler events in memory ([see example](slug:databinding_scheduler#automatic-data-processing)). * * Processing includes expanding of recurring events and filtering data for * the currently active period. * * @example * ```html * <kendo-scheduler [kendoSchedulerBinding]="data"> * </kendo-scheduler> * ``` * * @remarks * Applied to: {@link SchedulerComponent} */ export class DataBindingDirective { scheduler; changeDetector; intl; localDataChangesService; /** * Sets the data array for the Scheduler. */ set data(value) { this.originalData = value || []; if (this.localDataChangesService) { this.localDataChangesService.data = value; } this.scheduler.events = this.process(); } dateRange; originalData = []; subscription; dataChangedSubscription; constructor(scheduler, changeDetector, intl, localDataChangesService) { this.scheduler = scheduler; this.changeDetector = changeDetector; this.intl = intl; this.localDataChangesService = localDataChangesService; if (localDataChangesService) { this.dataChangedSubscription = this.localDataChangesService.changes.subscribe(this.rebind.bind(this)); } } /** * @hidden */ ngOnInit() { this.subscription = this.scheduler .dateChange .subscribe(e => this.onDateChange(e)); } /** * @hidden */ ngOnDestroy() { if (this.subscription) { this.subscription.unsubscribe(); } if (this.dataChangedSubscription) { this.dataChangedSubscription.unsubscribe(); } } /** * @hidden */ rebind() { this.data = this.originalData; this.changeDetector.markForCheck(); } process() { if (!this.dateRange) { // No processing until a date range is set return []; } const data = []; const fields = this.scheduler.modelFields; this.originalData .forEach(item => { if (getField(item, fields.recurrenceRule)) { const series = occurrences(item, fields, this.dateRange, this.scheduler.timezone, this.scheduler.weekStart); data.push(...series); } else { data.push(item); } }); return data; } onDateChange(e) { this.dateRange = e.dateRange; this.rebind(); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataBindingDirective, deps: [{ token: i1.SchedulerComponent }, { token: i0.ChangeDetectorRef }, { token: i2.IntlService }, { token: i3.LocalDataChangesService }], target: i0.ɵɵFactoryTarget.Directive }); static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: DataBindingDirective, isStandalone: true, selector: "[kendoSchedulerBinding]", inputs: { data: ["kendoSchedulerBinding", "data"] }, ngImport: i0 }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataBindingDirective, decorators: [{ type: Directive, args: [{ selector: '[kendoSchedulerBinding]', standalone: true }] }], ctorParameters: function () { return [{ type: i1.SchedulerComponent }, { type: i0.ChangeDetectorRef }, { type: i2.IntlService }, { type: i3.LocalDataChangesService }]; }, propDecorators: { data: [{ type: Input, args: ['kendoSchedulerBinding'] }] } });