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.

472 lines (459 loc) 22.2 kB
/**----------------------------------------------------------------------------------------- * Copyright © 2025 Progress Software Corporation. All rights reserved. * Licensed under commercial license. See LICENSE.md in the project root for more information *-------------------------------------------------------------------------------------------*/ import { Component, ViewChildren, QueryList, Input } from '@angular/core'; import { RecurrenceService } from './recurrence.service'; import { isPresent } from '../../common/util'; import { dayRule, weekdayRule, weekendRule } from './recurrence.service'; import { RepeatOnRadioButtonDirective } from './repeat-on-radio-button.directive'; import { LocalizationService } from '@progress/kendo-angular-l10n'; import { NumericTextBoxComponent, NumericTextBoxCustomMessagesComponent } from '@progress/kendo-angular-inputs'; import { DropDownListComponent } from '@progress/kendo-angular-dropdowns'; import { NgIf } from '@angular/common'; import { LabelComponent, LabelDirective } from '@progress/kendo-angular-label'; import * as i0 from "@angular/core"; import * as i1 from "./recurrence.service"; import * as i2 from "@progress/kendo-angular-l10n"; /** * @hidden */ export class RecurrenceMonthlyYearlyEditorComponent { recurrence; localization; set userNumericOptions(options) { this.numericOptions = { ...this.numericOptions, ...options }; } repeatOnRadioButtons; extendedWeekDays; offsetPositions; months; currentMonthDay; currentMonthMonthDay; currentMonthWeekDay; currentOffset; currentWeekDay; uniqueId; numericOptions = { min: 1, max: 31, format: '#', autoCorrect: true, step: 1, spinners: true }; subs; constructor(recurrence, localization) { this.recurrence = recurrence; this.localization = localization; this.uniqueId = this.recurrence.getUniqueId(); this.setInitialValues(); this.subscribeEventHandlers(); } setInitialValues() { this.extendedWeekDays = this.recurrence.extendedWeekDays; this.offsetPositions = this.recurrence.offsetPositions; this.currentOffset = this.defaultOffset; this.currentWeekDay = this.defaultWeekDay; if (this.currentFreq === 'yearly') { this.months = this.recurrence.months; this.currentMonthMonthDay = this.currentMonthWeekDay = this.recurrence.rrule.byMonth[0]; } } subscribeEventHandlers() { this.subs = this.recurrence.repeatOnRuleChange.subscribe(this.onRepeatOnRuleChange.bind(this)); this.subs.add(this.recurrence.frequencyChange.subscribe(this.onFrequencyChange.bind(this))); } onRepeatOnRuleChange(newRepeatOnRule) { if (newRepeatOnRule === 'monthday') { this.recurrence.rrule.byMonthDay = [this.monthDay]; if (this.currentFreq === 'yearly') { this.recurrence.rrule.byMonth = [this.currentMonthMonthDay]; } } else if (newRepeatOnRule === 'weekday') { if (typeof this.weekDay === 'string') { /* day, weekday or weekend */ this.recurrence.rrule.bySetPosition = [this.offset]; this.recurrence.rrule.byWeekDay = this.weekDayRuleFromString(this.weekDay); } else { /* specific weekday */ this.recurrence.rrule.byWeekDay = [{ day: this.weekDay, offset: this.offset }]; } if (this.currentFreq === 'yearly') { this.recurrence.rrule.byMonth = [this.currentMonthWeekDay]; } } } onFrequencyChange() { this.setInitialValues(); } ngOnDestroy() { if (this.subs) { this.subs.unsubscribe(); } } get monthDay() { const rrule = this.recurrence.rrule; if (isPresent(rrule.byMonthDay) && rrule.byMonthDay.length > 0) { return rrule.byMonthDay[0]; } else if (isPresent(this.currentMonthDay)) { return this.currentMonthDay; } else { return this.recurrence.start.getDate(); } } get weekDay() { const rrule = this.recurrence.rrule; if (isPresent(rrule.byWeekDay)) { const weekDaysCount = rrule.byWeekDay.length; switch (weekDaysCount) { case 7: return 'day'; case 5: return 'weekday'; case 2: return 'weekend'; case 1: return rrule.byWeekDay[0].day; default: break; } } else if (isPresent(this.currentWeekDay)) { return this.currentWeekDay; } return this.defaultWeekDay; } get offset() { const rrule = this.recurrence.rrule; if (isPresent(rrule.byWeekDay)) { const weekDaysCount = rrule.byWeekDay.length; switch (weekDaysCount) { case 7: case 5: case 2: return rrule.bySetPosition[0]; case 1: return rrule.byWeekDay[0].offset; default: break; } } else if (isPresent(this.currentOffset)) { return this.currentOffset; } return this.defaultOffset; } onMonthChange(month, repeatOnRule) { if (repeatOnRule === 'monthday') { this.currentMonthMonthDay = month; } else { this.currentMonthWeekDay = month; } this.recurrence.setMonths([month]); } onMonthDayChange(monthDay) { this.currentMonthDay = monthDay; this.recurrence.monthDays = [monthDay]; } onOffsetPositionChange(offset) { const rrule = this.recurrence.rrule; if (isPresent(rrule.byWeekDay)) { const weekDaysCount = rrule.byWeekDay.length; switch (weekDaysCount) { case 7: case 5: case 2: this.recurrence.positions = [offset]; break; case 1: rrule.byWeekDay[0].offset = offset; this.recurrence.onChange(); break; default: break; } } this.currentOffset = offset; } onWeekDayChange(weekDay) { let weekDays; if (typeof weekDay === 'string') { /* day, weekday or weekend */ weekDays = this.weekDayRuleFromString(weekDay); this.recurrence.positions = [this.offset]; } else { /* specific weekday */ this.recurrence.rrule.bySetPosition = null; this.recurrence.rrule.byWeekDay = null; weekDays = [{ day: weekDay, offset: this.offset }]; } this.currentWeekDay = weekDay; this.recurrence.setWeekDays(weekDays); } isDisabled(repeatOn) { return this.recurrence.repeatOnRule !== repeatOn; } get currentFreq() { return this.recurrence.frequency; } get defaultOffset() { return 1; } get defaultWeekDay() { return this.recurrence.start.getDay(); } weekDayRuleFromString(weekDay) { switch (weekDay) { case 'day': return dayRule; case 'weekday': return weekdayRule; case 'weekend': return weekendRule; default: break; } return null; } textForRepeatOn() { const freq = this.currentFreq; switch (freq) { case 'monthly': return this.textFor('monthlyRepeatOn'); case 'yearly': return this.textFor('yearlyRepeatOn'); default: break; } } textFor(key) { return this.localization.get(key); } onRepeatOnLabelClick() { const selected = this.repeatOnRadioButtons.toArray().find(r => r.elem.checked); if (selected) { selected.elem.focus(); } } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RecurrenceMonthlyYearlyEditorComponent, deps: [{ token: i1.RecurrenceService }, { token: i2.LocalizationService }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: RecurrenceMonthlyYearlyEditorComponent, isStandalone: true, selector: "kendo-recurrence-monthly-yearly-editor", inputs: { userNumericOptions: "userNumericOptions" }, viewQueries: [{ propertyName: "repeatOnRadioButtons", predicate: RepeatOnRadioButtonDirective, descendants: true }], ngImport: i0, template: ` <div class='k-form-field'> <kendo-label [text]="textForRepeatOn()" labelCssClass="k-form-label" (click)="onRepeatOnLabelClick()" ></kendo-label> <div class="k-form-field-wrap"> <ul class='k-radio-list'> <li class='k-radio-list-item'> <span class="k-radio-wrap"> <input kendoRecurrenceRepeatOnRadioButton='monthday-{{uniqueId}}' /> </span> <label [labelClass]="false" class='k-radio-label' for='k-repeaton-monthday-{{uniqueId}}'> <ng-template [ngIf]="currentFreq === 'monthly'"> {{ textFor('monthlyDay') }} </ng-template> </label> <ng-template [ngIf]="currentFreq === 'yearly'"> <kendo-dropdownlist [data]='months' textField='text' valueField='value' [value]='currentMonthMonthDay' [valuePrimitive]='true' (valueChange)="onMonthChange($event, 'monthday')" [disabled]="isDisabled('monthday')" [style.width.px]="170" [style.margin]="'0 .4ex 0 1ex'"> </kendo-dropdownlist> </ng-template> <kendo-numerictextbox class="k-recur-monthday" [min]="numericOptions.min" [max]="numericOptions.max" [decimals]="0" [format]="numericOptions.format" [autoCorrect]="numericOptions.autoCorrect" [readonly]="numericOptions.readonly" [selectOnFocus]="numericOptions.selectOnFocus" [spinners]="numericOptions.spinners" [step]="numericOptions.step" [title]="numericOptions.title" [value]='monthDay' (valueChange)='onMonthDayChange($event)' [disabled]="isDisabled('monthday')" > <kendo-numerictextbox-messages [increment]="textFor('numericIncrement')" [decrement]="textFor('numericDecrement')" > </kendo-numerictextbox-messages> </kendo-numerictextbox> </li> <li class='k-radio-list-item'> <span class="k-radio-wrap"> <input kendoRecurrenceRepeatOnRadioButton='weekday-{{uniqueId}}' /> </span> <label [labelClass]="false" class='k-radio-label' for='k-repeaton-weekday-{{uniqueId}}'></label> <kendo-dropdownlist [data]='offsetPositions' textField='text' valueField='value' [value]='offset' [valuePrimitive]='true' (valueChange)='onOffsetPositionChange($event)' [disabled]="isDisabled('weekday')" [style.margin]="'0 .4ex 0 1ex'"> </kendo-dropdownlist> <kendo-dropdownlist [data]="extendedWeekDays" textField='text' valueField='value' [value]='weekDay' [valuePrimitive]='true' (valueChange)='onWeekDayChange($event)' [disabled]="isDisabled('weekday')" [style.margin]="'0 .4ex 0 1ex'"> </kendo-dropdownlist> <ng-template [ngIf]="currentFreq === 'yearly'"> <span>{{ textFor('yearlyOf') }}</span> <kendo-dropdownlist [data]='months' textField='text' valueField='value' [value]='currentMonthWeekDay' [valuePrimitive]='true' (valueChange)="onMonthChange($event, 'weekday')" [disabled]="isDisabled('weekday')" [style.margin]="'0 .4ex 0 1ex'"> </kendo-dropdownlist> </ng-template> </li> </ul> </div> </div> `, isInline: true, dependencies: [{ kind: "component", type: LabelComponent, selector: "kendo-label", inputs: ["text", "for", "optional", "labelCssStyle", "labelCssClass"], exportAs: ["kendoLabel"] }, { kind: "directive", type: RepeatOnRadioButtonDirective, selector: "[kendoRecurrenceRepeatOnRadioButton]", inputs: ["kendoRecurrenceRepeatOnRadioButton"] }, { kind: "directive", type: LabelDirective, selector: "label[for]", inputs: ["for", "labelClass"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["customIconClass", "showStickyHeader", "icon", "svgIcon", "loading", "data", "value", "textField", "valueField", "adaptiveMode", "title", "subtitle", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "leftRightArrowsNavigation", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }, { kind: "component", type: NumericTextBoxComponent, selector: "kendo-numerictextbox", inputs: ["focusableId", "disabled", "readonly", "title", "autoCorrect", "format", "max", "min", "decimals", "placeholder", "step", "spinners", "rangeValidation", "tabindex", "tabIndex", "changeValueOnScroll", "selectOnFocus", "value", "maxlength", "size", "rounded", "fillMode", "inputAttributes"], outputs: ["valueChange", "focus", "blur", "inputFocus", "inputBlur"], exportAs: ["kendoNumericTextBox"] }, { kind: "component", type: NumericTextBoxCustomMessagesComponent, selector: "kendo-numerictextbox-messages" }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RecurrenceMonthlyYearlyEditorComponent, decorators: [{ type: Component, args: [{ selector: 'kendo-recurrence-monthly-yearly-editor', template: ` <div class='k-form-field'> <kendo-label [text]="textForRepeatOn()" labelCssClass="k-form-label" (click)="onRepeatOnLabelClick()" ></kendo-label> <div class="k-form-field-wrap"> <ul class='k-radio-list'> <li class='k-radio-list-item'> <span class="k-radio-wrap"> <input kendoRecurrenceRepeatOnRadioButton='monthday-{{uniqueId}}' /> </span> <label [labelClass]="false" class='k-radio-label' for='k-repeaton-monthday-{{uniqueId}}'> <ng-template [ngIf]="currentFreq === 'monthly'"> {{ textFor('monthlyDay') }} </ng-template> </label> <ng-template [ngIf]="currentFreq === 'yearly'"> <kendo-dropdownlist [data]='months' textField='text' valueField='value' [value]='currentMonthMonthDay' [valuePrimitive]='true' (valueChange)="onMonthChange($event, 'monthday')" [disabled]="isDisabled('monthday')" [style.width.px]="170" [style.margin]="'0 .4ex 0 1ex'"> </kendo-dropdownlist> </ng-template> <kendo-numerictextbox class="k-recur-monthday" [min]="numericOptions.min" [max]="numericOptions.max" [decimals]="0" [format]="numericOptions.format" [autoCorrect]="numericOptions.autoCorrect" [readonly]="numericOptions.readonly" [selectOnFocus]="numericOptions.selectOnFocus" [spinners]="numericOptions.spinners" [step]="numericOptions.step" [title]="numericOptions.title" [value]='monthDay' (valueChange)='onMonthDayChange($event)' [disabled]="isDisabled('monthday')" > <kendo-numerictextbox-messages [increment]="textFor('numericIncrement')" [decrement]="textFor('numericDecrement')" > </kendo-numerictextbox-messages> </kendo-numerictextbox> </li> <li class='k-radio-list-item'> <span class="k-radio-wrap"> <input kendoRecurrenceRepeatOnRadioButton='weekday-{{uniqueId}}' /> </span> <label [labelClass]="false" class='k-radio-label' for='k-repeaton-weekday-{{uniqueId}}'></label> <kendo-dropdownlist [data]='offsetPositions' textField='text' valueField='value' [value]='offset' [valuePrimitive]='true' (valueChange)='onOffsetPositionChange($event)' [disabled]="isDisabled('weekday')" [style.margin]="'0 .4ex 0 1ex'"> </kendo-dropdownlist> <kendo-dropdownlist [data]="extendedWeekDays" textField='text' valueField='value' [value]='weekDay' [valuePrimitive]='true' (valueChange)='onWeekDayChange($event)' [disabled]="isDisabled('weekday')" [style.margin]="'0 .4ex 0 1ex'"> </kendo-dropdownlist> <ng-template [ngIf]="currentFreq === 'yearly'"> <span>{{ textFor('yearlyOf') }}</span> <kendo-dropdownlist [data]='months' textField='text' valueField='value' [value]='currentMonthWeekDay' [valuePrimitive]='true' (valueChange)="onMonthChange($event, 'weekday')" [disabled]="isDisabled('weekday')" [style.margin]="'0 .4ex 0 1ex'"> </kendo-dropdownlist> </ng-template> </li> </ul> </div> </div> `, standalone: true, imports: [LabelComponent, RepeatOnRadioButtonDirective, LabelDirective, NgIf, DropDownListComponent, NumericTextBoxComponent, NumericTextBoxCustomMessagesComponent] }] }], ctorParameters: function () { return [{ type: i1.RecurrenceService }, { type: i2.LocalizationService }]; }, propDecorators: { userNumericOptions: [{ type: Input }], repeatOnRadioButtons: [{ type: ViewChildren, args: [RepeatOnRadioButtonDirective] }] } });