@syncfusion/ej2-schedule 20.1.61 → 20.2.40

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 (81) hide show
  1. package/CHANGELOG.md +31 -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 +257 -84
  5. package/dist/es6/ej2-schedule.es2015.js.map +1 -1
  6. package/dist/es6/ej2-schedule.es5.js +261 -83
  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/crud.d.ts +1 -0
  17. package/src/schedule/actions/crud.js +36 -9
  18. package/src/schedule/base/interface.d.ts +7 -1
  19. package/src/schedule/base/schedule.d.ts +8 -0
  20. package/src/schedule/base/schedule.js +75 -21
  21. package/src/schedule/event-renderer/agenda-base.js +6 -6
  22. package/src/schedule/event-renderer/event-base.d.ts +2 -0
  23. package/src/schedule/event-renderer/event-base.js +21 -5
  24. package/src/schedule/event-renderer/month.js +2 -3
  25. package/src/schedule/event-renderer/vertical-view.js +3 -3
  26. package/src/schedule/event-renderer/year.js +2 -2
  27. package/src/schedule/exports/calendar-export.d.ts +1 -0
  28. package/src/schedule/exports/calendar-export.js +6 -2
  29. package/src/schedule/exports/calendar-import.js +32 -18
  30. package/src/schedule/exports/excel-export.js +8 -4
  31. package/src/schedule/popups/event-window.js +3 -1
  32. package/src/schedule/popups/quick-popups.js +3 -3
  33. package/src/schedule/renderer/agenda.js +2 -2
  34. package/src/schedule/renderer/timeline-month.d.ts +1 -0
  35. package/src/schedule/renderer/timeline-month.js +9 -0
  36. package/src/schedule/renderer/timeline-view.d.ts +1 -0
  37. package/src/schedule/renderer/timeline-view.js +14 -0
  38. package/src/schedule/renderer/timeline-year.js +3 -0
  39. package/src/schedule/renderer/vertical-view.d.ts +1 -0
  40. package/src/schedule/renderer/vertical-view.js +21 -4
  41. package/src/schedule/renderer/view-base.d.ts +1 -0
  42. package/src/schedule/renderer/view-base.js +11 -0
  43. package/src/schedule/renderer/year.js +2 -1
  44. package/styles/bootstrap-dark.css +5 -1
  45. package/styles/bootstrap.css +5 -1
  46. package/styles/bootstrap4.css +5 -1
  47. package/styles/bootstrap5-dark.css +5 -1
  48. package/styles/bootstrap5.css +5 -1
  49. package/styles/fabric-dark.css +5 -1
  50. package/styles/fabric.css +5 -1
  51. package/styles/fluent-dark.css +20 -16
  52. package/styles/fluent.css +7 -3
  53. package/styles/highcontrast-light.css +5 -1
  54. package/styles/highcontrast.css +5 -1
  55. package/styles/material-dark.css +5 -1
  56. package/styles/material.css +5 -1
  57. package/styles/recurrence-editor/_fusionnew-definition.scss +15 -0
  58. package/styles/recurrence-editor/_material3-definition.scss +15 -0
  59. package/styles/schedule/_fluent-definition.scss +1 -1
  60. package/styles/schedule/_fusionnew-definition.scss +224 -0
  61. package/styles/schedule/_layout.scss +6 -1
  62. package/styles/schedule/_material3-definition.scss +224 -0
  63. package/styles/schedule/bootstrap-dark.css +5 -1
  64. package/styles/schedule/bootstrap.css +5 -1
  65. package/styles/schedule/bootstrap4.css +5 -1
  66. package/styles/schedule/bootstrap5-dark.css +5 -1
  67. package/styles/schedule/bootstrap5.css +5 -1
  68. package/styles/schedule/fabric-dark.css +5 -1
  69. package/styles/schedule/fabric.css +5 -1
  70. package/styles/schedule/fluent-dark.css +20 -16
  71. package/styles/schedule/fluent.css +7 -3
  72. package/styles/schedule/highcontrast-light.css +5 -1
  73. package/styles/schedule/highcontrast.css +5 -1
  74. package/styles/schedule/icons/_fusionnew.scss +232 -0
  75. package/styles/schedule/icons/_material3.scss +232 -0
  76. package/styles/schedule/material-dark.css +5 -1
  77. package/styles/schedule/material.css +5 -1
  78. package/styles/schedule/tailwind-dark.css +5 -1
  79. package/styles/schedule/tailwind.css +5 -1
  80. package/styles/tailwind-dark.css +5 -1
  81. package/styles/tailwind.css +5 -1
@@ -5154,7 +5154,7 @@ class EventBase {
5154
5154
  if (timeZonePropChanged) {
5155
5155
  this.processTimezoneChange(event, oldTimezone);
5156
5156
  }
5157
- else if (!this.parent.isPrinting && !this.parent.uiStateValues.isResize) {
5157
+ else if (!this.parent.isPrinting && !this.parent.uiStateValues.isPreventTimezone) {
5158
5158
  event = this.processTimezone(event);
5159
5159
  }
5160
5160
  for (let level = 0; level < resourceCollection.length; level++) {
@@ -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();
@@ -5946,7 +5946,7 @@ class EventBase {
5946
5946
  const exception = event[this.parent.eventFields.recurrenceException];
5947
5947
  let maxCount;
5948
5948
  if (this.parent.currentView !== 'Agenda' && isMaxCount) {
5949
- maxCount = getDateCount(this.parent.activeView.startDate(), this.parent.activeView.endDate()) + 1;
5949
+ maxCount = getDateCount(viewDate, this.parent.activeView.endDate()) + 1;
5950
5950
  }
5951
5951
  const newTimezone = this.parent.timezone || this.parent.tzModule.getLocalTimezoneName();
5952
5952
  const firstDay = this.parent.activeViewOptions.firstDayOfWeek;
@@ -5966,8 +5966,9 @@ class EventBase {
5966
5966
  }
5967
5967
  }
5968
5968
  const occurrenceCollection = [];
5969
- for (const date of dates) {
5969
+ for (let date of dates) {
5970
5970
  const clonedObject = extend({}, event, null, true);
5971
+ date = this.getDSTAdjustedTime(date, clonedObject);
5971
5972
  clonedObject[this.parent.eventFields.startTime] = new Date(date);
5972
5973
  clonedObject[this.parent.eventFields.endTime] = new Date(new Date(date).setMilliseconds(duration));
5973
5974
  clonedObject[this.parent.eventFields.recurrenceID] = clonedObject[this.parent.eventFields.id];
@@ -5978,6 +5979,21 @@ class EventBase {
5978
5979
  }
5979
5980
  return occurrenceCollection;
5980
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
+ }
5981
5997
  getParentEvent(eventObj, isParent = false) {
5982
5998
  let parentEvent;
5983
5999
  do {
@@ -6123,7 +6139,7 @@ class EventBase {
6123
6139
  className: BLOCK_APPOINTMENT_CLASS,
6124
6140
  attrs: {
6125
6141
  'data-id': 'Appointment_' + record[this.parent.eventFields.id],
6126
- 'aria-readonly': 'true', 'aria-selected': 'false'
6142
+ 'aria-disabled': 'true', 'aria-pressed': 'false'
6127
6143
  }
6128
6144
  });
6129
6145
  let templateElement;
@@ -6547,8 +6563,8 @@ class VerticalEvent extends EventBase {
6547
6563
  'data-guid': record.Guid,
6548
6564
  'role': 'button',
6549
6565
  'tabindex': '0',
6550
- 'aria-readonly': this.parent.eventBase.getReadonlyAttribute(record),
6551
- 'aria-selected': 'false',
6566
+ 'aria-disabled': this.parent.eventBase.getReadonlyAttribute(record),
6567
+ 'aria-pressed': 'false',
6552
6568
  'aria-grabbed': 'true',
6553
6569
  'aria-label': this.parent.getAnnouncementString(record)
6554
6570
  }
@@ -6643,7 +6659,7 @@ class VerticalEvent extends EventBase {
6643
6659
  });
6644
6660
  const moreIndicatorElement = createElement('div', {
6645
6661
  className: MORE_INDICATOR_CLASS,
6646
- attrs: { 'tabindex': '0', 'role': 'list', 'data-index': index.toString(), 'data-count': '1' },
6662
+ attrs: { 'tabindex': '0', 'data-index': index.toString(), 'data-count': '1' },
6647
6663
  innerHTML: '+1&nbsp;' + (this.parent.isAdaptive ? '' : this.parent.localeObj.getConstant('more'))
6648
6664
  });
6649
6665
  innerCountWrap.appendChild(moreIndicatorElement);
@@ -7436,7 +7452,7 @@ class MonthEvent extends EventBase {
7436
7452
  const attrs = {
7437
7453
  'data-id': 'Appointment_' + record[this.fields.id],
7438
7454
  'role': 'button', 'tabindex': '0',
7439
- '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',
7440
7456
  'aria-label': this.parent.getAnnouncementString(newRecord, eventSubject)
7441
7457
  };
7442
7458
  if (!isCloneElement) {
@@ -7726,8 +7742,7 @@ class MonthEvent extends EventBase {
7726
7742
  'tabindex': '0',
7727
7743
  'data-count': count.toString(),
7728
7744
  'data-start-date': startDate.getTime().toString(),
7729
- 'data-end-date': endDate.getTime().toString(),
7730
- 'role': 'list'
7745
+ 'data-end-date': endDate.getTime().toString()
7731
7746
  }
7732
7747
  });
7733
7748
  return moreIndicatorElement;
@@ -8893,8 +8908,8 @@ class QuickPopups {
8893
8908
  attrs: {
8894
8909
  'data-id': '' + eventData[fields.id],
8895
8910
  'data-guid': eventData.Guid, 'role': 'button', 'tabindex': '0',
8896
- 'aria-readonly': this.parent.eventBase.getReadonlyAttribute(eventData),
8897
- '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)
8898
8913
  }
8899
8914
  });
8900
8915
  let templateElement;
@@ -8985,7 +9000,7 @@ class QuickPopups {
8985
9000
  this.quickPopupHide();
8986
9001
  return;
8987
9002
  }
8988
- const targetEle = args.event.target;
9003
+ const targetEle = !isNullOrUndefined(args.event) ? args.event.target : args.element;
8989
9004
  if (this.parent.isAdaptive) {
8990
9005
  this.quickPopupHide();
8991
9006
  let newEventClone = this.parent.element.querySelector('.' + NEW_EVENT_CLASS);
@@ -10372,7 +10387,7 @@ let RecurrenceEditor = class RecurrenceEditor extends Component {
10372
10387
  value: VALUEFIELD
10373
10388
  },
10374
10389
  placeholder: this.localeObj.getConstant(REPEAT),
10375
- htmlAttributes: { 'title': this.localeObj.getConstant(REPEAT) },
10390
+ htmlAttributes: { 'title': this.localeObj.getConstant(REPEAT), role: 'option' },
10376
10391
  change: (args) => {
10377
10392
  self.setProperties({ selectedType: this.frequencies.indexOf(args.value) }, false);
10378
10393
  self.element.querySelector('.' + REPEATCONTENT).innerHTML =
@@ -10394,6 +10409,7 @@ let RecurrenceEditor = class RecurrenceEditor extends Component {
10394
10409
  text: TEXTFIELD,
10395
10410
  value: VALUEFIELD
10396
10411
  },
10412
+ htmlAttributes: { role: 'option' },
10397
10413
  change: (args) => {
10398
10414
  self.freshOnEndForm();
10399
10415
  self.updateEndOnForm(args.value);
@@ -10411,6 +10427,7 @@ let RecurrenceEditor = class RecurrenceEditor extends Component {
10411
10427
  text: TEXTFIELD,
10412
10428
  value: VALUEFIELD
10413
10429
  },
10430
+ htmlAttributes: { role: 'option' },
10414
10431
  index: 1,
10415
10432
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
10416
10433
  change: (args) => {
@@ -10430,6 +10447,7 @@ let RecurrenceEditor = class RecurrenceEditor extends Component {
10430
10447
  text: TEXTFIELD,
10431
10448
  value: VALUEFIELD
10432
10449
  },
10450
+ htmlAttributes: { role: 'option' },
10433
10451
  enableRtl: this.enableRtl,
10434
10452
  index: 7,
10435
10453
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -11272,6 +11290,7 @@ class EventWindow {
11272
11290
  setDialogContent() {
11273
11291
  this.dialogObject.content = this.getEventWindowContent();
11274
11292
  this.dialogObject.dataBind();
11293
+ this.applyFormValidation();
11275
11294
  }
11276
11295
  preventEventSave(e) {
11277
11296
  if (this.parent && !this.parent.allowKeyboardInteraction && e.code === 'Enter') {
@@ -11528,6 +11547,7 @@ class EventWindow {
11528
11547
  resourceData.colorField + '}"></div><div class="e-resource-text">${' + resourceData.textField + '}</div></div>';
11529
11548
  if (resourceData.allowMultiple) {
11530
11549
  const listObj = new MultiSelect({
11550
+ enableRtl: this.parent.enableRtl,
11531
11551
  cssClass: this.parent.cssClass || '',
11532
11552
  dataSource: resourceData.dataSource,
11533
11553
  change: this.onMultiselectResourceChange.bind(this),
@@ -11585,7 +11605,7 @@ class EventWindow {
11585
11605
  query = (e.text !== '') ? query.where('Text', 'contains', e.text, true) : query;
11586
11606
  e.updateData(this.parent.timezoneDataSource, query);
11587
11607
  },
11588
- htmlAttributes: { 'title': this.getFieldLabel(value), 'name': fieldName },
11608
+ htmlAttributes: { 'title': this.getFieldLabel(value), 'name': fieldName, role: 'option' },
11589
11609
  floatLabelType: 'Always',
11590
11610
  placeholder: this.getFieldLabel(value),
11591
11611
  popupHeight: '230px'
@@ -13382,7 +13402,7 @@ class Crud {
13382
13402
  const resultData = extend([], args.result, null, true);
13383
13403
  this.parent.eventsData = resultData.filter((data) => !data[this.parent.eventFields.isBlock]);
13384
13404
  this.parent.blockData = resultData.filter((data) => data[this.parent.eventFields.isBlock]);
13385
- this.parent.refreshEvents(false);
13405
+ this.refreshProcessedData();
13386
13406
  if (this.parent.dragAndDropModule && this.parent.dragAndDropModule.actionObj.action === 'drag') {
13387
13407
  this.parent.dragAndDropModule.navigationWrapper();
13388
13408
  }
@@ -13400,6 +13420,31 @@ class Crud {
13400
13420
  }
13401
13421
  this.parent.trigger(actionFailure, { error: e }, () => this.parent.hideSpinner());
13402
13422
  }
13423
+ refreshProcessedData() {
13424
+ if (this.parent.dragAndDropModule) {
13425
+ this.parent.dragAndDropModule.actionObj.action = '';
13426
+ removeClass([this.parent.element], 'e-event-action');
13427
+ }
13428
+ if (this.parent.activeViewOptions && this.parent.activeViewOptions.eventTemplate) {
13429
+ let templateNames = ['eventTemplate'];
13430
+ if (this.crudObj.isCrudAction &&
13431
+ ['Agenda', 'MonthAgenda', 'Year', 'TimelineYear'].indexOf(this.parent.currentView) === -1) {
13432
+ templateNames = [];
13433
+ for (let i = 0, len = this.crudObj.sourceEvent.length; i < len; i++) {
13434
+ templateNames.push('eventTemplate_' + this.crudObj.sourceEvent[i].groupIndex);
13435
+ if (this.crudObj.targetEvent[i] && this.crudObj.sourceEvent[i].groupIndex !==
13436
+ this.crudObj.targetEvent[i].groupIndex) {
13437
+ templateNames.push('eventTemplate_' + this.crudObj.targetEvent[i].groupIndex);
13438
+ }
13439
+ }
13440
+ }
13441
+ this.parent.resetTemplates(templateNames);
13442
+ }
13443
+ const eventsData = this.parent.eventsData || [];
13444
+ const blockData = this.parent.blockData || [];
13445
+ const data = eventsData.concat(blockData);
13446
+ this.parent.notify(dataReady, { processedData: this.parent.eventBase ? this.parent.eventBase.processData(data) : [] });
13447
+ }
13403
13448
  refreshData(args) {
13404
13449
  const actionArgs = {
13405
13450
  requestType: args.requestType, cancel: false, data: args.data,
@@ -13927,13 +13972,15 @@ class Crud {
13927
13972
  else {
13928
13973
  endDate = new Date(+followEvent[fields.startTime]);
13929
13974
  const newRecurrenceRule = followEvent[fields.recurrenceRule];
13930
- const startDate = parentEvent[fields.startTime];
13931
- const ruleException = (this.parent.currentAction === 'DeleteFollowingEvents') ? followEvent[fields.recurrenceException] : null;
13932
- const dateCollection = generate(startDate, newRecurrenceRule, ruleException, this.parent.activeViewOptions.firstDayOfWeek);
13933
- const untilDate = new Date(dateCollection.slice(-1)[0]);
13934
- untilDate.setHours(endDate.getHours(), endDate.getMinutes(), endDate.getSeconds());
13935
- endDate.setHours(startDate.getHours(), startDate.getMinutes(), startDate.getSeconds());
13936
- followEvent[fields.recurrenceRule] = this.getUpdatedRecurrenceRule(newRecurrenceRule, new Date(+untilDate), false);
13975
+ if (newRecurrenceRule) {
13976
+ const startDate = parentEvent[fields.startTime];
13977
+ const ruleException = (this.parent.currentAction === 'DeleteFollowingEvents') ? followEvent[fields.recurrenceException] : null;
13978
+ const dateCollection = generate(startDate, newRecurrenceRule, ruleException, this.parent.activeViewOptions.firstDayOfWeek);
13979
+ const untilDate = new Date(dateCollection.slice(-1)[0]);
13980
+ untilDate.setHours(endDate.getHours(), endDate.getMinutes(), endDate.getSeconds());
13981
+ endDate.setHours(startDate.getHours(), startDate.getMinutes(), startDate.getSeconds());
13982
+ followEvent[fields.recurrenceRule] = this.getUpdatedRecurrenceRule(newRecurrenceRule, new Date(+untilDate), false);
13983
+ }
13937
13984
  }
13938
13985
  parentEvent[fields.recurrenceRule] = this.getUpdatedRecurrenceRule(recurrenceRule, addDays(new Date(endDate.getTime()), -1), true);
13939
13986
  }
@@ -15897,7 +15944,7 @@ let Schedule = class Schedule extends Component {
15897
15944
  if (this && isNullOrUndefined(this.uiStateValues) || !(this.enablePersistence)) {
15898
15945
  this.uiStateValues = {
15899
15946
  expand: false, isInitial: true, left: 0, top: 0, isGroupAdaptive: false,
15900
- isIgnoreOccurrence: false, groupIndex: 0, action: false, isBlock: false, isCustomMonth: true, isResize: false
15947
+ isIgnoreOccurrence: false, groupIndex: 0, action: false, isBlock: false, isCustomMonth: true, isPreventTimezone: false
15901
15948
  };
15902
15949
  }
15903
15950
  this.activeCellsData = { startTime: this.getCurrentTime(), endTime: this.getCurrentTime(), isAllDay: false };
@@ -16357,11 +16404,9 @@ let Schedule = class Schedule extends Component {
16357
16404
  }
16358
16405
  if (this.currentView === 'Month' || ((this.currentView !== 'Agenda' && this.currentView !== 'MonthAgenda')
16359
16406
  && !this.activeViewOptions.timeScale.enable) || this.activeView.isTimelineView()) {
16360
- this.uiStateValues.isResize = true;
16361
16407
  this.activeView.resetColWidth();
16362
16408
  this.notify(scrollUiUpdate, { cssProperties: this.getCssProperties(), isPreventScrollUpdate: true });
16363
16409
  this.refreshEvents(false);
16364
- this.uiStateValues.isResize = false;
16365
16410
  }
16366
16411
  else {
16367
16412
  this.notify(contentReady, {});
@@ -17427,25 +17472,15 @@ let Schedule = class Schedule extends Component {
17427
17472
  this.crudModule.refreshDataManager();
17428
17473
  }
17429
17474
  else {
17430
- if (this.activeViewOptions && this.activeViewOptions.eventTemplate) {
17431
- let templateNames = ['eventTemplate'];
17432
- if (this.crudModule && this.crudModule.crudObj.isCrudAction &&
17433
- ['Agenda', 'MonthAgenda', 'Year', 'TimelineYear'].indexOf(this.currentView) === -1) {
17434
- templateNames = [];
17435
- for (let i = 0, len = this.crudModule.crudObj.sourceEvent.length; i < len; i++) {
17436
- templateNames.push('eventTemplate_' + this.crudModule.crudObj.sourceEvent[i].groupIndex);
17437
- if (this.crudModule.crudObj.targetEvent[i] && this.crudModule.crudObj.sourceEvent[i].groupIndex !==
17438
- this.crudModule.crudObj.targetEvent[i].groupIndex) {
17439
- templateNames.push('eventTemplate_' + this.crudModule.crudObj.targetEvent[i].groupIndex);
17440
- }
17441
- }
17442
- }
17443
- this.resetTemplates(templateNames);
17475
+ if (this.uiStateValues) {
17476
+ this.uiStateValues.isPreventTimezone = true;
17477
+ }
17478
+ if (this.crudModule) {
17479
+ this.crudModule.refreshProcessedData();
17480
+ }
17481
+ if (this.uiStateValues) {
17482
+ this.uiStateValues.isPreventTimezone = false;
17444
17483
  }
17445
- const eventsData = this.eventsData || [];
17446
- const blockData = this.blockData || [];
17447
- const data = eventsData.concat(blockData);
17448
- this.notify(dataReady, { processedData: this.eventBase ? this.eventBase.processData(data) : [] });
17449
17484
  }
17450
17485
  }
17451
17486
  /**
@@ -17628,6 +17663,67 @@ let Schedule = class Schedule extends Component {
17628
17663
  this.eventWindow.dialogClose();
17629
17664
  }
17630
17665
  }
17666
+ /**
17667
+ * To manually open the quick info popup based on cell or event details.
17668
+ *
17669
+ * @param {object} data Defines the cell or event data. If the data contains valid ID, it will open event quick info popup,
17670
+ * otherwise cell quick info popup displayed.
17671
+ * @returns {void}
17672
+ */
17673
+ openQuickInfoPopup(data) {
17674
+ if (this.currentView === 'Year' || isNullOrUndefined(data)) {
17675
+ return;
17676
+ }
17677
+ if (isNullOrUndefined(data[this.eventFields.id])) {
17678
+ if (this.currentView === 'Agenda' || this.currentView === 'MonthAgenda' || isNullOrUndefined(this.activeView)) {
17679
+ return;
17680
+ }
17681
+ const cellData = {
17682
+ startTime: this.activeCellsData.startTime = this.getDateTime(data[this.eventFields.startTime]),
17683
+ endTime: this.activeCellsData.endTime = this.getDateTime(data[this.eventFields.endTime]),
17684
+ isAllDay: this.activeCellsData.isAllDay =
17685
+ !isNullOrUndefined(data[this.eventFields.isAllDay]) ? data[this.eventFields.isAllDay] : false
17686
+ };
17687
+ const startTime = this.activeView.getAdjustedDate(new Date(cellData.startTime));
17688
+ if (startTime) {
17689
+ let query = '.' + WORK_CELLS_CLASS + '[data-date="' + startTime.getTime() + '"]';
17690
+ if (this.activeViewOptions.group.resources.length > 0 && !this.uiStateValues.isGroupAdaptive
17691
+ && this.resourceBase && this.eventBase) {
17692
+ cellData.groupIndex = this.eventBase.getGroupIndexFromEvent(data);
17693
+ query = '.' + WORK_CELLS_CLASS + '[data-date="' + startTime.getTime() + '"][data-group-index="' + cellData.groupIndex + '"]';
17694
+ }
17695
+ const workCell = this.element.querySelector(query);
17696
+ if (workCell) {
17697
+ workCell.focus();
17698
+ cellData.element = workCell;
17699
+ this.notify(cellClick, cellData);
17700
+ }
17701
+ }
17702
+ }
17703
+ else {
17704
+ const app = this.getCurrentViewEvents().filter((item) => data[this.eventFields.id] === item[this.eventFields.id]);
17705
+ if (app.length <= 0) {
17706
+ return;
17707
+ }
17708
+ let selectEvent = app[0];
17709
+ if (data[this.eventFields.recurrenceRule]) {
17710
+ const occurence = app.filter((x) => x[this.eventFields.startTime].getTime() === data[this.eventFields.startTime].getTime());
17711
+ if (occurence.length > 0) {
17712
+ selectEvent = occurence[0];
17713
+ }
17714
+ }
17715
+ const element = this.element.querySelector('div[data-guid="' + selectEvent.Guid + '"]');
17716
+ if (element) {
17717
+ this.eventBase.removeSelectedAppointmentClass();
17718
+ this.eventBase.addSelectedAppointments([element]);
17719
+ this.activeEventData = { event: selectEvent, element: element };
17720
+ if (this.currentView === 'Agenda' || this.currentView === 'MonthAgenda') {
17721
+ addClass([this.activeEventData.element], AGENDA_SELECTED_CELL);
17722
+ }
17723
+ this.notify(eventClick, this.activeEventData);
17724
+ }
17725
+ }
17726
+ }
17631
17727
  /**
17632
17728
  * To manually close the quick info popup
17633
17729
  *
@@ -19061,7 +19157,7 @@ class YearEvent extends TimelineEvent {
19061
19157
  }
19062
19158
  }
19063
19159
  timelineYearViewEvents() {
19064
- const workCell = this.parent.element.querySelector('.' + WORK_CELLS_CLASS);
19160
+ const workCell = this.parent.element.querySelector('.' + WORK_CELLS_CLASS + ':not(.' + OTHERMONTH_CLASS + ')');
19065
19161
  this.cellWidth = workCell.offsetWidth;
19066
19162
  this.cellHeader = getOuterHeight(workCell.querySelector('.' + DATE_HEADER_CLASS));
19067
19163
  const eventTable = this.parent.element.querySelector('.' + EVENT_TABLE_CLASS);
@@ -19337,7 +19433,7 @@ class YearEvent extends TimelineEvent {
19337
19433
  'data-id': 'Appointment_' + record[this.fields.id],
19338
19434
  'data-guid': record.Guid,
19339
19435
  'role': 'button', 'tabindex': '0',
19340
- 'aria-readonly': this.parent.eventBase.getReadonlyAttribute(record), 'aria-selected': 'false', 'aria-grabbed': 'true',
19436
+ 'aria-disabled': this.parent.eventBase.getReadonlyAttribute(record), 'aria-pressed': 'false', 'aria-grabbed': 'true',
19341
19437
  'aria-label': this.parent.getAnnouncementString(record)
19342
19438
  }
19343
19439
  });
@@ -21279,6 +21375,17 @@ class ViewBase {
21279
21375
  }
21280
21376
  return endDate;
21281
21377
  }
21378
+ getAdjustedDate(startTime) {
21379
+ if (!this.parent.activeViewOptions.timeScale.enable || this.parent.currentView === 'Month' ||
21380
+ (this.parent.currentView === 'TimelineYear' && this.parent.activeViewOptions.group.resources.length === 0)) {
21381
+ return new Date(startTime.setHours(0, 0, 0, 0));
21382
+ }
21383
+ else if (this.parent.currentView === 'TimelineYear' && this.parent.activeViewOptions.group.resources.length > 0) {
21384
+ startTime.setHours(0, 0, 0, 0);
21385
+ return new Date(startTime.setDate(1));
21386
+ }
21387
+ return null;
21388
+ }
21282
21389
  destroy() {
21283
21390
  if (this.element && this.element.parentNode) {
21284
21391
  remove(this.element);
@@ -21774,12 +21881,11 @@ class VerticalView extends ViewBase {
21774
21881
  const wrap = createElement('div', { className: DATE_HEADER_WRAP_CLASS });
21775
21882
  container.appendChild(wrap);
21776
21883
  const tbl = this.createTableLayout();
21777
- const trEle = createElement('tr');
21884
+ const trEle = createElement('tr', { className: HEADER_ROW_CLASS });
21778
21885
  const rowCount = this.colLevels.length;
21779
21886
  const lastLevel = this.colLevels[rowCount - 1];
21780
21887
  for (let i = 0; i < rowCount; i++) {
21781
21888
  const ntr = trEle.cloneNode();
21782
- addClass([ntr], HEADER_ROW_CLASS);
21783
21889
  const level = this.colLevels[i];
21784
21890
  for (let j = 0; j < level.length; j++) {
21785
21891
  ntr.appendChild(this.createTd(level[j]));
@@ -21792,13 +21898,13 @@ class VerticalView extends ViewBase {
21792
21898
  return container;
21793
21899
  }
21794
21900
  createAllDayRow(table, tdData) {
21795
- const ntr = createElement('tr');
21796
- addClass([ntr], ALLDAY_ROW_CLASS);
21901
+ const ntr = createElement('tr', { className: ALLDAY_ROW_CLASS });
21797
21902
  for (let j = 0; j < tdData.length; j++) {
21798
21903
  const td = extend({}, tdData[j]);
21799
21904
  td.className = [ALLDAY_CELLS_CLASS];
21800
21905
  td.type = 'alldayCells';
21801
21906
  const ntd = this.createTd(td);
21907
+ ntd.setAttribute('role', 'gridcell');
21802
21908
  ntd.setAttribute('data-date', td.date.getTime().toString());
21803
21909
  if (!isNullOrUndefined(td.groupIndex)) {
21804
21910
  ntd.setAttribute('data-group-index', '' + td.groupIndex);
@@ -21831,6 +21937,7 @@ class VerticalView extends ViewBase {
21831
21937
  }
21832
21938
  if (td.type === 'dateHeader' && td.className.indexOf(HEADER_CELLS_CLASS) >= 0) {
21833
21939
  tdEle.setAttribute('data-date', td.date.getTime().toString());
21940
+ tdEle.setAttribute('role', 'gridcell');
21834
21941
  if (!isNullOrUndefined(td.groupIndex)) {
21835
21942
  tdEle.setAttribute('data-group-index', '' + td.groupIndex);
21836
21943
  }
@@ -22029,6 +22136,23 @@ class VerticalView extends ViewBase {
22029
22136
  }
22030
22137
  return rows;
22031
22138
  }
22139
+ getAdjustedDate(startTime) {
22140
+ if (!this.parent.activeViewOptions.timeScale.enable) {
22141
+ return new Date(startTime.setHours(0, 0, 0, 0));
22142
+ }
22143
+ else {
22144
+ const timeSlots = this.getTimeSlotRows();
22145
+ const startDate = new Date(new Date(timeSlots[0].date.getTime()).
22146
+ setHours(startTime.getHours(), startTime.getMinutes(), startTime.getMilliseconds()));
22147
+ for (let i = 0; i < timeSlots.length; i++) {
22148
+ if (timeSlots[i].date.getTime() > startDate.getTime()) {
22149
+ startTime.setHours(timeSlots[i - 1].date.getHours(), timeSlots[i - 1].date.getMinutes(), timeSlots[i - 1].date.getMilliseconds());
22150
+ return new Date(startTime);
22151
+ }
22152
+ }
22153
+ }
22154
+ return null;
22155
+ }
22032
22156
  destroy() {
22033
22157
  if (!this.parent || this.parent && this.parent.isDestroyed) {
22034
22158
  return;
@@ -23079,7 +23203,8 @@ class Year extends ViewBase {
23079
23203
  return this.parent.currentView === 'Year' ? getWeekFirstDate(this.getStartDate(), this.parent.firstDayOfWeek) : this.getStartDate();
23080
23204
  }
23081
23205
  endDate() {
23082
- return this.parent.currentView === 'Year' ? addDays(getWeekLastDate(this.getEndDate(), this.parent.firstDayOfWeek), 1) : this.getEndDate();
23206
+ return this.parent.currentView === 'Year' ? addDays(getWeekLastDate(this.getEndDate(), this.parent.firstDayOfWeek), 1) :
23207
+ addDays(this.getEndDate(), 1);
23083
23208
  }
23084
23209
  getEndDateFromStartDate(start) {
23085
23210
  let date = new Date(start.getTime());
@@ -23189,8 +23314,8 @@ class AgendaBase extends ViewBase {
23189
23314
  'data-guid': listData[li].Guid,
23190
23315
  'role': 'button',
23191
23316
  'tabindex': '0',
23192
- 'aria-readonly': this.parent.eventBase.getReadonlyAttribute(listData[li]),
23193
- 'aria-selected': 'false',
23317
+ 'aria-disabled': this.parent.eventBase.getReadonlyAttribute(listData[li]),
23318
+ 'aria-pressed': 'false',
23194
23319
  'aria-grabbed': 'true',
23195
23320
  'aria-label': this.parent.getAnnouncementString(listData[li])
23196
23321
  }
@@ -23455,8 +23580,8 @@ class AgendaBase extends ViewBase {
23455
23580
  ntd.appendChild(this.createDateHeaderElement(tempData.date));
23456
23581
  addClass([ntd], [AGENDA_CELLS_CLASS, AGENDA_DATE_CLASS, DATE_BORDER_CLASS]);
23457
23582
  const daysCount = getDaysCount(this.parent.selectedDate.getTime(), tempData.date.getTime());
23458
- ntr.setAttribute('aria-rowindex', daysCount.toString());
23459
- if (this.parent.element.querySelector(`.e-agenda-view tr[aria-rowindex="${daysCount}"]`)) {
23583
+ ntr.setAttribute('data-row-index', daysCount.toString());
23584
+ if (this.parent.element.querySelector(`.e-agenda-view tr[data-row-index="${daysCount}"]`)) {
23460
23585
  break;
23461
23586
  }
23462
23587
  ntr.insertBefore(ntd, ntr.childNodes[0]);
@@ -23492,13 +23617,13 @@ class AgendaBase extends ViewBase {
23492
23617
  }
23493
23618
  createTableRowElement(date, type) {
23494
23619
  const daysCount = getDaysCount(this.parent.selectedDate.getTime(), date.getTime());
23495
- const tr = createElement('tr', { attrs: { 'role': 'row', 'aria-rowindex': daysCount.toString() } });
23620
+ const tr = createElement('tr', { attrs: { 'role': 'row', 'data-row-index': daysCount.toString() } });
23496
23621
  const td = createElement('td', {
23497
23622
  attrs: {
23498
23623
  'class': (type === 'monthHeader') ? MONTH_HEADER_CLASS : AGENDA_CELLS_CLASS,
23499
23624
  'role': 'gridcell',
23500
23625
  'aria-selected': 'false',
23501
- 'aria-colindex': daysCount.toString(),
23626
+ 'data-column-index': daysCount.toString(),
23502
23627
  'data-date': date.getTime().toString()
23503
23628
  }
23504
23629
  });
@@ -23665,7 +23790,7 @@ class Agenda extends AgendaBase {
23665
23790
  for (let day = 0; day < this.parent.agendaDaysCount; day++) {
23666
23791
  const filterData = this.appointmentFiltering(agendaDate);
23667
23792
  const nTr = this.createTableRowElement(agendaDate, 'data');
23668
- if (this.element.querySelector('tr[aria-rowindex="' + parseInt(nTr.getAttribute('aria-rowindex'), 10) + '"]')) {
23793
+ if (this.element.querySelector('tr[data-row-index="' + parseInt(nTr.getAttribute('data-row-index'), 10) + '"]')) {
23669
23794
  agendaDate = addDays(agendaDate, 1);
23670
23795
  continue;
23671
23796
  }
@@ -23729,7 +23854,7 @@ class Agenda extends AgendaBase {
23729
23854
  prepend([].slice.call(emptyTBody.childNodes), tBody);
23730
23855
  this.wireEventActions();
23731
23856
  for (let s = 0, element = tBody.children; s < element.length; s++) {
23732
- if (element[s].getAttribute('aria-rowindex') === topElement.getAttribute('aria-colindex')) {
23857
+ if (element[s].getAttribute('data-row-index') === topElement.getAttribute('data-column-index')) {
23733
23858
  const scrollToValue = element[s].offsetTop -
23734
23859
  this.element.querySelector('.e-agenda-item').offsetHeight;
23735
23860
  target.scrollTop = scrollToValue;
@@ -24429,6 +24554,20 @@ class TimelineViews extends VerticalView {
24429
24554
  this.timelineAppointment.renderAppointments();
24430
24555
  this.parent.notify(eventsLoaded, {});
24431
24556
  }
24557
+ getAdjustedDate(date) {
24558
+ if (!this.parent.activeViewOptions.timeScale.enable) {
24559
+ return new Date(date.setHours(0, 0, 0, 0));
24560
+ }
24561
+ else {
24562
+ const timeSlots = this.colLevels[this.colLevels.length - 1];
24563
+ for (let i = 0; i < timeSlots.length; i++) {
24564
+ if (timeSlots[i].date.getTime() > date.getTime()) {
24565
+ return timeSlots[i - 1].date;
24566
+ }
24567
+ }
24568
+ }
24569
+ return null;
24570
+ }
24432
24571
  destroy() {
24433
24572
  if (!this.parent || this.parent && this.parent.isDestroyed) {
24434
24573
  return;
@@ -24569,6 +24708,15 @@ class TimelineMonth extends Month {
24569
24708
  this.colLevels = colLevels;
24570
24709
  return colLevels;
24571
24710
  }
24711
+ getAdjustedDate(startTime) {
24712
+ const timeSlots = this.colLevels[this.colLevels.length - 1];
24713
+ for (let i = 0; i < timeSlots.length; i++) {
24714
+ if (timeSlots[i].date.getTime() > startTime.getTime()) {
24715
+ return timeSlots[i - 1].date;
24716
+ }
24717
+ }
24718
+ return null;
24719
+ }
24572
24720
  destroy() {
24573
24721
  if (!this.parent || this.parent && this.parent.isDestroyed) {
24574
24722
  return;
@@ -24838,6 +24986,9 @@ class TimelineYear extends Year {
24838
24986
  else {
24839
24987
  addClass([td], OTHERMONTH_CLASS);
24840
24988
  }
24989
+ if (td.classList.contains(OTHERMONTH_CLASS)) {
24990
+ continue;
24991
+ }
24841
24992
  td.appendChild(dateHeader);
24842
24993
  if (isDateAvail) {
24843
24994
  td.setAttribute('data-date', date.getTime().toString());
@@ -25014,6 +25165,10 @@ class ICalendarExport {
25014
25165
  this.parent = parent;
25015
25166
  }
25016
25167
  initializeCalendarExport(fileName, customData) {
25168
+ const icsString = this.getCalendarString(fileName, customData);
25169
+ this.download(icsString, fileName);
25170
+ }
25171
+ getCalendarString(fileName, customData) {
25017
25172
  let eventsData = (customData) ? customData :
25018
25173
  extend([], this.parent.eventsData, null, true);
25019
25174
  eventsData = this.parent.eventBase.sortByTime(eventsData);
@@ -25023,7 +25178,7 @@ class ICalendarExport {
25023
25178
  const timeZone = this.parent.timezone || this.parent.tzModule.getLocalTimezoneName();
25024
25179
  const fields = this.parent.eventFields;
25025
25180
  eventsData.forEach((eventObj) => {
25026
- let uId = this.parent.eventBase.generateGuid();
25181
+ let uId = eventObj[fields.id] || eventObj.Guid || this.parent.eventBase.generateGuid();
25027
25182
  const editedExDate = [];
25028
25183
  if (eventObj[fields.recurrenceID]) {
25029
25184
  const filter = this.filterEvents(filterCollection, fields.id, eventObj[fields.recurrenceID]);
@@ -25096,7 +25251,7 @@ class ICalendarExport {
25096
25251
  'X-WR-TIMEZONE:' + timeZone
25097
25252
  ].join(SEPARATOR);
25098
25253
  const icsString = iCalendar + SEPARATOR + iCalendarEvents.join(SEPARATOR) + SEPARATOR + 'END:VCALENDAR';
25099
- this.download(icsString, fileName);
25254
+ return icsString;
25100
25255
  }
25101
25256
  customFieldFilter(eventObj, fields) {
25102
25257
  const defaultFields = Object.keys(fields).map((key) => fields[key]);
@@ -25222,8 +25377,16 @@ class ICalendarImport {
25222
25377
  break;
25223
25378
  case 'UID':
25224
25379
  curEvent[uId] = value;
25225
- curEvent[fields.id] = typeof (id) === 'string' ? id + count.toString() : id + count;
25226
- count++;
25380
+ if (typeof (id) == 'number') {
25381
+ curEvent[fields.id] = parseInt(value, 10);
25382
+ if (isNaN(curEvent[fields.id])) {
25383
+ curEvent[fields.id] = id + count;
25384
+ count++;
25385
+ }
25386
+ }
25387
+ else {
25388
+ curEvent[fields.id] = value;
25389
+ }
25227
25390
  break;
25228
25391
  case 'SUMMARY':
25229
25392
  curEvent[fields.subject] = value;
@@ -25259,6 +25422,10 @@ class ICalendarImport {
25259
25422
  const appoint = [];
25260
25423
  const uId = 'UID';
25261
25424
  const fields = this.parent.eventFields;
25425
+ let appointmentIds = [];
25426
+ this.parent.eventsData.forEach((eventObj) => {
25427
+ appointmentIds.push(eventObj[fields.id]);
25428
+ });
25262
25429
  app.forEach((eventObj) => {
25263
25430
  let parentObj;
25264
25431
  let id;
@@ -25267,24 +25434,26 @@ class ICalendarImport {
25267
25434
  parentObj = eventObj;
25268
25435
  id = eventObj[fields.id];
25269
25436
  }
25270
- const data = app.filter((data) => data.UID === eventObj[uId]);
25271
- if (data.length > 1 && isNullOrUndefined(eventObj[fields.recurrenceID])) {
25272
- for (let i = 0; i < data.length; i++) {
25273
- // eslint-disable-next-line no-prototype-builtins
25274
- if (data[i].hasOwnProperty(fields.recurrenceID)) {
25275
- const exdate = data[i][fields.recurrenceID];
25276
- data[i][fields.recurrenceID] = id;
25277
- data[i][fields.recurrenceException] = null;
25278
- parentObj[fields.recurrenceException] = (isNullOrUndefined(parentObj[fields.recurrenceException])) ?
25279
- exdate : parentObj[fields.recurrenceException] + ',' + exdate;
25280
- appoint.push(data[i]);
25437
+ if (appointmentIds.indexOf(eventObj[fields.id]) < 0) {
25438
+ const data = app.filter((data) => data.UID === eventObj[uId]);
25439
+ if (data.length > 1 && isNullOrUndefined(eventObj[fields.recurrenceID])) {
25440
+ for (let i = 0; i < data.length; i++) {
25441
+ // eslint-disable-next-line no-prototype-builtins
25442
+ if (data[i].hasOwnProperty(fields.recurrenceID)) {
25443
+ const exdate = data[i][fields.recurrenceID];
25444
+ data[i][fields.recurrenceID] = id;
25445
+ data[i][fields.recurrenceException] = null;
25446
+ parentObj[fields.recurrenceException] = (isNullOrUndefined(parentObj[fields.recurrenceException])) ?
25447
+ exdate : parentObj[fields.recurrenceException] + ',' + exdate;
25448
+ appoint.push(data[i]);
25449
+ }
25281
25450
  }
25451
+ appoint.push(parentObj);
25452
+ // eslint-disable-next-line no-prototype-builtins
25453
+ }
25454
+ else if (!eventObj.hasOwnProperty(fields.recurrenceID)) {
25455
+ appoint.push(eventObj);
25282
25456
  }
25283
- appoint.push(parentObj);
25284
- // eslint-disable-next-line no-prototype-builtins
25285
- }
25286
- else if (!eventObj.hasOwnProperty(fields.recurrenceID)) {
25287
- appoint.push(eventObj);
25288
25457
  }
25289
25458
  });
25290
25459
  return appoint;
@@ -25342,6 +25511,10 @@ class ExcelExport {
25342
25511
  const exportName = excelExportOptions.fileName || 'Schedule';
25343
25512
  const exportType = excelExportOptions.exportType || 'xlsx';
25344
25513
  const isIncludeOccurrences = excelExportOptions.includeOccurrences || false;
25514
+ let separator;
25515
+ if (!isNullOrUndefined(excelExportOptions.separator) && excelExportOptions.separator !== ',') {
25516
+ separator = excelExportOptions.separator;
25517
+ }
25345
25518
  let eventCollection;
25346
25519
  if (excelExportOptions.customData) {
25347
25520
  eventCollection = !isIncludeOccurrences ? excelExportOptions.customData :
@@ -25350,9 +25523,9 @@ class ExcelExport {
25350
25523
  else {
25351
25524
  eventCollection = !isIncludeOccurrences ? this.parent.eventsData : this.parent.eventsProcessed;
25352
25525
  }
25353
- this.processWorkbook(exportColumns, exportName, exportType, eventCollection);
25526
+ this.processWorkbook(exportColumns, exportName, exportType, eventCollection, separator);
25354
25527
  }
25355
- processWorkbook(fields, name, type, eventCollection) {
25528
+ processWorkbook(fields, name, type, eventCollection, separator) {
25356
25529
  const columns = [];
25357
25530
  const rows = [];
25358
25531
  const columnHeader = [];
@@ -25373,7 +25546,7 @@ class ExcelExport {
25373
25546
  rows.push({ index: i + 2, cells: columnData });
25374
25547
  });
25375
25548
  const workSheet = [{ columns: columns, rows: rows }];
25376
- const book = new Workbook({ worksheets: workSheet }, type, this.parent.locale);
25549
+ const book = new Workbook({ worksheets: workSheet }, type, this.parent.locale, undefined, separator);
25377
25550
  book.save(name + '.' + type);
25378
25551
  }
25379
25552
  getExportColumns(exportOptions) {