@syncfusion/ej2-schedule 20.4.52 → 21.1.35

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 (114) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/ej2-schedule.min.js +2 -2
  3. package/dist/ej2-schedule.umd.min.js +2 -2
  4. package/dist/ej2-schedule.umd.min.js.map +1 -1
  5. package/dist/es6/ej2-schedule.es2015.js +374 -153
  6. package/dist/es6/ej2-schedule.es2015.js.map +1 -1
  7. package/dist/es6/ej2-schedule.es5.js +409 -174
  8. package/dist/es6/ej2-schedule.es5.js.map +1 -1
  9. package/dist/global/ej2-schedule.min.js +2 -2
  10. package/dist/global/ej2-schedule.min.js.map +1 -1
  11. package/dist/global/index.d.ts +1 -1
  12. package/package.json +16 -16
  13. package/src/common/calendar-util.d.ts +7 -0
  14. package/src/recurrence-editor/recurrence-editor.d.ts +10 -0
  15. package/src/recurrence-editor/recurrence-editor.js +3 -3
  16. package/src/schedule/actions/action-base.js +5 -0
  17. package/src/schedule/actions/crud.js +14 -2
  18. package/src/schedule/actions/data.d.ts +14 -2
  19. package/src/schedule/actions/data.js +26 -2
  20. package/src/schedule/actions/drag.js +6 -1
  21. package/src/schedule/actions/keyboard.d.ts +1 -1
  22. package/src/schedule/actions/keyboard.js +17 -15
  23. package/src/schedule/actions/virtual-scroll.js +2 -2
  24. package/src/schedule/base/interface.d.ts +23 -23
  25. package/src/schedule/base/resource.js +8 -7
  26. package/src/schedule/base/schedule-model.d.ts +34 -27
  27. package/src/schedule/base/schedule.d.ts +57 -27
  28. package/src/schedule/base/schedule.js +56 -9
  29. package/src/schedule/base/type.d.ts +66 -1
  30. package/src/schedule/event-renderer/agenda-base.js +6 -2
  31. package/src/schedule/event-renderer/event-base.d.ts +1 -0
  32. package/src/schedule/event-renderer/event-base.js +27 -10
  33. package/src/schedule/event-renderer/month.js +4 -5
  34. package/src/schedule/event-renderer/vertical-view.d.ts +0 -1
  35. package/src/schedule/event-renderer/vertical-view.js +6 -30
  36. package/src/schedule/event-renderer/year.d.ts +1 -0
  37. package/src/schedule/event-renderer/year.js +135 -54
  38. package/src/schedule/models/event-settings-model.d.ts +11 -2
  39. package/src/schedule/models/event-settings.d.ts +10 -2
  40. package/src/schedule/models/event-settings.js +3 -0
  41. package/src/schedule/models/fields-model.d.ts +4 -2
  42. package/src/schedule/models/fields.d.ts +6 -4
  43. package/src/schedule/models/fields.js +2 -2
  44. package/src/schedule/models/header-rows-model.d.ts +5 -5
  45. package/src/schedule/models/header-rows.d.ts +5 -5
  46. package/src/schedule/models/quick-info-templates-model.d.ts +3 -3
  47. package/src/schedule/models/quick-info-templates.d.ts +3 -3
  48. package/src/schedule/models/views-model.d.ts +16 -15
  49. package/src/schedule/models/views.d.ts +16 -15
  50. package/src/schedule/popups/event-tooltip.js +2 -1
  51. package/src/schedule/popups/event-window.js +27 -6
  52. package/src/schedule/popups/quick-popups.js +32 -10
  53. package/src/schedule/renderer/header-renderer.js +1 -0
  54. package/src/schedule/renderer/month-agenda.d.ts +2 -1
  55. package/src/schedule/renderer/month-agenda.js +5 -0
  56. package/src/schedule/renderer/month.d.ts +1 -0
  57. package/src/schedule/renderer/month.js +5 -3
  58. package/src/schedule/renderer/timeline-year.js +12 -8
  59. package/src/schedule/renderer/vertical-view.js +1 -1
  60. package/src/schedule/renderer/view-base.js +3 -4
  61. package/src/schedule/renderer/year.js +5 -1
  62. package/styles/bootstrap-dark.css +99 -89
  63. package/styles/bootstrap.css +99 -89
  64. package/styles/bootstrap4.css +99 -89
  65. package/styles/bootstrap5-dark.css +110 -100
  66. package/styles/bootstrap5.css +110 -100
  67. package/styles/fabric-dark.css +98 -88
  68. package/styles/fabric.css +98 -88
  69. package/styles/fluent-dark.css +109 -99
  70. package/styles/fluent.css +109 -99
  71. package/styles/highcontrast-light.css +98 -88
  72. package/styles/highcontrast.css +98 -88
  73. package/styles/material-dark.css +98 -88
  74. package/styles/material.css +98 -88
  75. package/styles/recurrence-editor/_bootstrap5-definition.scss +1 -1
  76. package/styles/recurrence-editor/_fluent-definition.scss +1 -1
  77. package/styles/recurrence-editor/_tailwind-definition.scss +1 -1
  78. package/styles/schedule/_bootstrap-dark-definition.scss +8 -1
  79. package/styles/schedule/_bootstrap-definition.scss +8 -1
  80. package/styles/schedule/_bootstrap4-definition.scss +7 -0
  81. package/styles/schedule/_bootstrap5-definition.scss +17 -10
  82. package/styles/schedule/_fabric-dark-definition.scss +7 -0
  83. package/styles/schedule/_fabric-definition.scss +7 -0
  84. package/styles/schedule/_fluent-definition.scss +15 -8
  85. package/styles/schedule/_fusionnew-definition.scss +7 -0
  86. package/styles/schedule/_highcontrast-definition.scss +7 -0
  87. package/styles/schedule/_highcontrast-light-definition.scss +7 -0
  88. package/styles/schedule/_layout.scss +63 -48
  89. package/styles/schedule/_material-dark-definition.scss +7 -0
  90. package/styles/schedule/_material-definition.scss +7 -0
  91. package/styles/schedule/_tailwind-definition.scss +17 -10
  92. package/styles/schedule/_theme.scss +40 -41
  93. package/styles/schedule/bootstrap-dark.css +99 -89
  94. package/styles/schedule/bootstrap.css +99 -89
  95. package/styles/schedule/bootstrap4.css +99 -89
  96. package/styles/schedule/bootstrap5-dark.css +110 -100
  97. package/styles/schedule/bootstrap5.css +110 -100
  98. package/styles/schedule/fabric-dark.css +98 -88
  99. package/styles/schedule/fabric.css +98 -88
  100. package/styles/schedule/fluent-dark.css +109 -99
  101. package/styles/schedule/fluent.css +109 -99
  102. package/styles/schedule/highcontrast-light.css +98 -88
  103. package/styles/schedule/highcontrast.css +98 -88
  104. package/styles/schedule/material-dark.css +98 -88
  105. package/styles/schedule/material.css +98 -88
  106. package/styles/schedule/tailwind-dark.css +106 -96
  107. package/styles/schedule/tailwind.css +106 -96
  108. package/styles/tailwind-dark.css +106 -96
  109. package/styles/tailwind.css +106 -96
  110. package/GitLeaksReport.json +0 -1
  111. package/gitleaks-ci/gitleaks +0 -0
  112. package/gitleaks-ci.tar.gz +0 -0
  113. package/styles/recurrence-editor/_material3-definition.scss +0 -13
  114. package/styles/schedule/_material3-definition.scss +0 -283
@@ -1021,6 +1021,7 @@ class HeaderRenderer {
1021
1021
  overflowMode: 'Popup',
1022
1022
  clicked: this.toolbarClickHandler.bind(this),
1023
1023
  enableRtl: this.parent.enableRtl,
1024
+ enableHtmlSanitizer: this.parent.enableHtmlSanitizer,
1024
1025
  locale: this.parent.locale
1025
1026
  });
1026
1027
  this.toolbarObj.appendTo(this.parent.element.querySelector('.' + HEADER_TOOLBAR));
@@ -2049,7 +2050,7 @@ class KeyboardInteraction {
2049
2050
  if (this.parent.eventWindow) {
2050
2051
  this.parent.eventWindow.convertToEventData(this.parent.activeCellsData, cellData);
2051
2052
  }
2052
- const selectedCells = this.parent.getSelectedElements();
2053
+ const selectedCells = this.parent.getSelectedCells();
2053
2054
  const args = {
2054
2055
  data: cellData, element: this.parent.activeCellsData.element, event: e,
2055
2056
  requestType: cellSelect, showQuickPopup: false
@@ -2273,15 +2274,16 @@ class KeyboardInteraction {
2273
2274
  const args = {
2274
2275
  element: target, requestType: cellSelect
2275
2276
  };
2276
- const cellData = {};
2277
- const cellDetails = this.parent.getCellDetails(target);
2278
- if (this.parent.eventWindow && cellDetails) {
2279
- if (this.parent.activeCellsData.element !== cellDetails.element) {
2280
- this.parent.activeCellsData = cellDetails;
2281
- }
2282
- this.parent.eventWindow.convertToEventData(this.parent.activeCellsData, cellData);
2283
- args.data = cellData;
2284
- }
2277
+ // activeCellsData is not reset on schedule property changed(group properties)
2278
+ // const cellData: Record<string, any> = {};
2279
+ // const cellDetails: CellClickEventArgs = this.parent.getCellDetails(target);
2280
+ // if (this.parent.eventWindow && cellDetails) {
2281
+ // if (this.parent.activeCellsData.element !== cellDetails.element) {
2282
+ // this.parent.activeCellsData = cellDetails;
2283
+ // }
2284
+ // this.parent.eventWindow.convertToEventData(this.parent.activeCellsData as unknown as Record<string, any>, cellData);
2285
+ // args.data = cellData;
2286
+ // }
2285
2287
  this.parent.trigger(select, args, () => {
2286
2288
  this.initialTarget = target;
2287
2289
  this.selectedCells = [target];
@@ -2397,7 +2399,7 @@ class KeyboardInteraction {
2397
2399
  return;
2398
2400
  }
2399
2401
  let target = (e.target);
2400
- const selectedElements = this.parent.getSelectedElements();
2402
+ const selectedElements = this.parent.getSelectedCells();
2401
2403
  const selectedEventElements = this.parent.eventBase.getSelectedAppointments();
2402
2404
  const moreEventWrapper = this.parent.element.querySelector('.' + MORE_POPUP_WRAPPER_CLASS);
2403
2405
  const quickPopupWrapper = this.getQuickPopupElement();
@@ -2444,7 +2446,7 @@ class KeyboardInteraction {
2444
2446
  return;
2445
2447
  }
2446
2448
  let target = (e.target);
2447
- const selectedCells = this.parent.getSelectedElements();
2449
+ const selectedCells = this.parent.getSelectedCells();
2448
2450
  const selectedElements = this.parent.eventBase.getSelectedAppointments();
2449
2451
  const moreEventWrapper = this.parent.element.querySelector('.' + MORE_POPUP_WRAPPER_CLASS);
2450
2452
  const quickPopupWrapper = this.getQuickPopupElement();
@@ -2552,7 +2554,7 @@ class KeyboardInteraction {
2552
2554
  if (this.isCancelLeftRightAction(e, isMultiple, isTimelineYear)) {
2553
2555
  return;
2554
2556
  }
2555
- const selectedCells = this.parent.getSelectedElements();
2557
+ const selectedCells = this.parent.getSelectedCells();
2556
2558
  let targetCell;
2557
2559
  const selectedAppointments = this.parent.eventBase.getSelectedAppointments();
2558
2560
  let target = (e.target);
@@ -2624,7 +2626,7 @@ class KeyboardInteraction {
2624
2626
  return;
2625
2627
  }
2626
2628
  let target = (e.target);
2627
- const selectedCells = this.parent.getSelectedElements();
2629
+ const selectedCells = this.parent.getSelectedCells();
2628
2630
  let targetCell;
2629
2631
  if (selectedCells.length > 0 && !target.classList.contains(WORK_CELLS_CLASS) &&
2630
2632
  !target.classList.contains(ALLDAY_CELLS_CLASS)) {
@@ -2848,7 +2850,7 @@ class KeyboardInteraction {
2848
2850
  }
2849
2851
  return;
2850
2852
  }
2851
- const selectedCells = this.parent.getSelectedElements();
2853
+ const selectedCells = this.parent.getSelectedCells();
2852
2854
  if (selectedCells.length > 0 && !target.classList.contains(APPOINTMENT_CLASS)) {
2853
2855
  target = selectedCells[selectedCells.length - 1];
2854
2856
  this.selectAppointmentElementFromWorkCell(isReverse, target);
@@ -2967,6 +2969,7 @@ class KeyboardInteraction {
2967
2969
  */
2968
2970
  destroy() {
2969
2971
  this.removeEventListener();
2972
+ this.selectedCells = [];
2970
2973
  this.keyboardModule.destroy();
2971
2974
  }
2972
2975
  }
@@ -2981,11 +2984,13 @@ class Data {
2981
2984
  /**
2982
2985
  * Constructor for data module
2983
2986
  *
2987
+ * @param {Schedule} parent Accepts the schedule element instance
2984
2988
  * @param {Object | DataManager} dataSource Accepts the datasource as JSON objects or DataManager
2985
2989
  * @param {Query} query Accepts the query to process the data
2986
2990
  * @private
2987
2991
  */
2988
- constructor(dataSource, query) {
2992
+ constructor(parent, dataSource, query) {
2993
+ this.parent = parent;
2989
2994
  this.initDataManager(dataSource, query);
2990
2995
  }
2991
2996
  /**
@@ -3010,6 +3015,11 @@ class Data {
3010
3015
  */
3011
3016
  generateQuery(startDate, endDate) {
3012
3017
  const query = this.query.clone();
3018
+ if (this.parent && this.parent.eventSettings.includeFiltersInQuery && startDate && endDate) {
3019
+ const dateQuery = this.getStartEndQuery(startDate, endDate);
3020
+ const recurrenceQuery = new Predicate(this.parent.eventFields.recurrenceRule, 'notequal', null).and(new Predicate(this.parent.eventFields.recurrenceRule, 'notequal', ''));
3021
+ return query.where(dateQuery.or(recurrenceQuery));
3022
+ }
3013
3023
  if (startDate) {
3014
3024
  query.addParams('StartDate', startDate.toISOString());
3015
3025
  }
@@ -3018,6 +3028,23 @@ class Data {
3018
3028
  }
3019
3029
  return query;
3020
3030
  }
3031
+ /**
3032
+ * The function used to generate updated Query from schedule model
3033
+ *
3034
+ * @param {Date} startDate Accepts the start date
3035
+ * @param {Date} endDate Accepts the end date
3036
+ * @returns {void}
3037
+ * @private
3038
+ */
3039
+ getStartEndQuery(startDate, endDate) {
3040
+ const fieldMapping = this.parent.eventFields;
3041
+ const dateQuery = new Predicate(fieldMapping.startTime, 'greaterthanorequal', startDate)
3042
+ .and(new Predicate(fieldMapping.endTime, 'greaterthanorequal', startDate))
3043
+ .and(new Predicate(fieldMapping.startTime, 'lessthan', endDate))
3044
+ .or(new Predicate(fieldMapping.startTime, 'lessthanorequal', startDate)
3045
+ .and(new Predicate(fieldMapping.endTime, 'greaterthan', startDate)));
3046
+ return dateQuery;
3047
+ }
3021
3048
  /**
3022
3049
  * The function used to get dataSource by executing given Query
3023
3050
  *
@@ -5395,12 +5422,7 @@ class EventBase {
5395
5422
  return this.filterEvents(eStart, eEnd, blockEvents, resourceData);
5396
5423
  }
5397
5424
  filterEvents(startDate, endDate, appointments = this.parent.eventsProcessed, resourceTdData) {
5398
- const fieldMapping = this.parent.eventFields;
5399
- const predicate = new Predicate(fieldMapping.startTime, 'greaterthanorequal', startDate).
5400
- and(new Predicate(fieldMapping.endTime, 'greaterthanorequal', startDate)).
5401
- and(new Predicate(fieldMapping.startTime, 'lessthan', endDate)).
5402
- or(new Predicate(fieldMapping.startTime, 'lessthanorequal', startDate).
5403
- and(new Predicate(fieldMapping.endTime, 'greaterthan', startDate)));
5425
+ const predicate = this.parent.dataModule.getStartEndQuery(startDate, endDate);
5404
5426
  let filter = new DataManager({ json: appointments }).executeLocal(new Query().where(predicate));
5405
5427
  if (resourceTdData) {
5406
5428
  filter = this.filterEventsByResource(resourceTdData, filter);
@@ -5706,7 +5728,7 @@ class EventBase {
5706
5728
  return;
5707
5729
  }
5708
5730
  const activeEle = document.activeElement;
5709
- const selectedCell = this.parent.getSelectedElements();
5731
+ const selectedCell = this.parent.getSelectedCells();
5710
5732
  if (selectedCell.length > 0 && ((activeEle && (this.parent.element.contains(activeEle) ||
5711
5733
  selectedCell.indexOf(activeEle) !== -1)) || isFocused)) {
5712
5734
  if (this.parent.keyboardInteractionModule) {
@@ -6233,9 +6255,8 @@ class EventBase {
6233
6255
  templateElement = this.parent.getAppointmentTemplate()(record, this.parent, templateName, templateId, false);
6234
6256
  }
6235
6257
  else {
6236
- const appointmentSubject = createElement('div', {
6237
- className: SUBJECT_CLASS, innerHTML: eventSubject
6238
- });
6258
+ const appointmentSubject = createElement('div', { className: SUBJECT_CLASS });
6259
+ appointmentSubject.innerText = this.parent.sanitize(eventSubject);
6239
6260
  templateElement = [appointmentSubject];
6240
6261
  }
6241
6262
  append(templateElement, appointmentWrapper);
@@ -6413,6 +6434,29 @@ class EventBase {
6413
6434
  return eventArgs && eventArgs.changedTouches ? eventArgs.changedTouches[0] : e.changedTouches ? e.changedTouches[0] :
6414
6435
  eventArgs || e;
6415
6436
  }
6437
+ renderSpannedIcon(element, spanEvent) {
6438
+ const iconElement = createElement('div', { className: EVENT_INDICATOR_CLASS + ' ' + ICON });
6439
+ if (spanEvent.isLeft) {
6440
+ const iconLeft = iconElement.cloneNode();
6441
+ addClass([iconLeft], EVENT_ICON_LEFT_CLASS);
6442
+ prepend([iconLeft], element);
6443
+ }
6444
+ if (spanEvent.isRight) {
6445
+ const iconRight = iconElement.cloneNode();
6446
+ addClass([iconRight], EVENT_ICON_RIGHT_CLASS);
6447
+ append([iconRight], element);
6448
+ }
6449
+ if (spanEvent.isTop) {
6450
+ const iconTop = iconElement.cloneNode();
6451
+ addClass([iconTop], EVENT_ICON_UP_CLASS);
6452
+ prepend([iconTop], element);
6453
+ }
6454
+ if (spanEvent.isBottom) {
6455
+ const iconBottom = iconElement.cloneNode();
6456
+ addClass([iconBottom], EVENT_ICON_DOWN_CLASS);
6457
+ append([iconBottom], element);
6458
+ }
6459
+ }
6416
6460
  unWireEvents() {
6417
6461
  const appElements = [].slice.call(this.parent.element.querySelectorAll('.' + APPOINTMENT_CLASS));
6418
6462
  for (const element of appElements) {
@@ -6737,7 +6781,8 @@ class VerticalEvent extends EventBase {
6737
6781
  templateElement = this.parent.getAppointmentTemplate()(record, this.parent, templateName, templateId, false);
6738
6782
  }
6739
6783
  else {
6740
- const appointmentSubject = createElement('div', { className: SUBJECT_CLASS, innerHTML: recordSubject });
6784
+ const appointmentSubject = createElement('div', { className: SUBJECT_CLASS });
6785
+ appointmentSubject.innerText = this.parent.sanitize(recordSubject);
6741
6786
  if (isAllDay) {
6742
6787
  if (record[fieldMapping.isAllDay]) {
6743
6788
  templateElement = [appointmentSubject];
@@ -6769,10 +6814,8 @@ class VerticalEvent extends EventBase {
6769
6814
  className: APPOINTMENT_TIME + (this.parent.isAdaptive ? ' ' + DISABLE_CLASS : ''),
6770
6815
  innerHTML: timeStr
6771
6816
  });
6772
- const appointmentLocation = createElement('div', {
6773
- className: LOCATION_CLASS,
6774
- innerHTML: (record[fieldMapping.location] || this.parent.eventSettings.fields.location.default || '')
6775
- });
6817
+ const appointmentLocation = createElement('div', { className: LOCATION_CLASS });
6818
+ appointmentLocation.innerText = this.parent.sanitize((record[fieldMapping.location] || this.parent.eventSettings.fields.location.default || ''));
6776
6819
  templateElement = [appointmentSubject, appointmentTime, appointmentLocation];
6777
6820
  }
6778
6821
  }
@@ -6789,7 +6832,7 @@ class VerticalEvent extends EventBase {
6789
6832
  appointmentWrapper.appendChild(recurrenceIcon);
6790
6833
  }
6791
6834
  }
6792
- this.renderSpannedIcon(isAllDay ? appointmentDetails : appointmentWrapper, eventData);
6835
+ this.parent.eventBase.renderSpannedIcon(isAllDay ? appointmentDetails : appointmentWrapper, eventData);
6793
6836
  if (!isNullOrUndefined(this.cssClass)) {
6794
6837
  addClass([appointmentWrapper], this.cssClass);
6795
6838
  }
@@ -6821,29 +6864,6 @@ class VerticalEvent extends EventBase {
6821
6864
  countCell.innerHTML = '+' + this.parent.globalize.formatNumber(moreCount) + '&nbsp;' + (this.parent.isAdaptive ? '' : this.parent.localeObj.getConstant('more'));
6822
6865
  }
6823
6866
  }
6824
- renderSpannedIcon(element, spanEvent) {
6825
- const iconElement = createElement('div', { className: EVENT_INDICATOR_CLASS + ' ' + ICON });
6826
- if (spanEvent.isLeft) {
6827
- const iconLeft = iconElement.cloneNode();
6828
- addClass([iconLeft], EVENT_ICON_LEFT_CLASS);
6829
- prepend([iconLeft], element);
6830
- }
6831
- if (spanEvent.isRight) {
6832
- const iconRight = iconElement.cloneNode();
6833
- addClass([iconRight], EVENT_ICON_RIGHT_CLASS);
6834
- append([iconRight], element);
6835
- }
6836
- if (spanEvent.isTop) {
6837
- const iconTop = iconElement.cloneNode();
6838
- addClass([iconTop], EVENT_ICON_UP_CLASS);
6839
- prepend([iconTop], element);
6840
- }
6841
- if (spanEvent.isBottom) {
6842
- const iconBottom = iconElement.cloneNode();
6843
- addClass([iconBottom], EVENT_ICON_DOWN_CLASS);
6844
- append([iconBottom], element);
6845
- }
6846
- }
6847
6867
  isSpannedEvent(record, day, resource) {
6848
6868
  let currentDate = resetTime(this.dateRender[parseInt(resource.toString(), 10)][parseInt(day.toString(), 10)]);
6849
6869
  const renderedDate = this.getRenderedDates(this.dateRender[parseInt(resource.toString(), 10)]) || [currentDate];
@@ -7645,10 +7665,8 @@ class MonthEvent extends EventBase {
7645
7665
  }
7646
7666
  else {
7647
7667
  const eventLocation = (record[this.fields.location] || this.parent.eventSettings.fields.location.default || '');
7648
- const appointmentSubject = createElement('div', {
7649
- className: SUBJECT_CLASS,
7650
- innerHTML: (eventSubject + (eventLocation ? ';&nbsp' + eventLocation : ''))
7651
- });
7668
+ const appointmentSubject = createElement('div', { className: SUBJECT_CLASS });
7669
+ appointmentSubject.innerText = this.parent.sanitize((eventSubject + (eventLocation ? '; ' + eventLocation : '')));
7652
7670
  const appointmentStartTime = createElement('div', {
7653
7671
  className: APPOINTMENT_TIME + (this.parent.isAdaptive ? ' ' + DISABLE_CLASS : ''),
7654
7672
  innerHTML: this.parent.getTimeString(eventData[this.fields.startTime])
@@ -7691,7 +7709,8 @@ class MonthEvent extends EventBase {
7691
7709
  const appTime = createElement('div', {
7692
7710
  className: APPOINTMENT_TIME + (this.parent.isAdaptive ? ' ' + DISABLE_CLASS : ''), innerHTML: timeString
7693
7711
  });
7694
- const appLocation = createElement('div', { className: LOCATION_CLASS, innerHTML: eventLocation });
7712
+ const appLocation = createElement('div', { className: LOCATION_CLASS });
7713
+ appLocation.innerText = this.parent.sanitize(eventLocation);
7695
7714
  innerElement = [appointmentSubject, appTime, appLocation];
7696
7715
  }
7697
7716
  const wrap = createElement('div', { className: 'e-inner-wrap' });
@@ -8887,6 +8906,7 @@ class QuickPopups {
8887
8906
  cssClass: QUICK_DIALOG_CLASS,
8888
8907
  closeOnEscape: true,
8889
8908
  enableRtl: this.parent.enableRtl,
8909
+ enableHtmlSanitizer: this.parent.enableHtmlSanitizer,
8890
8910
  beforeClose: this.beforeQuickDialogClose.bind(this),
8891
8911
  isModal: true,
8892
8912
  position: { X: 'center', Y: 'center' },
@@ -8918,6 +8938,7 @@ class QuickPopups {
8918
8938
  cssClass: className,
8919
8939
  disabled: isDisabled,
8920
8940
  enableRtl: this.parent.enableRtl,
8941
+ enableHtmlSanitizer: this.parent.enableHtmlSanitizer,
8921
8942
  iconCss: iconName
8922
8943
  });
8923
8944
  buttonObj.appendTo(element);
@@ -9111,7 +9132,8 @@ class QuickPopups {
9111
9132
  append(templateElement, appointmentElement);
9112
9133
  }
9113
9134
  else {
9114
- appointmentElement.appendChild(createElement('div', { className: SUBJECT_CLASS, innerHTML: eventText }));
9135
+ appointmentElement.appendChild(createElement('div', { className: SUBJECT_CLASS }));
9136
+ appointmentElement.firstElementChild.innerText = this.parent.sanitize(eventText);
9115
9137
  }
9116
9138
  if (!isNullOrUndefined(groupIndex)) {
9117
9139
  appointmentElement.setAttribute('data-group-index', groupIndex);
@@ -9360,10 +9382,14 @@ class QuickPopups {
9360
9382
  `<button class="${DELETE_CLASS + ' ' + ICON}" title="${this.l10n.getConstant('delete')}"></button>` +
9361
9383
  `<button class="${CLOSE_CLASS}" title="${this.l10n.getConstant('close')}"></button></div>` +
9362
9384
  `<div class="${SUBJECT_WRAP}"><div class="${SUBJECT_CLASS} ${TEXT_ELLIPSIS}" ` +
9363
- `title="${args.eventSubject ? args.eventSubject.replaceAll('"', '\'') : args.eventSubject}">${args.eventSubject}</div></div >`;
9385
+ `title="${args.eventSubject ? args.eventSubject.replaceAll('"', '\'') : args.eventSubject}"></div></div >`;
9364
9386
  break;
9365
9387
  }
9366
9388
  const templateWrapper = createElement('div', { innerHTML: header });
9389
+ if (headerType === 'Event') {
9390
+ const subjectText = templateWrapper.querySelector('.' + SUBJECT_CLASS);
9391
+ subjectText.innerText = this.parent.sanitize(args.eventSubject);
9392
+ }
9367
9393
  append([].slice.call(templateWrapper.childNodes), headerTemplate);
9368
9394
  }
9369
9395
  return headerTemplate;
@@ -9391,7 +9417,7 @@ class QuickPopups {
9391
9417
  `${TEXT_ELLIPSIS}">${cellDetails.details}</div></div>` +
9392
9418
  `${this.parent.activeViewOptions.group.resources.length > 0 ? `<div class="${RESOURCE_CLASS}">` +
9393
9419
  `<div class="${RESOURCE_ICON_CLASS} ${ICON} "></div><div class="${RESOURCE_DETAILS_CLASS} ` +
9394
- `${TEXT_ELLIPSIS}">${resourceText}</div></div>` : ''}</td></tr></tbody></table>`;
9420
+ `${TEXT_ELLIPSIS}"></div></div>` : ''}</td></tr></tbody></table>`;
9395
9421
  break;
9396
9422
  case 'Event':
9397
9423
  argsData = this.getFormattedString(data);
@@ -9405,8 +9431,7 @@ class QuickPopups {
9405
9431
  content += '</div></div>';
9406
9432
  if (data[this.parent.eventFields.location]) {
9407
9433
  content += '<div class="' + LOCATION_CLASS + '"><div class="' + LOCATION_ICON_CLASS + ' ' +
9408
- ICON + '"></div><div class="' + LOCATION_DETAILS_CLASS + ' ' + TEXT_ELLIPSIS + '">' +
9409
- data[this.parent.eventFields.location] + '</div></div>';
9434
+ ICON + '"></div><div class="' + LOCATION_DETAILS_CLASS + ' ' + TEXT_ELLIPSIS + '"></div></div>';
9410
9435
  }
9411
9436
  if (data[this.parent.eventFields.startTimezone] || data[this.parent.eventFields.endTimezone]) {
9412
9437
  content += '<div class="' + TIME_ZONE_CLASS + '"><div class="' + TIME_ZONE_ICON_CLASS + ' ' + ICON +
@@ -9415,17 +9440,33 @@ class QuickPopups {
9415
9440
  }
9416
9441
  if (data[this.parent.eventFields.description]) {
9417
9442
  content += '<div class="' + DESCRIPTION_CLASS + '"><div class="' + DESCRIPTION_ICON_CLASS + ' ' + ICON +
9418
- '"></div><div class="' + DESCRIPTION_DETAILS_CLASS + ' ' + TEXT_ELLIPSIS + '">' +
9419
- data[this.parent.eventFields.description] + '</div></div>';
9443
+ '"></div><div class="' + DESCRIPTION_DETAILS_CLASS + ' ' + TEXT_ELLIPSIS + '"></div></div>';
9420
9444
  }
9421
9445
  if (this.parent.resourceCollection.length > 0) {
9422
9446
  content += '<div class="' + RESOURCE_CLASS + '"><div class="' + RESOURCE_ICON_CLASS + ' ' + ICON +
9423
- '"></div><div class="' + RESOURCE_DETAILS_CLASS + ' ' + TEXT_ELLIPSIS + '">' +
9424
- resourceText + '</div></div>';
9447
+ '"></div><div class="' + RESOURCE_DETAILS_CLASS + ' ' + TEXT_ELLIPSIS + '"></div></div>';
9425
9448
  }
9426
9449
  break;
9427
9450
  }
9428
9451
  const templateWrapper = createElement('div', { innerHTML: content });
9452
+ if (data[this.parent.eventFields.location]) {
9453
+ const locationDetails = templateWrapper.querySelector('.' + LOCATION_DETAILS_CLASS);
9454
+ if (!isNullOrUndefined(locationDetails)) {
9455
+ locationDetails.innerText = this.parent.sanitize(data[this.parent.eventFields.location]);
9456
+ }
9457
+ }
9458
+ if (data[this.parent.eventFields.description]) {
9459
+ const descriptionDetails = templateWrapper.querySelector('.' + DESCRIPTION_DETAILS_CLASS);
9460
+ if (!isNullOrUndefined(descriptionDetails)) {
9461
+ descriptionDetails.innerText = this.parent.sanitize(data[this.parent.eventFields.description]);
9462
+ }
9463
+ }
9464
+ if (resourceText) {
9465
+ const resourceDetails = templateWrapper.querySelector('.' + RESOURCE_DETAILS_CLASS);
9466
+ if (!isNullOrUndefined(resourceDetails)) {
9467
+ resourceDetails.innerText = this.parent.sanitize(resourceText);
9468
+ }
9469
+ }
9429
9470
  append([].slice.call(templateWrapper.childNodes), contentTemplate);
9430
9471
  }
9431
9472
  return contentTemplate;
@@ -9954,7 +9995,7 @@ class QuickPopups {
9954
9995
  }
9955
9996
  quickPopupClose() {
9956
9997
  this.parent.eventBase.focusElement();
9957
- this.quickPopup.relateTo = WORK_CELLS_CLASS;
9998
+ this.quickPopup.relateTo = '.' + WORK_CELLS_CLASS;
9958
9999
  this.fieldValidator.destroyToolTip();
9959
10000
  if (this.quickPopup.element.querySelectorAll('.e-formvalidator').length) {
9960
10001
  this.fieldValidator.destroy();
@@ -10171,7 +10212,8 @@ class EventTooltip {
10171
10212
  target: this.getTargets(),
10172
10213
  beforeRender: this.onBeforeRender.bind(this),
10173
10214
  beforeClose: this.onBeforeClose.bind(this),
10174
- enableRtl: this.parent.enableRtl
10215
+ enableRtl: this.parent.enableRtl,
10216
+ enableHtmlSanitizer: this.parent.enableHtmlSanitizer
10175
10217
  });
10176
10218
  this.tooltipObj.appendTo(this.parent.element);
10177
10219
  }
@@ -10981,7 +11023,7 @@ let RecurrenceEditor = class RecurrenceEditor extends Component {
10981
11023
  '"label="' + REPEATELEMENT.substr(2) + '" />' +
10982
11024
  '</div><div class="' + INPUTWARAPPER + ' ' +
10983
11025
  INTERVALCLASS + ' ' + FORMRIGHT + '"><table class="' + RECURRENCETABLE + ' ' + REPEATCONTENTWRAPPER + '"><tr>' +
10984
- '<td><input type="text" tabindex="0" class="' + REPEATINTERVAL +
11026
+ '<td><input type="text" tabindex="0" id="' + this.element.id + '_' + REPEATINTERVAL + '" class="' + REPEATINTERVAL +
10985
11027
  '"title="' + this.localeObj.getConstant('repeatEvery') + '" /></td>' +
10986
11028
  '<td><span class="' + REPEATCONTENT + '"></span></td>' +
10987
11029
  '</tr></table></div><div class="' + INPUTWARAPPERSIDE + ' ' + DAYWRAPPER + ' ' + FORMLEFT + '">' +
@@ -11005,7 +11047,7 @@ let RecurrenceEditor = class RecurrenceEditor extends Component {
11005
11047
  '<input class="' + MONTHEXPANDERELEMENT + '"title="' + this.localeObj.getConstant('monthExpander') + '" type="radio">' +
11006
11048
  '</div></td>' +
11007
11049
  '<td colspan="2"><div class="' + INPUTWARAPPER + ' ' + MONTHDAYELEMENT + '">' +
11008
- '<input type="text" tabindex="0" class="' + MONTHDAYWRAPPER + '"title="' +
11050
+ '<input type="text" tabindex="0" id="' + this.element.id + '_' + MONTHDAYWRAPPER + '" class="' + MONTHDAYWRAPPER + '"title="' +
11009
11051
  this.localeObj.getConstant('on') + '" />' +
11010
11052
  '</div></td></tr>' +
11011
11053
  '<tr><td>' +
@@ -11028,7 +11070,7 @@ let RecurrenceEditor = class RecurrenceEditor extends Component {
11028
11070
  '<input type="text" tabindex="0" class="' + UNTILDATE + '"title="' + this.localeObj.getConstant(UNTIL$1) + '" />' +
11029
11071
  '</div>' +
11030
11072
  '<div class="' + INPUTWARAPPER + ' ' + ENDONCOUNTWRAPPER + '">' +
11031
- '<input type="text" tabindex="0" class="' + ENDONCOUNT + '"title="' + this.localeObj.getConstant(COUNT) + '" />' +
11073
+ '<input type="text" tabindex="0" id="' + this.element.id + '_' + ENDONCOUNT + '" class="' + ENDONCOUNT + '"title="' + this.localeObj.getConstant(COUNT) + '" />' +
11032
11074
  '</div></div>' +
11033
11075
  '</div></div>';
11034
11076
  }
@@ -11433,6 +11475,7 @@ class EventWindow {
11433
11475
  content: this.getEventWindowContent(),
11434
11476
  cssClass: EVENT_WINDOW_DIALOG_CLASS,
11435
11477
  enableRtl: this.parent.enableRtl,
11478
+ enableHtmlSanitizer: this.parent.enableHtmlSanitizer,
11436
11479
  height: this.parent.isAdaptive ? '100%' : 'auto',
11437
11480
  minHeight: '300px',
11438
11481
  isModal: true,
@@ -11640,6 +11683,10 @@ class EventWindow {
11640
11683
  renderFormElements(form, args) {
11641
11684
  if (!isNullOrUndefined(this.parent.editorTemplate)) {
11642
11685
  if (args) {
11686
+ if (this.fieldValidator) {
11687
+ this.fieldValidator.destroy();
11688
+ this.fieldValidator = null;
11689
+ }
11643
11690
  if (this.recurrenceEditor) {
11644
11691
  this.recurrenceEditor.destroy();
11645
11692
  this.recurrenceEditor = null;
@@ -11720,7 +11767,7 @@ class EventWindow {
11720
11767
  return parentDiv;
11721
11768
  }
11722
11769
  createRecurrenceEditor(parentDiv) {
11723
- const recurrenceEditor = this.createDivElement();
11770
+ const recurrenceEditor = createElement('div', { id: this.parent.element.id + '_recurrence_editor' });
11724
11771
  parentDiv.appendChild(recurrenceEditor);
11725
11772
  this.recurrenceEditor = this.renderRecurrenceEditor();
11726
11773
  this.recurrenceEditor.appendTo(recurrenceEditor);
@@ -11812,6 +11859,7 @@ class EventWindow {
11812
11859
  if (resourceData.allowMultiple) {
11813
11860
  const listObj = new MultiSelect({
11814
11861
  enableRtl: this.parent.enableRtl,
11862
+ enableHtmlSanitizer: this.parent.enableHtmlSanitizer,
11815
11863
  cssClass: this.parent.cssClass || '',
11816
11864
  dataSource: resourceData.dataSource,
11817
11865
  change: this.onMultiselectResourceChange.bind(this),
@@ -11949,6 +11997,7 @@ class EventWindow {
11949
11997
  change: this.onChange.bind(this),
11950
11998
  cssClass: value + ' ' + this.parent.cssClass,
11951
11999
  enableRtl: this.parent.enableRtl,
12000
+ enableHtmlSanitizer: this.parent.enableHtmlSanitizer,
11952
12001
  label: this.getFieldLabel(value)
11953
12002
  });
11954
12003
  checkBox.appendTo(checkBoxInput);
@@ -12075,6 +12124,7 @@ class EventWindow {
12075
12124
  target: this.element,
12076
12125
  animationSettings: { effect: 'Zoom' },
12077
12126
  enableRtl: this.parent.enableRtl,
12127
+ enableHtmlSanitizer: this.parent.enableHtmlSanitizer,
12078
12128
  isModal: true,
12079
12129
  cssClass: REPEAT_DIALOG_CLASS,
12080
12130
  open: this.repeatOpenDialog.bind(this)
@@ -12142,6 +12192,9 @@ class EventWindow {
12142
12192
  if (!this.parent.eventSettings.allowAdding) {
12143
12193
  return;
12144
12194
  }
12195
+ if (this.parent.isAdaptive && repeatType && !this.repeatDialogObject) {
12196
+ this.renderRepeatDialog();
12197
+ }
12145
12198
  this.element.querySelector('.' + FORM_CLASS).removeAttribute('data-id');
12146
12199
  this.element.querySelector('.' + EVENT_WINDOW_TITLE_TEXT_CLASS).innerHTML = this.l10n.getConstant('newEvent');
12147
12200
  eventObj.Timezone = false;
@@ -12171,10 +12224,18 @@ class EventWindow {
12171
12224
  selectedType: !isNullOrUndefined(repeatType) ? repeatType : !isNullOrUndefined(eventObj[this.fields.recurrenceRule]) ?
12172
12225
  this.recurrenceEditor.selectedType : 0
12173
12226
  });
12227
+ this.repeatRule = this.recurrenceEditor.value;
12174
12228
  }
12175
12229
  if (this.parent.isAdaptive && isNullOrUndefined(this.parent.editorTemplate)) {
12176
12230
  const element = this.element.querySelector('.' + REPEAT_CONTAINER_CLASS);
12177
- addClass([element], HIDE_STYLE_CLASS);
12231
+ if (eventObj[this.fields.recurrenceRule] || repeatType) {
12232
+ removeClass([element], HIDE_STYLE_CLASS);
12233
+ this.repeatStatus.setProperties({ checked: true });
12234
+ }
12235
+ else {
12236
+ addClass([element], HIDE_STYLE_CLASS);
12237
+ this.repeatStatus.setProperties({ checked: false });
12238
+ }
12178
12239
  this.updateRepeatLabel(this.repeatRule);
12179
12240
  }
12180
12241
  else {
@@ -12815,9 +12876,11 @@ class EventWindow {
12815
12876
  }
12816
12877
  const currentStartTime = new Date(+currentData[this.fields.startTime]);
12817
12878
  const currentEndTime = new Date(+currentData[this.fields.endTime]);
12879
+ let nextStartTime;
12880
+ let nextEndTime;
12818
12881
  if (index !== recurColl.length - 1) {
12819
- var nextStartTime = new Date(+recurColl[index + 1][this.fields.startTime]);
12820
- var nextEndTime = new Date(+recurColl[index + 1][this.fields.endTime]);
12882
+ nextStartTime = new Date(+recurColl[index + 1][this.fields.startTime]);
12883
+ nextEndTime = new Date(+recurColl[index + 1][this.fields.endTime]);
12821
12884
  }
12822
12885
  const lastEndTime = new Date(+recurColl[recurColl.length - 1][this.fields.endTime]);
12823
12886
  if (index === 0) {
@@ -13008,7 +13071,7 @@ class EventWindow {
13008
13071
  value = element.checked;
13009
13072
  }
13010
13073
  else {
13011
- value = SanitizeHtmlHelper.sanitize(element.value);
13074
+ value = this.parent.sanitize(element.value);
13012
13075
  }
13013
13076
  }
13014
13077
  return value;
@@ -13334,7 +13397,7 @@ class VirtualScroll {
13334
13397
  }
13335
13398
  if (!isNullOrUndefined(resCollection) && resCollection.length > 0) {
13336
13399
  this.parent.showSpinner();
13337
- const selectedEle = this.parent.getSelectedElements();
13400
+ const selectedEle = this.parent.getSelectedCells();
13338
13401
  this.focusedEle = selectedEle[selectedEle.length - 1] || this.focusedEle;
13339
13402
  this.updateContent(resWrap, conWrap, eventWrap, resCollection);
13340
13403
  this.setTranslate(resWrap, conWrap, eventWrap, timeIndicator);
@@ -13514,7 +13577,7 @@ class VirtualScroll {
13514
13577
  }
13515
13578
  updateHorizontalContent(conWrap, resCollection) {
13516
13579
  this.parent.resourceBase.expandedResources = resCollection;
13517
- const selectedEle = this.parent.getSelectedElements();
13580
+ const selectedEle = this.parent.getSelectedCells();
13518
13581
  this.focusedEle = selectedEle[selectedEle.length - 1] || this.focusedEle;
13519
13582
  const renderedLength = conWrap.querySelectorAll('tbody tr').length;
13520
13583
  for (let i = 0; i < renderedLength; i++) {
@@ -13904,7 +13967,9 @@ class Crud {
13904
13967
  }
13905
13968
  }
13906
13969
  }
13907
- this.parent.resetTemplates(templateNames);
13970
+ if (templateNames.length > 0) {
13971
+ this.parent.resetTemplates(templateNames);
13972
+ }
13908
13973
  }
13909
13974
  if (isVirtualScrollAction) {
13910
13975
  this.parent.notify(dataReady, { processedData: this.parent.eventsProcessed });
@@ -13978,6 +14043,9 @@ class Crud {
13978
14043
  return;
13979
14044
  }
13980
14045
  const addEvents = (eventData instanceof Array) ? eventData : [eventData];
14046
+ if (addEvents.length === 0) {
14047
+ return;
14048
+ }
13981
14049
  const args = {
13982
14050
  requestType: 'eventCreate', cancel: false, data: addEvents,
13983
14051
  addedRecords: addEvents, changedRecords: [], deletedRecords: []
@@ -14013,6 +14081,11 @@ class Crud {
14013
14081
  if (this.parent.currentAction !== 'EditFollowingEvents' && !this.isBlockEvent(eventData)
14014
14082
  && this.parent.eventBase.isBlockRange(eventData)) {
14015
14083
  this.parent.quickPopup.openValidationError('blockAlert', eventData);
14084
+ this.parent.crudModule.crudObj.isCrudAction = false;
14085
+ return;
14086
+ }
14087
+ const updateEvents = (eventData instanceof Array) ? eventData : [eventData];
14088
+ if (updateEvents.length === 0) {
14016
14089
  return;
14017
14090
  }
14018
14091
  this.parent.currentAction = action;
@@ -14033,7 +14106,6 @@ class Crud {
14033
14106
  }
14034
14107
  }
14035
14108
  else {
14036
- const updateEvents = (eventData instanceof Array) ? eventData : [eventData];
14037
14109
  const args = {
14038
14110
  requestType: 'eventChange', cancel: false, data: eventData,
14039
14111
  addedRecords: [], changedRecords: updateEvents, deletedRecords: []
@@ -14076,6 +14148,9 @@ class Crud {
14076
14148
  else {
14077
14149
  deleteEvents = (eventData instanceof Array ? eventData : [eventData]);
14078
14150
  }
14151
+ if (deleteEvents.length === 0) {
14152
+ return;
14153
+ }
14079
14154
  if (action) {
14080
14155
  switch (action) {
14081
14156
  case 'Delete':
@@ -14653,8 +14728,8 @@ var __decorate$7 = (undefined && undefined.__decorate) || function (decorators,
14653
14728
  return c > 3 && r && Object.defineProperty(target, key, r), r;
14654
14729
  };
14655
14730
  /**
14656
- * A Class that holds the collection of event fields that requires to be mapped with the dataSource
14657
- * fields along with its available configuration settings. Each field in it accepts both string and Object
14731
+ * A class that holds the collection of event fields that requires to be mapped with the dataSource
14732
+ * fields along with its available configuration settings. Each field in it accepts both string and object
14658
14733
  * data type. When each of the field is assigned with simple `string` value, it is assumed that the dataSource field
14659
14734
  * name is mapped with it. If the `object` type is defined on each fields, then the validation related settings and mapping of
14660
14735
  * those fields with dataSource can be given altogether within it.
@@ -14770,6 +14845,9 @@ __decorate$6([
14770
14845
  __decorate$6([
14771
14846
  Property()
14772
14847
  ], EventSettings.prototype, "sortComparer", void 0);
14848
+ __decorate$6([
14849
+ Property()
14850
+ ], EventSettings.prototype, "includeFiltersInQuery", void 0);
14773
14851
 
14774
14852
  var __decorate$9 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
14775
14853
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -15051,7 +15129,7 @@ class ResourceBase {
15051
15129
  classList(target, [RESOURCE_COLLAPSE_CLASS], [RESOURCE_EXPAND_CLASS]);
15052
15130
  hide = false;
15053
15131
  }
15054
- const eventElements = [].slice.call(this.parent.element.querySelectorAll('.' + APPOINTMENT_CLASS));
15132
+ const eventElements = [].slice.call(this.parent.element.querySelectorAll('.' + APPOINTMENT_CLASS + ',.' + MORE_INDICATOR_CLASS));
15055
15133
  for (const element of eventElements) {
15056
15134
  remove(element);
15057
15135
  }
@@ -15180,6 +15258,7 @@ class ResourceBase {
15180
15258
  this.treeViewObj = new TreeView({
15181
15259
  cssClass: this.parent.cssClass,
15182
15260
  enableRtl: this.parent.enableRtl,
15261
+ enableHtmlSanitizer: this.parent.enableHtmlSanitizer,
15183
15262
  fields: {
15184
15263
  dataSource: [].slice.call(this.generateTreeData()),
15185
15264
  id: 'resourceId',
@@ -15276,10 +15355,8 @@ class ResourceBase {
15276
15355
  for (let i = 0, len = resource.groupOrder.length; i < len; i++) {
15277
15356
  const resourceLevel = this.resourceCollection[parseInt(i.toString(), 10)];
15278
15357
  const resourceText = resourceLevel.dataSource.filter((resData) => resData[resourceLevel.idField] === resource.groupOrder[parseInt(i.toString(), 10)]);
15279
- const resourceName = createElement('div', {
15280
- className: RESOURCE_NAME,
15281
- innerHTML: resourceText[0][resourceLevel.textField]
15282
- });
15358
+ const resourceName = createElement('div', { className: RESOURCE_NAME });
15359
+ resourceName.innerText = this.parent.sanitize(resourceText[0][resourceLevel.textField]);
15283
15360
  headerCollection.push(resourceName);
15284
15361
  const levelIcon = createElement('div', { className: 'e-icons e-icon-next' });
15285
15362
  headerCollection.push(levelIcon);
@@ -15351,7 +15428,7 @@ class ResourceBase {
15351
15428
  this.parent.showSpinner();
15352
15429
  const promises = [];
15353
15430
  for (const resource of this.parent.resources) {
15354
- const dataModule = new Data(resource.dataSource, resource.query);
15431
+ const dataModule = new Data(this.parent, resource.dataSource, resource.query);
15355
15432
  promises.push(dataModule.getData(dataModule.generateQuery()));
15356
15433
  }
15357
15434
  Promise.all(promises).then((e) => this.dataManagerSuccess(e, isSetModel))
@@ -15874,7 +15951,9 @@ class ResourceBase {
15874
15951
  if (this.treeViewObj) {
15875
15952
  if (this.treeViewObj.portals && this.treeViewObj.portals.length > 0) {
15876
15953
  const treeViewTemplates = this.treeViewObj.portals.map((x) => x.propName);
15877
- this.parent.resetTemplates(treeViewTemplates);
15954
+ if (treeViewTemplates.length > 0) {
15955
+ this.parent.resetTemplates(treeViewTemplates);
15956
+ }
15878
15957
  }
15879
15958
  this.treeViewObj.destroy();
15880
15959
  this.treeViewObj = null;
@@ -15983,7 +16062,7 @@ let Schedule = class Schedule extends Component {
15983
16062
  /**
15984
16063
  * Method to render react templates
15985
16064
  *
15986
- * @param {Function} callBack - specifies the callBack method
16065
+ * @param {Function} callback - Specifies the callBack method
15987
16066
  * @returns {void}
15988
16067
  * @private
15989
16068
  */
@@ -16007,6 +16086,19 @@ let Schedule = class Schedule extends Component {
16007
16086
  this.clearTemplate(templates);
16008
16087
  }
16009
16088
  }
16089
+ /**
16090
+ * Method to sanitize any suspected untrusted strings and scripts before rendering them.
16091
+ *
16092
+ * @param {string} value - A string value representing the HTML string value to be sanitized.
16093
+ * @returns {string} A sanitized Html string.
16094
+ * @private
16095
+ */
16096
+ sanitize(value) {
16097
+ if (this.enableHtmlSanitizer) {
16098
+ return SanitizeHtmlHelper.sanitize(value);
16099
+ }
16100
+ return value;
16101
+ }
16010
16102
  initializeResources(isSetModel = false) {
16011
16103
  if (this.resources.length > 0) {
16012
16104
  this.resourceBase = new ResourceBase(this);
@@ -16216,7 +16308,7 @@ let Schedule = class Schedule extends Component {
16216
16308
  followingID: this.eventSettings.fields.followingID
16217
16309
  };
16218
16310
  this.setEditorTitles();
16219
- this.dataModule = new Data(this.eventSettings.dataSource, this.eventSettings.query);
16311
+ this.dataModule = new Data(this, this.eventSettings.dataSource, this.eventSettings.query);
16220
16312
  this.crudModule = new Crud(this);
16221
16313
  }
16222
16314
  setEditorTitles() {
@@ -16627,12 +16719,17 @@ let Schedule = class Schedule extends Component {
16627
16719
  * @private
16628
16720
  */
16629
16721
  removeSelectedClass() {
16630
- const selectedCells = this.getSelectedElements();
16722
+ const selectedCells = this.getSelectedCells();
16631
16723
  for (const cell of selectedCells) {
16632
- cell.setAttribute('aria-selected', 'false');
16724
+ if (this.currentView !== 'Year') {
16725
+ cell.setAttribute('aria-selected', 'false');
16726
+ }
16633
16727
  cell.removeAttribute('tabindex');
16634
16728
  }
16635
16729
  removeClass(selectedCells, SELECTED_CELL_CLASS);
16730
+ if (this.keyboardInteractionModule && this.keyboardInteractionModule.selectedCells.length > 0) {
16731
+ this.keyboardInteractionModule.selectedCells = [];
16732
+ }
16636
16733
  }
16637
16734
  /**
16638
16735
  * Method to add selected class
@@ -16644,8 +16741,10 @@ let Schedule = class Schedule extends Component {
16644
16741
  * @private
16645
16742
  */
16646
16743
  addSelectedClass(cells, focusCell, isPreventScroll) {
16647
- for (const cell of cells) {
16648
- cell.setAttribute('aria-selected', 'true');
16744
+ if (this.currentView !== 'Year') {
16745
+ for (const cell of cells) {
16746
+ cell.setAttribute('aria-selected', 'true');
16747
+ }
16649
16748
  }
16650
16749
  addClass(cells, SELECTED_CELL_CLASS);
16651
16750
  if (focusCell) {
@@ -17011,6 +17110,15 @@ let Schedule = class Schedule extends Component {
17011
17110
  }
17012
17111
  return undefined;
17013
17112
  }
17113
+ /**
17114
+ * Retrieves the selected cells.
17115
+ *
17116
+ * @returns {Element[]} The elements of currently selected cells will be returned.
17117
+ * @private
17118
+ */
17119
+ getSelectedCells() {
17120
+ return [].slice.call(this.element.querySelectorAll('.' + SELECTED_CELL_CLASS));
17121
+ }
17014
17122
  /**
17015
17123
  * Method to generate the announcement string
17016
17124
  *
@@ -17466,6 +17574,7 @@ let Schedule = class Schedule extends Component {
17466
17574
  case 'dataSource':
17467
17575
  case 'query':
17468
17576
  case 'fields':
17577
+ case 'includeFiltersInQuery':
17469
17578
  this.initializeDataModule();
17470
17579
  state.isDataManager = true;
17471
17580
  break;
@@ -17696,7 +17805,10 @@ let Schedule = class Schedule extends Component {
17696
17805
  * @returns {Element[]} The elements of currently selected cells will be returned.
17697
17806
  */
17698
17807
  getSelectedElements() {
17699
- return [].slice.call(this.element.querySelectorAll('.' + SELECTED_CELL_CLASS));
17808
+ if (this.keyboardInteractionModule && this.keyboardInteractionModule.selectedCells.length > 0) {
17809
+ return this.keyboardInteractionModule.selectedCells;
17810
+ }
17811
+ return this.getSelectedCells();
17700
17812
  }
17701
17813
  /**
17702
17814
  * To get the resource collection
@@ -17863,6 +17975,17 @@ let Schedule = class Schedule extends Component {
17863
17975
  addEvent(data) {
17864
17976
  this.crudModule.addEvent(data);
17865
17977
  }
17978
+ /**
17979
+ * Generates the occurrences of a single recurrence event based on the provided event.
17980
+ *
17981
+ * @function generateEventOccurrences
17982
+ * @param {Object} event Accepts the parent recurrence event from which the occurrences are generated.
17983
+ * @param {Date} startDate Accepts the start date for the event occurrences. If not provided, the event's start date will be used.
17984
+ * @returns {Object[]} Returns the collection of occurrence event objects.
17985
+ */
17986
+ generateEventOccurrences(event, startDate) {
17987
+ return (this.eventBase) ? this.eventBase.generateOccurrence(event, startDate) : [];
17988
+ }
17866
17989
  /**
17867
17990
  * Allows the Scheduler events data to be exported as an Excel file either in .xlsx or .csv file formats.
17868
17991
  * By default, the whole event collection bound to the Scheduler gets exported as an Excel file.
@@ -18529,6 +18652,9 @@ __decorate([
18529
18652
  __decorate([
18530
18653
  Property(null)
18531
18654
  ], Schedule.prototype, "timeFormat", void 0);
18655
+ __decorate([
18656
+ Property(true)
18657
+ ], Schedule.prototype, "enableHtmlSanitizer", void 0);
18532
18658
  __decorate([
18533
18659
  Property(false)
18534
18660
  ], Schedule.prototype, "enableAllDayScroll", void 0);
@@ -18777,6 +18903,7 @@ class ActionBase {
18777
18903
  parseInt(this.actionObj.element.getAttribute('data-group-index'), 10) === this.actionObj.groupIndex : true;
18778
18904
  if (+eventObj[this.parent.eventFields.startTime] === +this.actionObj.event[this.parent.eventFields.startTime] &&
18779
18905
  +eventObj[this.parent.eventFields.endTime] === +this.actionObj.event[this.parent.eventFields.endTime] && isSameResource) {
18906
+ this.parent.crudModule.crudObj.isCrudAction = false;
18780
18907
  return;
18781
18908
  }
18782
18909
  if (eventObj[this.parent.eventFields.recurrenceRule]) {
@@ -19050,6 +19177,10 @@ class ActionBase {
19050
19177
  }
19051
19178
  appWidth = eventObj.isSpanned.count * this.actionObj.cellWidth;
19052
19179
  }
19180
+ if (!isResize && this.parent.activeViewOptions.orientation === 'Vertical' && this.parent.activeViewOptions.group.resources.length !== 0) {
19181
+ const eventObj = this.yearEvent.isSpannedEvent(event, event[this.parent.eventFields.startTime]);
19182
+ appWidth = eventObj.isSpanned.count * this.actionObj.cellWidth;
19183
+ }
19053
19184
  const appointmentElement = this.createAppointmentElement(this.actionObj.groupIndex, event[this.parent.eventFields.subject]);
19054
19185
  appointmentElement.setAttribute('drag', 'true');
19055
19186
  addClass([appointmentElement], CLONE_ELEMENT_CLASS);
@@ -19784,7 +19915,7 @@ class YearEvent extends TimelineEvent {
19784
19915
  }
19785
19916
  timelineYearViewEvents() {
19786
19917
  const workCell = this.parent.element.querySelector('.' + WORK_CELLS_CLASS + ':not(.' + OTHERMONTH_CLASS + ')');
19787
- this.cellWidth = workCell.offsetWidth;
19918
+ this.cellWidth = workCell.getBoundingClientRect().width;
19788
19919
  this.cellHeader = getOuterHeight(workCell.querySelector('.' + DATE_HEADER_CLASS));
19789
19920
  const eventTable = this.parent.element.querySelector('.' + EVENT_TABLE_CLASS);
19790
19921
  this.eventHeight = getElementHeightFromClass(eventTable, APPOINTMENT_CLASS);
@@ -19795,7 +19926,7 @@ class YearEvent extends TimelineEvent {
19795
19926
  for (let row = 0; row < months.length; row++) {
19796
19927
  const wrapper = wrapperCollection[parseInt(row.toString(), 10)];
19797
19928
  let td = row + 1;
19798
- const eventWrapper = createElement('div', { className: APPOINTMENT_WRAPPER_CLASS });
19929
+ let eventWrapper = createElement('div', { className: APPOINTMENT_WRAPPER_CLASS });
19799
19930
  wrapper.appendChild(eventWrapper);
19800
19931
  let monthStart = new Date(this.parent.selectedDate.getFullYear(), months[parseInt(row.toString(), 10)], 1);
19801
19932
  const monthEnd = new Date(monthStart.getFullYear(), monthStart.getMonth() + 1, 0);
@@ -19810,7 +19941,7 @@ class YearEvent extends TimelineEvent {
19810
19941
  if (this.parent.activeViewOptions.orientation === 'Vertical') {
19811
19942
  const wrapper = wrapperCollection[parseInt(dayIndex.toString(), 10)];
19812
19943
  td = dayIndex + 1;
19813
- let eventWrapper = wrapper.querySelector('.' + APPOINTMENT_WRAPPER_CLASS);
19944
+ eventWrapper = wrapper.querySelector('.' + APPOINTMENT_WRAPPER_CLASS);
19814
19945
  if (!eventWrapper) {
19815
19946
  eventWrapper = createElement('div', { className: APPOINTMENT_WRAPPER_CLASS });
19816
19947
  wrapper.appendChild(eventWrapper);
@@ -19862,8 +19993,7 @@ class YearEvent extends TimelineEvent {
19862
19993
  continue;
19863
19994
  }
19864
19995
  }
19865
- const isRowAutoHeight = this.parent.rowAutoHeight && this.parent.activeViewOptions.orientation === 'Horizontal';
19866
- if (isRowAutoHeight || this.cellHeight > availedHeight) {
19996
+ if (this.parent.rowAutoHeight || this.cellHeight > availedHeight) {
19867
19997
  this.renderEvent(eventWrapper, eventData, row, leftValue, rightValue, monthStart, dayIndex);
19868
19998
  this.updateCellHeight(rowTd, availedHeight);
19869
19999
  isSpannedCollection.push(eventData);
@@ -19885,6 +20015,19 @@ class YearEvent extends TimelineEvent {
19885
20015
  }
19886
20016
  }
19887
20017
  }
20018
+ if (this.parent.rowAutoHeight && this.parent.activeViewOptions.orientation === 'Vertical') {
20019
+ const appContainer = [].slice.call(this.parent.element.querySelectorAll('.' + APPOINTMENT_CONTAINER_CLASS));
20020
+ const tr = [].slice.call(this.parent.element.querySelectorAll('.' + CONTENT_TABLE_CLASS + ' tbody tr'));
20021
+ appContainer.forEach((ele, index) => {
20022
+ const app = [].slice.call(ele.querySelectorAll('.' + APPOINTMENT_CLASS));
20023
+ const appTop = tr[parseInt(index.toString(), 10)].offsetTop + this.cellHeader + EVENT_GAP$2;
20024
+ app.forEach((app) => {
20025
+ const overlap = parseInt(app.getAttribute('data-index'), 10);
20026
+ app.style.top = appTop + (overlap * this.eventHeight) + 'px';
20027
+ app.removeAttribute('data-index');
20028
+ });
20029
+ });
20030
+ }
19888
20031
  }
19889
20032
  updateSpannedEvents(eventObj, dayStart, dayEnd) {
19890
20033
  const isLeftRightResize = (this.isResource && this.parent.activeViewOptions.orientation === 'Vertical') ||
@@ -19899,7 +20042,8 @@ class YearEvent extends TimelineEvent {
19899
20042
  }
19900
20043
  }
19901
20044
  if ((dayEnd.getTime() >= eventObj[this.fields.endTime].getTime()) || (isLeftRightResize && !this.isResource &&
19902
- addDays(dayEnd, -1).getMonth() === eventObj[this.fields.endTime].getMonth())) {
20045
+ addDays(dayEnd, -1).getMonth() === eventObj[this.fields.endTime].getMonth()) ||
20046
+ (isLeftRightResize && this.isResource && (dayEnd.getTime() <= eventObj[this.fields.endTime].getTime()))) {
19903
20047
  if (isLeftRightResize) {
19904
20048
  data.isRight = false;
19905
20049
  }
@@ -19910,8 +20054,10 @@ class YearEvent extends TimelineEvent {
19910
20054
  eventObj.data = data;
19911
20055
  }
19912
20056
  timelineResourceEvents() {
20057
+ const contentTable = this.parent.element.querySelector('.' + CONTENT_WRAP_CLASS);
20058
+ const isVerticalScrollbarAvail = contentTable.offsetWidth > contentTable.clientWidth;
19913
20059
  const workCell = this.parent.element.querySelector('.' + WORK_CELLS_CLASS);
19914
- this.cellWidth = workCell.offsetWidth;
20060
+ this.cellWidth = workCell.getBoundingClientRect().width;
19915
20061
  this.cellHeader = 0;
19916
20062
  const eventTable = this.parent.element.querySelector('.' + EVENT_TABLE_CLASS);
19917
20063
  this.eventHeight = getElementHeightFromClass(eventTable, APPOINTMENT_CLASS);
@@ -19939,6 +20085,39 @@ class YearEvent extends TimelineEvent {
19939
20085
  }
19940
20086
  }
19941
20087
  }
20088
+ if (this.parent.rowAutoHeight && !isVerticalScrollbarAvail && contentTable.offsetWidth > contentTable.clientWidth) {
20089
+ const appointments = [].slice.call(this.parent.element.querySelectorAll('.' + APPOINTMENT_CLASS));
20090
+ appointments.forEach((ele) => {
20091
+ ele.style.removeProperty('left');
20092
+ ele.style.removeProperty('right');
20093
+ });
20094
+ const appContainer = [].slice.call(this.parent.element.querySelectorAll('.' + APPOINTMENT_CONTAINER_CLASS));
20095
+ const conTable = this.parent.element.querySelector('.' + CONTENT_TABLE_CLASS);
20096
+ const tr = [].slice.call(conTable.querySelectorAll('tbody tr'));
20097
+ appContainer.forEach((ele, index) => {
20098
+ const appWrapper = [].slice.call(ele.children);
20099
+ const row = tr[parseInt(index.toString(), 10)];
20100
+ appWrapper.forEach((appWrap, cellIndex) => {
20101
+ const td = row.querySelector(`td:nth-child(${cellIndex + 1})`);
20102
+ const app = [].slice.call(appWrap.children);
20103
+ const width = td.getBoundingClientRect().width;
20104
+ const left = td.offsetLeft;
20105
+ if (this.parent.enableRtl) {
20106
+ const right = conTable.offsetWidth - left - td.offsetWidth;
20107
+ app.forEach((app) => {
20108
+ app.style.width = Math.floor(parseInt(app.style.width, 10) / width) * width + 'px';
20109
+ app.style.right = right + 'px';
20110
+ });
20111
+ }
20112
+ else {
20113
+ app.forEach((app) => {
20114
+ app.style.width = Math.floor(parseInt(app.style.width, 10) / width) * width + 'px';
20115
+ app.style.left = left + 'px';
20116
+ });
20117
+ }
20118
+ });
20119
+ });
20120
+ }
19942
20121
  }
19943
20122
  renderResourceEvent(wrapper, resource, month, index, monthStart) {
19944
20123
  const eventWrapper = createElement('div', { className: APPOINTMENT_WRAPPER_CLASS });
@@ -19949,6 +20128,7 @@ class YearEvent extends TimelineEvent {
19949
20128
  const td = this.parent.element.querySelector(`.e-content-wrap tr:nth-child(${rowIndex + 1}) td`);
19950
20129
  this.cellHeight = td.offsetHeight;
19951
20130
  this.groupOrder = resource.groupOrder;
20131
+ const isSpannedCollection = [];
19952
20132
  for (let a = 0; a < eventDatas.length; a++) {
19953
20133
  const data = eventDatas[parseInt(a.toString(), 10)];
19954
20134
  let overlapIndex;
@@ -19968,9 +20148,17 @@ class YearEvent extends TimelineEvent {
19968
20148
  if (!this.parent.isMinMaxDate(eventData[this.fields.startTime])) {
19969
20149
  return;
19970
20150
  }
20151
+ if (this.parent.activeViewOptions.orientation === 'Vertical' && this.parent.activeViewOptions.group.resources.length > 0) {
20152
+ const isRendered = this.renderedEvents.filter((eventObj) => eventObj.Guid === eventData.Guid);
20153
+ const isSpanned = isSpannedCollection.filter((eventObj) => eventObj.Guid === eventData.Guid);
20154
+ if (isRendered.length > 0 || isSpanned.length > 0) {
20155
+ continue;
20156
+ }
20157
+ }
19971
20158
  if (this.parent.rowAutoHeight || this.cellHeight > availedHeight) {
19972
20159
  this.renderEvent(eventWrapper, eventData, month, leftValue, leftValue, monthStart, index);
19973
20160
  this.updateCellHeight(td, availedHeight);
20161
+ isSpannedCollection.push(eventData);
19974
20162
  }
19975
20163
  else {
19976
20164
  const moreIndex = this.parent.activeViewOptions.orientation === 'Horizontal' ? month : index;
@@ -20006,13 +20194,16 @@ class YearEvent extends TimelineEvent {
20006
20194
  }
20007
20195
  else {
20008
20196
  index = rowIndex + 1;
20009
- width = this.cellWidth;
20197
+ width = this.isResource ? eventObj.isSpanned.count * this.cellWidth : this.cellWidth;
20010
20198
  }
20011
20199
  const rowTd = this.parent.element.querySelector(`.e-content-wrap tr:nth-child(${index}) td`);
20012
20200
  const top = rowTd.offsetTop + this.cellHeader + (this.eventHeight * eventObj.Index) + EVENT_GAP$2;
20013
20201
  setStyleAttribute(wrap, {
20014
20202
  'width': width + 'px', 'height': this.eventHeight + 'px', 'left': left + 'px', 'right': right + 'px', 'top': top + 'px'
20015
20203
  });
20204
+ if (!this.isResource && this.parent.rowAutoHeight && this.parent.activeViewOptions.orientation === 'Vertical') {
20205
+ wrap.setAttribute('data-index', eventObj.Index.toString());
20206
+ }
20016
20207
  const args = { data: eventObj, element: wrap, cancel: false, type: 'event' };
20017
20208
  this.parent.trigger(eventRendered, args, (eventArgs) => {
20018
20209
  if (!eventArgs.cancel) {
@@ -20118,6 +20309,7 @@ class YearEvent extends TimelineEvent {
20118
20309
  const appointmentDetails = createElement('div', { className: APPOINTMENT_DETAILS });
20119
20310
  append(templateElement, appointmentDetails);
20120
20311
  eventWrapper.appendChild(appointmentDetails);
20312
+ this.parent.eventBase.renderSpannedIcon(eventWrapper, record.isSpanned);
20121
20313
  this.renderResizeHandler(eventWrapper, record.data, record[this.fields.isReadonly]);
20122
20314
  this.applyResourceColor(eventWrapper, eventObj, 'backgroundColor', this.groupOrder);
20123
20315
  return eventWrapper;
@@ -20129,24 +20321,28 @@ class YearEvent extends TimelineEvent {
20129
20321
  const eventStart = eventData[this.fields.startTime];
20130
20322
  const eventEnd = eventData[this.fields.endTime];
20131
20323
  const isSpanned = { isLeft: false, isRight: false, count: 1 };
20324
+ const yearStart = new Date(this.parent.selectedDate.getFullYear(), this.parent.firstMonthOfYear, 1);
20325
+ const yearEnd = addMonths(yearStart, this.parent.monthsCount);
20132
20326
  if (this.isResource) {
20133
20327
  this.updateSpannedEvents(eventObj, monthStart, monthEnd);
20134
20328
  }
20135
- if (eventStart.getTime() < monthStart.getTime()) {
20136
- eventData[this.fields.startTime] = monthStart;
20137
- isSpanned.isLeft = true;
20138
- }
20139
- if (eventEnd.getTime() > monthEnd.getTime()) {
20140
- eventData[this.fields.endTime] = monthEnd;
20141
- isSpanned.isRight = true;
20329
+ if (this.parent.activeViewOptions.orientation === 'Vertical' && this.parent.activeViewOptions.group.resources.length > 0) {
20330
+ this.updateSpannedEventDetails(eventStart, eventEnd, yearStart, yearEnd, eventData, isSpanned);
20331
+ const originalStartTime = eventData[this.fields.startTime];
20332
+ const originalEndTime = new Date(eventData[this.fields.endTime] - 1);
20333
+ isSpanned.count = (originalEndTime.getMonth() - originalStartTime.getMonth()) +
20334
+ (this.parent.monthsCount * (originalEndTime.getFullYear() - originalStartTime.getFullYear())) + 1;
20142
20335
  }
20143
- if (this.parent.activeViewOptions.group.resources.length === 0 || this.parent.uiStateValues.isGroupAdaptive) {
20144
- let end = resetTime(eventData[this.fields.endTime]).getTime();
20145
- const start = resetTime(eventData[this.fields.startTime]).getTime();
20146
- if (eventObj[this.fields.isAllDay] && end === eventObj[this.fields.endTime].getTime() || isSpanned.isRight) {
20147
- end = addDays(new Date(end), -1).getTime();
20336
+ else {
20337
+ this.updateSpannedEventDetails(eventStart, eventEnd, monthStart, monthEnd, eventData, isSpanned);
20338
+ if (this.parent.activeViewOptions.group.resources.length === 0 || this.parent.uiStateValues.isGroupAdaptive) {
20339
+ let end = resetTime(eventData[this.fields.endTime]).getTime();
20340
+ const start = resetTime(eventData[this.fields.startTime]).getTime();
20341
+ if (eventObj[this.fields.isAllDay] && end === eventObj[this.fields.endTime].getTime() || isSpanned.isRight) {
20342
+ end = addDays(new Date(end), -1).getTime();
20343
+ }
20344
+ isSpanned.count = Math.ceil((end - start) / MS_PER_DAY) + 1;
20148
20345
  }
20149
- isSpanned.count = Math.ceil((end - start) / MS_PER_DAY) + 1;
20150
20346
  }
20151
20347
  eventData.isSpanned = isSpanned;
20152
20348
  if (resetTime(eventStart).getTime() < resetTime(this.parent.minDate).getTime()) {
@@ -20157,6 +20353,16 @@ class YearEvent extends TimelineEvent {
20157
20353
  }
20158
20354
  return eventData;
20159
20355
  }
20356
+ updateSpannedEventDetails(eventStart, eventEnd, viewStart, viewEnd, eventObj, isSpanned) {
20357
+ if (eventStart.getTime() < viewStart.getTime()) {
20358
+ eventObj[this.fields.startTime] = viewStart;
20359
+ isSpanned.isLeft = true;
20360
+ }
20361
+ if (eventEnd.getTime() > viewEnd.getTime()) {
20362
+ eventObj[this.fields.endTime] = viewEnd;
20363
+ isSpanned.isRight = true;
20364
+ }
20365
+ }
20160
20366
  getOverlapEvents(date, appointments) {
20161
20367
  const appointmentsList = [];
20162
20368
  let dateStart;
@@ -20179,19 +20385,11 @@ class YearEvent extends TimelineEvent {
20179
20385
  for (const app of appointments) {
20180
20386
  const appStart = new Date(app[this.fields.startTime].getTime());
20181
20387
  const appEnd = new Date(app[this.fields.endTime].getTime());
20182
- if (this.parent.activeViewOptions.orientation === 'Vertical' &&
20183
- this.parent.activeViewOptions.group.resources.length > 0) {
20184
- if ((resetTime(appStart).getTime() >= dateStart) && (resetTime(appEnd).getTime() <= dateEnd)) {
20185
- appointmentsList.push(app);
20186
- }
20187
- }
20188
- else {
20189
- const timeCondition = app[this.fields.isAllDay] ? resetTime(appEnd).getTime() > dateStart :
20190
- resetTime(appEnd).getTime() >= dateStart;
20191
- if (((resetTime(appStart).getTime() <= dateStart) && (timeCondition)) ||
20192
- (resetTime(appStart).getTime() >= dateStart) && (resetTime(appEnd).getTime() <= dateEnd)) {
20193
- appointmentsList.push(app);
20194
- }
20388
+ const timeCondition = app[this.fields.isAllDay] ? resetTime(appEnd).getTime() > dateStart :
20389
+ resetTime(appEnd).getTime() >= dateStart;
20390
+ if (((resetTime(appStart).getTime() <= dateStart) && (timeCondition)) ||
20391
+ (resetTime(appStart).getTime() >= dateStart) && (resetTime(appEnd).getTime() <= dateEnd)) {
20392
+ appointmentsList.push(app);
20195
20393
  }
20196
20394
  }
20197
20395
  return appointmentsList;
@@ -20922,7 +21120,12 @@ class DragAndDrop extends ActionBase {
20922
21120
  }
20923
21121
  getDayIndex(event) {
20924
21122
  const eventObj = extend({}, event, null, true);
20925
- const startTime = resetTime(eventObj[this.parent.eventFields.startTime]).getTime();
21123
+ const startDate = resetTime(eventObj[this.parent.eventFields.startTime]);
21124
+ if (this.parent.activeViewOptions.timeScale.enable && !eventObj[this.parent.eventFields.isAllDay]) {
21125
+ const startHour = this.parent.activeView.getStartHour();
21126
+ startDate.setMilliseconds(startHour.getTime() - resetTime(startHour).getTime());
21127
+ }
21128
+ const startTime = startDate.getTime();
20926
21129
  let query = '';
20927
21130
  let wrapper = DAY_WRAPPER_CLASS;
20928
21131
  if (this.parent.activeViewOptions.timeScale.enable && (eventObj[this.parent.eventFields.isAllDay])) {
@@ -21916,9 +22119,9 @@ class ViewBase {
21916
22119
  append(quickTemplate, tdElement);
21917
22120
  }
21918
22121
  else {
21919
- tdElement.appendChild(createElement('div', {
21920
- className: className, innerHTML: tdData.resourceData[tdData.resource.textField]
21921
- }));
22122
+ const resourceText = createElement('div', { className: className });
22123
+ resourceText.innerText = this.parent.sanitize(tdData.resourceData[tdData.resource.textField]);
22124
+ tdElement.appendChild(resourceText);
21922
22125
  }
21923
22126
  }
21924
22127
  renderResourceMobileLayout() {
@@ -21942,7 +22145,6 @@ class ViewBase {
21942
22145
  const colElements = this.getColElements();
21943
22146
  const contentBody = this.element.querySelector('.' + CONTENT_TABLE_CLASS + ' tbody');
21944
22147
  const colWidth = (contentBody.getBoundingClientRect().width / (colElements.length / 2));
21945
- colElements.forEach((col) => setStyleAttribute(col, { 'width': formatUnit(colWidth) }));
21946
22148
  if (content.offsetHeight !== content.clientHeight) {
21947
22149
  const resourceColumn = this.parent.element.querySelector('.' + RESOURCE_COLUMN_WRAP_CLASS);
21948
22150
  if (!isNullOrUndefined(resourceColumn)) {
@@ -22154,8 +22356,8 @@ class VerticalView extends ViewBase {
22154
22356
  const content = this.getScrollableElement();
22155
22357
  const header = this.getDatesHeaderElement();
22156
22358
  const scrollerHeight = this.parent.element.offsetHeight - headerBarHeight - header.offsetHeight;
22157
- this.setColWidth(content);
22158
22359
  this.setContentHeight(content, timeCells, scrollerHeight);
22360
+ this.setColWidth(content);
22159
22361
  const scrollBarWidth = getScrollBarWidth();
22160
22362
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
22161
22363
  header.firstElementChild.style[args.cssProperties.rtlBorder] = '';
@@ -23380,9 +23582,11 @@ class Month extends ViewBase {
23380
23582
  if (!this.parent.isMinMaxDate(data.date)) {
23381
23583
  data.className.push(DISABLE_DATES);
23382
23584
  }
23383
- if (this.parent.currentView === 'MonthAgenda' && this.parent.isSelectedDate(data.date)) {
23384
- data.className.push(SELECTED_CELL_CLASS);
23385
- }
23585
+ this.updateSelectedCellClass(data);
23586
+ }
23587
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
23588
+ updateSelectedCellClass(data) {
23589
+ return;
23386
23590
  }
23387
23591
  isOtherMonth(date) {
23388
23592
  return date.getTime() < this.monthDates.start.getTime() || date.getTime() > this.monthDates.end.getTime();
@@ -23713,6 +23917,7 @@ class Year extends ViewBase {
23713
23917
  calendarElement.appendChild(this.renderCalendarContent(currentMonth));
23714
23918
  calendarWrapper.appendChild(calendarElement);
23715
23919
  }
23920
+ this.renderDates.splice(0, 1);
23716
23921
  }
23717
23922
  renderCalendarHeader(currentDate) {
23718
23923
  const headerWrapper = createElement('div', { className: 'e-header e-month' });
@@ -23771,7 +23976,7 @@ class Year extends ViewBase {
23771
23976
  for (const date of weekDates) {
23772
23977
  const td = createElement('td', {
23773
23978
  className: 'e-cell ' + WORK_CELLS_CLASS,
23774
- attrs: { 'aria-selected': 'false', 'data-date': date.getTime().toString() }
23979
+ attrs: { 'data-date': date.getTime().toString() }
23775
23980
  });
23776
23981
  if (this.parent.activeViewOptions.cellHeaderTemplate) {
23777
23982
  const args = { date: date, type: 'monthCells' };
@@ -23799,6 +24004,9 @@ class Year extends ViewBase {
23799
24004
  addClass([td], classList$$1);
23800
24005
  }
23801
24006
  tr.appendChild(td);
24007
+ if (currentDate.getMonth() === date.getMonth()) {
24008
+ this.renderDates.push(new Date(date));
24009
+ }
23802
24010
  if (!this.parent.isMinMaxDate(date)) {
23803
24011
  addClass([td], DISABLE_DATES);
23804
24012
  }
@@ -24148,9 +24356,13 @@ class AgendaBase extends ViewBase {
24148
24356
  if (!isNullOrUndefined(eventLocation) && eventLocation !== '') {
24149
24357
  eventSubject += ',';
24150
24358
  }
24151
- appSubjectWrap.appendChild(createElement('div', { className: SUBJECT_CLASS, innerHTML: eventSubject }));
24359
+ const appSubjectText = createElement('div', { className: SUBJECT_CLASS });
24360
+ appSubjectText.innerText = this.parent.sanitize(eventSubject);
24361
+ appSubjectWrap.appendChild(appSubjectText);
24152
24362
  if (!isNullOrUndefined(eventLocation) && eventLocation !== '') {
24153
- appSubjectWrap.appendChild(createElement('div', { className: LOCATION_CLASS, innerHTML: eventLocation }));
24363
+ const appLocation = createElement('div', { className: LOCATION_CLASS });
24364
+ appLocation.innerText = this.parent.sanitize(eventLocation);
24365
+ appSubjectWrap.appendChild(appLocation);
24154
24366
  }
24155
24367
  if (!isNullOrUndefined(event[fieldMapping.recurrenceRule])) {
24156
24368
  const iconClass = (event[fieldMapping.id] === event[fieldMapping.recurrenceID]) ?
@@ -24891,6 +25103,11 @@ class MonthAgenda extends Month {
24891
25103
  }
24892
25104
  return 'abbreviated';
24893
25105
  }
25106
+ updateSelectedCellClass(data) {
25107
+ if (resetTime(data.date).getTime() === resetTime(this.monthAgendaDate).getTime()) {
25108
+ data.className.push(SELECTED_CELL_CLASS);
25109
+ }
25110
+ }
24894
25111
  setEventWrapperHeight() {
24895
25112
  let headerHeight = (this.parent.headerModule ? this.parent.headerModule.getHeaderElement().offsetHeight : 0) + 2;
24896
25113
  const resourceWrapper = this.parent.element.querySelector('.' + RESOURCE_HEADER_TOOLBAR);
@@ -25697,15 +25914,15 @@ class TimelineYear extends Year {
25697
25914
  this.parent.virtualScrollModule.renderVirtualTrack(content);
25698
25915
  }
25699
25916
  const contentTBody = contentTable.querySelector('tbody');
25700
- if (this.parent.activeViewOptions.group.resources.length > 0 && !this.parent.uiStateValues.isGroupAdaptive) {
25701
- if (this.parent.rowAutoHeight) {
25702
- const addClassTable = [contentTable];
25703
- const monthHeader = this.parent.element.querySelector('.' + MONTH_HEADER_WRAPPER + ' .' + SCHEDULE_TABLE_CLASS);
25704
- if (monthHeader) {
25705
- addClassTable.push(monthHeader);
25706
- }
25707
- addClass(addClassTable, AUTO_HEIGHT);
25917
+ if (this.parent.rowAutoHeight) {
25918
+ const addClassTable = [contentTable];
25919
+ const monthHeader = this.parent.element.querySelector('.' + MONTH_HEADER_WRAPPER + ' .' + SCHEDULE_TABLE_CLASS);
25920
+ if (monthHeader) {
25921
+ addClassTable.push(monthHeader);
25708
25922
  }
25923
+ addClass(addClassTable, AUTO_HEIGHT);
25924
+ }
25925
+ if (this.parent.activeViewOptions.group.resources.length > 0 && !this.parent.uiStateValues.isGroupAdaptive) {
25709
25926
  const colCount = this.parent.activeViewOptions.orientation === 'Horizontal' ? this.colLevels.slice(-1)[0].length : this.columnCount;
25710
25927
  contentTable.appendChild(this.createTableColGroup(colCount));
25711
25928
  this.renderResourceContent(eventWrapper, monthTBody, contentTBody);
@@ -25807,6 +26024,9 @@ class TimelineYear extends Year {
25807
26024
  if (td.classList.contains(OTHERMONTH_CLASS)) {
25808
26025
  continue;
25809
26026
  }
26027
+ else {
26028
+ this.renderDates.push(new Date(date));
26029
+ }
25810
26030
  td.appendChild(dateHeader);
25811
26031
  if (isDateAvail) {
25812
26032
  td.setAttribute('data-date', date.getTime().toString());
@@ -25821,6 +26041,7 @@ class TimelineYear extends Year {
25821
26041
  }
25822
26042
  }
25823
26043
  }
26044
+ this.renderDates.splice(0, 1);
25824
26045
  }
25825
26046
  getContentRows() {
25826
26047
  const tRow = [];