@syncfusion/ej2-schedule 20.1.52 → 20.1.55

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.
Files changed (72) hide show
  1. package/CHANGELOG.md +46 -11
  2. package/dist/ej2-schedule.umd.min.js +2 -2
  3. package/dist/ej2-schedule.umd.min.js.map +1 -1
  4. package/dist/es6/ej2-schedule.es2015.js +133 -46
  5. package/dist/es6/ej2-schedule.es2015.js.map +1 -1
  6. package/dist/es6/ej2-schedule.es5.js +133 -46
  7. package/dist/es6/ej2-schedule.es5.js.map +1 -1
  8. package/dist/global/ej2-schedule.min.js +2 -2
  9. package/dist/global/ej2-schedule.min.js.map +1 -1
  10. package/dist/global/index.d.ts +1 -1
  11. package/package.json +15 -15
  12. package/src/recurrence-editor/date-generator.js +11 -1
  13. package/src/schedule/base/schedule.js +4 -0
  14. package/src/schedule/event-renderer/agenda-base.js +1 -1
  15. package/src/schedule/event-renderer/event-base.js +3 -0
  16. package/src/schedule/event-renderer/month.d.ts +1 -0
  17. package/src/schedule/event-renderer/month.js +38 -29
  18. package/src/schedule/event-renderer/vertical-view.js +3 -0
  19. package/src/schedule/event-renderer/year.js +3 -1
  20. package/src/schedule/exports/calendar-export.js +1 -1
  21. package/src/schedule/popups/event-window.js +4 -2
  22. package/src/schedule/renderer/month.js +8 -5
  23. package/src/schedule/renderer/renderer.js +2 -1
  24. package/src/schedule/renderer/timeline-year.d.ts +2 -1
  25. package/src/schedule/renderer/timeline-year.js +49 -4
  26. package/src/schedule/renderer/vertical-view.js +2 -1
  27. package/src/schedule/renderer/year.js +4 -0
  28. package/styles/bootstrap-dark.css +83 -968
  29. package/styles/bootstrap.css +83 -967
  30. package/styles/bootstrap4.css +83 -990
  31. package/styles/bootstrap5-dark.css +83 -988
  32. package/styles/bootstrap5.css +83 -988
  33. package/styles/fabric-dark.css +83 -968
  34. package/styles/fabric.css +83 -970
  35. package/styles/fluent-dark.css +83 -968
  36. package/styles/fluent.css +83 -968
  37. package/styles/highcontrast-light.css +83 -967
  38. package/styles/highcontrast.css +83 -972
  39. package/styles/material-dark.css +83 -967
  40. package/styles/material.css +83 -967
  41. package/styles/recurrence-editor/bootstrap-dark.css +6 -94
  42. package/styles/recurrence-editor/bootstrap.css +6 -94
  43. package/styles/recurrence-editor/bootstrap4.css +6 -94
  44. package/styles/recurrence-editor/bootstrap5-dark.css +6 -94
  45. package/styles/recurrence-editor/bootstrap5.css +6 -94
  46. package/styles/recurrence-editor/fabric-dark.css +6 -94
  47. package/styles/recurrence-editor/fabric.css +6 -94
  48. package/styles/recurrence-editor/fluent-dark.css +6 -94
  49. package/styles/recurrence-editor/fluent.css +6 -94
  50. package/styles/recurrence-editor/highcontrast-light.css +6 -94
  51. package/styles/recurrence-editor/highcontrast.css +6 -94
  52. package/styles/recurrence-editor/material-dark.css +6 -94
  53. package/styles/recurrence-editor/material.css +6 -94
  54. package/styles/recurrence-editor/tailwind-dark.css +6 -94
  55. package/styles/recurrence-editor/tailwind.css +6 -94
  56. package/styles/schedule/bootstrap-dark.css +78 -875
  57. package/styles/schedule/bootstrap.css +78 -874
  58. package/styles/schedule/bootstrap4.css +78 -897
  59. package/styles/schedule/bootstrap5-dark.css +78 -895
  60. package/styles/schedule/bootstrap5.css +78 -895
  61. package/styles/schedule/fabric-dark.css +78 -875
  62. package/styles/schedule/fabric.css +78 -877
  63. package/styles/schedule/fluent-dark.css +78 -875
  64. package/styles/schedule/fluent.css +78 -875
  65. package/styles/schedule/highcontrast-light.css +78 -874
  66. package/styles/schedule/highcontrast.css +78 -879
  67. package/styles/schedule/material-dark.css +78 -874
  68. package/styles/schedule/material.css +78 -874
  69. package/styles/schedule/tailwind-dark.css +78 -895
  70. package/styles/schedule/tailwind.css +78 -895
  71. package/styles/tailwind-dark.css +83 -988
  72. package/styles/tailwind.css +83 -988
@@ -3631,6 +3631,10 @@ function generate(startDate, rule, excludeDate, startDayOfWeek, maximumCount = M
3631
3631
  }
3632
3632
  maxOccurrence = maximumCount;
3633
3633
  setFirstDayOfWeek(DAYINDEX[startDayOfWeek]);
3634
+ if (ruleObject.until) {
3635
+ const end = resetTime(ruleObject.until);
3636
+ ruleObject.until = new Date(end.getFullYear(), end.getMonth(), end.getDate(), 23, 59, 59);
3637
+ }
3634
3638
  switch (ruleObject.freq) {
3635
3639
  case 'DAILY':
3636
3640
  dailyType(modifiedDate, ruleObject.until, data, ruleObject);
@@ -3727,6 +3731,9 @@ function dailyType(startDate, endDate, data, ruleObject) {
3727
3731
  }
3728
3732
  }
3729
3733
  tempDate.setDate(tempDate.getDate() + interval);
3734
+ if (tempDate.getHours() !== startDate.getHours()) {
3735
+ tempDate.setHours(startDate.getHours());
3736
+ }
3730
3737
  }
3731
3738
  }
3732
3739
  /**
@@ -3771,6 +3778,9 @@ function weeklyType(startDate, endDate, data, ruleObject) {
3771
3778
  break;
3772
3779
  }
3773
3780
  tempDate.setDate(tempDate.getDate() + 1);
3781
+ if (tempDate.getHours() !== startDate.getHours()) {
3782
+ tempDate.setHours(startDate.getHours());
3783
+ }
3774
3784
  compareTempDate = new Date(tempDate.getTime());
3775
3785
  compareTempDate = resetTime(compareTempDate);
3776
3786
  }
@@ -4652,7 +4662,7 @@ function insertDateCollection(state, startDate, endDate, data, ruleObject, dayDa
4652
4662
  function weekCount(year, startDayOfWeek, monthCollection, week, ruleObject) {
4653
4663
  const firstDayOfWeek = startDayOfWeek || 0;
4654
4664
  const firstOfMonth = new Date(year, ruleObject.month[0] - 1, 1);
4655
- const lastOfMonth = new Date(year, ruleObject.month[0] - 1, 0);
4665
+ const lastOfMonth = new Date(year, ruleObject.month[0], 0);
4656
4666
  const numberOfDaysInMonth = lastOfMonth.getDate();
4657
4667
  const firstWeekDay = (firstOfMonth.getDay() - firstDayOfWeek + 7) % 7;
4658
4668
  const used = firstWeekDay + numberOfDaysInMonth;
@@ -5605,6 +5615,9 @@ class EventBase {
5605
5615
  this.parent.removeSelectedClass();
5606
5616
  }
5607
5617
  addClass(cells, APPOINTMENT_BORDER);
5618
+ if (cells.length > 0) {
5619
+ cells[cells.length - 1].focus();
5620
+ }
5608
5621
  }
5609
5622
  getSelectedAppointments() {
5610
5623
  return [].slice.call(this.parent.element.querySelectorAll('.' + APPOINTMENT_BORDER + ',.' + APPOINTMENT_CLASS + ':focus'));
@@ -6773,6 +6786,9 @@ class VerticalEvent extends EventBase {
6773
6786
  const currentDate = resetTime(new Date(this.dateRender[resource][dayIndex].getTime()));
6774
6787
  const schedule = getStartEndHours(currentDate, this.startHour, this.endHour);
6775
6788
  const isValidEvent = this.isValidEvent(eventObj, eStart, eEnd, schedule);
6789
+ if ((eStart.getTime() < this.parent.minDate.getTime()) || (eEnd.getTime() > this.parent.maxDate.getTime())) {
6790
+ return;
6791
+ }
6776
6792
  if (eStart <= eEnd && isValidEvent) {
6777
6793
  const appHeight = this.getHeight(eStart, eEnd);
6778
6794
  if (eStart.getTime() > schedule.startHour.getTime()) {
@@ -7096,7 +7112,7 @@ class MonthEvent extends EventBase {
7096
7112
  if (appElement.length > 0) {
7097
7113
  appElement = (this.parent.currentView === 'Month') ? appElement : [appElement[0]];
7098
7114
  for (const wrap of appElement) {
7099
- if (!wrap.classList.contains('e-more-indicator') && wrap.parentElement && wrap.parentElement.parentNode) {
7115
+ if (wrap.parentElement && wrap.parentElement.parentNode) {
7100
7116
  remove(wrap.parentElement);
7101
7117
  }
7102
7118
  }
@@ -7226,11 +7242,18 @@ class MonthEvent extends EventBase {
7226
7242
  const filteredDates = this.getRenderedDates(dateRender);
7227
7243
  this.getSlotDates(workDays || this.parent.activeViewOptions.workDays);
7228
7244
  this.processBlockEvents(blockList, resIndex, resData);
7245
+ let events = [];
7229
7246
  for (const event of eventsList) {
7230
7247
  if (this.parent.resourceBase && !resData) {
7231
7248
  this.cssClass = this.parent.resourceBase.getCssClass(event);
7232
7249
  }
7233
- const spannedEvents = this.splitEvent(event, filteredDates || this.dateRender);
7250
+ events = events.concat(this.splitEvent(event, filteredDates || this.dateRender));
7251
+ }
7252
+ for (let level = 0; level < this.slots.length; level++) {
7253
+ this.renderedEvents = [];
7254
+ const slot = this.slots[level];
7255
+ const endDate = addDays(new Date(slot[slot.length - 1]), 1);
7256
+ const spannedEvents = this.filterEvents(new Date(slot[0]), endDate, events);
7234
7257
  for (const event of spannedEvents) {
7235
7258
  if (this.maxHeight) {
7236
7259
  const sDate = this.parent.currentView === 'Month' ? event[this.fields.startTime] :
@@ -7526,24 +7549,20 @@ class MonthEvent extends EventBase {
7526
7549
  const startTime = event[this.fields.startTime];
7527
7550
  const endTime = event[this.fields.endTime];
7528
7551
  const day = this.parent.getIndexOfDate(this.dateRender, resetTime(startTime));
7529
- if (day < 0) {
7530
- return;
7531
- }
7532
- if ((startTime.getTime() < this.parent.minDate.getTime()) || (endTime.getTime() > this.parent.maxDate.getTime())) {
7552
+ if ((day < 0) || (startTime.getTime() < this.parent.minDate.getTime()) || (endTime.getTime() > this.parent.maxDate.getTime())) {
7533
7553
  return;
7534
7554
  }
7535
7555
  const overlapCount = this.getIndex(startTime);
7536
7556
  event.Index = overlapCount;
7537
- let appHeight = this.eventHeight;
7538
- this.renderedEvents.push(extend({}, event, null, true));
7539
7557
  const diffInDays = event.data.count;
7540
7558
  if (startTime.getTime() <= endTime.getTime()) {
7541
7559
  const appWidth = (diffInDays * this.cellWidth) - 5;
7542
7560
  const cellTd = this.workCells[day];
7543
- const appTop = (overlapCount * (appHeight + EVENT_GAP));
7544
- const height = this.monthHeaderHeight + ((overlapCount + 1) * (appHeight + EVENT_GAP)) + this.moreIndicatorHeight;
7561
+ const appTop = (overlapCount * (this.eventHeight + EVENT_GAP));
7562
+ const height = this.monthHeaderHeight + ((overlapCount + 1) * (this.eventHeight + EVENT_GAP)) + this.moreIndicatorHeight;
7545
7563
  const enableAppRender = this.maxOrIndicator ? overlapCount < 1 ? true : false : this.cellHeight > height;
7546
7564
  if (this.parent.rowAutoHeight || enableAppRender) {
7565
+ this.renderedEvents.push(extend({}, event, null, true));
7547
7566
  let appointmentElement;
7548
7567
  if (this.inlineValue) {
7549
7568
  appointmentElement = this.parent.inlineModule.createInlineAppointmentElement();
@@ -7562,24 +7581,26 @@ class MonthEvent extends EventBase {
7562
7581
  }
7563
7582
  else {
7564
7583
  for (let i = 0; i < diffInDays; i++) {
7565
- const cellTd = this.workCells[day + i];
7566
- if (cellTd && isNullOrUndefined(cellTd.querySelector('.' + MORE_INDICATOR_CLASS))) {
7567
- const startDate = new Date(this.dateRender[day + i].getTime());
7568
- const endDate = addDays(this.dateRender[day + i], 1);
7569
- const groupIndex = cellTd.getAttribute('data-group-index');
7570
- const filterEvents = this.getFilteredEvents(startDate, endDate, groupIndex);
7571
- const appArea = this.cellHeight - this.monthHeaderHeight - this.moreIndicatorHeight;
7572
- appHeight = this.withIndicator ? appArea : appHeight;
7573
- const renderedAppCount = Math.floor(appArea / (appHeight + EVENT_GAP));
7574
- const count = (filterEvents.length - renderedAppCount) <= 0 ? 1 : (filterEvents.length - renderedAppCount);
7575
- const moreIndicatorElement = this.getMoreIndicatorElement(count, startDate, endDate);
7576
- if (!isNullOrUndefined(groupIndex)) {
7577
- moreIndicatorElement.setAttribute('data-group-index', groupIndex);
7584
+ if (this.workCells[day + i]) {
7585
+ const indicator = this.workCells[day + i].querySelector('.' + MORE_INDICATOR_CLASS);
7586
+ if (indicator) {
7587
+ const count = parseInt(indicator.getAttribute('data-count'), 10) + 1;
7588
+ indicator.setAttribute('data-count', count.toString());
7589
+ indicator.innerHTML = this.getMoreIndicatorText(count);
7590
+ }
7591
+ else {
7592
+ const startDate = new Date(this.dateRender[day + i].getTime());
7593
+ const endDate = addDays(this.dateRender[day + i], 1);
7594
+ const groupIndex = this.workCells[day + i].getAttribute('data-group-index');
7595
+ const moreIndicatorElement = this.getMoreIndicatorElement(1, startDate, endDate);
7596
+ if (!isNullOrUndefined(groupIndex)) {
7597
+ moreIndicatorElement.setAttribute('data-group-index', groupIndex);
7598
+ }
7599
+ moreIndicatorElement.style.top = (this.cellHeight - this.monthHeaderHeight - this.moreIndicatorHeight) + 'px';
7600
+ moreIndicatorElement.style.width = this.cellWidth - 2 + 'px';
7601
+ this.renderElement(this.workCells[day + i], moreIndicatorElement);
7602
+ EventHandler.add(moreIndicatorElement, 'click', this.moreIndicatorClick, this);
7578
7603
  }
7579
- moreIndicatorElement.style.top = appArea + 'px';
7580
- moreIndicatorElement.style.width = this.cellWidth - 2 + 'px';
7581
- this.renderElement(cellTd, moreIndicatorElement);
7582
- EventHandler.add(moreIndicatorElement, 'click', this.moreIndicatorClick, this);
7583
7604
  }
7584
7605
  }
7585
7606
  }
@@ -7615,8 +7636,8 @@ class MonthEvent extends EventBase {
7615
7636
  }
7616
7637
  getOverlapEvents(date, appointments) {
7617
7638
  const appointmentsList = [];
7639
+ const dateTime = resetTime(date).getTime();
7618
7640
  for (const app of appointments) {
7619
- const dateTime = resetTime(date).getTime();
7620
7641
  if ((resetTime(app[this.fields.startTime]).getTime() <= dateTime) &&
7621
7642
  (resetTime(app[this.fields.endTime]).getTime() >= dateTime)) {
7622
7643
  appointmentsList.push(app);
@@ -7697,9 +7718,10 @@ class MonthEvent extends EventBase {
7697
7718
  getMoreIndicatorElement(count, startDate, endDate) {
7698
7719
  const moreIndicatorElement = createElement('div', {
7699
7720
  className: MORE_INDICATOR_CLASS,
7700
- innerHTML: '+' + this.parent.globalize.formatNumber(count) + '&nbsp;' + (this.parent.isAdaptive ? '' : this.parent.localeObj.getConstant('more')),
7721
+ innerHTML: this.getMoreIndicatorText(count),
7701
7722
  attrs: {
7702
7723
  'tabindex': '0',
7724
+ 'data-count': count.toString(),
7703
7725
  'data-start-date': startDate.getTime().toString(),
7704
7726
  'data-end-date': endDate.getTime().toString(),
7705
7727
  'role': 'list'
@@ -7707,6 +7729,9 @@ class MonthEvent extends EventBase {
7707
7729
  });
7708
7730
  return moreIndicatorElement;
7709
7731
  }
7732
+ getMoreIndicatorText(count) {
7733
+ return '+' + this.parent.globalize.formatNumber(count) + '&nbsp;' + (this.parent.isAdaptive ? '' : this.parent.localeObj.getConstant('more'));
7734
+ }
7710
7735
  removeHeightProperty(selector) {
7711
7736
  const rows = [].slice.call(this.element.querySelectorAll('.' + selector + ' tbody tr'));
7712
7737
  for (const row of rows) {
@@ -11731,7 +11756,8 @@ class EventWindow {
11731
11756
  return labelText;
11732
11757
  }
11733
11758
  onChange(args) {
11734
- const target = args.event.currentTarget.querySelector('input');
11759
+ const targetSelector = `.${EVENT_WINDOW_ALL_DAY_CLASS},.${TIME_ZONE_CLASS},.${EVENT_WINDOW_REPEAT_CLASS}`;
11760
+ const target = closest(args.event.target, targetSelector);
11735
11761
  if (target.classList.contains(EVENT_WINDOW_ALL_DAY_CLASS)) {
11736
11762
  this.onAllDayChange(args.checked);
11737
11763
  }
@@ -11895,7 +11921,8 @@ class EventWindow {
11895
11921
  }
11896
11922
  showDetails(eventData) {
11897
11923
  const eventObj = extend({}, eventData, null, true);
11898
- if (eventObj[this.fields.endTime].getHours() === 0 && eventObj[this.fields.endTime].getMinutes() === 0) {
11924
+ if ((!this.cellClickAction || this.cellClickAction && !isNullOrUndefined(this.parent.editorTemplate)) &&
11925
+ eventObj[this.fields.endTime].getHours() === 0 && eventObj[this.fields.endTime].getMinutes() === 0) {
11899
11926
  this.trimAllDay(eventObj);
11900
11927
  }
11901
11928
  this.eventData = eventObj;
@@ -13183,7 +13210,8 @@ class Render {
13183
13210
  this.parent.virtualScrollModule.destroy();
13184
13211
  this.parent.virtualScrollModule = null;
13185
13212
  }
13186
- if (this.parent.currentView.indexOf('Timeline') !== -1 && this.parent.currentView.indexOf('Year') === -1
13213
+ if (this.parent.currentView.indexOf('Timeline') !== -1 && (this.parent.currentView.indexOf('Year') === -1 ||
13214
+ (this.parent.currentView === 'TimelineYear' && this.parent.activeViewOptions.orientation === 'Vertical'))
13187
13215
  && this.parent.activeViewOptions.allowVirtualScrolling
13188
13216
  && this.parent.activeViewOptions.group.resources.length > 0 && !this.parent.uiStateValues.isGroupAdaptive) {
13189
13217
  this.parent.virtualScrollModule = new VirtualScroll(this.parent);
@@ -15729,6 +15757,7 @@ let Schedule = class Schedule extends Component {
15729
15757
  };
15730
15758
  this.trigger(navigating, navArgs, (navigationArgs) => {
15731
15759
  if (!navigationArgs.cancel) {
15760
+ this.uiStateValues.isInitial = view.indexOf('Timeline') > -1 || this.currentView.indexOf('Timeline') > -1 ? true : this.uiStateValues.isInitial;
15732
15761
  this.viewIndex = navigationArgs.viewIndex;
15733
15762
  this.setProperties({ currentView: view }, true);
15734
15763
  if (this.headerModule) {
@@ -16347,6 +16376,9 @@ let Schedule = class Schedule extends Component {
16347
16376
  if (document.querySelectorAll(template).length) {
16348
16377
  return compile(document.querySelector(template).innerHTML.trim());
16349
16378
  }
16379
+ else {
16380
+ return compile(template);
16381
+ }
16350
16382
  }
16351
16383
  catch (error) {
16352
16384
  return compile(template);
@@ -19152,7 +19184,9 @@ class YearEvent extends TimelineEvent {
19152
19184
  this.eventHeight = getElementHeightFromClass(eventTable, APPOINTMENT_CLASS);
19153
19185
  const wrapperCollection = [].slice.call(this.parent.element.querySelectorAll('.' + APPOINTMENT_CONTAINER_CLASS));
19154
19186
  const resources = this.parent.uiStateValues.isGroupAdaptive ?
19155
- [this.parent.resourceBase.lastResourceLevel[this.parent.uiStateValues.groupIndex]] : this.parent.resourceBase.lastResourceLevel;
19187
+ [this.parent.resourceBase.lastResourceLevel[this.parent.uiStateValues.groupIndex]] :
19188
+ this.parent.activeViewOptions.allowVirtualScrolling ? this.parent.resourceBase.renderedResources :
19189
+ this.parent.resourceBase.lastResourceLevel;
19156
19190
  const months = this.getMonths();
19157
19191
  if (this.parent.activeViewOptions.orientation === 'Horizontal') {
19158
19192
  for (let month = 0; month < months.length; month++) {
@@ -21931,8 +21965,9 @@ class VerticalView extends ViewBase {
21931
21965
  const msStartHour = startHour.getTime();
21932
21966
  const msEndHour = endHour.getTime();
21933
21967
  if (msStartHour !== msEndHour) {
21968
+ const duration = this.parent.activeViewOptions.timeScale.interval / this.parent.activeViewOptions.timeScale.slotCount;
21934
21969
  length = (Math.abs(msEndHour - msStartHour) / msInterval) - ((new Date(msEndHour).getTimezoneOffset()
21935
- - new Date(msStartHour).getTimezoneOffset()) / (60 / this.parent.activeViewOptions.timeScale.slotCount));
21970
+ - new Date(msStartHour).getTimezoneOffset()) / duration);
21936
21971
  }
21937
21972
  if (!this.parent.activeViewOptions.timeScale.enable) {
21938
21973
  length = 1;
@@ -22142,16 +22177,16 @@ class Month extends ViewBase {
22142
22177
  }
22143
22178
  this.setColWidth(content);
22144
22179
  if (args.scrollPosition || !args.isPreventScrollUpdate && this.parent.currentView === 'TimelineMonth') {
22180
+ const top = this.parent.currentView === 'TimelineMonth' ? this.parent.uiStateValues.top : args.scrollPosition.top;
22181
+ if (leftPanel) {
22182
+ leftPanel.scrollTop = top;
22183
+ }
22184
+ content.scrollTop = top;
22145
22185
  if (this.parent.uiStateValues.isInitial) {
22146
22186
  this.scrollToSelectedDate();
22147
22187
  this.parent.uiStateValues.isInitial = false;
22148
22188
  }
22149
22189
  else {
22150
- const top = this.parent.currentView === 'TimelineMonth' ? this.parent.uiStateValues.top : args.scrollPosition.top;
22151
- if (leftPanel) {
22152
- leftPanel.scrollTop = top;
22153
- }
22154
- content.scrollTop = top;
22155
22190
  content.scrollLeft = this.parent.currentView === 'TimelineMonth' ? this.parent.uiStateValues.left :
22156
22191
  args.scrollPosition.left;
22157
22192
  }
@@ -22172,6 +22207,9 @@ class Month extends ViewBase {
22172
22207
  else {
22173
22208
  content.scrollLeft = 0;
22174
22209
  }
22210
+ if (content.scrollLeft === 0 && this.parent.uiStateValues.isInitial) {
22211
+ this.parent.uiStateValues.left = 0;
22212
+ }
22175
22213
  }
22176
22214
  setContentHeight(content, leftPanelElement, height) {
22177
22215
  content.style.height = 'auto';
@@ -22727,6 +22765,9 @@ class Year extends ViewBase {
22727
22765
  const viewTypeClass = this.parent.activeViewOptions.orientation === 'Horizontal' ? 'e-horizontal' : 'e-vertical';
22728
22766
  addClass([this.element], [this.viewClass, viewTypeClass, className]);
22729
22767
  this.renderPanel(className);
22768
+ if (this.parent.activeViewOptions.allowVirtualScrolling) {
22769
+ addClass([this.element], [VIRTUAL_SCROLL_CLASS]);
22770
+ }
22730
22771
  const calendarTable = this.createTableLayout(OUTER_TABLE_CLASS);
22731
22772
  this.element.appendChild(calendarTable);
22732
22773
  this.element.querySelector('table').setAttribute('role', 'presentation');
@@ -22939,6 +22980,7 @@ class Year extends ViewBase {
22939
22980
  onContentScroll(e) {
22940
22981
  const target = e.target;
22941
22982
  const headerWrapper = this.getDatesHeaderElement();
22983
+ this.parent.notify(virtualScroll, e);
22942
22984
  if (headerWrapper) {
22943
22985
  headerWrapper.firstElementChild.scrollLeft = target.scrollLeft;
22944
22986
  }
@@ -23095,7 +23137,7 @@ class AgendaBase extends ViewBase {
23095
23137
  moduleName: 'agenda',
23096
23138
  listClass: this.parent.activeView.viewClass,
23097
23139
  itemClass: this.parent.activeView.viewClass,
23098
- template: '<div class=' + AGENDA_NO_EVENT_CLASS + '>${subject}</div>'
23140
+ template: `<div class="${AGENDA_NO_EVENT_CLASS}">${this.parent.localeObj.getConstant('noEvents')}</div>`
23099
23141
  });
23100
23142
  }
23101
23143
  else {
@@ -24639,7 +24681,7 @@ class TimelineYear extends Year {
24639
24681
  !this.parent.uiStateValues.isGroupAdaptive) {
24640
24682
  tdCollection.push(firstTd);
24641
24683
  firstTd.appendChild(this.parent.resourceBase.createResourceColumn());
24642
- this.rowCount = this.parent.resourceBase.lastResourceLevel.length;
24684
+ this.rowCount = this.parent.resourceBase.renderedResources.length;
24643
24685
  }
24644
24686
  else {
24645
24687
  tdCollection.push(firstTd);
@@ -24656,6 +24698,9 @@ class TimelineYear extends Year {
24656
24698
  content.appendChild(contentTable);
24657
24699
  const eventWrapper = createElement('div', { className: EVENT_TABLE_CLASS });
24658
24700
  content.appendChild(eventWrapper);
24701
+ if (this.parent.virtualScrollModule) {
24702
+ this.parent.virtualScrollModule.renderVirtualTrack(content);
24703
+ }
24659
24704
  const contentTBody = contentTable.querySelector('tbody');
24660
24705
  if (this.parent.activeViewOptions.group.resources.length > 0 && !this.parent.uiStateValues.isGroupAdaptive) {
24661
24706
  if (this.parent.rowAutoHeight) {
@@ -24773,6 +24818,47 @@ class TimelineYear extends Year {
24773
24818
  }
24774
24819
  }
24775
24820
  }
24821
+ getContentRows() {
24822
+ const tRow = [];
24823
+ const monthCells = this.getMonths();
24824
+ for (let row = 0; row < this.parent.resourceBase.renderedResources.length; row++) {
24825
+ const tr = createElement('tr', { attrs: { 'role': 'row' } });
24826
+ tRow.push(tr);
24827
+ let resData;
24828
+ if (this.parent.activeViewOptions.group.resources.length > 0 && !this.parent.uiStateValues.isGroupAdaptive) {
24829
+ resData = this.parent.resourceBase.renderedResources[row];
24830
+ }
24831
+ let monthDate = new Date(this.parent.selectedDate.getFullYear(), monthCells[row], 1);
24832
+ let date = this.parent.calendarUtil.getMonthStartDate(new Date(monthDate.getTime()));
24833
+ for (let month = 0; month < this.columnCount; month++) {
24834
+ let classList$$1 = [];
24835
+ const groupIndex = resData.groupIndex;
24836
+ classList$$1 = classList$$1.concat(resData.className);
24837
+ if (classList$$1.indexOf(RESOURCE_PARENT_CLASS) > -1) {
24838
+ classList$$1.push(RESOURCE_GROUP_CELLS_CLASS);
24839
+ }
24840
+ else {
24841
+ classList$$1.push(WORKDAY_CLASS);
24842
+ }
24843
+ monthDate = new Date(this.parent.selectedDate.getFullYear(), monthCells[month], 1);
24844
+ date = this.parent.calendarUtil.getMonthStartDate(new Date(monthDate.getTime()));
24845
+ const tdELe = createElement('td', {
24846
+ className: WORK_CELLS_CLASS,
24847
+ attrs: {
24848
+ 'role': 'gridcell', 'aria-selected': 'false',
24849
+ 'data-date': date.getTime().toString()
24850
+ }
24851
+ });
24852
+ addClass([tdELe], classList$$1);
24853
+ tdELe.setAttribute('data-group-index', groupIndex.toString());
24854
+ this.renderCellTemplate({ date: date, type: 'resourceGroupCells', groupIndex: groupIndex }, tdELe);
24855
+ this.wireEvents(tdELe, 'cell');
24856
+ this.parent.trigger(renderCell, { elementType: 'resourceGroupCells', element: tdELe, date: date });
24857
+ tr.appendChild(tdELe);
24858
+ }
24859
+ }
24860
+ return tRow;
24861
+ }
24776
24862
  renderResourceContent(wrapper, monthBody, contentBody) {
24777
24863
  const months = this.getMonths();
24778
24864
  for (let row = 0; row < this.rowCount; row++) {
@@ -24780,8 +24866,8 @@ class TimelineYear extends Year {
24780
24866
  const tr = createElement('tr', { attrs: { 'role': 'row' } });
24781
24867
  contentBody.appendChild(tr);
24782
24868
  let resData;
24783
- if (this.parent.activeViewOptions.group.resources.length > 0 && !this.parent.uiStateValues.isGroupAdaptive) {
24784
- resData = this.parent.resourceBase.lastResourceLevel[row];
24869
+ if (this.parent.activeViewOptions.orientation === 'Vertical' && this.parent.activeViewOptions.group.resources.length > 0 && !this.parent.uiStateValues.isGroupAdaptive) {
24870
+ resData = this.parent.resourceBase.renderedResources[row];
24785
24871
  }
24786
24872
  let monthDate = new Date(this.parent.selectedDate.getFullYear(), months[row], 1);
24787
24873
  let date = this.parent.calendarUtil.getMonthStartDate(new Date(monthDate.getTime()));
@@ -24802,8 +24888,9 @@ class TimelineYear extends Year {
24802
24888
  }
24803
24889
  for (let month = 0; month < this.columnCount; month++) {
24804
24890
  let classList$$1 = [];
24805
- let groupIndex = row;
24891
+ let groupIndex;
24806
24892
  if (this.parent.activeViewOptions.orientation === 'Vertical') {
24893
+ groupIndex = resData.groupIndex;
24807
24894
  classList$$1 = classList$$1.concat(resData.className);
24808
24895
  if (classList$$1.indexOf(RESOURCE_PARENT_CLASS) > -1) {
24809
24896
  classList$$1.push(RESOURCE_GROUP_CELLS_CLASS);
@@ -24905,7 +24992,7 @@ class ICalendarExport {
24905
24992
  const editedExDate = [];
24906
24993
  if (eventObj[fields.recurrenceID]) {
24907
24994
  const filter = this.filterEvents(filterCollection, fields.id, eventObj[fields.recurrenceID]);
24908
- uId = filter[0].UID;
24995
+ uId = filter.length > 0 ? filter[0].UID : uId;
24909
24996
  }
24910
24997
  if (!eventObj[fields.recurrenceID] && eventObj[fields.recurrenceRule] && eventObj[fields.recurrenceException]) {
24911
24998
  const exDate = (eventObj[fields.recurrenceException]).split(',');