@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
JavaScript
/**-----------------------------------------------------------------------------------------
* 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
[ ]="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
class="k-recur-count"
[ ]='70'
[ ]='numericOptions.autoCorrect'
[ ]='0'
[ ]='isCountDisabled'
[ ]="numericOptions.format"
[ ]='numericOptions.min'
[ ]="numericOptions.max"
[ ]="numericOptions.readonly"
[ ]="numericOptions.selectOnFocus"
[ ]="numericOptions.spinners"
[ ]="numericOptions.step"
[ ]="numericOptions.title"
[(value)]='countValue'
(blur)="onCountBlur()"
(valueChange)='onCountChange($event)'
>
<kendo-numerictextbox-messages
[ ]="textFor('numericIncrement')"
[ ]="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"
[ ]='150'
[ ]="true"
[ ]='isUntilDisabled'
[ ]="datePickerOptions.activeView"
[ ]="datePickerOptions.bottomView"
[ ]="datePickerOptions.disabledDatesValidation"
[ ]="datePickerOptions.focusedDate"
[ ]="datePickerOptions.format"
[ ]="datePickerOptions.formatPlaceHolder"
[ ]="datePickerOptions.max"
[ ]="datePickerOptions.min"
[ ]="datePickerOptions.navigation"
[ ]="datePickerOptions.placeholder"
[ ]="datePickerOptions.readOnlyInput"
[ ]="datePickerOptions.readonly"
[ ]="datePickerOptions.title"
[ ]="datePickerOptions.topView"
[ ]="datePickerOptions.weekNumber"
[ ]="datePickerOptions.disabledDates"
[ ]="datePickerOptions.popupSettings"
[(value)]='untilValue'
(blur)="onUntilBlur()"
(valueChange)='onUntilChange($event)'
>
<kendo-datepicker-messages
[ ]="textFor('dateInputsToday')"
[ ]="textFor('dateInputsToggle')"
[ ]="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
[ ]="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
class="k-recur-count"
[ ]='70'
[ ]='numericOptions.autoCorrect'
[ ]='0'
[ ]='isCountDisabled'
[ ]="numericOptions.format"
[ ]='numericOptions.min'
[ ]="numericOptions.max"
[ ]="numericOptions.readonly"
[ ]="numericOptions.selectOnFocus"
[ ]="numericOptions.spinners"
[ ]="numericOptions.step"
[ ]="numericOptions.title"
[(value)]='countValue'
(blur)="onCountBlur()"
(valueChange)='onCountChange($event)'
>
<kendo-numerictextbox-messages
[ ]="textFor('numericIncrement')"
[ ]="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"
[ ]='150'
[ ]="true"
[ ]='isUntilDisabled'
[ ]="datePickerOptions.activeView"
[ ]="datePickerOptions.bottomView"
[ ]="datePickerOptions.disabledDatesValidation"
[ ]="datePickerOptions.focusedDate"
[ ]="datePickerOptions.format"
[ ]="datePickerOptions.formatPlaceHolder"
[ ]="datePickerOptions.max"
[ ]="datePickerOptions.min"
[ ]="datePickerOptions.navigation"
[ ]="datePickerOptions.placeholder"
[ ]="datePickerOptions.readOnlyInput"
[ ]="datePickerOptions.readonly"
[ ]="datePickerOptions.title"
[ ]="datePickerOptions.topView"
[ ]="datePickerOptions.weekNumber"
[ ]="datePickerOptions.disabledDates"
[ ]="datePickerOptions.popupSettings"
[(value)]='untilValue'
(blur)="onUntilBlur()"
(valueChange)='onUntilChange($event)'
>
<kendo-datepicker-messages
[ ]="textFor('dateInputsToday')"
[ ]="textFor('dateInputsToggle')"
[ ]="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]
}] } });