@progress/kendo-angular-scheduler 16.11.0-develop.9 → 16.12.0-develop.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,7 +9,7 @@ export const packageMetadata = {
9
9
  name: '@progress/kendo-angular-scheduler',
10
10
  productName: 'Kendo UI for Angular',
11
11
  productCodes: ['KENDOUIANGULAR', 'KENDOUICOMPLETE'],
12
- publishDate: 1727855434,
13
- version: '16.11.0-develop.9',
12
+ publishDate: 1728573087,
13
+ version: '16.12.0-develop.1',
14
14
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
15
15
  };
@@ -6,7 +6,7 @@ import { NgModule } from '@angular/core';
6
6
  import { KENDO_SCHEDULER } from './directives';
7
7
  import { ResizeBatchService } from '@progress/kendo-angular-common';
8
8
  import { DialogContainerService, DialogService, WindowContainerService, WindowService, } from '@progress/kendo-angular-dialog';
9
- import { CalendarDOMService, CenturyViewService, DayPeriodService, DecadeViewService, HoursService, MillisecondsService, MinutesService, MonthViewService, NavigationService, SecondsService, TimePickerDOMService, WeekNamesService, YearViewService, } from '@progress/kendo-angular-dateinputs';
9
+ import { CalendarDOMService, CenturyViewService, DayPeriodService, DecadeViewService, HoursService, MillisecondsService, MinutesService, MonthViewService, NavigationService, SecondsService, TimePickerDOMService, YearViewService, } from '@progress/kendo-angular-dateinputs';
10
10
  import { IconsService } from '@progress/kendo-angular-icons';
11
11
  import { PopupService } from '@progress/kendo-angular-popup';
12
12
  import { ViewContextService } from './views/view-context.service';
@@ -90,7 +90,6 @@ SchedulerModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version
90
90
  DecadeViewService,
91
91
  MonthViewService,
92
92
  YearViewService,
93
- WeekNamesService,
94
93
  NavigationService,
95
94
  TimePickerDOMService,
96
95
  HoursService,
@@ -123,7 +122,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
123
122
  DecadeViewService,
124
123
  MonthViewService,
125
124
  YearViewService,
126
- WeekNamesService,
127
125
  NavigationService,
128
126
  TimePickerDOMService,
129
127
  HoursService,
@@ -25,3 +25,7 @@ export const ONGOING_EVENT_CSS_CLASS = 'k-event-ongoing';
25
25
  export const DAYS_IN_WEEK_COUNT = 7;
26
26
  /** @hidden */
27
27
  export const WEEKS_COUNT = 6;
28
+ /** @hidden */
29
+ export const MORE_BUTTON_HEIGHT = 13;
30
+ /** @hidden */
31
+ export const EVENT_SPACING = 2;
@@ -84,7 +84,7 @@ export class MonthSlotComponent extends BaseSlotDirective {
84
84
  }
85
85
  }
86
86
  MonthSlotComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MonthSlotComponent, deps: [{ token: i0.ElementRef }, { token: i1.MonthSlotService }, { token: i2.LocalizationService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
87
- MonthSlotComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: MonthSlotComponent, isStandalone: true, selector: "[monthSlot]", inputs: { resourcesByIndex: "resourcesByIndex", monthDaySlotTemplateRef: "monthDaySlotTemplateRef", day: ["monthSlot", "day"] }, usesInheritance: true, ngImport: i0, template: `
87
+ MonthSlotComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: MonthSlotComponent, isStandalone: true, selector: "[monthSlot]", inputs: { resourcesByIndex: "resourcesByIndex", monthDaySlotTemplateRef: "monthDaySlotTemplateRef", eventsPerDay: "eventsPerDay", eventHeight: "eventHeight", adaptiveSlotHeight: "adaptiveSlotHeight", day: ["monthSlot", "day"] }, usesInheritance: true, ngImport: i0, template: `
88
88
  <span *ngIf="!monthDaySlotTemplateRef" aria-hidden="true" class="k-link k-nav-day">
89
89
  {{ day | kendoDate: isFirstDayOfMonth(day) ? 'MMM dd' : 'dd' }}
90
90
  </span>
@@ -134,6 +134,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
134
134
  type: Input
135
135
  }], monthDaySlotTemplateRef: [{
136
136
  type: Input
137
+ }], eventsPerDay: [{
138
+ type: Input
139
+ }], eventHeight: [{
140
+ type: Input
141
+ }], adaptiveSlotHeight: [{
142
+ type: Input
137
143
  }], day: [{
138
144
  type: Input,
139
145
  args: ['monthSlot']
@@ -6,10 +6,7 @@ import { orderBy } from '@progress/kendo-data-query';
6
6
  import { intersects, findRowIndex, addUTCDays, rectContains, dateWithTime } from '../utils';
7
7
  import { ItemMap } from '../view-items/item-map';
8
8
  import { BaseSlotService } from '../view-items/base-slot.service';
9
- import { BORDER_WIDTH } from '../constants';
10
- //better try to measure this one
11
- const MORE_BUTTON_HEIGHT = 13;
12
- const EVENT_OFFSET = 2;
9
+ import { BORDER_WIDTH, DEFAULT_EVENT_HEIGHT, EVENT_SPACING, MORE_BUTTON_HEIGHT } from '../constants';
13
10
  /**
14
11
  * @hidden
15
12
  */
@@ -73,8 +70,17 @@ export class SlotRange {
73
70
  unregisterSlot(slot) {
74
71
  this.slotMap.removeItem(slot.id.index, slot);
75
72
  }
76
- layout(eventHeight) {
73
+ layout(eventHeight, eventsPerDay, adaptiveSlotHeight) {
74
+ const dateHeader = this.slots[0].element.nativeElement.firstElementChild;
77
75
  if (!this.hasItems) {
76
+ if (eventHeight !== 'auto') {
77
+ const eventsTotalHeight = adaptiveSlotHeight ? eventHeight : eventHeight * eventsPerDay;
78
+ const height = (eventsTotalHeight + EVENT_SPACING) + dateHeader.offsetHeight + MORE_BUTTON_HEIGHT + EVENT_SPACING;
79
+ this.slots.forEach(slot => {
80
+ slot.height = height;
81
+ slot.element.nativeElement.style.height = height + 'px';
82
+ });
83
+ }
78
84
  return;
79
85
  }
80
86
  const items = this.items;
@@ -89,24 +95,76 @@ export class SlotRange {
89
95
  const rect = slot.rect;
90
96
  const data = event.item.data[event.resourceIndex];
91
97
  data.rowIndex = findRowIndex(value.events, data);
92
- if (value.height + eventHeight + EVENT_OFFSET + MORE_BUTTON_HEIGHT > rect.height || data.hidden) {
98
+ let showMore;
99
+ const _eventHeight = eventHeight === 'auto' ? DEFAULT_EVENT_HEIGHT : eventHeight;
100
+ if (eventHeight === 'auto' || eventsPerDay) {
101
+ showMore = eventsPerDay && eventsPerDay !== 'auto' && data.rowIndex >= eventsPerDay;
102
+ }
103
+ else {
104
+ showMore = value.height + _eventHeight + EVENT_SPACING + MORE_BUTTON_HEIGHT > rect.height || data.hidden;
105
+ }
106
+ if (showMore) {
93
107
  data.hidden = true;
94
- slot.showMore({ width: rect.width, left: rect.left, top: rect.top + slot.linkHeight + ((data.rowIndex) * (eventHeight + EVENT_OFFSET)) });
108
+ // Needed for when eventHeight is 'auto' in order to render the button at later point
109
+ slot.hasShowMore = true;
110
+ // If eventHeight is 'auto', showMore button needs to be displayed after slot accumulated height is calculated
111
+ if (eventHeight !== 'auto') {
112
+ slot.showMore({ width: rect.width, left: rect.left, top: rect.top + slot.linkHeight + ((data.rowIndex) * (eventHeight + EVENT_SPACING)) });
113
+ }
95
114
  }
96
115
  else {
116
+ if (eventHeight === 'auto') {
117
+ // If multiday event spanning on new row (group), it will be rendered on top (1st item)
118
+ // for simplicity and for consistency with jQuery's implementation
119
+ if (event.item.tail) {
120
+ event.item.data[event.resourceIndex].rowIndex = 0;
121
+ }
122
+ if (value.events[data.rowIndex]) {
123
+ event.item.data[event.resourceIndex].rowIndex = value.events.length;
124
+ }
125
+ }
97
126
  value.events[data.rowIndex] = event;
98
- if (!event.rect) {
99
- event.rect = {
100
- top: rect.top + slot.linkHeight + (data.rowIndex * (eventHeight + EVENT_OFFSET)),
101
- left: rect.left,
102
- height: eventHeight,
103
- width: 0
104
- };
127
+ if (eventHeight !== 'auto') {
128
+ // eventHeight is fixed => each event can be rendered on the go
129
+ if (!event.rect) {
130
+ event.rect = {
131
+ top: rect.top + slot.linkHeight + (data.rowIndex * (eventHeight + EVENT_SPACING)),
132
+ left: rect.left,
133
+ height: eventHeight,
134
+ width: 0
135
+ };
136
+ }
137
+ event.rect.width += rect.width + BORDER_WIDTH;
138
+ value.height += eventHeight + EVENT_SPACING;
139
+ // Calculate tha actual rendered items to be able to calculate the height
140
+ if (adaptiveSlotHeight) {
141
+ slots.forEach(_slot => {
142
+ if (_slot.key === slot.key) {
143
+ _slot.eventsCount = !_slot.eventsCount || data.rowIndex + 1 > _slot.eventsCount ? data.rowIndex + 1 : _slot.eventsCount;
144
+ }
145
+ });
146
+ }
105
147
  }
106
- event.rect.width += rect.width + BORDER_WIDTH;
107
- value.height += eventHeight + EVENT_OFFSET;
108
148
  }
109
149
  }));
150
+ if (eventHeight === 'auto') {
151
+ // eventHeight is 'auto' => first get all slotItems for a slot and then render them, after they are in the correct rendering order (L140-L146)
152
+ this.renderAutoHeightEvents(slotItems, dateHeader);
153
+ }
154
+ else if (eventsPerDay) {
155
+ slots.forEach(slot => {
156
+ const multiplier = !adaptiveSlotHeight ? eventsPerDay : slot.eventsCount;
157
+ const height = BORDER_WIDTH +
158
+ dateHeader.offsetHeight +
159
+ EVENT_SPACING +
160
+ (multiplier * (eventHeight + EVENT_SPACING)) +
161
+ MORE_BUTTON_HEIGHT +
162
+ EVENT_SPACING;
163
+ slot.eventsCount = 0;
164
+ slot.height = height;
165
+ slot.element.nativeElement.style.height = height + 'px';
166
+ });
167
+ }
110
168
  sorted.forEach(event => {
111
169
  if (event.rect) {
112
170
  event.rect.width -= BORDER_WIDTH;
@@ -114,6 +172,73 @@ export class SlotRange {
114
172
  event.reflow();
115
173
  });
116
174
  }
175
+ renderAutoHeightEvents(slotItems, dateHeader) {
176
+ // Iterate through the slotItems
177
+ Object.keys(slotItems).forEach((key) => {
178
+ const slotItem = slotItems[key];
179
+ const slotRect = slotItem.slot.rect;
180
+ // Iterate over each event in the events array
181
+ let accumulatedHeight = dateHeader.offsetHeight;
182
+ slotItem.events.forEach((event, index) => {
183
+ const prevEvent = slotItem.events[index - 1];
184
+ if (!event.rect) {
185
+ // Each event is position depending on where the previous event is already positioned
186
+ const eventOffset = !prevEvent ? 0 : prevEvent.element.nativeElement.clientHeight + prevEvent.rect.top;
187
+ const top = !prevEvent ? slotRect.top + slotItem.slot.linkHeight : eventOffset + EVENT_SPACING;
188
+ event.rect = {
189
+ top: top,
190
+ left: slotRect.left,
191
+ width: 0
192
+ };
193
+ }
194
+ // The number of slots an event spans in current group
195
+ let eventWidth;
196
+ if (event.item.isMultiDay) {
197
+ const slotMatch = this.slots.filter(slot => intersects(event.item.startTime, event.item.endTime, slot.start, slot.end));
198
+ eventWidth = slotMatch.reduce((acc, currentValue) => acc + currentValue.rect.width + BORDER_WIDTH, 0) - BORDER_WIDTH;
199
+ if (prevEvent) {
200
+ const newHeight = prevEvent.element.nativeElement.clientHeight + prevEvent.rect.top;
201
+ const newTop = newHeight + EVENT_SPACING;
202
+ // If event is spanning in multiple slots, it needs to be positioned so that its top
203
+ // is calculated based on the most 'accumulated height' among all slots
204
+ if (event.rect.top < newTop) {
205
+ event.rect.top = newTop;
206
+ // Consequently, all previously renderd events (after that multi-span event) need to
207
+ // be reposition so that they don't overlap
208
+ slotMatch.forEach(slot => {
209
+ const slotKey = slot.id.resourceIndex + ':' + slot.id.rangeIndex + ':' + slot.id.index;
210
+ if (slotKey !== key) {
211
+ slotItems[slotKey].events.forEach((e, index) => {
212
+ if (index > event.item.data[event.resourceIndex].rowIndex) {
213
+ e.rect.top = event.rect.top + event.element.nativeElement.clientHeight + EVENT_SPACING;
214
+ }
215
+ });
216
+ }
217
+ });
218
+ }
219
+ }
220
+ }
221
+ else {
222
+ eventWidth = slotRect.width;
223
+ }
224
+ event.rect.width = eventWidth;
225
+ event.element.nativeElement.style.width = event.rect.width + 'px';
226
+ event.element.nativeElement.style.height = 'auto';
227
+ accumulatedHeight += event.element.nativeElement.clientHeight + EVENT_SPACING;
228
+ });
229
+ const slotHeight = slotItem.height = BORDER_WIDTH +
230
+ dateHeader.offsetHeight +
231
+ EVENT_SPACING +
232
+ accumulatedHeight +
233
+ (slotItem.slot.hasShowMore ? 0 : MORE_BUTTON_HEIGHT);
234
+ slotItem.slot.element.nativeElement.style.height = slotHeight + 'px';
235
+ // After events are rendered, position the showMore button
236
+ if (slotItem.slot.hasShowMore) {
237
+ const top = slotRect.top + slotItem.slot.linkHeight + accumulatedHeight - MORE_BUTTON_HEIGHT;
238
+ slotItem.slot.showMore({ width: slotRect.width, left: slotRect.left, top: top });
239
+ }
240
+ });
241
+ }
117
242
  }
118
243
  /**
119
244
  * @hidden
@@ -168,8 +293,8 @@ export class MonthResourceGroup {
168
293
  * @hidden
169
294
  */
170
295
  export class MonthSlotService extends BaseSlotService {
171
- layout(eventHeight) {
172
- this.groups.forEach((group) => group.forEachRange(range => range.layout(eventHeight)));
296
+ layout(eventHeight, eventsPerDay, adaptiveSlotHeight) {
297
+ this.groups.forEach((group) => group.forEachRange(range => range.layout(eventHeight, eventsPerDay, adaptiveSlotHeight)));
173
298
  }
174
299
  slotByIndex(slotIndex) {
175
300
  const [resourceIndex, rangeIndex, index] = slotIndex.split(':').map(part => parseInt(part, 10));
@@ -56,6 +56,15 @@ export class MonthViewRendererComponent extends BaseView {
56
56
  }
57
57
  super.ngOnChanges(changes);
58
58
  }
59
+ ngOnInit() {
60
+ this.viewState.layoutEnd.subscribe(() => {
61
+ if (this.adaptiveSlotHeight) {
62
+ this.slotService.invalidate();
63
+ this.reflow();
64
+ }
65
+ });
66
+ super.ngOnInit();
67
+ }
59
68
  ngAfterViewInit() {
60
69
  this.updateOngoingEvents();
61
70
  super.ngAfterViewInit();
@@ -134,7 +143,7 @@ export class MonthViewRendererComponent extends BaseView {
134
143
  // this changes the table and slots size during rendering before the browser re-adjusts the 100% table width
135
144
  content.style.overflow = 'visible';
136
145
  }
137
- this.slotService.layout(this.eventHeight);
146
+ this.slotService.layout(this.eventHeight, this.eventsPerDay, this.adaptiveSlotHeight);
138
147
  if (this.contentHeight === 'auto') {
139
148
  content.style.overflow = 'auto';
140
149
  }
@@ -231,7 +240,7 @@ export class MonthViewRendererComponent extends BaseView {
231
240
  }
232
241
  }
233
242
  MonthViewRendererComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MonthViewRendererComponent, deps: [{ token: i1.ViewContextService }, { token: i2.ViewStateService }, { token: i3.IntlService }, { token: i4.MonthSlotService }, { token: i0.NgZone }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i5.PDFService }, { token: i6.LocalizationService }, { token: i0.ChangeDetectorRef }, { token: i7.ScrollbarWidthService }], target: i0.ɵɵFactoryTarget.Component });
234
- MonthViewRendererComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: MonthViewRendererComponent, isStandalone: true, selector: "month-view", inputs: { monthDaySlotTemplate: "monthDaySlotTemplate", highlightOngoingEvents: "highlightOngoingEvents", type: "type", numberOfWeeks: "numberOfWeeks", newRange: "newRange", dateRangeFn: "dateRangeFn" }, providers: [
243
+ MonthViewRendererComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: MonthViewRendererComponent, isStandalone: true, selector: "month-view", inputs: { monthDaySlotTemplate: "monthDaySlotTemplate", highlightOngoingEvents: "highlightOngoingEvents", type: "type", eventsPerDay: "eventsPerDay", adaptiveSlotHeight: "adaptiveSlotHeight", numberOfWeeks: "numberOfWeeks", newRange: "newRange", dateRangeFn: "dateRangeFn" }, providers: [
235
244
  MonthSlotService
236
245
  ], viewQueries: [{ propertyName: "eventElements", predicate: MonthViewItemComponent, descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: `
237
246
  <table class="k-scheduler-layout k-scheduler-monthview">
@@ -308,13 +317,16 @@ MonthViewRendererComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0
308
317
  [attr.aria-owns]="matchOwned(items | async)"
309
318
  [style.overflowY]="'auto'">
310
319
  <!-- Main content -->
311
- <table class="k-scheduler-table" #contentTable role="presentation">
320
+ <table class="k-scheduler-table" [class.k-scheduler-table-auto]="adaptiveSlotHeight" #contentTable role="presentation">
312
321
  <tbody>
313
322
  <ng-container *ngFor="let resourceItem of verticalResources | resourceIterator; let verticalIndex = index; trackBy: itemIndex">
314
323
  <tr *ngFor="let week of weeks; let rangeIndex = index; trackBy: itemIndex">
315
324
  <ng-container *ngFor="let resource of horizontalResources | resourceIterator; let horizontalIndex = index; trackBy: itemIndex">
316
325
  <td *ngFor="let day of week; let index = index; trackBy: itemIndex"
317
326
  [monthSlot]="day"
327
+ [eventHeight]="eventHeight"
328
+ [eventsPerDay]="eventsPerDay"
329
+ [adaptiveSlotHeight]="adaptiveSlotHeight"
318
330
  [monthDaySlotTemplateRef]="monthDaySlotTemplateRef"
319
331
  [resourcesByIndex]="resourcesByIndex(verticalResources.length ? verticalIndex : horizontalIndex)"
320
332
  [ngClass]="daySlotClass(day, verticalResources.length ? verticalIndex : horizontalIndex)"
@@ -378,7 +390,7 @@ MonthViewRendererComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0
378
390
  </tr>
379
391
  </tbody>
380
392
  </table>
381
- `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: MonthSlotComponent, selector: "[monthSlot]", inputs: ["resourcesByIndex", "monthDaySlotTemplateRef", "monthSlot"] }, { kind: "component", type: MonthViewItemComponent, selector: "[monthViewItem]" }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: FocusableDirective, selector: "[kendoSchedulerFocusIndex]", inputs: ["kendoSchedulerFocusIndex", "containerType"] }, { kind: "component", type: HintContainerComponent, selector: "kendo-hint-container" }, { kind: "component", type: ResizeHintComponent, selector: "[kendoResizeHint]", inputs: ["hint", "format"] }, { kind: "pipe", type: RepeatPipe, name: "repeat" }, { kind: "pipe", type: ResourceIteratorPipe, name: "resourceIterator" }, { kind: "pipe", type: DatePipe, name: "kendoDate" }, { kind: "pipe", type: AsyncPipe, name: "async" }] });
393
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: MonthSlotComponent, selector: "[monthSlot]", inputs: ["resourcesByIndex", "monthDaySlotTemplateRef", "eventsPerDay", "eventHeight", "adaptiveSlotHeight", "monthSlot"] }, { kind: "component", type: MonthViewItemComponent, selector: "[monthViewItem]" }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: FocusableDirective, selector: "[kendoSchedulerFocusIndex]", inputs: ["kendoSchedulerFocusIndex", "containerType"] }, { kind: "component", type: HintContainerComponent, selector: "kendo-hint-container" }, { kind: "component", type: ResizeHintComponent, selector: "[kendoResizeHint]", inputs: ["hint", "format"] }, { kind: "pipe", type: RepeatPipe, name: "repeat" }, { kind: "pipe", type: ResourceIteratorPipe, name: "resourceIterator" }, { kind: "pipe", type: DatePipe, name: "kendoDate" }, { kind: "pipe", type: AsyncPipe, name: "async" }] });
382
394
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MonthViewRendererComponent, decorators: [{
383
395
  type: Component,
384
396
  args: [{
@@ -462,13 +474,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
462
474
  [attr.aria-owns]="matchOwned(items | async)"
463
475
  [style.overflowY]="'auto'">
464
476
  <!-- Main content -->
465
- <table class="k-scheduler-table" #contentTable role="presentation">
477
+ <table class="k-scheduler-table" [class.k-scheduler-table-auto]="adaptiveSlotHeight" #contentTable role="presentation">
466
478
  <tbody>
467
479
  <ng-container *ngFor="let resourceItem of verticalResources | resourceIterator; let verticalIndex = index; trackBy: itemIndex">
468
480
  <tr *ngFor="let week of weeks; let rangeIndex = index; trackBy: itemIndex">
469
481
  <ng-container *ngFor="let resource of horizontalResources | resourceIterator; let horizontalIndex = index; trackBy: itemIndex">
470
482
  <td *ngFor="let day of week; let index = index; trackBy: itemIndex"
471
483
  [monthSlot]="day"
484
+ [eventHeight]="eventHeight"
485
+ [eventsPerDay]="eventsPerDay"
486
+ [adaptiveSlotHeight]="adaptiveSlotHeight"
472
487
  [monthDaySlotTemplateRef]="monthDaySlotTemplateRef"
473
488
  [resourcesByIndex]="resourcesByIndex(verticalResources.length ? verticalIndex : horizontalIndex)"
474
489
  [ngClass]="daySlotClass(day, verticalResources.length ? verticalIndex : horizontalIndex)"
@@ -542,6 +557,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
542
557
  type: Input
543
558
  }], type: [{
544
559
  type: Input
560
+ }], eventsPerDay: [{
561
+ type: Input
562
+ }], adaptiveSlotHeight: [{
563
+ type: Input
545
564
  }], numberOfWeeks: [{
546
565
  type: Input
547
566
  }], newRange: [{
@@ -52,9 +52,32 @@ export class MonthViewComponent extends ConfigurationViewBase {
52
52
  get title() {
53
53
  return this.localization.get('monthViewTitle');
54
54
  }
55
+ /**
56
+ * The number of events to be rendered per day. Setting this property to 'auto'
57
+ * will display all events in the respective slot.
58
+ * > When set to `'auto'` it will automatically set the `adaptiveSlotHeight` property to `true`.
59
+ * > If set to `0` it will be normalized internally to `1`.
60
+ * @default 2
61
+ */
62
+ set eventsPerDay(events) {
63
+ this._eventsPerDay = !events ? 1 : events;
64
+ }
65
+ get eventsPerDay() {
66
+ return this._eventsPerDay;
67
+ }
55
68
  get viewEventHeight() {
56
69
  return isPresent(this.eventHeight) ? this.eventHeight : (this.schedulerOptions.eventHeight || DEFAULT_EVENT_HEIGHT);
57
70
  }
71
+ ngOnChanges(changes) {
72
+ if ((changes['eventHeight'] && changes['eventHeight'].currentValue === 'auto') ||
73
+ (changes['eventsPerDay'] && changes['eventsPerDay'].currentValue === 'auto')) {
74
+ this.adaptiveSlotHeight = true;
75
+ }
76
+ if ((changes['eventHeight'] && changes['eventHeight'].currentValue === 'auto' && !this.eventsPerDay) ||
77
+ (changes['adaptiveSlotHeight'] && changes['adaptiveSlotHeight'].currentValue === true && !this.eventsPerDay)) {
78
+ this.eventsPerDay = 2;
79
+ }
80
+ }
58
81
  /**
59
82
  * @hidden
60
83
  */
@@ -74,14 +97,16 @@ export class MonthViewComponent extends ConfigurationViewBase {
74
97
  }
75
98
  }
76
99
  MonthViewComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MonthViewComponent, deps: [{ token: i1.LocalizationService }, { token: i0.ChangeDetectorRef }, { token: i2.ViewContextService }, { token: i3.ViewStateService }, { token: i4.IntlService }], target: i0.ɵɵFactoryTarget.Component });
77
- MonthViewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: MonthViewComponent, isStandalone: true, selector: "kendo-scheduler-month-view", inputs: { eventHeight: "eventHeight", selectedDateFormat: "selectedDateFormat", selectedShortDateFormat: "selectedShortDateFormat" }, providers: [{
100
+ MonthViewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: MonthViewComponent, isStandalone: true, selector: "kendo-scheduler-month-view", inputs: { eventsPerDay: "eventsPerDay", eventHeight: "eventHeight", adaptiveSlotHeight: "adaptiveSlotHeight", selectedDateFormat: "selectedDateFormat", selectedShortDateFormat: "selectedShortDateFormat" }, providers: [{
78
101
  provide: SchedulerView,
79
102
  useExisting: forwardRef(() => MonthViewComponent)
80
- }], queries: [{ propertyName: "monthDaySlotTemplate", first: true, predicate: MonthDaySlotTemplateDirective, descendants: true }], usesInheritance: true, ngImport: i0, template: `
103
+ }], queries: [{ propertyName: "monthDaySlotTemplate", first: true, predicate: MonthDaySlotTemplateDirective, descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: `
81
104
  <ng-template #content>
82
105
  <month-view
83
106
  type="month"
84
107
  [eventHeight]="viewEventHeight"
108
+ [adaptiveSlotHeight]="adaptiveSlotHeight"
109
+ [eventsPerDay]="eventsPerDay"
85
110
  [eventTemplate]="eventTemplate?.templateRef"
86
111
  [slotClass]="viewSlotClass"
87
112
  [eventClass]="viewEventClass"
@@ -96,7 +121,7 @@ MonthViewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", ver
96
121
  [newRange]="newRange">
97
122
  </month-view>
98
123
  </ng-template>
99
- `, isInline: true, dependencies: [{ kind: "component", type: MonthViewRendererComponent, selector: "month-view", inputs: ["monthDaySlotTemplate", "highlightOngoingEvents", "type", "numberOfWeeks", "newRange", "dateRangeFn"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
124
+ `, isInline: true, dependencies: [{ kind: "component", type: MonthViewRendererComponent, selector: "month-view", inputs: ["monthDaySlotTemplate", "highlightOngoingEvents", "type", "eventsPerDay", "adaptiveSlotHeight", "numberOfWeeks", "newRange", "dateRangeFn"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
100
125
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MonthViewComponent, decorators: [{
101
126
  type: Component,
102
127
  args: [{
@@ -111,6 +136,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
111
136
  <month-view
112
137
  type="month"
113
138
  [eventHeight]="viewEventHeight"
139
+ [adaptiveSlotHeight]="adaptiveSlotHeight"
140
+ [eventsPerDay]="eventsPerDay"
114
141
  [eventTemplate]="eventTemplate?.templateRef"
115
142
  [slotClass]="viewSlotClass"
116
143
  [eventClass]="viewEventClass"
@@ -129,7 +156,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
129
156
  standalone: true,
130
157
  imports: [MonthViewRendererComponent]
131
158
  }]
132
- }], ctorParameters: function () { return [{ type: i1.LocalizationService }, { type: i0.ChangeDetectorRef }, { type: i2.ViewContextService }, { type: i3.ViewStateService }, { type: i4.IntlService }]; }, propDecorators: { eventHeight: [{
159
+ }], ctorParameters: function () { return [{ type: i1.LocalizationService }, { type: i0.ChangeDetectorRef }, { type: i2.ViewContextService }, { type: i3.ViewStateService }, { type: i4.IntlService }]; }, propDecorators: { eventsPerDay: [{
160
+ type: Input
161
+ }], eventHeight: [{
162
+ type: Input
163
+ }], adaptiveSlotHeight: [{
133
164
  type: Input
134
165
  }], selectedDateFormat: [{
135
166
  type: Input
@@ -56,9 +56,32 @@ export class MultiWeekViewComponent extends ConfigurationViewBase {
56
56
  get title() {
57
57
  return this.localization.get('multiWeekViewTitle');
58
58
  }
59
+ /**
60
+ * The number of events to be rendered per day. Setting this property to 'auto'
61
+ * will display all events in the respective slot.
62
+ * > When set to `'auto'` it will automatically set the `adaptiveSlotHeight` property to `true`.
63
+ * > If set to `0` it will be normalized internally to `1`.
64
+ * @default 2
65
+ */
66
+ set eventsPerDay(events) {
67
+ this._eventsPerDay = !events ? 1 : events;
68
+ }
69
+ get eventsPerDay() {
70
+ return this._eventsPerDay;
71
+ }
59
72
  get viewEventHeight() {
60
73
  return isPresent(this.eventHeight) ? this.eventHeight : (this.schedulerOptions.eventHeight || DEFAULT_EVENT_HEIGHT);
61
74
  }
75
+ ngOnChanges(changes) {
76
+ if ((changes['eventHeight'] && changes['eventHeight'].currentValue === 'auto') ||
77
+ (changes['eventsPerDay'] && changes['eventsPerDay'].currentValue === 'auto')) {
78
+ this.adaptiveSlotHeight = true;
79
+ }
80
+ if ((changes['eventHeight'] && changes['eventHeight'].currentValue === 'auto' && !this.eventsPerDay) ||
81
+ (changes['adaptiveSlotHeight'] && changes['adaptiveSlotHeight'].currentValue === true && !this.eventsPerDay)) {
82
+ this.eventsPerDay = 2;
83
+ }
84
+ }
62
85
  /**
63
86
  * @hidden
64
87
  */
@@ -78,14 +101,16 @@ export class MultiWeekViewComponent extends ConfigurationViewBase {
78
101
  }
79
102
  }
80
103
  MultiWeekViewComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MultiWeekViewComponent, deps: [{ token: i1.LocalizationService }, { token: i0.ChangeDetectorRef }, { token: i2.ViewContextService }, { token: i3.ViewStateService }, { token: i4.IntlService }], target: i0.ɵɵFactoryTarget.Component });
81
- MultiWeekViewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: MultiWeekViewComponent, isStandalone: true, selector: "kendo-scheduler-multi-week-view", inputs: { eventHeight: "eventHeight", numberOfWeeks: "numberOfWeeks", selectedDateFormat: "selectedDateFormat", selectedShortDateFormat: "selectedShortDateFormat" }, providers: [{
104
+ MultiWeekViewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: MultiWeekViewComponent, isStandalone: true, selector: "kendo-scheduler-multi-week-view", inputs: { eventHeight: "eventHeight", eventsPerDay: "eventsPerDay", adaptiveSlotHeight: "adaptiveSlotHeight", numberOfWeeks: "numberOfWeeks", selectedDateFormat: "selectedDateFormat", selectedShortDateFormat: "selectedShortDateFormat" }, providers: [{
82
105
  provide: SchedulerView,
83
106
  useExisting: forwardRef(() => MultiWeekViewComponent)
84
- }], queries: [{ propertyName: "multiWeekDaySlotTemplate", first: true, predicate: MultiWeekDaySlotTemplateDirective, descendants: true }], usesInheritance: true, ngImport: i0, template: `
107
+ }], queries: [{ propertyName: "multiWeekDaySlotTemplate", first: true, predicate: MultiWeekDaySlotTemplateDirective, descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: `
85
108
  <ng-template #content>
86
109
  <month-view
87
110
  type="multiWeek"
88
111
  [eventHeight]="viewEventHeight"
112
+ [adaptiveSlotHeight]="adaptiveSlotHeight"
113
+ [eventsPerDay]="eventsPerDay"
89
114
  [eventTemplate]="eventTemplate?.templateRef"
90
115
  [slotClass]="viewSlotClass"
91
116
  [eventClass]="viewEventClass"
@@ -101,7 +126,7 @@ MultiWeekViewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0",
101
126
  [newRange]="newRange">
102
127
  </month-view>
103
128
  </ng-template>
104
- `, isInline: true, dependencies: [{ kind: "component", type: MonthViewRendererComponent, selector: "month-view", inputs: ["monthDaySlotTemplate", "highlightOngoingEvents", "type", "numberOfWeeks", "newRange", "dateRangeFn"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
129
+ `, isInline: true, dependencies: [{ kind: "component", type: MonthViewRendererComponent, selector: "month-view", inputs: ["monthDaySlotTemplate", "highlightOngoingEvents", "type", "eventsPerDay", "adaptiveSlotHeight", "numberOfWeeks", "newRange", "dateRangeFn"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
105
130
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MultiWeekViewComponent, decorators: [{
106
131
  type: Component,
107
132
  args: [{
@@ -116,6 +141,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
116
141
  <month-view
117
142
  type="multiWeek"
118
143
  [eventHeight]="viewEventHeight"
144
+ [adaptiveSlotHeight]="adaptiveSlotHeight"
145
+ [eventsPerDay]="eventsPerDay"
119
146
  [eventTemplate]="eventTemplate?.templateRef"
120
147
  [slotClass]="viewSlotClass"
121
148
  [eventClass]="viewEventClass"
@@ -137,6 +164,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
137
164
  }]
138
165
  }], ctorParameters: function () { return [{ type: i1.LocalizationService }, { type: i0.ChangeDetectorRef }, { type: i2.ViewContextService }, { type: i3.ViewStateService }, { type: i4.IntlService }]; }, propDecorators: { eventHeight: [{
139
166
  type: Input
167
+ }], eventsPerDay: [{
168
+ type: Input
169
+ }], adaptiveSlotHeight: [{
170
+ type: Input
140
171
  }], numberOfWeeks: [{
141
172
  type: Input
142
173
  }], selectedDateFormat: [{
@@ -4,6 +4,7 @@
4
4
  *-------------------------------------------------------------------------------------------*/
5
5
  import { intersects, toUTCDate, addUTCDays } from '../utils';
6
6
  import { sortTasksByTime } from '../../common/util';
7
+ import { addDays } from '@progress/kendo-date-math';
7
8
  const last = (arr) => arr[arr.length - 1];
8
9
  /**
9
10
  * @hidden
@@ -35,9 +36,18 @@ export const createTasks = (periodStart, periodEnd, items, ranges) => {
35
36
  rangeIndex: rangeIdx,
36
37
  data: data
37
38
  };
38
- tasks.push(task);
39
39
  task.head = task.endTime > rangeEnd;
40
40
  task.tail = task.startTime < rangeStart;
41
+ let slotMatch;
42
+ range.forEach(slot => {
43
+ const slotStartTime = slot;
44
+ const slotEndTime = addDays(slot, 1);
45
+ if (task.event.start >= slotStartTime && task.event.start <= slotEndTime) {
46
+ slotMatch = { start: slotStartTime, end: slotEndTime };
47
+ }
48
+ });
49
+ task.isMultiDay = task.event.end > slotMatch?.end || task.head || task.tail;
50
+ tasks.push(task);
41
51
  }
42
52
  }
43
53
  }
@@ -95,9 +95,7 @@ export class BaseViewItem {
95
95
  this.subs.add(this.slotService.slotsChange.subscribe(() => {
96
96
  this.rect = null;
97
97
  this.setStyles({
98
- width: 0,
99
98
  left: 0,
100
- bottom: 0
101
99
  });
102
100
  const slotId = { index: this.index, resourceIndex: this.resourceIndex, rangeIndex: this.rangeIndex };
103
101
  this.slotService.unregisterItem(this, slotId);