@syncfusion/ej2-schedule 20.4.53 → 21.1.37

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 (107) hide show
  1. package/CHANGELOG.md +18 -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 +339 -144
  6. package/dist/es6/ej2-schedule.es2015.js.map +1 -1
  7. package/dist/es6/ej2-schedule.es5.js +374 -165
  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/schedule/actions/action-base.js +5 -0
  16. package/src/schedule/actions/crud.js +1 -0
  17. package/src/schedule/actions/data.d.ts +14 -2
  18. package/src/schedule/actions/data.js +26 -2
  19. package/src/schedule/actions/keyboard.js +15 -14
  20. package/src/schedule/base/interface.d.ts +23 -23
  21. package/src/schedule/base/resource.js +5 -6
  22. package/src/schedule/base/schedule-model.d.ts +34 -27
  23. package/src/schedule/base/schedule.d.ts +50 -27
  24. package/src/schedule/base/schedule.js +44 -8
  25. package/src/schedule/base/type.d.ts +66 -1
  26. package/src/schedule/event-renderer/agenda-base.js +6 -2
  27. package/src/schedule/event-renderer/event-base.d.ts +2 -1
  28. package/src/schedule/event-renderer/event-base.js +34 -13
  29. package/src/schedule/event-renderer/month.js +4 -5
  30. package/src/schedule/event-renderer/vertical-view.d.ts +0 -1
  31. package/src/schedule/event-renderer/vertical-view.js +6 -30
  32. package/src/schedule/event-renderer/year.d.ts +1 -0
  33. package/src/schedule/event-renderer/year.js +135 -54
  34. package/src/schedule/models/event-settings-model.d.ts +11 -2
  35. package/src/schedule/models/event-settings.d.ts +10 -2
  36. package/src/schedule/models/event-settings.js +3 -0
  37. package/src/schedule/models/fields-model.d.ts +4 -2
  38. package/src/schedule/models/fields.d.ts +6 -4
  39. package/src/schedule/models/fields.js +2 -2
  40. package/src/schedule/models/header-rows-model.d.ts +5 -5
  41. package/src/schedule/models/header-rows.d.ts +5 -5
  42. package/src/schedule/models/quick-info-templates-model.d.ts +3 -3
  43. package/src/schedule/models/quick-info-templates.d.ts +3 -3
  44. package/src/schedule/models/views-model.d.ts +16 -15
  45. package/src/schedule/models/views.d.ts +16 -15
  46. package/src/schedule/popups/event-tooltip.js +2 -1
  47. package/src/schedule/popups/event-window.js +26 -5
  48. package/src/schedule/popups/quick-popups.js +32 -10
  49. package/src/schedule/renderer/header-renderer.js +1 -0
  50. package/src/schedule/renderer/month-agenda.d.ts +3 -2
  51. package/src/schedule/renderer/month-agenda.js +5 -0
  52. package/src/schedule/renderer/month.d.ts +1 -0
  53. package/src/schedule/renderer/month.js +5 -3
  54. package/src/schedule/renderer/timeline-year.js +12 -8
  55. package/src/schedule/renderer/vertical-view.js +1 -1
  56. package/src/schedule/renderer/view-base.js +3 -4
  57. package/src/schedule/renderer/year.js +5 -1
  58. package/styles/bootstrap-dark.css +99 -89
  59. package/styles/bootstrap.css +99 -89
  60. package/styles/bootstrap4.css +99 -89
  61. package/styles/bootstrap5-dark.css +110 -100
  62. package/styles/bootstrap5.css +110 -100
  63. package/styles/fabric-dark.css +98 -88
  64. package/styles/fabric.css +98 -88
  65. package/styles/fluent-dark.css +109 -99
  66. package/styles/fluent.css +109 -99
  67. package/styles/highcontrast-light.css +98 -88
  68. package/styles/highcontrast.css +98 -88
  69. package/styles/material-dark.css +98 -88
  70. package/styles/material.css +98 -88
  71. package/styles/recurrence-editor/_bootstrap5-definition.scss +1 -1
  72. package/styles/recurrence-editor/_fluent-definition.scss +1 -1
  73. package/styles/recurrence-editor/_tailwind-definition.scss +1 -1
  74. package/styles/schedule/_bootstrap-dark-definition.scss +8 -1
  75. package/styles/schedule/_bootstrap-definition.scss +8 -1
  76. package/styles/schedule/_bootstrap4-definition.scss +7 -0
  77. package/styles/schedule/_bootstrap5-definition.scss +17 -10
  78. package/styles/schedule/_fabric-dark-definition.scss +7 -0
  79. package/styles/schedule/_fabric-definition.scss +7 -0
  80. package/styles/schedule/_fluent-definition.scss +15 -8
  81. package/styles/schedule/_fusionnew-definition.scss +7 -0
  82. package/styles/schedule/_highcontrast-definition.scss +7 -0
  83. package/styles/schedule/_highcontrast-light-definition.scss +7 -0
  84. package/styles/schedule/_layout.scss +63 -48
  85. package/styles/schedule/_material-dark-definition.scss +7 -0
  86. package/styles/schedule/_material-definition.scss +7 -0
  87. package/styles/schedule/_tailwind-definition.scss +17 -10
  88. package/styles/schedule/_theme.scss +40 -41
  89. package/styles/schedule/bootstrap-dark.css +99 -89
  90. package/styles/schedule/bootstrap.css +99 -89
  91. package/styles/schedule/bootstrap4.css +99 -89
  92. package/styles/schedule/bootstrap5-dark.css +110 -100
  93. package/styles/schedule/bootstrap5.css +110 -100
  94. package/styles/schedule/fabric-dark.css +98 -88
  95. package/styles/schedule/fabric.css +98 -88
  96. package/styles/schedule/fluent-dark.css +109 -99
  97. package/styles/schedule/fluent.css +109 -99
  98. package/styles/schedule/highcontrast-light.css +98 -88
  99. package/styles/schedule/highcontrast.css +98 -88
  100. package/styles/schedule/material-dark.css +98 -88
  101. package/styles/schedule/material.css +98 -88
  102. package/styles/schedule/tailwind-dark.css +106 -96
  103. package/styles/schedule/tailwind.css +106 -96
  104. package/styles/tailwind-dark.css +106 -96
  105. package/styles/tailwind.css +106 -96
  106. package/styles/recurrence-editor/_material3-definition.scss +0 -13
  107. 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));
@@ -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];
@@ -2304,7 +2306,7 @@ class KeyboardInteraction {
2304
2306
  nextAppEle = isReverse ? appointments[appointments.length - 1] : appointments[0];
2305
2307
  }
2306
2308
  if (nextAppEle) {
2307
- this.parent.eventBase.addSelectedAppointments([nextAppEle]);
2309
+ this.parent.eventBase.addSelectedAppointments([nextAppEle], true);
2308
2310
  nextAppEle.focus();
2309
2311
  addClass([nextAppEle], AGENDA_SELECTED_CELL);
2310
2312
  }
@@ -2330,7 +2332,7 @@ class KeyboardInteraction {
2330
2332
  if (filteredElements.length > 0) {
2331
2333
  const selectedElement = isReverse ? filteredElements[filteredElements.length - 1] : filteredElements[0];
2332
2334
  const focusElements = this.getAppointmentElementsByGuid(selectedElement.getAttribute('data-guid'));
2333
- this.parent.eventBase.addSelectedAppointments(focusElements);
2335
+ this.parent.eventBase.addSelectedAppointments(focusElements, true);
2334
2336
  (focusElements[focusElements.length - 1]).focus();
2335
2337
  }
2336
2338
  }
@@ -2788,7 +2790,7 @@ class KeyboardInteraction {
2788
2790
  if (appElements.length > 0) {
2789
2791
  this.parent.eventBase.removeSelectedAppointmentClass();
2790
2792
  const focusAppointment = isReverse ? appElements.slice(-1)[0] : appElements[0];
2791
- this.parent.eventBase.addSelectedAppointments([focusAppointment]);
2793
+ this.parent.eventBase.addSelectedAppointments([focusAppointment], true);
2792
2794
  focusAppointment.focus();
2793
2795
  e.preventDefault();
2794
2796
  }
@@ -2890,7 +2892,7 @@ class KeyboardInteraction {
2890
2892
  const nextAppEle = eventEle[0];
2891
2893
  if (nextAppEle) {
2892
2894
  this.parent.eventBase.removeSelectedAppointmentClass();
2893
- this.parent.eventBase.addSelectedAppointments([nextAppEle]);
2895
+ this.parent.eventBase.addSelectedAppointments([nextAppEle], true);
2894
2896
  nextAppEle.focus();
2895
2897
  }
2896
2898
  }
@@ -2902,7 +2904,7 @@ class KeyboardInteraction {
2902
2904
  if (appElements.length > 0) {
2903
2905
  this.parent.eventBase.removeSelectedAppointmentClass();
2904
2906
  const focusAppointment = appElements[0];
2905
- this.parent.eventBase.addSelectedAppointments([focusAppointment]);
2907
+ this.parent.eventBase.addSelectedAppointments([focusAppointment], true);
2906
2908
  focusAppointment.focus();
2907
2909
  e.preventDefault();
2908
2910
  }
@@ -2982,11 +2984,13 @@ class Data {
2982
2984
  /**
2983
2985
  * Constructor for data module
2984
2986
  *
2987
+ * @param {Schedule} parent Accepts the schedule element instance
2985
2988
  * @param {Object | DataManager} dataSource Accepts the datasource as JSON objects or DataManager
2986
2989
  * @param {Query} query Accepts the query to process the data
2987
2990
  * @private
2988
2991
  */
2989
- constructor(dataSource, query) {
2992
+ constructor(parent, dataSource, query) {
2993
+ this.parent = parent;
2990
2994
  this.initDataManager(dataSource, query);
2991
2995
  }
2992
2996
  /**
@@ -3011,6 +3015,11 @@ class Data {
3011
3015
  */
3012
3016
  generateQuery(startDate, endDate) {
3013
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
+ }
3014
3023
  if (startDate) {
3015
3024
  query.addParams('StartDate', startDate.toISOString());
3016
3025
  }
@@ -3019,6 +3028,23 @@ class Data {
3019
3028
  }
3020
3029
  return query;
3021
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
+ }
3022
3048
  /**
3023
3049
  * The function used to get dataSource by executing given Query
3024
3050
  *
@@ -5396,12 +5422,7 @@ class EventBase {
5396
5422
  return this.filterEvents(eStart, eEnd, blockEvents, resourceData);
5397
5423
  }
5398
5424
  filterEvents(startDate, endDate, appointments = this.parent.eventsProcessed, resourceTdData) {
5399
- const fieldMapping = this.parent.eventFields;
5400
- const predicate = new Predicate(fieldMapping.startTime, 'greaterthanorequal', startDate).
5401
- and(new Predicate(fieldMapping.endTime, 'greaterthanorequal', startDate)).
5402
- and(new Predicate(fieldMapping.startTime, 'lessthan', endDate)).
5403
- or(new Predicate(fieldMapping.startTime, 'lessthanorequal', startDate).
5404
- and(new Predicate(fieldMapping.endTime, 'greaterthan', startDate)));
5425
+ const predicate = this.parent.dataModule.getStartEndQuery(startDate, endDate);
5405
5426
  let filter = new DataManager({ json: appointments }).executeLocal(new Query().where(predicate));
5406
5427
  if (resourceTdData) {
5407
5428
  filter = this.filterEventsByResource(resourceTdData, filter);
@@ -5661,7 +5682,7 @@ class EventBase {
5661
5682
  }
5662
5683
  }
5663
5684
  if (target && this.parent.selectedElements.length > 0) {
5664
- this.addSelectedAppointments(this.parent.selectedElements);
5685
+ this.addSelectedAppointments(this.parent.selectedElements, false);
5665
5686
  }
5666
5687
  return this.parent.selectedElements;
5667
5688
  }
@@ -5690,12 +5711,12 @@ class EventBase {
5690
5711
  removeClass(selectedAppointments, AGENDA_SELECTED_CELL);
5691
5712
  }
5692
5713
  }
5693
- addSelectedAppointments(cells) {
5714
+ addSelectedAppointments(cells, preventFocus) {
5694
5715
  if (this.parent.currentView !== 'MonthAgenda') {
5695
5716
  this.parent.removeSelectedClass();
5696
5717
  }
5697
5718
  addClass(cells, APPOINTMENT_BORDER);
5698
- if (cells.length > 0) {
5719
+ if (cells.length > 0 && !preventFocus) {
5699
5720
  cells[cells.length - 1].focus();
5700
5721
  }
5701
5722
  }
@@ -5719,6 +5740,10 @@ class EventBase {
5719
5740
  }
5720
5741
  const selectedAppointments = this.getSelectedAppointments();
5721
5742
  if (selectedAppointments.length > 0) {
5743
+ if (this.parent.activeEventData && this.parent.activeEventData.element && selectedAppointments.indexOf(this.parent.activeEventData.element) > -1) {
5744
+ this.parent.activeEventData.element.focus();
5745
+ return;
5746
+ }
5722
5747
  selectedAppointments[selectedAppointments.length - 1].focus();
5723
5748
  return;
5724
5749
  }
@@ -6009,7 +6034,7 @@ class EventBase {
6009
6034
  const target = closest(eventData.target, '.' + APPOINTMENT_CLASS);
6010
6035
  const guid = target.getAttribute('data-guid');
6011
6036
  if (isMultiple) {
6012
- this.addSelectedAppointments([].slice.call(this.parent.element.querySelectorAll('div[data-guid="' + guid + '"]')));
6037
+ this.addSelectedAppointments([].slice.call(this.parent.element.querySelectorAll('div[data-guid="' + guid + '"]')), true);
6013
6038
  target.focus();
6014
6039
  }
6015
6040
  let eventObject = this.getEventByGuid(guid);
@@ -6234,9 +6259,8 @@ class EventBase {
6234
6259
  templateElement = this.parent.getAppointmentTemplate()(record, this.parent, templateName, templateId, false);
6235
6260
  }
6236
6261
  else {
6237
- const appointmentSubject = createElement('div', {
6238
- className: SUBJECT_CLASS, innerHTML: eventSubject
6239
- });
6262
+ const appointmentSubject = createElement('div', { className: SUBJECT_CLASS });
6263
+ appointmentSubject.innerText = this.parent.sanitize(eventSubject);
6240
6264
  templateElement = [appointmentSubject];
6241
6265
  }
6242
6266
  append(templateElement, appointmentWrapper);
@@ -6414,6 +6438,29 @@ class EventBase {
6414
6438
  return eventArgs && eventArgs.changedTouches ? eventArgs.changedTouches[0] : e.changedTouches ? e.changedTouches[0] :
6415
6439
  eventArgs || e;
6416
6440
  }
6441
+ renderSpannedIcon(element, spanEvent) {
6442
+ const iconElement = createElement('div', { className: EVENT_INDICATOR_CLASS + ' ' + ICON });
6443
+ if (spanEvent.isLeft) {
6444
+ const iconLeft = iconElement.cloneNode();
6445
+ addClass([iconLeft], EVENT_ICON_LEFT_CLASS);
6446
+ prepend([iconLeft], element);
6447
+ }
6448
+ if (spanEvent.isRight) {
6449
+ const iconRight = iconElement.cloneNode();
6450
+ addClass([iconRight], EVENT_ICON_RIGHT_CLASS);
6451
+ append([iconRight], element);
6452
+ }
6453
+ if (spanEvent.isTop) {
6454
+ const iconTop = iconElement.cloneNode();
6455
+ addClass([iconTop], EVENT_ICON_UP_CLASS);
6456
+ prepend([iconTop], element);
6457
+ }
6458
+ if (spanEvent.isBottom) {
6459
+ const iconBottom = iconElement.cloneNode();
6460
+ addClass([iconBottom], EVENT_ICON_DOWN_CLASS);
6461
+ append([iconBottom], element);
6462
+ }
6463
+ }
6417
6464
  unWireEvents() {
6418
6465
  const appElements = [].slice.call(this.parent.element.querySelectorAll('.' + APPOINTMENT_CLASS));
6419
6466
  for (const element of appElements) {
@@ -6738,7 +6785,8 @@ class VerticalEvent extends EventBase {
6738
6785
  templateElement = this.parent.getAppointmentTemplate()(record, this.parent, templateName, templateId, false);
6739
6786
  }
6740
6787
  else {
6741
- const appointmentSubject = createElement('div', { className: SUBJECT_CLASS, innerHTML: recordSubject });
6788
+ const appointmentSubject = createElement('div', { className: SUBJECT_CLASS });
6789
+ appointmentSubject.innerText = this.parent.sanitize(recordSubject);
6742
6790
  if (isAllDay) {
6743
6791
  if (record[fieldMapping.isAllDay]) {
6744
6792
  templateElement = [appointmentSubject];
@@ -6770,10 +6818,8 @@ class VerticalEvent extends EventBase {
6770
6818
  className: APPOINTMENT_TIME + (this.parent.isAdaptive ? ' ' + DISABLE_CLASS : ''),
6771
6819
  innerHTML: timeStr
6772
6820
  });
6773
- const appointmentLocation = createElement('div', {
6774
- className: LOCATION_CLASS,
6775
- innerHTML: (record[fieldMapping.location] || this.parent.eventSettings.fields.location.default || '')
6776
- });
6821
+ const appointmentLocation = createElement('div', { className: LOCATION_CLASS });
6822
+ appointmentLocation.innerText = this.parent.sanitize((record[fieldMapping.location] || this.parent.eventSettings.fields.location.default || ''));
6777
6823
  templateElement = [appointmentSubject, appointmentTime, appointmentLocation];
6778
6824
  }
6779
6825
  }
@@ -6790,7 +6836,7 @@ class VerticalEvent extends EventBase {
6790
6836
  appointmentWrapper.appendChild(recurrenceIcon);
6791
6837
  }
6792
6838
  }
6793
- this.renderSpannedIcon(isAllDay ? appointmentDetails : appointmentWrapper, eventData);
6839
+ this.parent.eventBase.renderSpannedIcon(isAllDay ? appointmentDetails : appointmentWrapper, eventData);
6794
6840
  if (!isNullOrUndefined(this.cssClass)) {
6795
6841
  addClass([appointmentWrapper], this.cssClass);
6796
6842
  }
@@ -6822,29 +6868,6 @@ class VerticalEvent extends EventBase {
6822
6868
  countCell.innerHTML = '+' + this.parent.globalize.formatNumber(moreCount) + '&nbsp;' + (this.parent.isAdaptive ? '' : this.parent.localeObj.getConstant('more'));
6823
6869
  }
6824
6870
  }
6825
- renderSpannedIcon(element, spanEvent) {
6826
- const iconElement = createElement('div', { className: EVENT_INDICATOR_CLASS + ' ' + ICON });
6827
- if (spanEvent.isLeft) {
6828
- const iconLeft = iconElement.cloneNode();
6829
- addClass([iconLeft], EVENT_ICON_LEFT_CLASS);
6830
- prepend([iconLeft], element);
6831
- }
6832
- if (spanEvent.isRight) {
6833
- const iconRight = iconElement.cloneNode();
6834
- addClass([iconRight], EVENT_ICON_RIGHT_CLASS);
6835
- append([iconRight], element);
6836
- }
6837
- if (spanEvent.isTop) {
6838
- const iconTop = iconElement.cloneNode();
6839
- addClass([iconTop], EVENT_ICON_UP_CLASS);
6840
- prepend([iconTop], element);
6841
- }
6842
- if (spanEvent.isBottom) {
6843
- const iconBottom = iconElement.cloneNode();
6844
- addClass([iconBottom], EVENT_ICON_DOWN_CLASS);
6845
- append([iconBottom], element);
6846
- }
6847
- }
6848
6871
  isSpannedEvent(record, day, resource) {
6849
6872
  let currentDate = resetTime(this.dateRender[parseInt(resource.toString(), 10)][parseInt(day.toString(), 10)]);
6850
6873
  const renderedDate = this.getRenderedDates(this.dateRender[parseInt(resource.toString(), 10)]) || [currentDate];
@@ -7646,10 +7669,8 @@ class MonthEvent extends EventBase {
7646
7669
  }
7647
7670
  else {
7648
7671
  const eventLocation = (record[this.fields.location] || this.parent.eventSettings.fields.location.default || '');
7649
- const appointmentSubject = createElement('div', {
7650
- className: SUBJECT_CLASS,
7651
- innerHTML: (eventSubject + (eventLocation ? ';&nbsp' + eventLocation : ''))
7652
- });
7672
+ const appointmentSubject = createElement('div', { className: SUBJECT_CLASS });
7673
+ appointmentSubject.innerText = this.parent.sanitize((eventSubject + (eventLocation ? '; ' + eventLocation : '')));
7653
7674
  const appointmentStartTime = createElement('div', {
7654
7675
  className: APPOINTMENT_TIME + (this.parent.isAdaptive ? ' ' + DISABLE_CLASS : ''),
7655
7676
  innerHTML: this.parent.getTimeString(eventData[this.fields.startTime])
@@ -7692,7 +7713,8 @@ class MonthEvent extends EventBase {
7692
7713
  const appTime = createElement('div', {
7693
7714
  className: APPOINTMENT_TIME + (this.parent.isAdaptive ? ' ' + DISABLE_CLASS : ''), innerHTML: timeString
7694
7715
  });
7695
- const appLocation = createElement('div', { className: LOCATION_CLASS, innerHTML: eventLocation });
7716
+ const appLocation = createElement('div', { className: LOCATION_CLASS });
7717
+ appLocation.innerText = this.parent.sanitize(eventLocation);
7696
7718
  innerElement = [appointmentSubject, appTime, appLocation];
7697
7719
  }
7698
7720
  const wrap = createElement('div', { className: 'e-inner-wrap' });
@@ -8888,6 +8910,7 @@ class QuickPopups {
8888
8910
  cssClass: QUICK_DIALOG_CLASS,
8889
8911
  closeOnEscape: true,
8890
8912
  enableRtl: this.parent.enableRtl,
8913
+ enableHtmlSanitizer: this.parent.enableHtmlSanitizer,
8891
8914
  beforeClose: this.beforeQuickDialogClose.bind(this),
8892
8915
  isModal: true,
8893
8916
  position: { X: 'center', Y: 'center' },
@@ -8919,6 +8942,7 @@ class QuickPopups {
8919
8942
  cssClass: className,
8920
8943
  disabled: isDisabled,
8921
8944
  enableRtl: this.parent.enableRtl,
8945
+ enableHtmlSanitizer: this.parent.enableHtmlSanitizer,
8922
8946
  iconCss: iconName
8923
8947
  });
8924
8948
  buttonObj.appendTo(element);
@@ -9112,7 +9136,8 @@ class QuickPopups {
9112
9136
  append(templateElement, appointmentElement);
9113
9137
  }
9114
9138
  else {
9115
- appointmentElement.appendChild(createElement('div', { className: SUBJECT_CLASS, innerHTML: eventText }));
9139
+ appointmentElement.appendChild(createElement('div', { className: SUBJECT_CLASS }));
9140
+ appointmentElement.firstElementChild.innerText = this.parent.sanitize(eventText);
9116
9141
  }
9117
9142
  if (!isNullOrUndefined(groupIndex)) {
9118
9143
  appointmentElement.setAttribute('data-group-index', groupIndex);
@@ -9361,10 +9386,14 @@ class QuickPopups {
9361
9386
  `<button class="${DELETE_CLASS + ' ' + ICON}" title="${this.l10n.getConstant('delete')}"></button>` +
9362
9387
  `<button class="${CLOSE_CLASS}" title="${this.l10n.getConstant('close')}"></button></div>` +
9363
9388
  `<div class="${SUBJECT_WRAP}"><div class="${SUBJECT_CLASS} ${TEXT_ELLIPSIS}" ` +
9364
- `title="${args.eventSubject ? args.eventSubject.replaceAll('"', '\'') : args.eventSubject}">${args.eventSubject}</div></div >`;
9389
+ `title="${args.eventSubject ? args.eventSubject.replaceAll('"', '\'') : args.eventSubject}"></div></div >`;
9365
9390
  break;
9366
9391
  }
9367
9392
  const templateWrapper = createElement('div', { innerHTML: header });
9393
+ if (headerType === 'Event') {
9394
+ const subjectText = templateWrapper.querySelector('.' + SUBJECT_CLASS);
9395
+ subjectText.innerText = this.parent.sanitize(args.eventSubject);
9396
+ }
9368
9397
  append([].slice.call(templateWrapper.childNodes), headerTemplate);
9369
9398
  }
9370
9399
  return headerTemplate;
@@ -9392,7 +9421,7 @@ class QuickPopups {
9392
9421
  `${TEXT_ELLIPSIS}">${cellDetails.details}</div></div>` +
9393
9422
  `${this.parent.activeViewOptions.group.resources.length > 0 ? `<div class="${RESOURCE_CLASS}">` +
9394
9423
  `<div class="${RESOURCE_ICON_CLASS} ${ICON} "></div><div class="${RESOURCE_DETAILS_CLASS} ` +
9395
- `${TEXT_ELLIPSIS}">${resourceText}</div></div>` : ''}</td></tr></tbody></table>`;
9424
+ `${TEXT_ELLIPSIS}"></div></div>` : ''}</td></tr></tbody></table>`;
9396
9425
  break;
9397
9426
  case 'Event':
9398
9427
  argsData = this.getFormattedString(data);
@@ -9406,8 +9435,7 @@ class QuickPopups {
9406
9435
  content += '</div></div>';
9407
9436
  if (data[this.parent.eventFields.location]) {
9408
9437
  content += '<div class="' + LOCATION_CLASS + '"><div class="' + LOCATION_ICON_CLASS + ' ' +
9409
- ICON + '"></div><div class="' + LOCATION_DETAILS_CLASS + ' ' + TEXT_ELLIPSIS + '">' +
9410
- data[this.parent.eventFields.location] + '</div></div>';
9438
+ ICON + '"></div><div class="' + LOCATION_DETAILS_CLASS + ' ' + TEXT_ELLIPSIS + '"></div></div>';
9411
9439
  }
9412
9440
  if (data[this.parent.eventFields.startTimezone] || data[this.parent.eventFields.endTimezone]) {
9413
9441
  content += '<div class="' + TIME_ZONE_CLASS + '"><div class="' + TIME_ZONE_ICON_CLASS + ' ' + ICON +
@@ -9416,17 +9444,33 @@ class QuickPopups {
9416
9444
  }
9417
9445
  if (data[this.parent.eventFields.description]) {
9418
9446
  content += '<div class="' + DESCRIPTION_CLASS + '"><div class="' + DESCRIPTION_ICON_CLASS + ' ' + ICON +
9419
- '"></div><div class="' + DESCRIPTION_DETAILS_CLASS + ' ' + TEXT_ELLIPSIS + '">' +
9420
- data[this.parent.eventFields.description] + '</div></div>';
9447
+ '"></div><div class="' + DESCRIPTION_DETAILS_CLASS + ' ' + TEXT_ELLIPSIS + '"></div></div>';
9421
9448
  }
9422
9449
  if (this.parent.resourceCollection.length > 0) {
9423
9450
  content += '<div class="' + RESOURCE_CLASS + '"><div class="' + RESOURCE_ICON_CLASS + ' ' + ICON +
9424
- '"></div><div class="' + RESOURCE_DETAILS_CLASS + ' ' + TEXT_ELLIPSIS + '">' +
9425
- resourceText + '</div></div>';
9451
+ '"></div><div class="' + RESOURCE_DETAILS_CLASS + ' ' + TEXT_ELLIPSIS + '"></div></div>';
9426
9452
  }
9427
9453
  break;
9428
9454
  }
9429
9455
  const templateWrapper = createElement('div', { innerHTML: content });
9456
+ if (data[this.parent.eventFields.location]) {
9457
+ const locationDetails = templateWrapper.querySelector('.' + LOCATION_DETAILS_CLASS);
9458
+ if (!isNullOrUndefined(locationDetails)) {
9459
+ locationDetails.innerText = this.parent.sanitize(data[this.parent.eventFields.location]);
9460
+ }
9461
+ }
9462
+ if (data[this.parent.eventFields.description]) {
9463
+ const descriptionDetails = templateWrapper.querySelector('.' + DESCRIPTION_DETAILS_CLASS);
9464
+ if (!isNullOrUndefined(descriptionDetails)) {
9465
+ descriptionDetails.innerText = this.parent.sanitize(data[this.parent.eventFields.description]);
9466
+ }
9467
+ }
9468
+ if (resourceText) {
9469
+ const resourceDetails = templateWrapper.querySelector('.' + RESOURCE_DETAILS_CLASS);
9470
+ if (!isNullOrUndefined(resourceDetails)) {
9471
+ resourceDetails.innerText = this.parent.sanitize(resourceText);
9472
+ }
9473
+ }
9430
9474
  append([].slice.call(templateWrapper.childNodes), contentTemplate);
9431
9475
  }
9432
9476
  return contentTemplate;
@@ -9955,7 +9999,7 @@ class QuickPopups {
9955
9999
  }
9956
10000
  quickPopupClose() {
9957
10001
  this.parent.eventBase.focusElement();
9958
- this.quickPopup.relateTo = WORK_CELLS_CLASS;
10002
+ this.quickPopup.relateTo = '.' + WORK_CELLS_CLASS;
9959
10003
  this.fieldValidator.destroyToolTip();
9960
10004
  if (this.quickPopup.element.querySelectorAll('.e-formvalidator').length) {
9961
10005
  this.fieldValidator.destroy();
@@ -10172,7 +10216,8 @@ class EventTooltip {
10172
10216
  target: this.getTargets(),
10173
10217
  beforeRender: this.onBeforeRender.bind(this),
10174
10218
  beforeClose: this.onBeforeClose.bind(this),
10175
- enableRtl: this.parent.enableRtl
10219
+ enableRtl: this.parent.enableRtl,
10220
+ enableHtmlSanitizer: this.parent.enableHtmlSanitizer
10176
10221
  });
10177
10222
  this.tooltipObj.appendTo(this.parent.element);
10178
10223
  }
@@ -11434,6 +11479,7 @@ class EventWindow {
11434
11479
  content: this.getEventWindowContent(),
11435
11480
  cssClass: EVENT_WINDOW_DIALOG_CLASS,
11436
11481
  enableRtl: this.parent.enableRtl,
11482
+ enableHtmlSanitizer: this.parent.enableHtmlSanitizer,
11437
11483
  height: this.parent.isAdaptive ? '100%' : 'auto',
11438
11484
  minHeight: '300px',
11439
11485
  isModal: true,
@@ -11641,6 +11687,10 @@ class EventWindow {
11641
11687
  renderFormElements(form, args) {
11642
11688
  if (!isNullOrUndefined(this.parent.editorTemplate)) {
11643
11689
  if (args) {
11690
+ if (this.fieldValidator) {
11691
+ this.fieldValidator.destroy();
11692
+ this.fieldValidator = null;
11693
+ }
11644
11694
  if (this.recurrenceEditor) {
11645
11695
  this.recurrenceEditor.destroy();
11646
11696
  this.recurrenceEditor = null;
@@ -11813,6 +11863,7 @@ class EventWindow {
11813
11863
  if (resourceData.allowMultiple) {
11814
11864
  const listObj = new MultiSelect({
11815
11865
  enableRtl: this.parent.enableRtl,
11866
+ enableHtmlSanitizer: this.parent.enableHtmlSanitizer,
11816
11867
  cssClass: this.parent.cssClass || '',
11817
11868
  dataSource: resourceData.dataSource,
11818
11869
  change: this.onMultiselectResourceChange.bind(this),
@@ -11950,6 +12001,7 @@ class EventWindow {
11950
12001
  change: this.onChange.bind(this),
11951
12002
  cssClass: value + ' ' + this.parent.cssClass,
11952
12003
  enableRtl: this.parent.enableRtl,
12004
+ enableHtmlSanitizer: this.parent.enableHtmlSanitizer,
11953
12005
  label: this.getFieldLabel(value)
11954
12006
  });
11955
12007
  checkBox.appendTo(checkBoxInput);
@@ -12076,6 +12128,7 @@ class EventWindow {
12076
12128
  target: this.element,
12077
12129
  animationSettings: { effect: 'Zoom' },
12078
12130
  enableRtl: this.parent.enableRtl,
12131
+ enableHtmlSanitizer: this.parent.enableHtmlSanitizer,
12079
12132
  isModal: true,
12080
12133
  cssClass: REPEAT_DIALOG_CLASS,
12081
12134
  open: this.repeatOpenDialog.bind(this)
@@ -12143,6 +12196,9 @@ class EventWindow {
12143
12196
  if (!this.parent.eventSettings.allowAdding) {
12144
12197
  return;
12145
12198
  }
12199
+ if (this.parent.isAdaptive && repeatType && !this.repeatDialogObject) {
12200
+ this.renderRepeatDialog();
12201
+ }
12146
12202
  this.element.querySelector('.' + FORM_CLASS).removeAttribute('data-id');
12147
12203
  this.element.querySelector('.' + EVENT_WINDOW_TITLE_TEXT_CLASS).innerHTML = this.l10n.getConstant('newEvent');
12148
12204
  eventObj.Timezone = false;
@@ -12172,10 +12228,18 @@ class EventWindow {
12172
12228
  selectedType: !isNullOrUndefined(repeatType) ? repeatType : !isNullOrUndefined(eventObj[this.fields.recurrenceRule]) ?
12173
12229
  this.recurrenceEditor.selectedType : 0
12174
12230
  });
12231
+ this.repeatRule = this.recurrenceEditor.value;
12175
12232
  }
12176
12233
  if (this.parent.isAdaptive && isNullOrUndefined(this.parent.editorTemplate)) {
12177
12234
  const element = this.element.querySelector('.' + REPEAT_CONTAINER_CLASS);
12178
- addClass([element], HIDE_STYLE_CLASS);
12235
+ if (eventObj[this.fields.recurrenceRule] || repeatType) {
12236
+ removeClass([element], HIDE_STYLE_CLASS);
12237
+ this.repeatStatus.setProperties({ checked: true });
12238
+ }
12239
+ else {
12240
+ addClass([element], HIDE_STYLE_CLASS);
12241
+ this.repeatStatus.setProperties({ checked: false });
12242
+ }
12179
12243
  this.updateRepeatLabel(this.repeatRule);
12180
12244
  }
12181
12245
  else {
@@ -12816,9 +12880,11 @@ class EventWindow {
12816
12880
  }
12817
12881
  const currentStartTime = new Date(+currentData[this.fields.startTime]);
12818
12882
  const currentEndTime = new Date(+currentData[this.fields.endTime]);
12883
+ let nextStartTime;
12884
+ let nextEndTime;
12819
12885
  if (index !== recurColl.length - 1) {
12820
- var nextStartTime = new Date(+recurColl[index + 1][this.fields.startTime]);
12821
- var nextEndTime = new Date(+recurColl[index + 1][this.fields.endTime]);
12886
+ nextStartTime = new Date(+recurColl[index + 1][this.fields.startTime]);
12887
+ nextEndTime = new Date(+recurColl[index + 1][this.fields.endTime]);
12822
12888
  }
12823
12889
  const lastEndTime = new Date(+recurColl[recurColl.length - 1][this.fields.endTime]);
12824
12890
  if (index === 0) {
@@ -13009,7 +13075,7 @@ class EventWindow {
13009
13075
  value = element.checked;
13010
13076
  }
13011
13077
  else {
13012
- value = SanitizeHtmlHelper.sanitize(element.value);
13078
+ value = this.parent.sanitize(element.value);
13013
13079
  }
13014
13080
  }
13015
13081
  return value;
@@ -14019,6 +14085,7 @@ class Crud {
14019
14085
  if (this.parent.currentAction !== 'EditFollowingEvents' && !this.isBlockEvent(eventData)
14020
14086
  && this.parent.eventBase.isBlockRange(eventData)) {
14021
14087
  this.parent.quickPopup.openValidationError('blockAlert', eventData);
14088
+ this.parent.crudModule.crudObj.isCrudAction = false;
14022
14089
  return;
14023
14090
  }
14024
14091
  const updateEvents = (eventData instanceof Array) ? eventData : [eventData];
@@ -14665,8 +14732,8 @@ var __decorate$7 = (undefined && undefined.__decorate) || function (decorators,
14665
14732
  return c > 3 && r && Object.defineProperty(target, key, r), r;
14666
14733
  };
14667
14734
  /**
14668
- * A Class that holds the collection of event fields that requires to be mapped with the dataSource
14669
- * fields along with its available configuration settings. Each field in it accepts both string and Object
14735
+ * A class that holds the collection of event fields that requires to be mapped with the dataSource
14736
+ * fields along with its available configuration settings. Each field in it accepts both string and object
14670
14737
  * data type. When each of the field is assigned with simple `string` value, it is assumed that the dataSource field
14671
14738
  * name is mapped with it. If the `object` type is defined on each fields, then the validation related settings and mapping of
14672
14739
  * those fields with dataSource can be given altogether within it.
@@ -14782,6 +14849,9 @@ __decorate$6([
14782
14849
  __decorate$6([
14783
14850
  Property()
14784
14851
  ], EventSettings.prototype, "sortComparer", void 0);
14852
+ __decorate$6([
14853
+ Property()
14854
+ ], EventSettings.prototype, "includeFiltersInQuery", void 0);
14785
14855
 
14786
14856
  var __decorate$9 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
14787
14857
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -15063,7 +15133,7 @@ class ResourceBase {
15063
15133
  classList(target, [RESOURCE_COLLAPSE_CLASS], [RESOURCE_EXPAND_CLASS]);
15064
15134
  hide = false;
15065
15135
  }
15066
- const eventElements = [].slice.call(this.parent.element.querySelectorAll('.' + APPOINTMENT_CLASS));
15136
+ const eventElements = [].slice.call(this.parent.element.querySelectorAll('.' + APPOINTMENT_CLASS + ',.' + MORE_INDICATOR_CLASS));
15067
15137
  for (const element of eventElements) {
15068
15138
  remove(element);
15069
15139
  }
@@ -15192,6 +15262,7 @@ class ResourceBase {
15192
15262
  this.treeViewObj = new TreeView({
15193
15263
  cssClass: this.parent.cssClass,
15194
15264
  enableRtl: this.parent.enableRtl,
15265
+ enableHtmlSanitizer: this.parent.enableHtmlSanitizer,
15195
15266
  fields: {
15196
15267
  dataSource: [].slice.call(this.generateTreeData()),
15197
15268
  id: 'resourceId',
@@ -15288,10 +15359,8 @@ class ResourceBase {
15288
15359
  for (let i = 0, len = resource.groupOrder.length; i < len; i++) {
15289
15360
  const resourceLevel = this.resourceCollection[parseInt(i.toString(), 10)];
15290
15361
  const resourceText = resourceLevel.dataSource.filter((resData) => resData[resourceLevel.idField] === resource.groupOrder[parseInt(i.toString(), 10)]);
15291
- const resourceName = createElement('div', {
15292
- className: RESOURCE_NAME,
15293
- innerHTML: resourceText[0][resourceLevel.textField]
15294
- });
15362
+ const resourceName = createElement('div', { className: RESOURCE_NAME });
15363
+ resourceName.innerText = this.parent.sanitize(resourceText[0][resourceLevel.textField]);
15295
15364
  headerCollection.push(resourceName);
15296
15365
  const levelIcon = createElement('div', { className: 'e-icons e-icon-next' });
15297
15366
  headerCollection.push(levelIcon);
@@ -15363,7 +15432,7 @@ class ResourceBase {
15363
15432
  this.parent.showSpinner();
15364
15433
  const promises = [];
15365
15434
  for (const resource of this.parent.resources) {
15366
- const dataModule = new Data(resource.dataSource, resource.query);
15435
+ const dataModule = new Data(this.parent, resource.dataSource, resource.query);
15367
15436
  promises.push(dataModule.getData(dataModule.generateQuery()));
15368
15437
  }
15369
15438
  Promise.all(promises).then((e) => this.dataManagerSuccess(e, isSetModel))
@@ -15997,7 +16066,7 @@ let Schedule = class Schedule extends Component {
15997
16066
  /**
15998
16067
  * Method to render react templates
15999
16068
  *
16000
- * @param {Function} callBack - specifies the callBack method
16069
+ * @param {Function} callback - Specifies the callBack method
16001
16070
  * @returns {void}
16002
16071
  * @private
16003
16072
  */
@@ -16021,6 +16090,19 @@ let Schedule = class Schedule extends Component {
16021
16090
  this.clearTemplate(templates);
16022
16091
  }
16023
16092
  }
16093
+ /**
16094
+ * Method to sanitize any suspected untrusted strings and scripts before rendering them.
16095
+ *
16096
+ * @param {string} value - A string value representing the HTML string value to be sanitized.
16097
+ * @returns {string} A sanitized Html string.
16098
+ * @private
16099
+ */
16100
+ sanitize(value) {
16101
+ if (this.enableHtmlSanitizer) {
16102
+ return SanitizeHtmlHelper.sanitize(value);
16103
+ }
16104
+ return value;
16105
+ }
16024
16106
  initializeResources(isSetModel = false) {
16025
16107
  if (this.resources.length > 0) {
16026
16108
  this.resourceBase = new ResourceBase(this);
@@ -16230,7 +16312,7 @@ let Schedule = class Schedule extends Component {
16230
16312
  followingID: this.eventSettings.fields.followingID
16231
16313
  };
16232
16314
  this.setEditorTitles();
16233
- this.dataModule = new Data(this.eventSettings.dataSource, this.eventSettings.query);
16315
+ this.dataModule = new Data(this, this.eventSettings.dataSource, this.eventSettings.query);
16234
16316
  this.crudModule = new Crud(this);
16235
16317
  }
16236
16318
  setEditorTitles() {
@@ -16428,6 +16510,9 @@ let Schedule = class Schedule extends Component {
16428
16510
  if (this.headerModule) {
16429
16511
  this.headerModule.setCalendarDate(navigationArgs.currentDate);
16430
16512
  }
16513
+ if (this.currentView === 'MonthAgenda' && this.monthAgendaModule) {
16514
+ this.monthAgendaModule.monthAgendaDate = new Date('' + this.selectedDate);
16515
+ }
16431
16516
  this.initializeView(this.currentView);
16432
16517
  this.animateLayout();
16433
16518
  args = { requestType: 'dateNavigate', cancel: false, event: event };
@@ -16643,7 +16728,9 @@ let Schedule = class Schedule extends Component {
16643
16728
  removeSelectedClass() {
16644
16729
  const selectedCells = this.getSelectedCells();
16645
16730
  for (const cell of selectedCells) {
16646
- cell.setAttribute('aria-selected', 'false');
16731
+ if (this.currentView !== 'Year') {
16732
+ cell.setAttribute('aria-selected', 'false');
16733
+ }
16647
16734
  cell.removeAttribute('tabindex');
16648
16735
  }
16649
16736
  removeClass(selectedCells, SELECTED_CELL_CLASS);
@@ -16661,8 +16748,10 @@ let Schedule = class Schedule extends Component {
16661
16748
  * @private
16662
16749
  */
16663
16750
  addSelectedClass(cells, focusCell, isPreventScroll) {
16664
- for (const cell of cells) {
16665
- cell.setAttribute('aria-selected', 'true');
16751
+ if (this.currentView !== 'Year') {
16752
+ for (const cell of cells) {
16753
+ cell.setAttribute('aria-selected', 'true');
16754
+ }
16666
16755
  }
16667
16756
  addClass(cells, SELECTED_CELL_CLASS);
16668
16757
  if (focusCell) {
@@ -17319,6 +17408,7 @@ let Schedule = class Schedule extends Component {
17319
17408
  this.changeDate(this.selectedDate);
17320
17409
  }
17321
17410
  else if (state.isLayout) {
17411
+ this.activeCellsData = null;
17322
17412
  this.initializeView(this.currentView);
17323
17413
  }
17324
17414
  else if (state.isDataManager && this.crudModule) {
@@ -17492,6 +17582,7 @@ let Schedule = class Schedule extends Component {
17492
17582
  case 'dataSource':
17493
17583
  case 'query':
17494
17584
  case 'fields':
17585
+ case 'includeFiltersInQuery':
17495
17586
  this.initializeDataModule();
17496
17587
  state.isDataManager = true;
17497
17588
  break;
@@ -17892,6 +17983,17 @@ let Schedule = class Schedule extends Component {
17892
17983
  addEvent(data) {
17893
17984
  this.crudModule.addEvent(data);
17894
17985
  }
17986
+ /**
17987
+ * Generates the occurrences of a single recurrence event based on the provided event.
17988
+ *
17989
+ * @function generateEventOccurrences
17990
+ * @param {Object} event Accepts the parent recurrence event from which the occurrences are generated.
17991
+ * @param {Date} startDate Accepts the start date for the event occurrences. If not provided, the event's start date will be used.
17992
+ * @returns {Object[]} Returns the collection of occurrence event objects.
17993
+ */
17994
+ generateEventOccurrences(event, startDate) {
17995
+ return (this.eventBase) ? this.eventBase.generateOccurrence(event, startDate) : [];
17996
+ }
17895
17997
  /**
17896
17998
  * Allows the Scheduler events data to be exported as an Excel file either in .xlsx or .csv file formats.
17897
17999
  * By default, the whole event collection bound to the Scheduler gets exported as an Excel file.
@@ -18344,7 +18446,7 @@ let Schedule = class Schedule extends Component {
18344
18446
  const element = this.element.querySelector('div[data-guid="' + selectEvent.Guid + '"]');
18345
18447
  if (element) {
18346
18448
  this.eventBase.removeSelectedAppointmentClass();
18347
- this.eventBase.addSelectedAppointments([element]);
18449
+ this.eventBase.addSelectedAppointments([element], false);
18348
18450
  this.activeEventData = { event: selectEvent, element: element };
18349
18451
  if (this.currentView === 'Agenda' || this.currentView === 'MonthAgenda') {
18350
18452
  addClass([this.activeEventData.element], AGENDA_SELECTED_CELL);
@@ -18558,6 +18660,9 @@ __decorate([
18558
18660
  __decorate([
18559
18661
  Property(null)
18560
18662
  ], Schedule.prototype, "timeFormat", void 0);
18663
+ __decorate([
18664
+ Property(true)
18665
+ ], Schedule.prototype, "enableHtmlSanitizer", void 0);
18561
18666
  __decorate([
18562
18667
  Property(false)
18563
18668
  ], Schedule.prototype, "enableAllDayScroll", void 0);
@@ -18806,6 +18911,7 @@ class ActionBase {
18806
18911
  parseInt(this.actionObj.element.getAttribute('data-group-index'), 10) === this.actionObj.groupIndex : true;
18807
18912
  if (+eventObj[this.parent.eventFields.startTime] === +this.actionObj.event[this.parent.eventFields.startTime] &&
18808
18913
  +eventObj[this.parent.eventFields.endTime] === +this.actionObj.event[this.parent.eventFields.endTime] && isSameResource) {
18914
+ this.parent.crudModule.crudObj.isCrudAction = false;
18809
18915
  return;
18810
18916
  }
18811
18917
  if (eventObj[this.parent.eventFields.recurrenceRule]) {
@@ -19079,6 +19185,10 @@ class ActionBase {
19079
19185
  }
19080
19186
  appWidth = eventObj.isSpanned.count * this.actionObj.cellWidth;
19081
19187
  }
19188
+ if (!isResize && this.parent.activeViewOptions.orientation === 'Vertical' && this.parent.activeViewOptions.group.resources.length !== 0) {
19189
+ const eventObj = this.yearEvent.isSpannedEvent(event, event[this.parent.eventFields.startTime]);
19190
+ appWidth = eventObj.isSpanned.count * this.actionObj.cellWidth;
19191
+ }
19082
19192
  const appointmentElement = this.createAppointmentElement(this.actionObj.groupIndex, event[this.parent.eventFields.subject]);
19083
19193
  appointmentElement.setAttribute('drag', 'true');
19084
19194
  addClass([appointmentElement], CLONE_ELEMENT_CLASS);
@@ -19813,7 +19923,7 @@ class YearEvent extends TimelineEvent {
19813
19923
  }
19814
19924
  timelineYearViewEvents() {
19815
19925
  const workCell = this.parent.element.querySelector('.' + WORK_CELLS_CLASS + ':not(.' + OTHERMONTH_CLASS + ')');
19816
- this.cellWidth = workCell.offsetWidth;
19926
+ this.cellWidth = workCell.getBoundingClientRect().width;
19817
19927
  this.cellHeader = getOuterHeight(workCell.querySelector('.' + DATE_HEADER_CLASS));
19818
19928
  const eventTable = this.parent.element.querySelector('.' + EVENT_TABLE_CLASS);
19819
19929
  this.eventHeight = getElementHeightFromClass(eventTable, APPOINTMENT_CLASS);
@@ -19824,7 +19934,7 @@ class YearEvent extends TimelineEvent {
19824
19934
  for (let row = 0; row < months.length; row++) {
19825
19935
  const wrapper = wrapperCollection[parseInt(row.toString(), 10)];
19826
19936
  let td = row + 1;
19827
- const eventWrapper = createElement('div', { className: APPOINTMENT_WRAPPER_CLASS });
19937
+ let eventWrapper = createElement('div', { className: APPOINTMENT_WRAPPER_CLASS });
19828
19938
  wrapper.appendChild(eventWrapper);
19829
19939
  let monthStart = new Date(this.parent.selectedDate.getFullYear(), months[parseInt(row.toString(), 10)], 1);
19830
19940
  const monthEnd = new Date(monthStart.getFullYear(), monthStart.getMonth() + 1, 0);
@@ -19839,7 +19949,7 @@ class YearEvent extends TimelineEvent {
19839
19949
  if (this.parent.activeViewOptions.orientation === 'Vertical') {
19840
19950
  const wrapper = wrapperCollection[parseInt(dayIndex.toString(), 10)];
19841
19951
  td = dayIndex + 1;
19842
- let eventWrapper = wrapper.querySelector('.' + APPOINTMENT_WRAPPER_CLASS);
19952
+ eventWrapper = wrapper.querySelector('.' + APPOINTMENT_WRAPPER_CLASS);
19843
19953
  if (!eventWrapper) {
19844
19954
  eventWrapper = createElement('div', { className: APPOINTMENT_WRAPPER_CLASS });
19845
19955
  wrapper.appendChild(eventWrapper);
@@ -19891,8 +20001,7 @@ class YearEvent extends TimelineEvent {
19891
20001
  continue;
19892
20002
  }
19893
20003
  }
19894
- const isRowAutoHeight = this.parent.rowAutoHeight && this.parent.activeViewOptions.orientation === 'Horizontal';
19895
- if (isRowAutoHeight || this.cellHeight > availedHeight) {
20004
+ if (this.parent.rowAutoHeight || this.cellHeight > availedHeight) {
19896
20005
  this.renderEvent(eventWrapper, eventData, row, leftValue, rightValue, monthStart, dayIndex);
19897
20006
  this.updateCellHeight(rowTd, availedHeight);
19898
20007
  isSpannedCollection.push(eventData);
@@ -19914,6 +20023,19 @@ class YearEvent extends TimelineEvent {
19914
20023
  }
19915
20024
  }
19916
20025
  }
20026
+ if (this.parent.rowAutoHeight && this.parent.activeViewOptions.orientation === 'Vertical') {
20027
+ const appContainer = [].slice.call(this.parent.element.querySelectorAll('.' + APPOINTMENT_CONTAINER_CLASS));
20028
+ const tr = [].slice.call(this.parent.element.querySelectorAll('.' + CONTENT_TABLE_CLASS + ' tbody tr'));
20029
+ appContainer.forEach((ele, index) => {
20030
+ const app = [].slice.call(ele.querySelectorAll('.' + APPOINTMENT_CLASS));
20031
+ const appTop = tr[parseInt(index.toString(), 10)].offsetTop + this.cellHeader + EVENT_GAP$2;
20032
+ app.forEach((app) => {
20033
+ const overlap = parseInt(app.getAttribute('data-index'), 10);
20034
+ app.style.top = appTop + (overlap * this.eventHeight) + 'px';
20035
+ app.removeAttribute('data-index');
20036
+ });
20037
+ });
20038
+ }
19917
20039
  }
19918
20040
  updateSpannedEvents(eventObj, dayStart, dayEnd) {
19919
20041
  const isLeftRightResize = (this.isResource && this.parent.activeViewOptions.orientation === 'Vertical') ||
@@ -19928,7 +20050,8 @@ class YearEvent extends TimelineEvent {
19928
20050
  }
19929
20051
  }
19930
20052
  if ((dayEnd.getTime() >= eventObj[this.fields.endTime].getTime()) || (isLeftRightResize && !this.isResource &&
19931
- addDays(dayEnd, -1).getMonth() === eventObj[this.fields.endTime].getMonth())) {
20053
+ addDays(dayEnd, -1).getMonth() === eventObj[this.fields.endTime].getMonth()) ||
20054
+ (isLeftRightResize && this.isResource && (dayEnd.getTime() <= eventObj[this.fields.endTime].getTime()))) {
19932
20055
  if (isLeftRightResize) {
19933
20056
  data.isRight = false;
19934
20057
  }
@@ -19939,8 +20062,10 @@ class YearEvent extends TimelineEvent {
19939
20062
  eventObj.data = data;
19940
20063
  }
19941
20064
  timelineResourceEvents() {
20065
+ const contentTable = this.parent.element.querySelector('.' + CONTENT_WRAP_CLASS);
20066
+ const isVerticalScrollbarAvail = contentTable.offsetWidth > contentTable.clientWidth;
19942
20067
  const workCell = this.parent.element.querySelector('.' + WORK_CELLS_CLASS);
19943
- this.cellWidth = workCell.offsetWidth;
20068
+ this.cellWidth = workCell.getBoundingClientRect().width;
19944
20069
  this.cellHeader = 0;
19945
20070
  const eventTable = this.parent.element.querySelector('.' + EVENT_TABLE_CLASS);
19946
20071
  this.eventHeight = getElementHeightFromClass(eventTable, APPOINTMENT_CLASS);
@@ -19968,6 +20093,39 @@ class YearEvent extends TimelineEvent {
19968
20093
  }
19969
20094
  }
19970
20095
  }
20096
+ if (this.parent.rowAutoHeight && !isVerticalScrollbarAvail && contentTable.offsetWidth > contentTable.clientWidth) {
20097
+ const appointments = [].slice.call(this.parent.element.querySelectorAll('.' + APPOINTMENT_CLASS));
20098
+ appointments.forEach((ele) => {
20099
+ ele.style.removeProperty('left');
20100
+ ele.style.removeProperty('right');
20101
+ });
20102
+ const appContainer = [].slice.call(this.parent.element.querySelectorAll('.' + APPOINTMENT_CONTAINER_CLASS));
20103
+ const conTable = this.parent.element.querySelector('.' + CONTENT_TABLE_CLASS);
20104
+ const tr = [].slice.call(conTable.querySelectorAll('tbody tr'));
20105
+ appContainer.forEach((ele, index) => {
20106
+ const appWrapper = [].slice.call(ele.children);
20107
+ const row = tr[parseInt(index.toString(), 10)];
20108
+ appWrapper.forEach((appWrap, cellIndex) => {
20109
+ const td = row.querySelector(`td:nth-child(${cellIndex + 1})`);
20110
+ const app = [].slice.call(appWrap.children);
20111
+ const width = td.getBoundingClientRect().width;
20112
+ const left = td.offsetLeft;
20113
+ if (this.parent.enableRtl) {
20114
+ const right = conTable.offsetWidth - left - td.offsetWidth;
20115
+ app.forEach((app) => {
20116
+ app.style.width = Math.floor(parseInt(app.style.width, 10) / width) * width + 'px';
20117
+ app.style.right = right + 'px';
20118
+ });
20119
+ }
20120
+ else {
20121
+ app.forEach((app) => {
20122
+ app.style.width = Math.floor(parseInt(app.style.width, 10) / width) * width + 'px';
20123
+ app.style.left = left + 'px';
20124
+ });
20125
+ }
20126
+ });
20127
+ });
20128
+ }
19971
20129
  }
19972
20130
  renderResourceEvent(wrapper, resource, month, index, monthStart) {
19973
20131
  const eventWrapper = createElement('div', { className: APPOINTMENT_WRAPPER_CLASS });
@@ -19978,6 +20136,7 @@ class YearEvent extends TimelineEvent {
19978
20136
  const td = this.parent.element.querySelector(`.e-content-wrap tr:nth-child(${rowIndex + 1}) td`);
19979
20137
  this.cellHeight = td.offsetHeight;
19980
20138
  this.groupOrder = resource.groupOrder;
20139
+ const isSpannedCollection = [];
19981
20140
  for (let a = 0; a < eventDatas.length; a++) {
19982
20141
  const data = eventDatas[parseInt(a.toString(), 10)];
19983
20142
  let overlapIndex;
@@ -19997,9 +20156,17 @@ class YearEvent extends TimelineEvent {
19997
20156
  if (!this.parent.isMinMaxDate(eventData[this.fields.startTime])) {
19998
20157
  return;
19999
20158
  }
20159
+ if (this.parent.activeViewOptions.orientation === 'Vertical' && this.parent.activeViewOptions.group.resources.length > 0) {
20160
+ const isRendered = this.renderedEvents.filter((eventObj) => eventObj.Guid === eventData.Guid);
20161
+ const isSpanned = isSpannedCollection.filter((eventObj) => eventObj.Guid === eventData.Guid);
20162
+ if (isRendered.length > 0 || isSpanned.length > 0) {
20163
+ continue;
20164
+ }
20165
+ }
20000
20166
  if (this.parent.rowAutoHeight || this.cellHeight > availedHeight) {
20001
20167
  this.renderEvent(eventWrapper, eventData, month, leftValue, leftValue, monthStart, index);
20002
20168
  this.updateCellHeight(td, availedHeight);
20169
+ isSpannedCollection.push(eventData);
20003
20170
  }
20004
20171
  else {
20005
20172
  const moreIndex = this.parent.activeViewOptions.orientation === 'Horizontal' ? month : index;
@@ -20035,13 +20202,16 @@ class YearEvent extends TimelineEvent {
20035
20202
  }
20036
20203
  else {
20037
20204
  index = rowIndex + 1;
20038
- width = this.cellWidth;
20205
+ width = this.isResource ? eventObj.isSpanned.count * this.cellWidth : this.cellWidth;
20039
20206
  }
20040
20207
  const rowTd = this.parent.element.querySelector(`.e-content-wrap tr:nth-child(${index}) td`);
20041
20208
  const top = rowTd.offsetTop + this.cellHeader + (this.eventHeight * eventObj.Index) + EVENT_GAP$2;
20042
20209
  setStyleAttribute(wrap, {
20043
20210
  'width': width + 'px', 'height': this.eventHeight + 'px', 'left': left + 'px', 'right': right + 'px', 'top': top + 'px'
20044
20211
  });
20212
+ if (!this.isResource && this.parent.rowAutoHeight && this.parent.activeViewOptions.orientation === 'Vertical') {
20213
+ wrap.setAttribute('data-index', eventObj.Index.toString());
20214
+ }
20045
20215
  const args = { data: eventObj, element: wrap, cancel: false, type: 'event' };
20046
20216
  this.parent.trigger(eventRendered, args, (eventArgs) => {
20047
20217
  if (!eventArgs.cancel) {
@@ -20147,6 +20317,7 @@ class YearEvent extends TimelineEvent {
20147
20317
  const appointmentDetails = createElement('div', { className: APPOINTMENT_DETAILS });
20148
20318
  append(templateElement, appointmentDetails);
20149
20319
  eventWrapper.appendChild(appointmentDetails);
20320
+ this.parent.eventBase.renderSpannedIcon(eventWrapper, record.isSpanned);
20150
20321
  this.renderResizeHandler(eventWrapper, record.data, record[this.fields.isReadonly]);
20151
20322
  this.applyResourceColor(eventWrapper, eventObj, 'backgroundColor', this.groupOrder);
20152
20323
  return eventWrapper;
@@ -20158,24 +20329,28 @@ class YearEvent extends TimelineEvent {
20158
20329
  const eventStart = eventData[this.fields.startTime];
20159
20330
  const eventEnd = eventData[this.fields.endTime];
20160
20331
  const isSpanned = { isLeft: false, isRight: false, count: 1 };
20332
+ const yearStart = new Date(this.parent.selectedDate.getFullYear(), this.parent.firstMonthOfYear, 1);
20333
+ const yearEnd = addMonths(yearStart, this.parent.monthsCount);
20161
20334
  if (this.isResource) {
20162
20335
  this.updateSpannedEvents(eventObj, monthStart, monthEnd);
20163
20336
  }
20164
- if (eventStart.getTime() < monthStart.getTime()) {
20165
- eventData[this.fields.startTime] = monthStart;
20166
- isSpanned.isLeft = true;
20167
- }
20168
- if (eventEnd.getTime() > monthEnd.getTime()) {
20169
- eventData[this.fields.endTime] = monthEnd;
20170
- isSpanned.isRight = true;
20337
+ if (this.parent.activeViewOptions.orientation === 'Vertical' && this.parent.activeViewOptions.group.resources.length > 0) {
20338
+ this.updateSpannedEventDetails(eventStart, eventEnd, yearStart, yearEnd, eventData, isSpanned);
20339
+ const originalStartTime = eventData[this.fields.startTime];
20340
+ const originalEndTime = new Date(eventData[this.fields.endTime] - 1);
20341
+ isSpanned.count = (originalEndTime.getMonth() - originalStartTime.getMonth()) +
20342
+ (this.parent.monthsCount * (originalEndTime.getFullYear() - originalStartTime.getFullYear())) + 1;
20171
20343
  }
20172
- if (this.parent.activeViewOptions.group.resources.length === 0 || this.parent.uiStateValues.isGroupAdaptive) {
20173
- let end = resetTime(eventData[this.fields.endTime]).getTime();
20174
- const start = resetTime(eventData[this.fields.startTime]).getTime();
20175
- if (eventObj[this.fields.isAllDay] && end === eventObj[this.fields.endTime].getTime() || isSpanned.isRight) {
20176
- end = addDays(new Date(end), -1).getTime();
20344
+ else {
20345
+ this.updateSpannedEventDetails(eventStart, eventEnd, monthStart, monthEnd, eventData, isSpanned);
20346
+ if (this.parent.activeViewOptions.group.resources.length === 0 || this.parent.uiStateValues.isGroupAdaptive) {
20347
+ let end = resetTime(eventData[this.fields.endTime]).getTime();
20348
+ const start = resetTime(eventData[this.fields.startTime]).getTime();
20349
+ if (eventObj[this.fields.isAllDay] && end === eventObj[this.fields.endTime].getTime() || isSpanned.isRight) {
20350
+ end = addDays(new Date(end), -1).getTime();
20351
+ }
20352
+ isSpanned.count = Math.ceil((end - start) / MS_PER_DAY) + 1;
20177
20353
  }
20178
- isSpanned.count = Math.ceil((end - start) / MS_PER_DAY) + 1;
20179
20354
  }
20180
20355
  eventData.isSpanned = isSpanned;
20181
20356
  if (resetTime(eventStart).getTime() < resetTime(this.parent.minDate).getTime()) {
@@ -20186,6 +20361,16 @@ class YearEvent extends TimelineEvent {
20186
20361
  }
20187
20362
  return eventData;
20188
20363
  }
20364
+ updateSpannedEventDetails(eventStart, eventEnd, viewStart, viewEnd, eventObj, isSpanned) {
20365
+ if (eventStart.getTime() < viewStart.getTime()) {
20366
+ eventObj[this.fields.startTime] = viewStart;
20367
+ isSpanned.isLeft = true;
20368
+ }
20369
+ if (eventEnd.getTime() > viewEnd.getTime()) {
20370
+ eventObj[this.fields.endTime] = viewEnd;
20371
+ isSpanned.isRight = true;
20372
+ }
20373
+ }
20189
20374
  getOverlapEvents(date, appointments) {
20190
20375
  const appointmentsList = [];
20191
20376
  let dateStart;
@@ -20208,19 +20393,11 @@ class YearEvent extends TimelineEvent {
20208
20393
  for (const app of appointments) {
20209
20394
  const appStart = new Date(app[this.fields.startTime].getTime());
20210
20395
  const appEnd = new Date(app[this.fields.endTime].getTime());
20211
- if (this.parent.activeViewOptions.orientation === 'Vertical' &&
20212
- this.parent.activeViewOptions.group.resources.length > 0) {
20213
- if ((resetTime(appStart).getTime() >= dateStart) && (resetTime(appEnd).getTime() <= dateEnd)) {
20214
- appointmentsList.push(app);
20215
- }
20216
- }
20217
- else {
20218
- const timeCondition = app[this.fields.isAllDay] ? resetTime(appEnd).getTime() > dateStart :
20219
- resetTime(appEnd).getTime() >= dateStart;
20220
- if (((resetTime(appStart).getTime() <= dateStart) && (timeCondition)) ||
20221
- (resetTime(appStart).getTime() >= dateStart) && (resetTime(appEnd).getTime() <= dateEnd)) {
20222
- appointmentsList.push(app);
20223
- }
20396
+ const timeCondition = app[this.fields.isAllDay] ? resetTime(appEnd).getTime() > dateStart :
20397
+ resetTime(appEnd).getTime() >= dateStart;
20398
+ if (((resetTime(appStart).getTime() <= dateStart) && (timeCondition)) ||
20399
+ (resetTime(appStart).getTime() >= dateStart) && (resetTime(appEnd).getTime() <= dateEnd)) {
20400
+ appointmentsList.push(app);
20224
20401
  }
20225
20402
  }
20226
20403
  return appointmentsList;
@@ -21950,9 +22127,9 @@ class ViewBase {
21950
22127
  append(quickTemplate, tdElement);
21951
22128
  }
21952
22129
  else {
21953
- tdElement.appendChild(createElement('div', {
21954
- className: className, innerHTML: tdData.resourceData[tdData.resource.textField]
21955
- }));
22130
+ const resourceText = createElement('div', { className: className });
22131
+ resourceText.innerText = this.parent.sanitize(tdData.resourceData[tdData.resource.textField]);
22132
+ tdElement.appendChild(resourceText);
21956
22133
  }
21957
22134
  }
21958
22135
  renderResourceMobileLayout() {
@@ -21976,7 +22153,6 @@ class ViewBase {
21976
22153
  const colElements = this.getColElements();
21977
22154
  const contentBody = this.element.querySelector('.' + CONTENT_TABLE_CLASS + ' tbody');
21978
22155
  const colWidth = (contentBody.getBoundingClientRect().width / (colElements.length / 2));
21979
- colElements.forEach((col) => setStyleAttribute(col, { 'width': formatUnit(colWidth) }));
21980
22156
  if (content.offsetHeight !== content.clientHeight) {
21981
22157
  const resourceColumn = this.parent.element.querySelector('.' + RESOURCE_COLUMN_WRAP_CLASS);
21982
22158
  if (!isNullOrUndefined(resourceColumn)) {
@@ -22188,8 +22364,8 @@ class VerticalView extends ViewBase {
22188
22364
  const content = this.getScrollableElement();
22189
22365
  const header = this.getDatesHeaderElement();
22190
22366
  const scrollerHeight = this.parent.element.offsetHeight - headerBarHeight - header.offsetHeight;
22191
- this.setColWidth(content);
22192
22367
  this.setContentHeight(content, timeCells, scrollerHeight);
22368
+ this.setColWidth(content);
22193
22369
  const scrollBarWidth = getScrollBarWidth();
22194
22370
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
22195
22371
  header.firstElementChild.style[args.cssProperties.rtlBorder] = '';
@@ -23414,9 +23590,11 @@ class Month extends ViewBase {
23414
23590
  if (!this.parent.isMinMaxDate(data.date)) {
23415
23591
  data.className.push(DISABLE_DATES);
23416
23592
  }
23417
- if (this.parent.currentView === 'MonthAgenda' && this.parent.isSelectedDate(data.date)) {
23418
- data.className.push(SELECTED_CELL_CLASS);
23419
- }
23593
+ this.updateSelectedCellClass(data);
23594
+ }
23595
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
23596
+ updateSelectedCellClass(data) {
23597
+ return;
23420
23598
  }
23421
23599
  isOtherMonth(date) {
23422
23600
  return date.getTime() < this.monthDates.start.getTime() || date.getTime() > this.monthDates.end.getTime();
@@ -23747,6 +23925,7 @@ class Year extends ViewBase {
23747
23925
  calendarElement.appendChild(this.renderCalendarContent(currentMonth));
23748
23926
  calendarWrapper.appendChild(calendarElement);
23749
23927
  }
23928
+ this.renderDates.splice(0, 1);
23750
23929
  }
23751
23930
  renderCalendarHeader(currentDate) {
23752
23931
  const headerWrapper = createElement('div', { className: 'e-header e-month' });
@@ -23805,7 +23984,7 @@ class Year extends ViewBase {
23805
23984
  for (const date of weekDates) {
23806
23985
  const td = createElement('td', {
23807
23986
  className: 'e-cell ' + WORK_CELLS_CLASS,
23808
- attrs: { 'aria-selected': 'false', 'data-date': date.getTime().toString() }
23987
+ attrs: { 'data-date': date.getTime().toString() }
23809
23988
  });
23810
23989
  if (this.parent.activeViewOptions.cellHeaderTemplate) {
23811
23990
  const args = { date: date, type: 'monthCells' };
@@ -23833,6 +24012,9 @@ class Year extends ViewBase {
23833
24012
  addClass([td], classList$$1);
23834
24013
  }
23835
24014
  tr.appendChild(td);
24015
+ if (currentDate.getMonth() === date.getMonth()) {
24016
+ this.renderDates.push(new Date(date));
24017
+ }
23836
24018
  if (!this.parent.isMinMaxDate(date)) {
23837
24019
  addClass([td], DISABLE_DATES);
23838
24020
  }
@@ -24182,9 +24364,13 @@ class AgendaBase extends ViewBase {
24182
24364
  if (!isNullOrUndefined(eventLocation) && eventLocation !== '') {
24183
24365
  eventSubject += ',';
24184
24366
  }
24185
- appSubjectWrap.appendChild(createElement('div', { className: SUBJECT_CLASS, innerHTML: eventSubject }));
24367
+ const appSubjectText = createElement('div', { className: SUBJECT_CLASS });
24368
+ appSubjectText.innerText = this.parent.sanitize(eventSubject);
24369
+ appSubjectWrap.appendChild(appSubjectText);
24186
24370
  if (!isNullOrUndefined(eventLocation) && eventLocation !== '') {
24187
- appSubjectWrap.appendChild(createElement('div', { className: LOCATION_CLASS, innerHTML: eventLocation }));
24371
+ const appLocation = createElement('div', { className: LOCATION_CLASS });
24372
+ appLocation.innerText = this.parent.sanitize(eventLocation);
24373
+ appSubjectWrap.appendChild(appLocation);
24188
24374
  }
24189
24375
  if (!isNullOrUndefined(event[fieldMapping.recurrenceRule])) {
24190
24376
  const iconClass = (event[fieldMapping.id] === event[fieldMapping.recurrenceID]) ?
@@ -24925,6 +25111,11 @@ class MonthAgenda extends Month {
24925
25111
  }
24926
25112
  return 'abbreviated';
24927
25113
  }
25114
+ updateSelectedCellClass(data) {
25115
+ if (resetTime(data.date).getTime() === resetTime(this.monthAgendaDate).getTime()) {
25116
+ data.className.push(SELECTED_CELL_CLASS);
25117
+ }
25118
+ }
24928
25119
  setEventWrapperHeight() {
24929
25120
  let headerHeight = (this.parent.headerModule ? this.parent.headerModule.getHeaderElement().offsetHeight : 0) + 2;
24930
25121
  const resourceWrapper = this.parent.element.querySelector('.' + RESOURCE_HEADER_TOOLBAR);
@@ -25731,15 +25922,15 @@ class TimelineYear extends Year {
25731
25922
  this.parent.virtualScrollModule.renderVirtualTrack(content);
25732
25923
  }
25733
25924
  const contentTBody = contentTable.querySelector('tbody');
25734
- if (this.parent.activeViewOptions.group.resources.length > 0 && !this.parent.uiStateValues.isGroupAdaptive) {
25735
- if (this.parent.rowAutoHeight) {
25736
- const addClassTable = [contentTable];
25737
- const monthHeader = this.parent.element.querySelector('.' + MONTH_HEADER_WRAPPER + ' .' + SCHEDULE_TABLE_CLASS);
25738
- if (monthHeader) {
25739
- addClassTable.push(monthHeader);
25740
- }
25741
- addClass(addClassTable, AUTO_HEIGHT);
25925
+ if (this.parent.rowAutoHeight) {
25926
+ const addClassTable = [contentTable];
25927
+ const monthHeader = this.parent.element.querySelector('.' + MONTH_HEADER_WRAPPER + ' .' + SCHEDULE_TABLE_CLASS);
25928
+ if (monthHeader) {
25929
+ addClassTable.push(monthHeader);
25742
25930
  }
25931
+ addClass(addClassTable, AUTO_HEIGHT);
25932
+ }
25933
+ if (this.parent.activeViewOptions.group.resources.length > 0 && !this.parent.uiStateValues.isGroupAdaptive) {
25743
25934
  const colCount = this.parent.activeViewOptions.orientation === 'Horizontal' ? this.colLevels.slice(-1)[0].length : this.columnCount;
25744
25935
  contentTable.appendChild(this.createTableColGroup(colCount));
25745
25936
  this.renderResourceContent(eventWrapper, monthTBody, contentTBody);
@@ -25841,6 +26032,9 @@ class TimelineYear extends Year {
25841
26032
  if (td.classList.contains(OTHERMONTH_CLASS)) {
25842
26033
  continue;
25843
26034
  }
26035
+ else {
26036
+ this.renderDates.push(new Date(date));
26037
+ }
25844
26038
  td.appendChild(dateHeader);
25845
26039
  if (isDateAvail) {
25846
26040
  td.setAttribute('data-date', date.getTime().toString());
@@ -25855,6 +26049,7 @@ class TimelineYear extends Year {
25855
26049
  }
25856
26050
  }
25857
26051
  }
26052
+ this.renderDates.splice(0, 1);
25858
26053
  }
25859
26054
  getContentRows() {
25860
26055
  const tRow = [];