@syncfusion/ej2-schedule 20.1.59 → 20.2.38

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 (82) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/dist/ej2-schedule.umd.min.js +2 -2
  3. package/dist/ej2-schedule.umd.min.js.map +1 -1
  4. package/dist/es6/ej2-schedule.es2015.js +250 -68
  5. package/dist/es6/ej2-schedule.es2015.js.map +1 -1
  6. package/dist/es6/ej2-schedule.es5.js +254 -67
  7. package/dist/es6/ej2-schedule.es5.js.map +1 -1
  8. package/dist/global/ej2-schedule.min.js +2 -2
  9. package/dist/global/ej2-schedule.min.js.map +1 -1
  10. package/dist/global/index.d.ts +1 -1
  11. package/helpers/e2e/index.js +9 -7
  12. package/helpers/e2e/recurrence-editor.js +41 -25
  13. package/helpers/e2e/schedule.js +44 -28
  14. package/package.json +15 -15
  15. package/src/recurrence-editor/recurrence-editor.js +4 -1
  16. package/src/schedule/actions/action-base.d.ts +1 -0
  17. package/src/schedule/actions/action-base.js +3 -2
  18. package/src/schedule/actions/crud.js +9 -7
  19. package/src/schedule/actions/drag.js +1 -1
  20. package/src/schedule/base/interface.d.ts +6 -0
  21. package/src/schedule/base/schedule.d.ts +8 -0
  22. package/src/schedule/base/schedule.js +66 -0
  23. package/src/schedule/event-renderer/agenda-base.js +6 -6
  24. package/src/schedule/event-renderer/event-base.d.ts +2 -0
  25. package/src/schedule/event-renderer/event-base.js +23 -4
  26. package/src/schedule/event-renderer/month.js +3 -6
  27. package/src/schedule/event-renderer/vertical-view.js +3 -3
  28. package/src/schedule/event-renderer/year.js +2 -2
  29. package/src/schedule/exports/calendar-export.js +1 -1
  30. package/src/schedule/exports/calendar-import.js +32 -18
  31. package/src/schedule/exports/excel-export.js +8 -4
  32. package/src/schedule/popups/event-window.js +3 -1
  33. package/src/schedule/popups/quick-popups.js +5 -4
  34. package/src/schedule/renderer/agenda.js +2 -2
  35. package/src/schedule/renderer/timeline-month.d.ts +1 -0
  36. package/src/schedule/renderer/timeline-month.js +9 -0
  37. package/src/schedule/renderer/timeline-view.d.ts +1 -0
  38. package/src/schedule/renderer/timeline-view.js +14 -0
  39. package/src/schedule/renderer/timeline-year.js +3 -0
  40. package/src/schedule/renderer/vertical-view.d.ts +2 -0
  41. package/src/schedule/renderer/vertical-view.js +37 -5
  42. package/src/schedule/renderer/view-base.d.ts +1 -0
  43. package/src/schedule/renderer/view-base.js +19 -0
  44. package/src/schedule/renderer/year.js +2 -1
  45. package/styles/bootstrap-dark.css +6 -5
  46. package/styles/bootstrap.css +6 -5
  47. package/styles/bootstrap4.css +6 -5
  48. package/styles/bootstrap5-dark.css +5 -3
  49. package/styles/bootstrap5.css +6 -5
  50. package/styles/fabric-dark.css +6 -5
  51. package/styles/fabric.css +6 -5
  52. package/styles/fluent-dark.css +20 -18
  53. package/styles/fluent.css +8 -7
  54. package/styles/highcontrast-light.css +6 -5
  55. package/styles/highcontrast.css +6 -5
  56. package/styles/material-dark.css +6 -5
  57. package/styles/material.css +6 -5
  58. package/styles/recurrence-editor/_fusionnew-definition.scss +15 -0
  59. package/styles/recurrence-editor/_material3-definition.scss +15 -0
  60. package/styles/schedule/_fluent-definition.scss +1 -1
  61. package/styles/schedule/_fusionnew-definition.scss +224 -0
  62. package/styles/schedule/_layout.scss +6 -2
  63. package/styles/schedule/_material3-definition.scss +224 -0
  64. package/styles/schedule/bootstrap-dark.css +6 -5
  65. package/styles/schedule/bootstrap.css +6 -5
  66. package/styles/schedule/bootstrap4.css +6 -5
  67. package/styles/schedule/bootstrap5-dark.css +5 -3
  68. package/styles/schedule/bootstrap5.css +6 -5
  69. package/styles/schedule/fabric-dark.css +6 -5
  70. package/styles/schedule/fabric.css +6 -5
  71. package/styles/schedule/fluent-dark.css +20 -18
  72. package/styles/schedule/fluent.css +8 -7
  73. package/styles/schedule/highcontrast-light.css +6 -5
  74. package/styles/schedule/highcontrast.css +6 -5
  75. package/styles/schedule/icons/_fusionnew.scss +232 -0
  76. package/styles/schedule/icons/_material3.scss +232 -0
  77. package/styles/schedule/material-dark.css +6 -5
  78. package/styles/schedule/material.css +6 -5
  79. package/styles/schedule/tailwind-dark.css +5 -3
  80. package/styles/schedule/tailwind.css +6 -5
  81. package/styles/tailwind-dark.css +5 -3
  82. package/styles/tailwind.css +6 -5
@@ -5600,7 +5600,7 @@ class EventBase {
5600
5600
  removeSelectedAppointmentClass() {
5601
5601
  const selectedAppointments = this.getSelectedAppointments();
5602
5602
  for (const appointment of selectedAppointments) {
5603
- appointment.setAttribute('aria-selected', 'false');
5603
+ appointment.setAttribute('aria-pressed', 'false');
5604
5604
  }
5605
5605
  removeClass(selectedAppointments, APPOINTMENT_BORDER);
5606
5606
  if (this.parent.currentView === 'Agenda' || this.parent.currentView === 'MonthAgenda') {
@@ -5609,7 +5609,7 @@ class EventBase {
5609
5609
  }
5610
5610
  addSelectedAppointments(cells) {
5611
5611
  for (const cell of cells) {
5612
- cell.setAttribute('aria-selected', 'true');
5612
+ cell.setAttribute('aria-pressed', 'true');
5613
5613
  }
5614
5614
  if (this.parent.currentView !== 'MonthAgenda') {
5615
5615
  this.parent.removeSelectedClass();
@@ -5737,6 +5737,7 @@ class EventBase {
5737
5737
  }
5738
5738
  else if (!closest(element, '.' + POPUP_OPEN)) {
5739
5739
  this.removeSelectedAppointmentClass();
5740
+ this.parent.selectedElements = [];
5740
5741
  }
5741
5742
  }
5742
5743
  wireAppointmentEvents(element, event, isPreventCrud = false) {
@@ -5838,6 +5839,7 @@ class EventBase {
5838
5839
  this.parent.trigger(eventClick, args, (eventClickArgs) => {
5839
5840
  if (eventClickArgs.cancel) {
5840
5841
  this.removeSelectedAppointmentClass();
5842
+ this.parent.selectedElements = [];
5841
5843
  if (this.parent.quickPopup) {
5842
5844
  this.parent.quickPopup.quickPopupHide();
5843
5845
  }
@@ -5869,6 +5871,7 @@ class EventBase {
5869
5871
  this.activeEventData(e, true);
5870
5872
  }
5871
5873
  this.removeSelectedAppointmentClass();
5874
+ this.parent.selectedElements = [];
5872
5875
  if (this.parent.activeEventData.element.classList.contains(INLINE_APPOINTMENT_CLASS) ||
5873
5876
  this.parent.activeEventData.element.querySelector('.' + INLINE_SUBJECT_CLASS)) {
5874
5877
  return;
@@ -5943,7 +5946,7 @@ class EventBase {
5943
5946
  const exception = event[this.parent.eventFields.recurrenceException];
5944
5947
  let maxCount;
5945
5948
  if (this.parent.currentView !== 'Agenda' && isMaxCount) {
5946
- maxCount = getDateCount(this.parent.activeView.startDate(), this.parent.activeView.endDate()) + 1;
5949
+ maxCount = getDateCount(viewDate, this.parent.activeView.endDate()) + 1;
5947
5950
  }
5948
5951
  const newTimezone = this.parent.timezone || this.parent.tzModule.getLocalTimezoneName();
5949
5952
  const firstDay = this.parent.activeViewOptions.firstDayOfWeek;
@@ -5963,8 +5966,9 @@ class EventBase {
5963
5966
  }
5964
5967
  }
5965
5968
  const occurrenceCollection = [];
5966
- for (const date of dates) {
5969
+ for (let date of dates) {
5967
5970
  const clonedObject = extend({}, event, null, true);
5971
+ date = this.getDSTAdjustedTime(date, clonedObject);
5968
5972
  clonedObject[this.parent.eventFields.startTime] = new Date(date);
5969
5973
  clonedObject[this.parent.eventFields.endTime] = new Date(new Date(date).setMilliseconds(duration));
5970
5974
  clonedObject[this.parent.eventFields.recurrenceID] = clonedObject[this.parent.eventFields.id];
@@ -5975,6 +5979,21 @@ class EventBase {
5975
5979
  }
5976
5980
  return occurrenceCollection;
5977
5981
  }
5982
+ getDSTAdjustedTime(date, event) {
5983
+ let occurDate = date;
5984
+ if (this.parent.timezone &&
5985
+ (event[this.parent.eventFields.startTimezone] || event[this.parent.eventFields.endTimezone])) {
5986
+ const eventOffset = this.getDSTDiff(event[this.parent.eventFields.startTime], new Date(date), event[this.parent.eventFields.startTimezone]);
5987
+ const schOffset = this.getDSTDiff(event[this.parent.eventFields.startTime], new Date(date), this.parent.timezone);
5988
+ occurDate = (new Date(date).getTime() - (eventOffset - schOffset) * 60000);
5989
+ }
5990
+ return occurDate;
5991
+ }
5992
+ getDSTDiff(startDate, occurDate, timezone) {
5993
+ const startOffset = this.parent.tzModule.offset(new Date(startDate), timezone);
5994
+ const occurOffset = this.parent.tzModule.offset(new Date(occurDate), timezone);
5995
+ return startOffset - occurOffset;
5996
+ }
5978
5997
  getParentEvent(eventObj, isParent = false) {
5979
5998
  let parentEvent;
5980
5999
  do {
@@ -6120,7 +6139,7 @@ class EventBase {
6120
6139
  className: BLOCK_APPOINTMENT_CLASS,
6121
6140
  attrs: {
6122
6141
  'data-id': 'Appointment_' + record[this.parent.eventFields.id],
6123
- 'aria-readonly': 'true', 'aria-selected': 'false'
6142
+ 'aria-disabled': 'true', 'aria-pressed': 'false'
6124
6143
  }
6125
6144
  });
6126
6145
  let templateElement;
@@ -6544,8 +6563,8 @@ class VerticalEvent extends EventBase {
6544
6563
  'data-guid': record.Guid,
6545
6564
  'role': 'button',
6546
6565
  'tabindex': '0',
6547
- 'aria-readonly': this.parent.eventBase.getReadonlyAttribute(record),
6548
- 'aria-selected': 'false',
6566
+ 'aria-disabled': this.parent.eventBase.getReadonlyAttribute(record),
6567
+ 'aria-pressed': 'false',
6549
6568
  'aria-grabbed': 'true',
6550
6569
  'aria-label': this.parent.getAnnouncementString(record)
6551
6570
  }
@@ -6640,7 +6659,7 @@ class VerticalEvent extends EventBase {
6640
6659
  });
6641
6660
  const moreIndicatorElement = createElement('div', {
6642
6661
  className: MORE_INDICATOR_CLASS,
6643
- attrs: { 'tabindex': '0', 'role': 'list', 'data-index': index.toString(), 'data-count': '1' },
6662
+ attrs: { 'tabindex': '0', 'data-index': index.toString(), 'data-count': '1' },
6644
6663
  innerHTML: '+1 ' + (this.parent.isAdaptive ? '' : this.parent.localeObj.getConstant('more'))
6645
6664
  });
6646
6665
  innerCountWrap.appendChild(moreIndicatorElement);
@@ -7229,9 +7248,7 @@ class MonthEvent extends EventBase {
7229
7248
  this.sortByDateTime(blockList);
7230
7249
  if (this.parent.currentView === 'Month' && this.parent.rowAutoHeight && this.parent.activeViewOptions.group.resources.length === 0) {
7231
7250
  const totalCells = [].slice.call(this.parent.element.querySelectorAll('.e-content-wrap table tr td:first-child'));
7232
- const height = this.parent.height === 'auto' ? (this.parent.element.querySelector('.e-content-wrap').clientHeight +
7233
- this.parent.element.querySelector('.e-date-header-wrap').clientHeight) / totalCells.length
7234
- : this.parent.element.querySelector('.e-schedule-table').clientHeight / totalCells.length;
7251
+ const height = this.parent.element.querySelector('.' + CONTENT_TABLE_CLASS).clientHeight / totalCells.length;
7235
7252
  totalCells.forEach((cell) => {
7236
7253
  setStyleAttribute(cell, { 'height': height + 'px' });
7237
7254
  });
@@ -7435,7 +7452,7 @@ class MonthEvent extends EventBase {
7435
7452
  const attrs = {
7436
7453
  'data-id': 'Appointment_' + record[this.fields.id],
7437
7454
  'role': 'button', 'tabindex': '0',
7438
- 'aria-readonly': this.parent.eventBase.getReadonlyAttribute(record), 'aria-selected': 'false', 'aria-grabbed': 'true',
7455
+ 'aria-disabled': this.parent.eventBase.getReadonlyAttribute(record), 'aria-pressed': 'false', 'aria-grabbed': 'true',
7439
7456
  'aria-label': this.parent.getAnnouncementString(newRecord, eventSubject)
7440
7457
  };
7441
7458
  if (!isCloneElement) {
@@ -7725,8 +7742,7 @@ class MonthEvent extends EventBase {
7725
7742
  'tabindex': '0',
7726
7743
  'data-count': count.toString(),
7727
7744
  'data-start-date': startDate.getTime().toString(),
7728
- 'data-end-date': endDate.getTime().toString(),
7729
- 'role': 'list'
7745
+ 'data-end-date': endDate.getTime().toString()
7730
7746
  }
7731
7747
  });
7732
7748
  return moreIndicatorElement;
@@ -8892,8 +8908,8 @@ class QuickPopups {
8892
8908
  attrs: {
8893
8909
  'data-id': '' + eventData[fields.id],
8894
8910
  'data-guid': eventData.Guid, 'role': 'button', 'tabindex': '0',
8895
- 'aria-readonly': this.parent.eventBase.getReadonlyAttribute(eventData),
8896
- 'aria-selected': 'false', 'aria-grabbed': 'true', 'aria-label': this.parent.getAnnouncementString(eventData)
8911
+ 'aria-disabled': this.parent.eventBase.getReadonlyAttribute(eventData),
8912
+ 'aria-pressed': 'false', 'aria-grabbed': 'true', 'aria-label': this.parent.getAnnouncementString(eventData)
8897
8913
  }
8898
8914
  });
8899
8915
  let templateElement;
@@ -8984,7 +9000,7 @@ class QuickPopups {
8984
9000
  this.quickPopupHide();
8985
9001
  return;
8986
9002
  }
8987
- const targetEle = args.event.target;
9003
+ const targetEle = !isNullOrUndefined(args.event) ? args.event.target : args.element;
8988
9004
  if (this.parent.isAdaptive) {
8989
9005
  this.quickPopupHide();
8990
9006
  let newEventClone = this.parent.element.querySelector('.' + NEW_EVENT_CLASS);
@@ -9080,6 +9096,7 @@ class QuickPopups {
9080
9096
  }
9081
9097
  else {
9082
9098
  const isSameTarget = this.isSameEventClick(events);
9099
+ this.parent.selectedElements = [];
9083
9100
  if (isSameTarget) {
9084
9101
  return;
9085
9102
  }
@@ -9145,7 +9162,7 @@ class QuickPopups {
9145
9162
  `<button class="${DELETE_CLASS + ' ' + ICON}" title="${this.l10n.getConstant('delete')}"></button>` +
9146
9163
  `<button class="${CLOSE_CLASS}" title="${this.l10n.getConstant('close')}"></button></div>` +
9147
9164
  `<div class="${SUBJECT_WRAP}"><div class="${SUBJECT_CLASS} ${TEXT_ELLIPSIS}" ` +
9148
- `title="${args.eventSubject}">${args.eventSubject}</div></div >`;
9165
+ `title="${args.eventSubject ? args.eventSubject.replaceAll('"', '\'') : args.eventSubject}">${args.eventSubject}</div></div >`;
9149
9166
  break;
9150
9167
  }
9151
9168
  const templateWrapper = createElement('div', { innerHTML: header });
@@ -10370,7 +10387,7 @@ let RecurrenceEditor = class RecurrenceEditor extends Component {
10370
10387
  value: VALUEFIELD
10371
10388
  },
10372
10389
  placeholder: this.localeObj.getConstant(REPEAT),
10373
- htmlAttributes: { 'title': this.localeObj.getConstant(REPEAT) },
10390
+ htmlAttributes: { 'title': this.localeObj.getConstant(REPEAT), role: 'option' },
10374
10391
  change: (args) => {
10375
10392
  self.setProperties({ selectedType: this.frequencies.indexOf(args.value) }, false);
10376
10393
  self.element.querySelector('.' + REPEATCONTENT).innerHTML =
@@ -10392,6 +10409,7 @@ let RecurrenceEditor = class RecurrenceEditor extends Component {
10392
10409
  text: TEXTFIELD,
10393
10410
  value: VALUEFIELD
10394
10411
  },
10412
+ htmlAttributes: { role: 'option' },
10395
10413
  change: (args) => {
10396
10414
  self.freshOnEndForm();
10397
10415
  self.updateEndOnForm(args.value);
@@ -10409,6 +10427,7 @@ let RecurrenceEditor = class RecurrenceEditor extends Component {
10409
10427
  text: TEXTFIELD,
10410
10428
  value: VALUEFIELD
10411
10429
  },
10430
+ htmlAttributes: { role: 'option' },
10412
10431
  index: 1,
10413
10432
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
10414
10433
  change: (args) => {
@@ -10428,6 +10447,7 @@ let RecurrenceEditor = class RecurrenceEditor extends Component {
10428
10447
  text: TEXTFIELD,
10429
10448
  value: VALUEFIELD
10430
10449
  },
10450
+ htmlAttributes: { role: 'option' },
10431
10451
  enableRtl: this.enableRtl,
10432
10452
  index: 7,
10433
10453
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -11270,6 +11290,7 @@ class EventWindow {
11270
11290
  setDialogContent() {
11271
11291
  this.dialogObject.content = this.getEventWindowContent();
11272
11292
  this.dialogObject.dataBind();
11293
+ this.applyFormValidation();
11273
11294
  }
11274
11295
  preventEventSave(e) {
11275
11296
  if (this.parent && !this.parent.allowKeyboardInteraction && e.code === 'Enter') {
@@ -11526,6 +11547,7 @@ class EventWindow {
11526
11547
  resourceData.colorField + '}"></div><div class="e-resource-text">${' + resourceData.textField + '}</div></div>';
11527
11548
  if (resourceData.allowMultiple) {
11528
11549
  const listObj = new MultiSelect({
11550
+ enableRtl: this.parent.enableRtl,
11529
11551
  cssClass: this.parent.cssClass || '',
11530
11552
  dataSource: resourceData.dataSource,
11531
11553
  change: this.onMultiselectResourceChange.bind(this),
@@ -11583,7 +11605,7 @@ class EventWindow {
11583
11605
  query = (e.text !== '') ? query.where('Text', 'contains', e.text, true) : query;
11584
11606
  e.updateData(this.parent.timezoneDataSource, query);
11585
11607
  },
11586
- htmlAttributes: { 'title': this.getFieldLabel(value), 'name': fieldName },
11608
+ htmlAttributes: { 'title': this.getFieldLabel(value), 'name': fieldName, role: 'option' },
11587
11609
  floatLabelType: 'Always',
11588
11610
  placeholder: this.getFieldLabel(value),
11589
11611
  popupHeight: '230px'
@@ -13925,13 +13947,15 @@ class Crud {
13925
13947
  else {
13926
13948
  endDate = new Date(+followEvent[fields.startTime]);
13927
13949
  const newRecurrenceRule = followEvent[fields.recurrenceRule];
13928
- const startDate = parentEvent[fields.startTime];
13929
- const ruleException = (this.parent.currentAction === 'DeleteFollowingEvents') ? followEvent[fields.recurrenceException] : null;
13930
- const dateCollection = generate(startDate, newRecurrenceRule, ruleException, this.parent.activeViewOptions.firstDayOfWeek);
13931
- const untilDate = new Date(dateCollection.slice(-1)[0]);
13932
- untilDate.setHours(endDate.getHours(), endDate.getMinutes(), endDate.getSeconds());
13933
- endDate.setHours(startDate.getHours(), startDate.getMinutes(), startDate.getSeconds());
13934
- followEvent[fields.recurrenceRule] = this.getUpdatedRecurrenceRule(newRecurrenceRule, new Date(+untilDate), false);
13950
+ if (newRecurrenceRule) {
13951
+ const startDate = parentEvent[fields.startTime];
13952
+ const ruleException = (this.parent.currentAction === 'DeleteFollowingEvents') ? followEvent[fields.recurrenceException] : null;
13953
+ const dateCollection = generate(startDate, newRecurrenceRule, ruleException, this.parent.activeViewOptions.firstDayOfWeek);
13954
+ const untilDate = new Date(dateCollection.slice(-1)[0]);
13955
+ untilDate.setHours(endDate.getHours(), endDate.getMinutes(), endDate.getSeconds());
13956
+ endDate.setHours(startDate.getHours(), startDate.getMinutes(), startDate.getSeconds());
13957
+ followEvent[fields.recurrenceRule] = this.getUpdatedRecurrenceRule(newRecurrenceRule, new Date(+untilDate), false);
13958
+ }
13935
13959
  }
13936
13960
  parentEvent[fields.recurrenceRule] = this.getUpdatedRecurrenceRule(recurrenceRule, addDays(new Date(endDate.getTime()), -1), true);
13937
13961
  }
@@ -17626,6 +17650,67 @@ let Schedule = class Schedule extends Component {
17626
17650
  this.eventWindow.dialogClose();
17627
17651
  }
17628
17652
  }
17653
+ /**
17654
+ * To manually open the quick info popup based on cell or event details.
17655
+ *
17656
+ * @param {object} data Defines the cell or event data. If the data contains valid ID, it will open event quick info popup,
17657
+ * otherwise cell quick info popup displayed.
17658
+ * @returns {void}
17659
+ */
17660
+ openQuickInfoPopup(data) {
17661
+ if (this.currentView === 'Year' || isNullOrUndefined(data)) {
17662
+ return;
17663
+ }
17664
+ if (isNullOrUndefined(data[this.eventFields.id])) {
17665
+ if (this.currentView === 'Agenda' || this.currentView === 'MonthAgenda' || isNullOrUndefined(this.activeView)) {
17666
+ return;
17667
+ }
17668
+ const cellData = {
17669
+ startTime: this.activeCellsData.startTime = this.getDateTime(data[this.eventFields.startTime]),
17670
+ endTime: this.activeCellsData.endTime = this.getDateTime(data[this.eventFields.endTime]),
17671
+ isAllDay: this.activeCellsData.isAllDay =
17672
+ !isNullOrUndefined(data[this.eventFields.isAllDay]) ? data[this.eventFields.isAllDay] : false
17673
+ };
17674
+ const startTime = this.activeView.getAdjustedDate(new Date(cellData.startTime));
17675
+ if (startTime) {
17676
+ let query = '.' + WORK_CELLS_CLASS + '[data-date="' + startTime.getTime() + '"]';
17677
+ if (this.activeViewOptions.group.resources.length > 0 && !this.uiStateValues.isGroupAdaptive
17678
+ && this.resourceBase && this.eventBase) {
17679
+ cellData.groupIndex = this.eventBase.getGroupIndexFromEvent(data);
17680
+ query = '.' + WORK_CELLS_CLASS + '[data-date="' + startTime.getTime() + '"][data-group-index="' + cellData.groupIndex + '"]';
17681
+ }
17682
+ const workCell = this.element.querySelector(query);
17683
+ if (workCell) {
17684
+ workCell.focus();
17685
+ cellData.element = workCell;
17686
+ this.notify(cellClick, cellData);
17687
+ }
17688
+ }
17689
+ }
17690
+ else {
17691
+ const app = this.getCurrentViewEvents().filter((item) => data[this.eventFields.id] === item[this.eventFields.id]);
17692
+ if (app.length <= 0) {
17693
+ return;
17694
+ }
17695
+ let selectEvent = app[0];
17696
+ if (data[this.eventFields.recurrenceRule]) {
17697
+ const occurence = app.filter((x) => x[this.eventFields.startTime].getTime() === data[this.eventFields.startTime].getTime());
17698
+ if (occurence.length > 0) {
17699
+ selectEvent = occurence[0];
17700
+ }
17701
+ }
17702
+ const element = this.element.querySelector('div[data-guid="' + selectEvent.Guid + '"]');
17703
+ if (element) {
17704
+ this.eventBase.removeSelectedAppointmentClass();
17705
+ this.eventBase.addSelectedAppointments([element]);
17706
+ this.activeEventData = { event: selectEvent, element: element };
17707
+ if (this.currentView === 'Agenda' || this.currentView === 'MonthAgenda') {
17708
+ addClass([this.activeEventData.element], AGENDA_SELECTED_CELL);
17709
+ }
17710
+ this.notify(eventClick, this.activeEventData);
17711
+ }
17712
+ }
17713
+ }
17629
17714
  /**
17630
17715
  * To manually close the quick info popup
17631
17716
  *
@@ -18294,6 +18379,7 @@ class ActionBase {
18294
18379
  }
18295
18380
  }
18296
18381
  updateScrollPosition(e) {
18382
+ this.scrollEventArgs = e;
18297
18383
  if (this.actionObj.scroll.enable && isNullOrUndefined(this.actionObj.scrollInterval)) {
18298
18384
  this.actionObj.scrollInterval = window.setInterval(() => {
18299
18385
  if (this.autoScrollValidation() && !this.actionObj.clone.classList.contains(ALLDAY_APPOINTMENT_CLASS)) {
@@ -18303,10 +18389,10 @@ class ActionBase {
18303
18389
  }
18304
18390
  this.autoScroll();
18305
18391
  if (this.actionObj.action === 'drag') {
18306
- this.parent.dragAndDropModule.updateDraggingDateTime(e);
18392
+ this.parent.dragAndDropModule.updateDraggingDateTime(this.scrollEventArgs);
18307
18393
  }
18308
18394
  else {
18309
- this.parent.resizeModule.updateResizingDirection(e);
18395
+ this.parent.resizeModule.updateResizingDirection(this.scrollEventArgs);
18310
18396
  }
18311
18397
  }
18312
18398
  }, this.actionObj.scroll.timeDelay);
@@ -19058,7 +19144,7 @@ class YearEvent extends TimelineEvent {
19058
19144
  }
19059
19145
  }
19060
19146
  timelineYearViewEvents() {
19061
- const workCell = this.parent.element.querySelector('.' + WORK_CELLS_CLASS);
19147
+ const workCell = this.parent.element.querySelector('.' + WORK_CELLS_CLASS + ':not(.' + OTHERMONTH_CLASS + ')');
19062
19148
  this.cellWidth = workCell.offsetWidth;
19063
19149
  this.cellHeader = getOuterHeight(workCell.querySelector('.' + DATE_HEADER_CLASS));
19064
19150
  const eventTable = this.parent.element.querySelector('.' + EVENT_TABLE_CLASS);
@@ -19334,7 +19420,7 @@ class YearEvent extends TimelineEvent {
19334
19420
  'data-id': 'Appointment_' + record[this.fields.id],
19335
19421
  'data-guid': record.Guid,
19336
19422
  'role': 'button', 'tabindex': '0',
19337
- 'aria-readonly': this.parent.eventBase.getReadonlyAttribute(record), 'aria-selected': 'false', 'aria-grabbed': 'true',
19423
+ 'aria-disabled': this.parent.eventBase.getReadonlyAttribute(record), 'aria-pressed': 'false', 'aria-grabbed': 'true',
19338
19424
  'aria-label': this.parent.getAnnouncementString(record)
19339
19425
  }
19340
19426
  });
@@ -20686,7 +20772,7 @@ class DragAndDrop extends ActionBase {
20686
20772
  const cursorElement = this.getCursorElement(e);
20687
20773
  if (cursorElement) {
20688
20774
  top = cursorElement.classList.contains(WORK_CELLS_CLASS) ? cursorElement.offsetTop :
20689
- cursorElement.offsetParent.classList.contains(APPOINTMENT_CLASS) ?
20775
+ (cursorElement.offsetParent && cursorElement.offsetParent.classList.contains(APPOINTMENT_CLASS)) ?
20690
20776
  cursorElement.offsetParent.offsetTop : top;
20691
20777
  }
20692
20778
  }
@@ -21225,6 +21311,14 @@ class ViewBase {
21225
21311
  const tdDate = new Date(resetTime(new Date(+scrollDate)).getTime()).getTime();
21226
21312
  const dateElement = scrollWrap.querySelector(`.${WORK_CELLS_CLASS}[data-date="${tdDate}"]`);
21227
21313
  if (this.parent.currentView === 'Month' && dateElement) {
21314
+ if (scrollWrap.scrollWidth > scrollWrap.clientWidth) {
21315
+ if (!this.parent.enableRtl) {
21316
+ scrollWrap.scrollLeft = dateElement.offsetLeft;
21317
+ }
21318
+ else {
21319
+ scrollWrap.scrollLeft = -(this.parent.getContentTable().offsetWidth - dateElement.offsetLeft - dateElement.offsetWidth);
21320
+ }
21321
+ }
21228
21322
  scrollWrap.scrollTop = dateElement.offsetTop;
21229
21323
  }
21230
21324
  if (this.parent.currentView === 'TimelineMonth' && dateElement) {
@@ -21268,6 +21362,17 @@ class ViewBase {
21268
21362
  }
21269
21363
  return endDate;
21270
21364
  }
21365
+ getAdjustedDate(startTime) {
21366
+ if (!this.parent.activeViewOptions.timeScale.enable || this.parent.currentView === 'Month' ||
21367
+ (this.parent.currentView === 'TimelineYear' && this.parent.activeViewOptions.group.resources.length === 0)) {
21368
+ return new Date(startTime.setHours(0, 0, 0, 0));
21369
+ }
21370
+ else if (this.parent.currentView === 'TimelineYear' && this.parent.activeViewOptions.group.resources.length > 0) {
21371
+ startTime.setHours(0, 0, 0, 0);
21372
+ return new Date(startTime.setDate(1));
21373
+ }
21374
+ return null;
21375
+ }
21271
21376
  destroy() {
21272
21377
  if (this.element && this.element.parentNode) {
21273
21378
  remove(this.element);
@@ -21413,11 +21518,26 @@ class VerticalView extends ViewBase {
21413
21518
  }
21414
21519
  scrollToHour(hour, scrollDate) {
21415
21520
  const date = this.parent.getStartEndTime(hour);
21416
- if (isNullOrUndefined(date) || !isNullOrUndefined(scrollDate)) {
21521
+ if (!isNullOrUndefined(scrollDate)) {
21522
+ const headerElement = this.element.querySelector('.' + HEADER_CELLS_CLASS + '[data-date="' + new Date(resetTime(scrollDate)).getTime() + '"]');
21523
+ if (headerElement) {
21524
+ if (this.parent.enableRtl) {
21525
+ const conWrap = this.element.querySelector('.' + CONTENT_TABLE_CLASS);
21526
+ this.getScrollableElement().scrollLeft = -(conWrap.offsetWidth - headerElement.offsetLeft - headerElement.offsetWidth);
21527
+ }
21528
+ else {
21529
+ this.getScrollableElement().scrollLeft = headerElement.offsetLeft;
21530
+ }
21531
+ }
21532
+ }
21533
+ if (isNullOrUndefined(date)) {
21417
21534
  return;
21418
21535
  }
21419
21536
  this.getScrollableElement().scrollTop = this.getTopFromDateTime(date);
21420
21537
  }
21538
+ scrollToDate(scrollDate) {
21539
+ this.scrollToHour(null, scrollDate);
21540
+ }
21421
21541
  generateColumnLevels() {
21422
21542
  const level = this.getDateSlots(this.renderDates, this.parent.activeViewOptions.workDays);
21423
21543
  let columnLevels = [];
@@ -21748,12 +21868,11 @@ class VerticalView extends ViewBase {
21748
21868
  const wrap = createElement('div', { className: DATE_HEADER_WRAP_CLASS });
21749
21869
  container.appendChild(wrap);
21750
21870
  const tbl = this.createTableLayout();
21751
- const trEle = createElement('tr');
21871
+ const trEle = createElement('tr', { className: HEADER_ROW_CLASS });
21752
21872
  const rowCount = this.colLevels.length;
21753
21873
  const lastLevel = this.colLevels[rowCount - 1];
21754
21874
  for (let i = 0; i < rowCount; i++) {
21755
21875
  const ntr = trEle.cloneNode();
21756
- addClass([ntr], HEADER_ROW_CLASS);
21757
21876
  const level = this.colLevels[i];
21758
21877
  for (let j = 0; j < level.length; j++) {
21759
21878
  ntr.appendChild(this.createTd(level[j]));
@@ -21766,13 +21885,13 @@ class VerticalView extends ViewBase {
21766
21885
  return container;
21767
21886
  }
21768
21887
  createAllDayRow(table, tdData) {
21769
- const ntr = createElement('tr');
21770
- addClass([ntr], ALLDAY_ROW_CLASS);
21888
+ const ntr = createElement('tr', { className: ALLDAY_ROW_CLASS });
21771
21889
  for (let j = 0; j < tdData.length; j++) {
21772
21890
  const td = extend({}, tdData[j]);
21773
21891
  td.className = [ALLDAY_CELLS_CLASS];
21774
21892
  td.type = 'alldayCells';
21775
21893
  const ntd = this.createTd(td);
21894
+ ntd.setAttribute('role', 'gridcell');
21776
21895
  ntd.setAttribute('data-date', td.date.getTime().toString());
21777
21896
  if (!isNullOrUndefined(td.groupIndex)) {
21778
21897
  ntd.setAttribute('data-group-index', '' + td.groupIndex);
@@ -21805,6 +21924,7 @@ class VerticalView extends ViewBase {
21805
21924
  }
21806
21925
  if (td.type === 'dateHeader' && td.className.indexOf(HEADER_CELLS_CLASS) >= 0) {
21807
21926
  tdEle.setAttribute('data-date', td.date.getTime().toString());
21927
+ tdEle.setAttribute('role', 'gridcell');
21808
21928
  if (!isNullOrUndefined(td.groupIndex)) {
21809
21929
  tdEle.setAttribute('data-group-index', '' + td.groupIndex);
21810
21930
  }
@@ -22003,6 +22123,23 @@ class VerticalView extends ViewBase {
22003
22123
  }
22004
22124
  return rows;
22005
22125
  }
22126
+ getAdjustedDate(startTime) {
22127
+ if (!this.parent.activeViewOptions.timeScale.enable) {
22128
+ return new Date(startTime.setHours(0, 0, 0, 0));
22129
+ }
22130
+ else {
22131
+ const timeSlots = this.getTimeSlotRows();
22132
+ const startDate = new Date(new Date(timeSlots[0].date.getTime()).
22133
+ setHours(startTime.getHours(), startTime.getMinutes(), startTime.getMilliseconds()));
22134
+ for (let i = 0; i < timeSlots.length; i++) {
22135
+ if (timeSlots[i].date.getTime() > startDate.getTime()) {
22136
+ startTime.setHours(timeSlots[i - 1].date.getHours(), timeSlots[i - 1].date.getMinutes(), timeSlots[i - 1].date.getMilliseconds());
22137
+ return new Date(startTime);
22138
+ }
22139
+ }
22140
+ }
22141
+ return null;
22142
+ }
22006
22143
  destroy() {
22007
22144
  if (!this.parent || this.parent && this.parent.isDestroyed) {
22008
22145
  return;
@@ -23053,7 +23190,8 @@ class Year extends ViewBase {
23053
23190
  return this.parent.currentView === 'Year' ? getWeekFirstDate(this.getStartDate(), this.parent.firstDayOfWeek) : this.getStartDate();
23054
23191
  }
23055
23192
  endDate() {
23056
- return this.parent.currentView === 'Year' ? addDays(getWeekLastDate(this.getEndDate(), this.parent.firstDayOfWeek), 1) : this.getEndDate();
23193
+ return this.parent.currentView === 'Year' ? addDays(getWeekLastDate(this.getEndDate(), this.parent.firstDayOfWeek), 1) :
23194
+ addDays(this.getEndDate(), 1);
23057
23195
  }
23058
23196
  getEndDateFromStartDate(start) {
23059
23197
  let date = new Date(start.getTime());
@@ -23163,8 +23301,8 @@ class AgendaBase extends ViewBase {
23163
23301
  'data-guid': listData[li].Guid,
23164
23302
  'role': 'button',
23165
23303
  'tabindex': '0',
23166
- 'aria-readonly': this.parent.eventBase.getReadonlyAttribute(listData[li]),
23167
- 'aria-selected': 'false',
23304
+ 'aria-disabled': this.parent.eventBase.getReadonlyAttribute(listData[li]),
23305
+ 'aria-pressed': 'false',
23168
23306
  'aria-grabbed': 'true',
23169
23307
  'aria-label': this.parent.getAnnouncementString(listData[li])
23170
23308
  }
@@ -23429,8 +23567,8 @@ class AgendaBase extends ViewBase {
23429
23567
  ntd.appendChild(this.createDateHeaderElement(tempData.date));
23430
23568
  addClass([ntd], [AGENDA_CELLS_CLASS, AGENDA_DATE_CLASS, DATE_BORDER_CLASS]);
23431
23569
  const daysCount = getDaysCount(this.parent.selectedDate.getTime(), tempData.date.getTime());
23432
- ntr.setAttribute('aria-rowindex', daysCount.toString());
23433
- if (this.parent.element.querySelector(`.e-agenda-view tr[aria-rowindex="${daysCount}"]`)) {
23570
+ ntr.setAttribute('data-row-index', daysCount.toString());
23571
+ if (this.parent.element.querySelector(`.e-agenda-view tr[data-row-index="${daysCount}"]`)) {
23434
23572
  break;
23435
23573
  }
23436
23574
  ntr.insertBefore(ntd, ntr.childNodes[0]);
@@ -23466,13 +23604,13 @@ class AgendaBase extends ViewBase {
23466
23604
  }
23467
23605
  createTableRowElement(date, type) {
23468
23606
  const daysCount = getDaysCount(this.parent.selectedDate.getTime(), date.getTime());
23469
- const tr = createElement('tr', { attrs: { 'role': 'row', 'aria-rowindex': daysCount.toString() } });
23607
+ const tr = createElement('tr', { attrs: { 'role': 'row', 'data-row-index': daysCount.toString() } });
23470
23608
  const td = createElement('td', {
23471
23609
  attrs: {
23472
23610
  'class': (type === 'monthHeader') ? MONTH_HEADER_CLASS : AGENDA_CELLS_CLASS,
23473
23611
  'role': 'gridcell',
23474
23612
  'aria-selected': 'false',
23475
- 'aria-colindex': daysCount.toString(),
23613
+ 'data-column-index': daysCount.toString(),
23476
23614
  'data-date': date.getTime().toString()
23477
23615
  }
23478
23616
  });
@@ -23639,7 +23777,7 @@ class Agenda extends AgendaBase {
23639
23777
  for (let day = 0; day < this.parent.agendaDaysCount; day++) {
23640
23778
  const filterData = this.appointmentFiltering(agendaDate);
23641
23779
  const nTr = this.createTableRowElement(agendaDate, 'data');
23642
- if (this.element.querySelector('tr[aria-rowindex="' + parseInt(nTr.getAttribute('aria-rowindex'), 10) + '"]')) {
23780
+ if (this.element.querySelector('tr[data-row-index="' + parseInt(nTr.getAttribute('data-row-index'), 10) + '"]')) {
23643
23781
  agendaDate = addDays(agendaDate, 1);
23644
23782
  continue;
23645
23783
  }
@@ -23703,7 +23841,7 @@ class Agenda extends AgendaBase {
23703
23841
  prepend([].slice.call(emptyTBody.childNodes), tBody);
23704
23842
  this.wireEventActions();
23705
23843
  for (let s = 0, element = tBody.children; s < element.length; s++) {
23706
- if (element[s].getAttribute('aria-rowindex') === topElement.getAttribute('aria-colindex')) {
23844
+ if (element[s].getAttribute('data-row-index') === topElement.getAttribute('data-column-index')) {
23707
23845
  const scrollToValue = element[s].offsetTop -
23708
23846
  this.element.querySelector('.e-agenda-item').offsetHeight;
23709
23847
  target.scrollTop = scrollToValue;
@@ -24403,6 +24541,20 @@ class TimelineViews extends VerticalView {
24403
24541
  this.timelineAppointment.renderAppointments();
24404
24542
  this.parent.notify(eventsLoaded, {});
24405
24543
  }
24544
+ getAdjustedDate(date) {
24545
+ if (!this.parent.activeViewOptions.timeScale.enable) {
24546
+ return new Date(date.setHours(0, 0, 0, 0));
24547
+ }
24548
+ else {
24549
+ const timeSlots = this.colLevels[this.colLevels.length - 1];
24550
+ for (let i = 0; i < timeSlots.length; i++) {
24551
+ if (timeSlots[i].date.getTime() > date.getTime()) {
24552
+ return timeSlots[i - 1].date;
24553
+ }
24554
+ }
24555
+ }
24556
+ return null;
24557
+ }
24406
24558
  destroy() {
24407
24559
  if (!this.parent || this.parent && this.parent.isDestroyed) {
24408
24560
  return;
@@ -24543,6 +24695,15 @@ class TimelineMonth extends Month {
24543
24695
  this.colLevels = colLevels;
24544
24696
  return colLevels;
24545
24697
  }
24698
+ getAdjustedDate(startTime) {
24699
+ const timeSlots = this.colLevels[this.colLevels.length - 1];
24700
+ for (let i = 0; i < timeSlots.length; i++) {
24701
+ if (timeSlots[i].date.getTime() > startTime.getTime()) {
24702
+ return timeSlots[i - 1].date;
24703
+ }
24704
+ }
24705
+ return null;
24706
+ }
24546
24707
  destroy() {
24547
24708
  if (!this.parent || this.parent && this.parent.isDestroyed) {
24548
24709
  return;
@@ -24812,6 +24973,9 @@ class TimelineYear extends Year {
24812
24973
  else {
24813
24974
  addClass([td], OTHERMONTH_CLASS);
24814
24975
  }
24976
+ if (td.classList.contains(OTHERMONTH_CLASS)) {
24977
+ continue;
24978
+ }
24815
24979
  td.appendChild(dateHeader);
24816
24980
  if (isDateAvail) {
24817
24981
  td.setAttribute('data-date', date.getTime().toString());
@@ -24997,7 +25161,7 @@ class ICalendarExport {
24997
25161
  const timeZone = this.parent.timezone || this.parent.tzModule.getLocalTimezoneName();
24998
25162
  const fields = this.parent.eventFields;
24999
25163
  eventsData.forEach((eventObj) => {
25000
- let uId = this.parent.eventBase.generateGuid();
25164
+ let uId = eventObj[fields.id] || eventObj.Guid || this.parent.eventBase.generateGuid();
25001
25165
  const editedExDate = [];
25002
25166
  if (eventObj[fields.recurrenceID]) {
25003
25167
  const filter = this.filterEvents(filterCollection, fields.id, eventObj[fields.recurrenceID]);
@@ -25196,8 +25360,16 @@ class ICalendarImport {
25196
25360
  break;
25197
25361
  case 'UID':
25198
25362
  curEvent[uId] = value;
25199
- curEvent[fields.id] = typeof (id) === 'string' ? id + count.toString() : id + count;
25200
- count++;
25363
+ if (typeof (id) == 'number') {
25364
+ curEvent[fields.id] = parseInt(value, 10);
25365
+ if (isNaN(curEvent[fields.id])) {
25366
+ curEvent[fields.id] = id + count;
25367
+ count++;
25368
+ }
25369
+ }
25370
+ else {
25371
+ curEvent[fields.id] = value;
25372
+ }
25201
25373
  break;
25202
25374
  case 'SUMMARY':
25203
25375
  curEvent[fields.subject] = value;
@@ -25233,6 +25405,10 @@ class ICalendarImport {
25233
25405
  const appoint = [];
25234
25406
  const uId = 'UID';
25235
25407
  const fields = this.parent.eventFields;
25408
+ let appointmentIds = [];
25409
+ this.parent.eventsData.forEach((eventObj) => {
25410
+ appointmentIds.push(eventObj[fields.id]);
25411
+ });
25236
25412
  app.forEach((eventObj) => {
25237
25413
  let parentObj;
25238
25414
  let id;
@@ -25241,24 +25417,26 @@ class ICalendarImport {
25241
25417
  parentObj = eventObj;
25242
25418
  id = eventObj[fields.id];
25243
25419
  }
25244
- const data = app.filter((data) => data.UID === eventObj[uId]);
25245
- if (data.length > 1 && isNullOrUndefined(eventObj[fields.recurrenceID])) {
25246
- for (let i = 0; i < data.length; i++) {
25247
- // eslint-disable-next-line no-prototype-builtins
25248
- if (data[i].hasOwnProperty(fields.recurrenceID)) {
25249
- const exdate = data[i][fields.recurrenceID];
25250
- data[i][fields.recurrenceID] = id;
25251
- data[i][fields.recurrenceException] = null;
25252
- parentObj[fields.recurrenceException] = (isNullOrUndefined(parentObj[fields.recurrenceException])) ?
25253
- exdate : parentObj[fields.recurrenceException] + ',' + exdate;
25254
- appoint.push(data[i]);
25420
+ if (appointmentIds.indexOf(eventObj[fields.id]) < 0) {
25421
+ const data = app.filter((data) => data.UID === eventObj[uId]);
25422
+ if (data.length > 1 && isNullOrUndefined(eventObj[fields.recurrenceID])) {
25423
+ for (let i = 0; i < data.length; i++) {
25424
+ // eslint-disable-next-line no-prototype-builtins
25425
+ if (data[i].hasOwnProperty(fields.recurrenceID)) {
25426
+ const exdate = data[i][fields.recurrenceID];
25427
+ data[i][fields.recurrenceID] = id;
25428
+ data[i][fields.recurrenceException] = null;
25429
+ parentObj[fields.recurrenceException] = (isNullOrUndefined(parentObj[fields.recurrenceException])) ?
25430
+ exdate : parentObj[fields.recurrenceException] + ',' + exdate;
25431
+ appoint.push(data[i]);
25432
+ }
25255
25433
  }
25434
+ appoint.push(parentObj);
25435
+ // eslint-disable-next-line no-prototype-builtins
25436
+ }
25437
+ else if (!eventObj.hasOwnProperty(fields.recurrenceID)) {
25438
+ appoint.push(eventObj);
25256
25439
  }
25257
- appoint.push(parentObj);
25258
- // eslint-disable-next-line no-prototype-builtins
25259
- }
25260
- else if (!eventObj.hasOwnProperty(fields.recurrenceID)) {
25261
- appoint.push(eventObj);
25262
25440
  }
25263
25441
  });
25264
25442
  return appoint;
@@ -25316,6 +25494,10 @@ class ExcelExport {
25316
25494
  const exportName = excelExportOptions.fileName || 'Schedule';
25317
25495
  const exportType = excelExportOptions.exportType || 'xlsx';
25318
25496
  const isIncludeOccurrences = excelExportOptions.includeOccurrences || false;
25497
+ let separator;
25498
+ if (!isNullOrUndefined(excelExportOptions.separator) && excelExportOptions.separator !== ',') {
25499
+ separator = excelExportOptions.separator;
25500
+ }
25319
25501
  let eventCollection;
25320
25502
  if (excelExportOptions.customData) {
25321
25503
  eventCollection = !isIncludeOccurrences ? excelExportOptions.customData :
@@ -25324,9 +25506,9 @@ class ExcelExport {
25324
25506
  else {
25325
25507
  eventCollection = !isIncludeOccurrences ? this.parent.eventsData : this.parent.eventsProcessed;
25326
25508
  }
25327
- this.processWorkbook(exportColumns, exportName, exportType, eventCollection);
25509
+ this.processWorkbook(exportColumns, exportName, exportType, eventCollection, separator);
25328
25510
  }
25329
- processWorkbook(fields, name, type, eventCollection) {
25511
+ processWorkbook(fields, name, type, eventCollection, separator) {
25330
25512
  const columns = [];
25331
25513
  const rows = [];
25332
25514
  const columnHeader = [];
@@ -25347,7 +25529,7 @@ class ExcelExport {
25347
25529
  rows.push({ index: i + 2, cells: columnData });
25348
25530
  });
25349
25531
  const workSheet = [{ columns: columns, rows: rows }];
25350
- const book = new Workbook({ worksheets: workSheet }, type, this.parent.locale);
25532
+ const book = new Workbook({ worksheets: workSheet }, type, this.parent.locale, undefined, separator);
25351
25533
  book.save(name + '.' + type);
25352
25534
  }
25353
25535
  getExportColumns(exportOptions) {