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.

333 lines (332 loc) 19.1 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, HostBinding } from '@angular/core'; import { RecurrenceService } from './recurrence.service'; import { isPresent } from '../../common/util'; import { EndRuleRadioButtonDirective } from './end-rule-radio-button.directive'; import { ZonedDate } from '@progress/kendo-date-math'; import { toUTCDate } from '../../views/utils'; import { LocalizationService } from '@progress/kendo-angular-l10n'; import { DatePickerComponent, DatePickerCustomMessagesComponent } from '@progress/kendo-angular-dateinputs'; import { NumericTextBoxComponent, NumericTextBoxCustomMessagesComponent } from '@progress/kendo-angular-inputs'; 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 RecurrenceEndRuleEditorComponent { recurrence; localization; cssClass = true; set userNumericOptions(options) { this.numericOptions = { ...this.numericOptions, ...options }; } set userDatePickerOptions(options) { this.datePickerOptions = { ...this.datePickerOptions, ...options }; } endRuleRadioButtons; countValue; untilValue; numericOptions = { min: 1, format: '#', autoCorrect: true, step: 1, spinners: true }; datePickerOptions = { activeView: 'month', bottomView: 'month', topView: 'century', disabledDatesValidation: true, navigation: true, format: 'd' }; uniqueId; subscriptions; constructor(recurrence, localization) { this.recurrence = recurrence; this.localization = localization; this.uniqueId = this.recurrence.getUniqueId(); this.setInitialValues(); this.subscribeChanges(); } ngOnDestroy() { if (this.subscriptions) { this.subscriptions.unsubscribe(); } } setEndRule(endRule) { if (endRule === 'count') { this.recurrence.rrule.count = this.countValue; } else if (endRule === 'until') { this.recurrence.until = this.untilValue; } } get rrule() { return this.recurrence.rrule; } get isCountDisabled() { return this.recurrence.endRule !== 'count'; } get isUntilDisabled() { return this.recurrence.endRule !== 'until'; } onCountChange(value) { if (isPresent(value)) { this.recurrence.count = value; } } onCountBlur() { if (!isPresent(this.countValue)) { this.recurrence.count = this.countValue = 1; } } onUntilChange(value) { if (isPresent(value)) { this.recurrence.until = this.createUntil(value); } } onUntilBlur() { if (!isPresent(this.untilValue)) { this.recurrence.until = this.untilValue = this.createUntil(this.recurrence.start); } } textFor(key) { return this.localization.get(key); } onEndLabelClick() { const selected = this.endRuleRadioButtons.toArray().find(r => r.elem.checked); if (selected) { selected.elem.focus(); } } setInitialValues() { this.countValue = this.rrule.count || 1; const currentUntil = this.recurrence.until; const currentStart = this.recurrence.start; this.untilValue = isPresent(currentUntil) ? currentUntil : this.createUntil(currentStart); } subscribeChanges() { this.subscriptions = this.recurrence.endRuleChange.subscribe((endRule) => { this.setEndRule(endRule); }); this.subscriptions.add(this.recurrence.frequencyChange.subscribe(() => { this.setInitialValues(); })); } createUntil(until) { // Read the until date as UTC date parts to avoid interfering with the local time zone. const untilDate = toUTCDate(until); // Set the time to the end of the day untilDate.setUTCHours(23); untilDate.setUTCMinutes(59); untilDate.setUTCSeconds(59); // Convert to the scheduler time zone. return ZonedDate.fromUTCDate(untilDate, this.recurrence.timezone).toLocalDate(); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RecurrenceEndRuleEditorComponent, deps: [{ token: i1.RecurrenceService }, { token: i2.LocalizationService }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: RecurrenceEndRuleEditorComponent, isStandalone: true, selector: "kendo-recurrence-end-rule-editor", inputs: { userNumericOptions: "userNumericOptions", userDatePickerOptions: "userDatePickerOptions" }, host: { properties: { "class.k-scheduler-recurrence-end-rule-editor": "this.cssClass" } }, viewQueries: [{ propertyName: "endRuleRadioButtons", predicate: EndRuleRadioButtonDirective, descendants: true }], ngImport: i0, template: ` <div class="k-form-field"> <kendo-label [text]="textFor('endLabel')" (click)="onEndLabelClick()" labelCssClass="k-form-label" ></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 kendoRecurrenceEndRuleRadioButton='k-endrule-never-{{uniqueId}}' /> </span> <label [labelClass]="false" class='k-radio-label' for='k-endrule-never-{{uniqueId}}'>{{ textFor('endNever') }}</label> </li> <li class='k-radio-list-item'> <span class="k-radio-wrap"> <input kendoRecurrenceEndRuleRadioButton='k-endrule-count-{{uniqueId}}' /> </span> <label [labelClass]="false" class='k-radio-label' for='k-endrule-count-{{uniqueId}}'>{{ textFor('endAfter') }}</label> <kendo-numerictextbox #afterOccurances class="k-recur-count" [style.width.px]='70' [autoCorrect]='numericOptions.autoCorrect' [decimals]='0' [disabled]='isCountDisabled' [format]="numericOptions.format" [min]='numericOptions.min' [max]="numericOptions.max" [readonly]="numericOptions.readonly" [selectOnFocus]="numericOptions.selectOnFocus" [spinners]="numericOptions.spinners" [step]="numericOptions.step" [title]="numericOptions.title" [(value)]='countValue' (blur)="onCountBlur()" (valueChange)='onCountChange($event)' > <kendo-numerictextbox-messages [increment]="textFor('numericIncrement')" [decrement]="textFor('numericDecrement')" > </kendo-numerictextbox-messages> </kendo-numerictextbox> <span>{{ textFor('endOccurrence') }}</span> </li> <li class='k-radio-list-item'> <span class="k-radio-wrap"> <input kendoRecurrenceEndRuleRadioButton='k-endrule-until-{{uniqueId}}' /> </span> <label [labelClass]="false" class='k-radio-label' for='k-endrule-until-{{uniqueId}}'>{{ textFor('endOn') }}</label> <kendo-datepicker class="k-recur-until" [style.width.px]='150' [clearButton]="true" [disabled]='isUntilDisabled' [activeView]="datePickerOptions.activeView" [bottomView]="datePickerOptions.bottomView" [disabledDatesValidation]="datePickerOptions.disabledDatesValidation" [focusedDate]="datePickerOptions.focusedDate" [format]="datePickerOptions.format" [formatPlaceholder]="datePickerOptions.formatPlaceHolder" [max]="datePickerOptions.max" [min]="datePickerOptions.min" [navigation]="datePickerOptions.navigation" [placeholder]="datePickerOptions.placeholder" [readOnlyInput]="datePickerOptions.readOnlyInput" [readonly]="datePickerOptions.readonly" [title]="datePickerOptions.title" [topView]="datePickerOptions.topView" [weekNumber]="datePickerOptions.weekNumber" [disabledDates]="datePickerOptions.disabledDates" [popupSettings]="datePickerOptions.popupSettings" [(value)]='untilValue' (blur)="onUntilBlur()" (valueChange)='onUntilChange($event)' > <kendo-datepicker-messages [today]="textFor('dateInputsToday')" [toggle]="textFor('dateInputsToggle')" [parentViewButtonTitle]="textFor('dateInputsParentViewButton')" > </kendo-datepicker-messages> </kendo-datepicker> </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: EndRuleRadioButtonDirective, selector: "[kendoRecurrenceEndRuleRadioButton]", inputs: ["kendoRecurrenceEndRuleRadioButton"] }, { kind: "directive", type: LabelDirective, selector: "label[for]", inputs: ["for", "labelClass"] }, { 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" }, { kind: "component", type: DatePickerComponent, selector: "kendo-datepicker", inputs: ["focusableId", "cellTemplate", "clearButton", "inputAttributes", "monthCellTemplate", "yearCellTemplate", "decadeCellTemplate", "centuryCellTemplate", "weekNumberTemplate", "headerTitleTemplate", "headerTemplate", "footerTemplate", "footer", "navigationItemTemplate", "weekDaysFormat", "showOtherMonthDays", "activeView", "bottomView", "topView", "calendarType", "animateCalendarNavigation", "disabled", "readonly", "readOnlyInput", "popupSettings", "navigation", "min", "max", "incompleteDateValidation", "autoCorrectParts", "autoSwitchParts", "autoSwitchKeys", "enableMouseWheel", "allowCaretMode", "autoFill", "focusedDate", "value", "format", "twoDigitYearMax", "formatPlaceholder", "placeholder", "tabindex", "tabIndex", "disabledDates", "title", "subtitle", "rangeValidation", "disabledDatesValidation", "weekNumber", "size", "rounded", "fillMode", "adaptiveMode"], outputs: ["valueChange", "focus", "blur", "open", "close", "escape"], exportAs: ["kendo-datepicker"] }, { kind: "component", type: DatePickerCustomMessagesComponent, selector: "kendo-datepicker-messages" }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RecurrenceEndRuleEditorComponent, decorators: [{ type: Component, args: [{ selector: 'kendo-recurrence-end-rule-editor', template: ` <div class="k-form-field"> <kendo-label [text]="textFor('endLabel')" (click)="onEndLabelClick()" labelCssClass="k-form-label" ></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 kendoRecurrenceEndRuleRadioButton='k-endrule-never-{{uniqueId}}' /> </span> <label [labelClass]="false" class='k-radio-label' for='k-endrule-never-{{uniqueId}}'>{{ textFor('endNever') }}</label> </li> <li class='k-radio-list-item'> <span class="k-radio-wrap"> <input kendoRecurrenceEndRuleRadioButton='k-endrule-count-{{uniqueId}}' /> </span> <label [labelClass]="false" class='k-radio-label' for='k-endrule-count-{{uniqueId}}'>{{ textFor('endAfter') }}</label> <kendo-numerictextbox #afterOccurances class="k-recur-count" [style.width.px]='70' [autoCorrect]='numericOptions.autoCorrect' [decimals]='0' [disabled]='isCountDisabled' [format]="numericOptions.format" [min]='numericOptions.min' [max]="numericOptions.max" [readonly]="numericOptions.readonly" [selectOnFocus]="numericOptions.selectOnFocus" [spinners]="numericOptions.spinners" [step]="numericOptions.step" [title]="numericOptions.title" [(value)]='countValue' (blur)="onCountBlur()" (valueChange)='onCountChange($event)' > <kendo-numerictextbox-messages [increment]="textFor('numericIncrement')" [decrement]="textFor('numericDecrement')" > </kendo-numerictextbox-messages> </kendo-numerictextbox> <span>{{ textFor('endOccurrence') }}</span> </li> <li class='k-radio-list-item'> <span class="k-radio-wrap"> <input kendoRecurrenceEndRuleRadioButton='k-endrule-until-{{uniqueId}}' /> </span> <label [labelClass]="false" class='k-radio-label' for='k-endrule-until-{{uniqueId}}'>{{ textFor('endOn') }}</label> <kendo-datepicker class="k-recur-until" [style.width.px]='150' [clearButton]="true" [disabled]='isUntilDisabled' [activeView]="datePickerOptions.activeView" [bottomView]="datePickerOptions.bottomView" [disabledDatesValidation]="datePickerOptions.disabledDatesValidation" [focusedDate]="datePickerOptions.focusedDate" [format]="datePickerOptions.format" [formatPlaceholder]="datePickerOptions.formatPlaceHolder" [max]="datePickerOptions.max" [min]="datePickerOptions.min" [navigation]="datePickerOptions.navigation" [placeholder]="datePickerOptions.placeholder" [readOnlyInput]="datePickerOptions.readOnlyInput" [readonly]="datePickerOptions.readonly" [title]="datePickerOptions.title" [topView]="datePickerOptions.topView" [weekNumber]="datePickerOptions.weekNumber" [disabledDates]="datePickerOptions.disabledDates" [popupSettings]="datePickerOptions.popupSettings" [(value)]='untilValue' (blur)="onUntilBlur()" (valueChange)='onUntilChange($event)' > <kendo-datepicker-messages [today]="textFor('dateInputsToday')" [toggle]="textFor('dateInputsToggle')" [parentViewButtonTitle]="textFor('dateInputsParentViewButton')" > </kendo-datepicker-messages> </kendo-datepicker> </li> </ul> </div> </div> `, standalone: true, imports: [LabelComponent, EndRuleRadioButtonDirective, LabelDirective, NumericTextBoxComponent, NumericTextBoxCustomMessagesComponent, DatePickerComponent, DatePickerCustomMessagesComponent] }] }], ctorParameters: function () { return [{ type: i1.RecurrenceService }, { type: i2.LocalizationService }]; }, propDecorators: { cssClass: [{ type: HostBinding, args: ['class.k-scheduler-recurrence-end-rule-editor'] }], userNumericOptions: [{ type: Input }], userDatePickerOptions: [{ type: Input }], endRuleRadioButtons: [{ type: ViewChildren, args: [EndRuleRadioButtonDirective] }] } });