@syncfusion/ej2-schedule 28.2.11 → 29.1.34

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 (155) hide show
  1. package/.gitleaksignore +4 -0
  2. package/README.md +2 -2
  3. package/dist/ej2-schedule.min.js +2 -2
  4. package/dist/ej2-schedule.umd.min.js +2 -2
  5. package/dist/ej2-schedule.umd.min.js.map +1 -1
  6. package/dist/es6/ej2-schedule.es2015.js +518 -146
  7. package/dist/es6/ej2-schedule.es2015.js.map +1 -1
  8. package/dist/es6/ej2-schedule.es5.js +570 -186
  9. package/dist/es6/ej2-schedule.es5.js.map +1 -1
  10. package/dist/global/ej2-schedule.min.js +2 -2
  11. package/dist/global/ej2-schedule.min.js.map +1 -1
  12. package/dist/global/index.d.ts +1 -1
  13. package/package.json +24 -26
  14. package/src/recurrence-editor/recurrence-editor-model.d.ts +14 -0
  15. package/src/recurrence-editor/recurrence-editor.d.ts +12 -0
  16. package/src/recurrence-editor/recurrence-editor.js +8 -1
  17. package/src/schedule/actions/action-base.js +4 -1
  18. package/src/schedule/actions/crud.d.ts +3 -0
  19. package/src/schedule/actions/crud.js +129 -63
  20. package/src/schedule/actions/drag.js +3 -0
  21. package/src/schedule/actions/resize.js +4 -1
  22. package/src/schedule/actions/virtual-scroll.js +3 -1
  23. package/src/schedule/base/constant.d.ts +6 -0
  24. package/src/schedule/base/constant.js +6 -0
  25. package/src/schedule/base/interface.d.ts +53 -0
  26. package/src/schedule/base/schedule-model.d.ts +54 -1
  27. package/src/schedule/base/schedule.d.ts +68 -2
  28. package/src/schedule/base/schedule.js +67 -0
  29. package/src/schedule/base/type.d.ts +2 -1
  30. package/src/schedule/event-renderer/event-base.d.ts +5 -0
  31. package/src/schedule/event-renderer/event-base.js +123 -27
  32. package/src/schedule/event-renderer/inline-edit.d.ts +3 -1
  33. package/src/schedule/event-renderer/inline-edit.js +18 -6
  34. package/src/schedule/event-renderer/month.d.ts +1 -0
  35. package/src/schedule/event-renderer/month.js +25 -0
  36. package/src/schedule/event-renderer/timeline-view.d.ts +1 -1
  37. package/src/schedule/event-renderer/timeline-view.js +12 -19
  38. package/src/schedule/event-renderer/vertical-view.js +2 -2
  39. package/src/schedule/event-renderer/year.js +1 -1
  40. package/src/schedule/exports/excel-export.js +9 -2
  41. package/src/schedule/exports/print.d.ts +2 -0
  42. package/src/schedule/exports/print.js +90 -52
  43. package/src/schedule/models/views-model.d.ts +32 -0
  44. package/src/schedule/models/views.d.ts +30 -0
  45. package/src/schedule/models/views.js +6 -0
  46. package/src/schedule/popups/event-tooltip.js +18 -0
  47. package/src/schedule/popups/event-window.d.ts +1 -0
  48. package/src/schedule/popups/event-window.js +35 -4
  49. package/src/schedule/popups/quick-popups.js +11 -4
  50. package/src/schedule/renderer/month.js +3 -1
  51. package/styles/bds-lite.css +35 -6
  52. package/styles/bds.css +37 -21
  53. package/styles/bootstrap-dark-lite.css +46 -17
  54. package/styles/bootstrap-dark.css +49 -33
  55. package/styles/bootstrap-lite.css +42 -13
  56. package/styles/bootstrap.css +44 -28
  57. package/styles/bootstrap4-lite.css +55 -26
  58. package/styles/bootstrap4.css +57 -41
  59. package/styles/bootstrap5-dark-lite.css +128 -99
  60. package/styles/bootstrap5-dark.css +131 -115
  61. package/styles/bootstrap5-lite.css +50 -21
  62. package/styles/bootstrap5.3-lite.css +35 -6
  63. package/styles/bootstrap5.3.css +37 -21
  64. package/styles/bootstrap5.css +52 -36
  65. package/styles/fabric-dark-lite.css +46 -17
  66. package/styles/fabric-dark.css +49 -33
  67. package/styles/fabric-lite.css +56 -27
  68. package/styles/fabric.css +58 -42
  69. package/styles/fluent-dark-lite.css +39 -10
  70. package/styles/fluent-dark.css +40 -24
  71. package/styles/fluent-lite.css +39 -10
  72. package/styles/fluent.css +40 -24
  73. package/styles/fluent2-lite.css +35 -6
  74. package/styles/fluent2.css +38 -22
  75. package/styles/highcontrast-light-lite.css +53 -24
  76. package/styles/highcontrast-light.css +56 -40
  77. package/styles/highcontrast-lite.css +53 -24
  78. package/styles/highcontrast.css +56 -40
  79. package/styles/material-dark-lite.css +34 -5
  80. package/styles/material-dark.css +35 -19
  81. package/styles/material-lite.css +34 -5
  82. package/styles/material.css +35 -19
  83. package/styles/material3-dark-lite.css +36 -7
  84. package/styles/material3-dark.css +39 -23
  85. package/styles/material3-lite.css +36 -7
  86. package/styles/material3.css +39 -23
  87. package/styles/recurrence-editor/_layout.scss +6 -1
  88. package/styles/recurrence-editor/bds.css +5 -1
  89. package/styles/recurrence-editor/bootstrap-dark.css +5 -1
  90. package/styles/recurrence-editor/bootstrap.css +5 -1
  91. package/styles/recurrence-editor/bootstrap4.css +5 -1
  92. package/styles/recurrence-editor/bootstrap5-dark.css +5 -1
  93. package/styles/recurrence-editor/bootstrap5.3.css +5 -1
  94. package/styles/recurrence-editor/bootstrap5.css +5 -1
  95. package/styles/recurrence-editor/fabric-dark.css +5 -1
  96. package/styles/recurrence-editor/fabric.css +5 -1
  97. package/styles/recurrence-editor/fluent-dark.css +5 -1
  98. package/styles/recurrence-editor/fluent.css +5 -1
  99. package/styles/recurrence-editor/fluent2.css +5 -1
  100. package/styles/recurrence-editor/highcontrast-light.css +5 -1
  101. package/styles/recurrence-editor/highcontrast.css +5 -1
  102. package/styles/recurrence-editor/material-dark.css +5 -1
  103. package/styles/recurrence-editor/material.css +5 -1
  104. package/styles/recurrence-editor/material3-dark.css +5 -1
  105. package/styles/recurrence-editor/material3.css +5 -1
  106. package/styles/recurrence-editor/tailwind-dark.css +5 -1
  107. package/styles/recurrence-editor/tailwind.css +5 -1
  108. package/styles/recurrence-editor/tailwind3.css +5 -1
  109. package/styles/schedule/_bds-definition.scss +2 -0
  110. package/styles/schedule/_bigger.scss +2 -17
  111. package/styles/schedule/_bootstrap-dark-definition.scss +5 -1
  112. package/styles/schedule/_bootstrap-definition.scss +5 -1
  113. package/styles/schedule/_bootstrap4-definition.scss +9 -5
  114. package/styles/schedule/_bootstrap5-definition.scss +5 -1
  115. package/styles/schedule/_bootstrap5.3-definition.scss +2 -0
  116. package/styles/schedule/_fabric-dark-definition.scss +2 -0
  117. package/styles/schedule/_fabric-definition.scss +5 -1
  118. package/styles/schedule/_fluent-definition.scss +3 -1
  119. package/styles/schedule/_fluent2-definition.scss +3 -1
  120. package/styles/schedule/_fusionnew-definition.scss +2 -0
  121. package/styles/schedule/_highcontrast-definition.scss +6 -2
  122. package/styles/schedule/_highcontrast-light-definition.scss +6 -2
  123. package/styles/schedule/_layout.scss +39 -9
  124. package/styles/schedule/_material-dark-definition.scss +2 -0
  125. package/styles/schedule/_material-definition.scss +2 -0
  126. package/styles/schedule/_material3-definition.scss +4 -2
  127. package/styles/schedule/_tailwind-definition.scss +2 -0
  128. package/styles/schedule/_tailwind3-definition.scss +4 -2
  129. package/styles/schedule/bds.css +32 -20
  130. package/styles/schedule/bootstrap-dark.css +44 -32
  131. package/styles/schedule/bootstrap.css +39 -27
  132. package/styles/schedule/bootstrap4.css +52 -40
  133. package/styles/schedule/bootstrap5-dark.css +126 -114
  134. package/styles/schedule/bootstrap5.3.css +32 -20
  135. package/styles/schedule/bootstrap5.css +47 -35
  136. package/styles/schedule/fabric-dark.css +44 -32
  137. package/styles/schedule/fabric.css +53 -41
  138. package/styles/schedule/fluent-dark.css +35 -23
  139. package/styles/schedule/fluent.css +35 -23
  140. package/styles/schedule/fluent2.css +33 -21
  141. package/styles/schedule/highcontrast-light.css +51 -39
  142. package/styles/schedule/highcontrast.css +51 -39
  143. package/styles/schedule/material-dark.css +30 -18
  144. package/styles/schedule/material.css +30 -18
  145. package/styles/schedule/material3-dark.css +34 -22
  146. package/styles/schedule/material3.css +34 -22
  147. package/styles/schedule/tailwind-dark.css +49 -37
  148. package/styles/schedule/tailwind.css +32 -20
  149. package/styles/schedule/tailwind3.css +34 -22
  150. package/styles/tailwind-dark-lite.css +52 -23
  151. package/styles/tailwind-dark.css +54 -38
  152. package/styles/tailwind-lite.css +35 -6
  153. package/styles/tailwind.css +37 -21
  154. package/styles/tailwind3-lite.css +36 -7
  155. package/styles/tailwind3.css +39 -23
@@ -527,8 +527,16 @@ var MonthEvent = /** @class */ (function (_super) {
527
527
  setStyleAttribute(appointmentElement, { 'width': appWidth + 'px', 'top': appTop + 'px' });
528
528
  this.renderEventElement(event, appointmentElement, cellTd);
529
529
  if (this.parent.rowAutoHeight) {
530
+ var conWrap = this.parent.element.querySelector('.' + cls.CONTENT_WRAP_CLASS);
531
+ var conWidth = this.parent.getElementWidth(conWrap);
532
+ var isWithoutScroll = conWrap.offsetHeight === conWrap.clientHeight &&
533
+ conWrap.offsetWidth === conWrap.clientWidth;
530
534
  var firstChild = cellTd.parentElement.firstElementChild;
531
535
  this.updateCellHeight(firstChild, height);
536
+ if (isWithoutScroll &&
537
+ (conWrap.offsetWidth > conWrap.clientWidth || conWidth !== this.parent.getElementWidth(conWrap))) {
538
+ this.adjustAppointments(conWidth);
539
+ }
532
540
  }
533
541
  }
534
542
  else {
@@ -559,6 +567,23 @@ var MonthEvent = /** @class */ (function (_super) {
559
567
  }
560
568
  }
561
569
  };
570
+ MonthEvent.prototype.adjustAppointments = function (conWidth) {
571
+ var _this = this;
572
+ var tr = this.parent.element.querySelector('.' + cls.CONTENT_TABLE_CLASS + ' tbody tr');
573
+ var actualCellWidth = this.parent.getElementWidth(this.workCells[0]);
574
+ this.cellWidth = actualCellWidth / +(this.workCells[0].getAttribute('colspan') || 1);
575
+ var currentPercentage = (actualCellWidth * tr.children.length) / (conWidth / 100);
576
+ var apps = [].slice.call(this.parent.element.querySelectorAll('.' + cls.APPOINTMENT_CLASS));
577
+ apps.forEach(function (app) {
578
+ if (_this.parent.enableRtl && app.style.right !== '0px') {
579
+ app.style.right = ((parseFloat(app.style.right) / 100) * currentPercentage) + 'px';
580
+ }
581
+ else if (app.style.left !== '0px') {
582
+ app.style.left = ((parseFloat(app.style.left) / 100) * currentPercentage) + 'px';
583
+ }
584
+ app.style.width = ((parseFloat(app.style.width) / 100) * currentPercentage) + 'px';
585
+ });
586
+ };
562
587
  MonthEvent.prototype.updateCellHeight = function (cell, height) {
563
588
  if ((height > cell.offsetHeight)) {
564
589
  setStyleAttribute(cell, { 'height': height + 'px' });
@@ -26,7 +26,6 @@ export declare class TimelineEvent extends MonthEvent {
26
26
  private adjustToNearestTimeSlot;
27
27
  private renderTimelineMoreIndicator;
28
28
  updateCellHeight(cell: HTMLElement, height: number): void;
29
- private adjustAppointments;
30
29
  private getFirstChild;
31
30
  updateBlockElements(): void;
32
31
  getStartTime(event: Record<string, any>, eventData: Record<string, any>): Date;
@@ -36,6 +35,7 @@ export declare class TimelineEvent extends MonthEvent {
36
35
  getEventWidth(startDate: Date, endDate: Date, isAllDay: boolean, count: number): number;
37
36
  private getSameDayEventsWidth;
38
37
  private getSpannedEventsWidth;
38
+ private getEndTimeOfLastSlot;
39
39
  private isSameDay;
40
40
  private getAppointmentLeft;
41
41
  getPosition(startTime: Date, endTime: Date, isAllDay: boolean, day: number): number;
@@ -344,23 +344,6 @@ var TimelineEvent = /** @class */ (function (_super) {
344
344
  }
345
345
  }
346
346
  };
347
- TimelineEvent.prototype.adjustAppointments = function (conWidth) {
348
- var _this = this;
349
- var tr = this.parent.element.querySelector('.' + cls.CONTENT_TABLE_CLASS + ' tbody tr');
350
- var actualCellWidth = this.parent.getElementWidth(this.workCells[0]);
351
- this.cellWidth = actualCellWidth / +(this.workCells[0].getAttribute('colspan') || 1);
352
- var currentPercentage = (actualCellWidth * tr.children.length) / (conWidth / 100);
353
- var apps = [].slice.call(this.parent.element.querySelectorAll('.' + cls.APPOINTMENT_CLASS));
354
- apps.forEach(function (app) {
355
- if (_this.parent.enableRtl && app.style.right !== '0px') {
356
- app.style.right = ((parseFloat(app.style.right) / 100) * currentPercentage) + 'px';
357
- }
358
- else if (app.style.left !== '0px') {
359
- app.style.left = ((parseFloat(app.style.left) / 100) * currentPercentage) + 'px';
360
- }
361
- app.style.width = ((parseFloat(app.style.width) / 100) * currentPercentage) + 'px';
362
- });
363
- };
364
347
  TimelineEvent.prototype.getFirstChild = function (index) {
365
348
  var query = '.' + cls.CONTENT_TABLE_CLASS + ' tbody td';
366
349
  var groupIndex = '';
@@ -477,13 +460,23 @@ var TimelineEvent = /** @class */ (function (_super) {
477
460
  endWidth = 0;
478
461
  }
479
462
  else {
480
- var end = util.getStartEndHours(util.resetTime(new Date(endDate.getTime())), this.startHour, this.endHour);
481
- endWidth = this.getSameDayEventsWidth(endDate, end.endHour);
463
+ var _a = util.getStartEndHours(util.resetTime(new Date(endDate.getTime())), this.startHour, this.endHour), startHour = _a.startHour, endHour = _a.endHour;
464
+ var interval = this.interval / this.slotCount;
465
+ var lastSlotEndTime = this.getEndTimeOfLastSlot(startHour, endHour, interval);
466
+ var adjustedEndDate = endHour < lastSlotEndTime ? endHour : lastSlotEndTime;
467
+ endWidth = this.getSameDayEventsWidth(endDate, adjustedEndDate);
482
468
  endWidth = ((this.slotsPerDay * this.cellWidth) === endWidth) ? 0 : endWidth;
483
469
  }
484
470
  var spannedWidth = startWidth + endWidth;
485
471
  return (width > spannedWidth) ? width - spannedWidth : width - startWidth;
486
472
  };
473
+ TimelineEvent.prototype.getEndTimeOfLastSlot = function (startHour, endHour, interval) {
474
+ var minutesInDay = (endHour.getTime() - startHour.getTime()) / (1000 * 60);
475
+ var lastSlotEndMinutes = Math.floor(minutesInDay / interval) * interval;
476
+ var lastSlotEndTime = new Date(startHour);
477
+ lastSlotEndTime.setMinutes(lastSlotEndMinutes);
478
+ return lastSlotEndTime;
479
+ };
487
480
  TimelineEvent.prototype.isSameDay = function (startTime, endTime) {
488
481
  var startDay = this.parent.getIndexOfDate(this.dateRender, util.resetTime(new Date(startTime.getTime())));
489
482
  var endDay = this.parent.getIndexOfDate(this.dateRender, util.resetTime(new Date(endTime.getTime())));
@@ -520,7 +520,7 @@ var VerticalEvent = /** @class */ (function (_super) {
520
520
  var widthAdjustment = record.data.isRight ? 0 :
521
521
  this.parent.currentView === 'Day' ? 4 : 7;
522
522
  if (allDayDifference_1 >= 0) {
523
- appWidth = (allDayDifference_1 * 100) - widthAdjustment;
523
+ appWidth = (allDayDifference_1 * 100) - (!this.parent.activeViewOptions.allowOverlap ? 0 : widthAdjustment);
524
524
  }
525
525
  if (isNullOrUndefined(this.renderedAllDayEvents[parseInt(resource.toString(), 10)])) {
526
526
  this.renderedAllDayEvents[parseInt(resource.toString(), 10)] = [];
@@ -613,7 +613,7 @@ var VerticalEvent = /** @class */ (function (_super) {
613
613
  appointmentElement = this.createAppointmentElement(eventObj, false, record.isSpanned, resource);
614
614
  }
615
615
  setStyleAttribute(appointmentElement, {
616
- 'width': (this.parent.eventSettings.enableMaxHeight ? '100%' : tempData.appWidth),
616
+ 'width': (this.parent.eventSettings.enableMaxHeight || !this.parent.activeViewOptions.allowOverlap ? '100%' : tempData.appWidth),
617
617
  'height': appHeight + 'px', 'top': topValue + 'px'
618
618
  });
619
619
  var iconHeight = appointmentElement.querySelectorAll('.' + cls.EVENT_INDICATOR_CLASS).length * 15;
@@ -34,7 +34,7 @@ var YearEvent = /** @class */ (function (_super) {
34
34
  this.parent.dragAndDropModule.setDragArea();
35
35
  }
36
36
  this.fields = this.parent.eventFields;
37
- var elementSelector = (this.parent.currentView === 'Year') ? '.' + cls.APPOINTMENT_CLASS :
37
+ var elementSelector = (this.parent.currentView === 'Year') ? '.' + cls.WORK_CELLS_CLASS + ' ' + '.' + cls.APPOINTMENT_CLASS :
38
38
  '.' + cls.APPOINTMENT_WRAPPER_CLASS + ',.' + cls.MORE_INDICATOR_CLASS;
39
39
  var eventWrappers = [].slice.call(this.parent.element.querySelectorAll(elementSelector));
40
40
  for (var _i = 0, eventWrappers_1 = eventWrappers; _i < eventWrappers_1.length; _i++) {
@@ -1,6 +1,7 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
2
  import { Workbook } from '@syncfusion/ej2-excel-export';
3
3
  import { extend, isNullOrUndefined } from '@syncfusion/ej2-base';
4
+ import * as events from '../base/constant';
4
5
  /**
5
6
  * Excel Export Module
6
7
  */
@@ -50,8 +51,14 @@ var ExcelExport = /** @class */ (function () {
50
51
  rows.push({ index: i + 2, cells: columnData });
51
52
  });
52
53
  var workSheet = [{ columns: columns, rows: rows }];
53
- var book = new Workbook({ worksheets: workSheet }, type, this.parent.locale, undefined, separator);
54
- book.save(name + '.' + type);
54
+ var args = { cancel: false, worksheets: workSheet };
55
+ this.parent.trigger(events.excelExport, args, function (args) {
56
+ if (args.cancel) {
57
+ return;
58
+ }
59
+ var book = new Workbook({ worksheets: args.worksheets }, type, _this.parent.locale, undefined, separator);
60
+ book.save(name + '.' + type);
61
+ });
55
62
  };
56
63
  ExcelExport.prototype.getExportColumns = function (exportOptions) {
57
64
  var _this = this;
@@ -13,6 +13,8 @@ export declare class Print {
13
13
  private printSchedulerWithModel;
14
14
  private getPrintScheduleModel;
15
15
  private contentReady;
16
+ private closePrintWindow;
17
+ private printCleanup;
16
18
  protected getModuleName(): string;
17
19
  destroy(): void;
18
20
  }
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import { print as basePrint, createElement, isNullOrUndefined } from '@syncfusion/ej2-base';
2
+ import { print as basePrint, createElement, isNullOrUndefined, Browser } from '@syncfusion/ej2-base';
3
3
  import { Schedule } from '../base/schedule';
4
4
  import { TimelineYear } from '../renderer/timeline-year';
5
5
  import { Year } from '../renderer/year';
@@ -28,51 +28,59 @@ var Print = /** @class */ (function () {
28
28
  }
29
29
  };
30
30
  Print.prototype.printScheduler = function () {
31
+ var _this = this;
31
32
  var clone = this.parent.element.cloneNode(true);
32
33
  clone.id = this.parent.element.id + '_print';
33
- document.body.appendChild(clone);
34
- var className = this.parent.currentView === 'MonthAgenda' ? '.e-appointment-wrap' : '.e-content-wrap';
35
- var scrollableEle = this.parent.element.querySelector(className);
36
- var links = [].slice.call(document.getElementsByTagName('head')[0].querySelectorAll('link, style'));
37
- var reference = '';
38
- for (var _i = 0, links_1 = links; _i < links_1.length; _i++) {
39
- var link = links_1[_i];
40
- reference += link.outerHTML;
41
- }
42
- var div = createElement('div');
43
- clone.style.width = this.parent.element.offsetWidth + 'px';
44
- var elementWidth = Math.round((parseInt(clone.style.width, 10)) / 100) * 100;
45
- div.appendChild(clone);
46
- var printWindow = window.open('', 'print', 'height=550,width=' + elementWidth + ',tabbar=no');
47
- printWindow.document.write('<!DOCTYPE html><html><head>' + reference + '</head><body>' + div.innerHTML +
48
- '<script>(function() { window.ready = true; })();</script></body></html>');
49
- printWindow.document.close();
50
- printWindow.focus();
51
- setTimeout(function () {
52
- if (printWindow.ready && scrollableEle) {
53
- // eslint-disable-next-line no-self-assign
54
- scrollableEle.scrollLeft = scrollableEle.scrollLeft;
55
- // eslint-disable-next-line no-self-assign
56
- scrollableEle.scrollTop = scrollableEle.scrollTop;
57
- var headerTimeCellsScroll = printWindow.document.querySelector('.e-date-header-wrap');
58
- if (headerTimeCellsScroll) {
59
- headerTimeCellsScroll.scrollLeft = scrollableEle.scrollLeft;
60
- }
61
- var timeCellsScroll = printWindow.document.querySelector('.e-time-cells-wrap');
62
- if (timeCellsScroll) {
63
- timeCellsScroll.scrollTop = scrollableEle.scrollTop;
64
- }
65
- var contentCellScroll = printWindow.document.querySelector(className);
66
- if (contentCellScroll) {
67
- contentCellScroll.scrollLeft = scrollableEle.scrollLeft;
68
- contentCellScroll.scrollTop = scrollableEle.scrollTop;
69
- }
70
- printWindow.print();
71
- printWindow.close();
34
+ var args = { cancel: false, printElement: clone };
35
+ this.parent.trigger(events.beforePrint, args, function (printElement) {
36
+ if (printElement.cancel) {
37
+ return;
38
+ }
39
+ document.body.appendChild(clone);
40
+ var className = _this.parent.currentView === 'MonthAgenda' ? '.e-appointment-wrap' : '.e-content-wrap';
41
+ var scrollableEle = _this.parent.element.querySelector(className);
42
+ var links = [].slice.call(document.getElementsByTagName('head')[0].querySelectorAll('link, style'));
43
+ var reference = '';
44
+ for (var _i = 0, links_1 = links; _i < links_1.length; _i++) {
45
+ var link = links_1[_i];
46
+ reference += link.outerHTML;
72
47
  }
73
- }, 500);
48
+ var div = createElement('div');
49
+ clone.style.width = _this.parent.element.offsetWidth + 'px';
50
+ var elementWidth = Math.round((parseInt(clone.style.width, 10)) / 100) * 100;
51
+ div.appendChild(clone);
52
+ var printWindow = window.open('', 'print', 'height=550,width=' + elementWidth + ',tabbar=no');
53
+ printWindow.document.write('<!DOCTYPE html><html><head>' + reference + '</head><body>' + div.innerHTML +
54
+ '<script>(function() { window.ready = true; })();</script></body></html>');
55
+ printWindow.document.close();
56
+ printWindow.focus();
57
+ setTimeout(function () {
58
+ if (printWindow.ready && scrollableEle) {
59
+ // eslint-disable-next-line no-self-assign
60
+ scrollableEle.scrollLeft = scrollableEle.scrollLeft;
61
+ // eslint-disable-next-line no-self-assign
62
+ scrollableEle.scrollTop = scrollableEle.scrollTop;
63
+ var headerTimeCellsScroll = printWindow.document.querySelector('.e-date-header-wrap');
64
+ if (headerTimeCellsScroll) {
65
+ headerTimeCellsScroll.scrollLeft = scrollableEle.scrollLeft;
66
+ }
67
+ var timeCellsScroll = printWindow.document.querySelector('.e-time-cells-wrap');
68
+ if (timeCellsScroll) {
69
+ timeCellsScroll.scrollTop = scrollableEle.scrollTop;
70
+ }
71
+ var contentCellScroll = printWindow.document.querySelector(className);
72
+ if (contentCellScroll) {
73
+ contentCellScroll.scrollLeft = scrollableEle.scrollLeft;
74
+ contentCellScroll.scrollTop = scrollableEle.scrollTop;
75
+ }
76
+ printWindow.print();
77
+ printWindow.close();
78
+ }
79
+ }, 500);
80
+ });
74
81
  };
75
82
  Print.prototype.printSchedulerWithModel = function (printOptions) {
83
+ var _this = this;
76
84
  var element = createElement('div', { id: this.parent.element.id + '_print', className: 'e-print-schedule' });
77
85
  document.body.appendChild(element);
78
86
  Schedule.Inject(Day, Week, WorkWeek, Month, Agenda, MonthAgenda, TimelineViews, TimelineMonth, Year, TimelineYear);
@@ -81,10 +89,17 @@ var Print = /** @class */ (function () {
81
89
  this.printInstance.registeredTemplate = this.parent.registeredTemplate;
82
90
  this.printInstance.root = this.parent.root ? this.parent.root : this.parent;
83
91
  this.printInstance.appendTo(element);
84
- this.printInstance.on(events.print, this.contentReady, this);
85
- this.printWindow = window.open('', 'print', 'height=' + window.outerHeight + ',width=' + window.outerWidth + ',tabbar=no');
86
- this.printWindow.moveTo(0, 0);
87
- this.printWindow.resizeTo(screen.availWidth, screen.availHeight);
92
+ var args = { cancel: false, printElement: element };
93
+ this.parent.trigger(events.beforePrint, args, function (printElement) {
94
+ if (printElement.cancel) {
95
+ _this.printCleanup();
96
+ return;
97
+ }
98
+ _this.printInstance.on(events.print, _this.contentReady, _this);
99
+ _this.printWindow = window.open('', 'print', 'height=' + window.outerHeight + ',width=' + window.outerWidth + ',tabbar=no');
100
+ _this.printWindow.moveTo(0, 0);
101
+ _this.printWindow.resizeTo(screen.availWidth, screen.availHeight);
102
+ });
88
103
  };
89
104
  Print.prototype.getPrintScheduleModel = function (printOptions) {
90
105
  var printModel = {};
@@ -168,16 +183,39 @@ var Print = /** @class */ (function () {
168
183
  Print.prototype.contentReady = function () {
169
184
  var _this = this;
170
185
  this.printWindow = basePrint(this.printInstance.element, this.printWindow);
186
+ this.closePrintWindow(this.printWindow, true);
171
187
  this.printWindow.onbeforeunload = function () {
172
- if (_this.printInstance) {
173
- _this.printInstance.off(events.print, _this.contentReady);
174
- _this.printInstance.element.remove();
175
- _this.printInstance.destroy();
176
- _this.printInstance = null;
177
- }
178
- _this.printWindow = null;
188
+ _this.printCleanup();
179
189
  };
180
190
  };
191
+ Print.prototype.closePrintWindow = function (printWindow, cleanupRequired) {
192
+ var _this = this;
193
+ if (Browser.isIos) {
194
+ var printInterval_1 = setInterval(function () {
195
+ if (printWindow.opener) {
196
+ printWindow.close();
197
+ }
198
+ else if (isNullOrUndefined(printWindow.opener)) {
199
+ if (cleanupRequired) {
200
+ _this.printCleanup();
201
+ }
202
+ clearInterval(printInterval_1);
203
+ }
204
+ }, 500);
205
+ }
206
+ };
207
+ Print.prototype.printCleanup = function () {
208
+ if (this.printInstance) {
209
+ this.printInstance.off(events.print, this.contentReady);
210
+ this.printInstance.element.remove();
211
+ this.printInstance.destroy();
212
+ this.printInstance = null;
213
+ }
214
+ if (this.printWindow) {
215
+ this.printWindow.onbeforeunload = null;
216
+ this.printWindow = null;
217
+ }
218
+ };
181
219
  Print.prototype.getModuleName = function () {
182
220
  return 'print';
183
221
  };
@@ -74,6 +74,38 @@ export interface ViewsModel {
74
74
  */
75
75
  allowVirtualScrolling?: boolean;
76
76
 
77
+ /**
78
+ * Specifies whether overlapping appointments are allowed within the same time slot in the Scheduler.
79
+ *
80
+ * @remarks
81
+ * When set to `false`, the Scheduler enforces restrictions to prevent creating or displaying overlapping appointments within the same time duration.
82
+ * This setting includes the following limitations:
83
+ *
84
+ * - **Initial Loading**: The alert for overlapping appointments will not display during the initial load. Overlapping events will be ignored in rendering, including occurrences.
85
+ *
86
+ * - **Dynamic Add/Edit**: When adding or editing events dynamically, overlapping validation is performed. If an overlap is detected for a single event, an alert will be shown, and the event will not be saved.
87
+ *
88
+ * For recurring events, an alert will be displayed, and the event will not be saved. To save recurring events while ignoring overlapping occurrences, trigger the `PopupOpen` event. The `Data` field will contain the parent recurrence data, and the `overlapEvents` field will contain the overlap events. Using these details, users can include exceptions in the recurrence events and save them with the `addEvent` method.
89
+ *
90
+ * - **Out-of-Date-Range Events**: The `allowOverlap` setting only prevents overlaps for events within the current view date range. To validate overlap events outside the current date range, use the `actionBegin` event to send a request to the server for validation and return a promise-based response. Assign this promise response to the `promise` field in `ActionEventArgs` to handle asynchronous server validation.
91
+ *
92
+ * @default true
93
+ */
94
+ allowOverlap?: boolean;
95
+
96
+ /**
97
+ * Specifies the number of additional rows or columns to render outside the visible area during virtual scrolling.
98
+ * This property helps in achieving smoother scrolling by pre-loading data just outside the visible region.
99
+ *
100
+ * @remarks
101
+ * The default value is 3. Increasing this value can result in smoother scrolling but may impact performance
102
+ * with larger datasets. Decreasing it can improve performance but may cause more frequent data fetches during scrolling.
103
+ * This property only takes effect when `allowVirtualScrolling` is enabled for the current view.
104
+ *
105
+ * @default 3
106
+ */
107
+ overscanCount?: number;
108
+
77
109
  /**
78
110
  * Specifies the maximum number of events to be displayed in a single row.
79
111
  * This property is applicable when the 'rowAutoHeight' property is disabled.
@@ -67,6 +67,36 @@ export declare class Views extends ChildProperty<Views> {
67
67
  * @default false
68
68
  */
69
69
  allowVirtualScrolling: boolean;
70
+ /**
71
+ * Specifies whether overlapping appointments are allowed within the same time slot in the Scheduler.
72
+ *
73
+ * @remarks
74
+ * When set to `false`, the Scheduler enforces restrictions to prevent creating or displaying overlapping appointments within the same time duration.
75
+ * This setting includes the following limitations:
76
+ *
77
+ * - **Initial Loading**: The alert for overlapping appointments will not display during the initial load. Overlapping events will be ignored in rendering, including occurrences.
78
+ *
79
+ * - **Dynamic Add/Edit**: When adding or editing events dynamically, overlapping validation is performed. If an overlap is detected for a single event, an alert will be shown, and the event will not be saved.
80
+ *
81
+ * For recurring events, an alert will be displayed, and the event will not be saved. To save recurring events while ignoring overlapping occurrences, trigger the `PopupOpen` event. The `Data` field will contain the parent recurrence data, and the `overlapEvents` field will contain the overlap events. Using these details, users can include exceptions in the recurrence events and save them with the `addEvent` method.
82
+ *
83
+ * - **Out-of-Date-Range Events**: The `allowOverlap` setting only prevents overlaps for events within the current view date range. To validate overlap events outside the current date range, use the `actionBegin` event to send a request to the server for validation and return a promise-based response. Assign this promise response to the `promise` field in `ActionEventArgs` to handle asynchronous server validation.
84
+ *
85
+ * @default true
86
+ */
87
+ allowOverlap: boolean;
88
+ /**
89
+ * Specifies the number of additional rows or columns to render outside the visible area during virtual scrolling.
90
+ * This property helps in achieving smoother scrolling by pre-loading data just outside the visible region.
91
+ *
92
+ * @remarks
93
+ * The default value is 3. Increasing this value can result in smoother scrolling but may impact performance
94
+ * with larger datasets. Decreasing it can improve performance but may cause more frequent data fetches during scrolling.
95
+ * This property only takes effect when `allowVirtualScrolling` is enabled for the current view.
96
+ *
97
+ * @default 3
98
+ */
99
+ overscanCount: number;
70
100
  /**
71
101
  * Specifies the maximum number of events to be displayed in a single row.
72
102
  * This property is applicable when the 'rowAutoHeight' property is disabled.
@@ -50,6 +50,12 @@ var Views = /** @class */ (function (_super) {
50
50
  __decorate([
51
51
  Property(false)
52
52
  ], Views.prototype, "allowVirtualScrolling", void 0);
53
+ __decorate([
54
+ Property(true)
55
+ ], Views.prototype, "allowOverlap", void 0);
56
+ __decorate([
57
+ Property(3)
58
+ ], Views.prototype, "overscanCount", void 0);
53
59
  __decorate([
54
60
  Property(null)
55
61
  ], Views.prototype, "maxEventsPerRow", void 0);
@@ -3,6 +3,7 @@ import { isNullOrUndefined, append, createElement, addClass, initializeCSPTempla
3
3
  import { Tooltip } from '@syncfusion/ej2-popups';
4
4
  import * as cls from '../base/css-constant';
5
5
  import * as util from '../base/util';
6
+ import * as events from '../base/constant';
6
7
  /**
7
8
  * Tooltip for Schedule
8
9
  */
@@ -145,6 +146,23 @@ var EventTooltip = /** @class */ (function () {
145
146
  if (args.element && this.parent.isReact && !isNullOrUndefined(this.parent.eventSettings.tooltipTemplate)) {
146
147
  addClass([args.element], cls.TOOLTIP_HIDDEN_CLASS);
147
148
  }
149
+ var record = this.parent.eventBase.getEventByGuid(args.target.getAttribute('data-guid'));
150
+ if (isNullOrUndefined(record)) {
151
+ return;
152
+ }
153
+ var callbackArgs = {
154
+ cancel: false,
155
+ data: record,
156
+ content: args.element,
157
+ target: args.target
158
+ };
159
+ this.parent.trigger(events.tooltipOpen, callbackArgs, function (callbackArgs) {
160
+ if (callbackArgs.cancel) {
161
+ args.cancel = true;
162
+ return;
163
+ }
164
+ args.element = callbackArgs.content;
165
+ });
148
166
  };
149
167
  EventTooltip.prototype.onTooltipClose = function (args) {
150
168
  if (args.element) {
@@ -56,6 +56,7 @@ export declare class EventWindow {
56
56
  refreshDateTimePicker(duration?: number): void;
57
57
  private onTimeChange;
58
58
  private renderResourceDetails;
59
+ private applyStylesAfterRender;
59
60
  private renderDropDown;
60
61
  private onMultiselectResourceChange;
61
62
  private createInstance;
@@ -283,6 +283,7 @@ var EventWindow = /** @class */ (function () {
283
283
  var callBackPromise = new Deferred();
284
284
  this.parent.trigger(event.popupOpen, eventProp, function (popupArgs) {
285
285
  args.cancel = popupArgs.cancel;
286
+ args.maxHeight = _this.parent.isAdaptive ? 'max-content' : args.maxHeight;
286
287
  _this.duration = _this.cellClickAction ? popupArgs.duration : null;
287
288
  if (_this.eventData[_this.fields.endTime].getTime() === endTime && !_this.cellClickAction &&
288
289
  _this.eventData[_this.fields.endTime].getHours() === 0 &&
@@ -436,7 +437,8 @@ var EventWindow = /** @class */ (function () {
436
437
  var description = this.createDivElement(cls.DESCRIPTION_CLASS + '-row');
437
438
  description.appendChild(this.renderTextBox(cls.DESCRIPTION_CLASS));
438
439
  parentDiv.appendChild(description);
439
- var submit = createElement('button', { attrs: { type: 'hidden', title: 'submit', style: 'display:none' } });
440
+ var submit = createElement('button', { attrs: { type: 'hidden', title: 'submit' } });
441
+ submit.style.display = 'none';
440
442
  parentDiv.appendChild(submit);
441
443
  return parentDiv;
442
444
  };
@@ -522,6 +524,7 @@ var EventWindow = /** @class */ (function () {
522
524
  }
523
525
  };
524
526
  EventWindow.prototype.renderResourceDetails = function (resourceData) {
527
+ var _this = this;
525
528
  var fieldName = resourceData.field;
526
529
  var value = 'e-' + fieldName;
527
530
  var labelValue = resourceData.title;
@@ -529,7 +532,7 @@ var EventWindow = /** @class */ (function () {
529
532
  var resourceInput = this.createInputElement(value + ' ' + EVENT_FIELD, fieldName);
530
533
  resourceDiv.appendChild(resourceInput);
531
534
  var resourceTemplate = function (data) {
532
- return SanitizeHtmlHelper.sanitize("<div class=\"e-resource-template\"><div class=\"e-resource-color\" style=\"background-color:" + data[resourceData.colorField] + "\"></div><div class=\"e-resource-text\">" + data[resourceData.textField] + "</div></div>");
535
+ return SanitizeHtmlHelper.sanitize("<div class=\"e-resource-template\">\n <div class=\"e-resource-color\" data-resource-color=\"" + data[resourceData.colorField] + "\"></div>\n <div class=\"e-resource-text\">" + data[resourceData.textField] + "</div></div>");
533
536
  };
534
537
  initializeCSPTemplate(resourceTemplate, resourceData);
535
538
  if (resourceData.allowMultiple) {
@@ -549,7 +552,12 @@ var EventWindow = /** @class */ (function () {
549
552
  placeholder: labelValue,
550
553
  popupHeight: '230px',
551
554
  popupWidth: '447px',
552
- mode: 'Box'
555
+ mode: 'Box',
556
+ open: function (args) {
557
+ Promise.resolve().then(function () {
558
+ _this.applyStylesAfterRender(args);
559
+ });
560
+ }
553
561
  });
554
562
  listObj.appendTo(resourceInput);
555
563
  }
@@ -568,12 +576,29 @@ var EventWindow = /** @class */ (function () {
568
576
  placeholder: labelValue,
569
577
  popupHeight: '230px',
570
578
  popupWidth: '447px',
571
- itemTemplate: resourceTemplate
579
+ itemTemplate: resourceTemplate,
580
+ open: function (args) {
581
+ Promise.resolve().then(function () {
582
+ _this.applyStylesAfterRender(args);
583
+ });
584
+ }
572
585
  });
573
586
  dropDownList.appendTo(resourceInput);
574
587
  }
575
588
  return resourceDiv;
576
589
  };
590
+ EventWindow.prototype.applyStylesAfterRender = function (args) {
591
+ if (!args.popup || !args.popup.element) {
592
+ return;
593
+ }
594
+ var resourceColors = args.popup.element.querySelectorAll('.e-resource-color[data-resource-color]');
595
+ resourceColors.forEach(function (element) {
596
+ var color = element.getAttribute('data-resource-color');
597
+ if (color) {
598
+ element.style.backgroundColor = color;
599
+ }
600
+ });
601
+ };
577
602
  EventWindow.prototype.renderDropDown = function (value) {
578
603
  var _this = this;
579
604
  var fieldName = this.getFieldName(value);
@@ -1391,6 +1416,9 @@ var EventWindow = /** @class */ (function () {
1391
1416
  if (eventObj[this.fields.isReadonly]) {
1392
1417
  return false;
1393
1418
  }
1419
+ if (this.parent.eventBase.checkOverlap(eventObj)) {
1420
+ return true;
1421
+ }
1394
1422
  var currentAction = void 0;
1395
1423
  if (!isNullOrUndefined(editedData[this.fields.recurrenceRule])) {
1396
1424
  currentAction = this.parent.currentAction;
@@ -1425,6 +1453,9 @@ var EventWindow = /** @class */ (function () {
1425
1453
  }
1426
1454
  else {
1427
1455
  this.parent.currentAction = 'Add';
1456
+ if (this.parent.eventBase.checkOverlap(eventObj)) {
1457
+ return true;
1458
+ }
1428
1459
  if (isResourceEventExpand) {
1429
1460
  this.resourceSaveEvent(eventObj, this.parent.currentAction);
1430
1461
  }
@@ -280,7 +280,7 @@ var QuickPopups = /** @class */ (function () {
280
280
  okButton.setAttribute('aria-label', cancelButton.innerHTML);
281
281
  }
282
282
  this.quickDialogClass('Alert');
283
- this.showQuickDialog('ValidationAlert', eventData);
283
+ this.showQuickDialog(type === 'overlapAlert' ? 'OverlapAlert' : 'ValidationAlert', eventData);
284
284
  };
285
285
  QuickPopups.prototype.showQuickDialog = function (popupType, eventData) {
286
286
  var _this = this;
@@ -289,6 +289,9 @@ var QuickPopups = /** @class */ (function () {
289
289
  type: popupType, cancel: false, element: this.quickDialog.element,
290
290
  data: extend({}, (eventData || this.parent.activeEventData.event), null, true)
291
291
  };
292
+ if (!this.parent.activeViewOptions.allowOverlap) {
293
+ eventProp.overlapEvents = this.parent.overlapAppointments;
294
+ }
292
295
  this.parent.trigger(event.popupOpen, eventProp, function (popupArgs) {
293
296
  if (!popupArgs.cancel) {
294
297
  _this.quickDialog.show();
@@ -1306,16 +1309,20 @@ var QuickPopups = /** @class */ (function () {
1306
1309
  };
1307
1310
  QuickPopups.prototype.documentClick = function (e) {
1308
1311
  var target = e.event.target;
1312
+ var isInsideDialog = !!closest(target, '.e-dialog');
1309
1313
  var classNames = '.' + cls.POPUP_WRAPPER_CLASS + ',.' + cls.HEADER_CELLS_CLASS + ',.' + cls.ALLDAY_CELLS_CLASS +
1310
1314
  ',.' + cls.WORK_CELLS_CLASS + ',.' + cls.APPOINTMENT_CLASS;
1315
+ if (!isInsideDialog) {
1316
+ classNames += ',.e-popup';
1317
+ }
1311
1318
  var popupWrap = this.parent.element.querySelector('.' + cls.POPUP_WRAPPER_CLASS);
1312
1319
  if ((popupWrap && popupWrap.childElementCount > 0 && !closest(target, classNames)) || !closest(target, classNames)) {
1313
1320
  this.quickPopupHide();
1314
1321
  this.parent.removeNewEventElement();
1315
1322
  }
1316
- var tar = this.parent.element.querySelector('.' + cls.INLINE_SUBJECT_CLASS);
1317
- if (tar && tar !== target && this.parent.allowInline) {
1318
- this.parent.inlineModule.documentClick();
1323
+ var tar = this.parent.allowInline ? this.parent.inlineModule.getInlineElement() : null;
1324
+ if (tar && tar !== target) {
1325
+ this.parent.inlineModule.documentClick(tar);
1319
1326
  }
1320
1327
  if (closest(target, '.' + cls.APPOINTMENT_CLASS + ',.' + cls.HEADER_CELLS_CLASS)) {
1321
1328
  this.parent.removeNewEventElement();
@@ -109,8 +109,10 @@ var Month = /** @class */ (function (_super) {
109
109
  this.retainScrollPosition();
110
110
  };
111
111
  Month.prototype.scrollToSelectedDate = function () {
112
+ var selectedDate = new Date(this.parent.selectedDate);
113
+ selectedDate.setHours(0, 0, 0, 0);
112
114
  var headerCell = this.element.querySelector('.' + cls.HEADER_CELLS_CLASS + '[data-date="'
113
- + this.parent.selectedDate.getTime().toString() + '"]');
115
+ + selectedDate.getTime().toString() + '"]');
114
116
  var content = this.getContentAreaElement();
115
117
  if (!isNullOrUndefined(headerCell)) {
116
118
  content.scrollLeft = !this.parent.enableRtl ?