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.

123 lines (122 loc) 4.48 kB
/**----------------------------------------------------------------------------------------- * Copyright © 2025 Progress Software Corporation. All rights reserved. * Licensed under commercial license. See LICENSE.md in the project root for more information *-------------------------------------------------------------------------------------------*/ import { isPresent, isRecurring, isException, readEvent, getField, setField, assignValues, clone } from '../common/util'; import { isDevMode } from '@angular/core'; import { guid } from '@progress/kendo-angular-common'; const isRecurrenceMaster = (ev) => !!(ev.id && ev.recurrenceRule); /** * @hidden */ export class LocalEditService { scheduler; localDataChangesService; get fields() { return this.scheduler.modelFields; } get hasLocalData() { return isPresent(this.localDataChangesService.data); } get data() { if (this.hasLocalData) { return this.localDataChangesService.data; } return this.scheduler.events; } constructor(scheduler, localDataChangesService) { this.scheduler = scheduler; this.localDataChangesService = localDataChangesService; } create(item) { const idField = this.fields.id; const id = getField(item, idField); if (!isPresent(id)) { setField(item, idField, this.nextId()); } this.data.push(item); this.dataChanged(); } createException(item, value) { const exception = this.buildException(value); this.removeOccurrenceInternal(item); this.create(exception); } update(item, value) { assignValues(item, value); this.dataChanged(); } remove(item) { const idField = this.fields.id; const itemId = getField(item, idField); const data = this.data; for (let idx = 0; idx < data.length; idx++) { if (itemId === getField(data[idx], idField)) { data.splice(idx, 1); break; } } this.dataChanged(); } removeSeries(item) { const event = readEvent(item, this.fields); const isHead = isRecurrenceMaster(event); this.removeItemAndExceptions(isHead ? event.id : event.recurrenceId); this.dataChanged(); } removeOccurrence(item) { this.removeOccurrenceInternal(item); this.dataChanged(); } findRecurrenceMaster(item) { const fields = this.scheduler.modelFields; const event = readEvent(item, fields); const headId = isRecurrenceMaster(event) ? event.id : event.recurrenceId; return this.data.find((dataItem) => getField(dataItem, fields.id) === headId); } isRecurring(event) { return isRecurring(event, this.scheduler.modelFields); } isException(event) { return isException(event, this.scheduler.modelFields); } nextId() { return guid(); } buildException(item) { const fields = this.fields; const head = this.findRecurrenceMaster(item); if (!head) { if (isDevMode()) { throw new Error('Unable to find recurrence head for event. Please check that recurrenceId is set and refers to an existing event.'); } return; } const exception = clone(item); setField(exception, fields.id, this.nextId()); setField(exception, fields.recurrenceId, getField(head, fields.id)); setField(exception, fields.recurrenceRule, null); return exception; } removeItemAndExceptions(itemId) { const data = this.data; const fields = this.scheduler.modelFields; for (let idx = data.length - 1; idx >= 0; idx--) { if (itemId === getField(data[idx], fields.recurrenceId) || itemId === getField(data[idx], fields.id)) { data.splice(idx, 1); } } } removeOccurrenceInternal(item) { const fields = this.fields; const head = this.findRecurrenceMaster(item); const exceptionDate = getField(item, fields.start); const currentExceptions = getField(head, fields.recurrenceExceptions) || []; setField(head, fields.recurrenceExceptions, [...currentExceptions, exceptionDate]); } dataChanged() { if (this.hasLocalData) { this.localDataChangesService.changes.emit(); } } }