@syncfusion/ej2-schedule 22.2.8 → 22.2.12

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.
@@ -389,6 +389,7 @@ function getScrollBarWidth() {
389
389
  * Method to reset scrollbar width
390
390
  *
391
391
  * @private
392
+ * @returns {void}
392
393
  */
393
394
  function resetScrollbarWidth() {
394
395
  const zoomPixelRatio = window.devicePixelRatio || window.screen.availWidth / document.documentElement.clientWidth;
@@ -2063,7 +2064,12 @@ class KeyboardInteraction {
2063
2064
  return;
2064
2065
  }
2065
2066
  const queryStr = '.' + WORK_CELLS_CLASS + ',.' + ALLDAY_CELLS_CLASS + ',.' + HEADER_CELLS_CLASS;
2066
- const target = closest(e.target, queryStr);
2067
+ let target = closest(e.target, queryStr);
2068
+ const selectedCells = this.parent.getSelectedCells();
2069
+ if (this.parent.activeViewOptions.group.resources.length > 0 && selectedCells.length > 0 &&
2070
+ selectedCells[0].getAttribute('data-group-index') !== target.getAttribute('data-group-index')) {
2071
+ target = selectedCells[selectedCells.length - 1];
2072
+ }
2067
2073
  if (this.parent.currentView === 'TimelineYear' && target.classList.contains(OTHERMONTH_CLASS)) {
2068
2074
  return;
2069
2075
  }
@@ -2072,7 +2078,6 @@ class KeyboardInteraction {
2072
2078
  if (this.parent.eventWindow) {
2073
2079
  this.parent.eventWindow.convertToEventData(this.parent.activeCellsData, cellData);
2074
2080
  }
2075
- const selectedCells = this.parent.getSelectedCells();
2076
2081
  const args = {
2077
2082
  data: cellData, element: this.parent.activeCellsData.element, event: e,
2078
2083
  requestType: cellSelect, showQuickPopup: false
@@ -3714,11 +3719,10 @@ function getMonthSummary(ruleObject, cldrObj, localeObj) {
3714
3719
  * @param {number} maximumCount Accepts the maximum number count to generate date collections
3715
3720
  * @param {Date} viewDate Accepts the current date instead of start date
3716
3721
  * @param {CalendarType} calendarMode Accepts the calendar type
3717
- * @param {string} oldTimezone Accepts the timezone name
3718
3722
  * @param {string} newTimezone Accepts the timezone name
3719
3723
  * @returns {number[]} Returns the collection of dates
3720
3724
  */
3721
- function generate(startDate, rule, excludeDate, startDayOfWeek, maximumCount = MAXOCCURRENCE, viewDate = null, calendarMode = 'Gregorian', oldTimezone = null, newTimezone = null) {
3725
+ function generate(startDate, rule, excludeDate, startDayOfWeek, maximumCount = MAXOCCURRENCE, viewDate = null, calendarMode = 'Gregorian', newTimezone = null) {
3722
3726
  const ruleObject = extractObjectFromRule(rule);
3723
3727
  let cacheDate;
3724
3728
  calendarUtil = getCalendarUtil(calendarMode);
@@ -3729,8 +3733,8 @@ function generate(startDate, rule, excludeDate, startDayOfWeek, maximumCount = M
3729
3733
  const tz = new Timezone();
3730
3734
  tempDate.forEach((content) => {
3731
3735
  let parsedDate = getDateFromRecurrenceDateString(content);
3732
- if (oldTimezone && newTimezone) {
3733
- parsedDate = tz.convert(new Date(parsedDate.getTime()), oldTimezone, newTimezone);
3736
+ if (newTimezone) {
3737
+ parsedDate = tz.add(new Date(parsedDate.getTime()), newTimezone);
3734
3738
  }
3735
3739
  tempExcludeDate.push(new Date(parsedDate.getTime()).setHours(0, 0, 0, 0));
3736
3740
  });
@@ -5287,12 +5291,12 @@ class EventBase {
5287
5291
  }
5288
5292
  if (!isNullOrUndefined(event[fields.recurrenceRule]) && isNullOrUndefined(event[fields.recurrenceID]) &&
5289
5293
  !(this.parent.crudModule && this.parent.crudModule.crudObj.isCrudAction)) {
5290
- processed = processed.concat(this.generateOccurrence(event, null, oldTimezone, true));
5294
+ processed = processed.concat(this.generateOccurrence(event, null, true));
5291
5295
  }
5292
5296
  else {
5293
5297
  if (this.parent.crudModule && this.parent.crudModule.crudObj.isCrudAction) {
5294
5298
  if (!isNullOrUndefined(event[fields.recurrenceRule]) && isNullOrUndefined(event[fields.recurrenceID])) {
5295
- const recurrenceEvent = this.generateOccurrence(event, null, oldTimezone, true);
5299
+ const recurrenceEvent = this.generateOccurrence(event, null, true);
5296
5300
  for (const occurrence of recurrenceEvent) {
5297
5301
  const app = this.parent.eventsProcessed.filter((data) => data[fields.startTime].getTime() - occurrence[fields.startTime].getTime() === 0 &&
5298
5302
  data[fields.id] === occurrence[fields.id]);
@@ -6067,7 +6071,7 @@ class EventBase {
6067
6071
  }
6068
6072
  this.parent.activeEventData = { event: eventObject, element: target };
6069
6073
  }
6070
- generateOccurrence(event, viewDate, oldTimezone, isMaxCount) {
6074
+ generateOccurrence(event, viewDate, isMaxCount) {
6071
6075
  const startDate = event[this.parent.eventFields.startTime];
6072
6076
  const endDate = event[this.parent.eventFields.endTime];
6073
6077
  const eventRule = event[this.parent.eventFields.recurrenceRule];
@@ -6082,7 +6086,7 @@ class EventBase {
6082
6086
  const newTimezone = this.parent.timezone || this.parent.tzModule.getLocalTimezoneName();
6083
6087
  const firstDay = this.parent.activeViewOptions.firstDayOfWeek;
6084
6088
  const calendarMode = this.parent.calendarMode;
6085
- const dates = generate(startDate, eventRule, exception, firstDay, maxCount, viewDate, calendarMode, oldTimezone, newTimezone);
6089
+ const dates = generate(startDate, eventRule, exception, firstDay, maxCount, viewDate, calendarMode, newTimezone);
6086
6090
  if (this.parent.currentView === 'Agenda' && eventRule.indexOf('COUNT') === -1 && eventRule.indexOf('UNTIL') === -1) {
6087
6091
  if (isNullOrUndefined(event.generatedDates)) {
6088
6092
  event.generatedDates = { start: new Date(dates[0]), end: new Date(dates[dates.length - 1]) };
@@ -8876,7 +8880,7 @@ class QuickPopups {
8876
8880
  this.renderQuickDialog();
8877
8881
  }
8878
8882
  renderQuickPopup() {
8879
- const quickPopupWrapper = createElement('div', { className: POPUP_WRAPPER_CLASS + ' e-popup-close' });
8883
+ const quickPopupWrapper = createElement('div', { className: POPUP_WRAPPER_CLASS + ' e-popup-close', attrs: { role: 'dialog' } });
8880
8884
  if (this.parent.isAdaptive) {
8881
8885
  document.body.appendChild(quickPopupWrapper);
8882
8886
  addClass([quickPopupWrapper], DEVICE_CLASS);
@@ -9292,6 +9296,7 @@ class QuickPopups {
9292
9296
  quickCellPopup.appendChild(this.getPopupHeader('Cell', temp));
9293
9297
  quickCellPopup.appendChild(this.getPopupContent('Cell', args, temp));
9294
9298
  quickCellPopup.appendChild(this.getPopupFooter('Cell', temp));
9299
+ this.quickPopup.element.setAttribute('aria-label', this.l10n.getConstant('newEvent'));
9295
9300
  const subjectElement = quickCellPopup.querySelector('.' + SUBJECT_CLASS);
9296
9301
  if (subjectElement) {
9297
9302
  Input.createInput({ element: subjectElement, properties: { placeholder: this.l10n.getConstant('addTitle') } });
@@ -9363,6 +9368,7 @@ class QuickPopups {
9363
9368
  quickEventPopup.appendChild(this.getPopupHeader('Event', eventData));
9364
9369
  quickEventPopup.appendChild(this.getPopupContent('Event', events, eventData));
9365
9370
  quickEventPopup.appendChild(this.getPopupFooter('Event', eventData));
9371
+ this.quickPopup.element.setAttribute('aria-label', this.l10n.getConstant('editEvent'));
9366
9372
  const readonly = this.parent.activeViewOptions.readonly || eventData[this.parent.eventFields.isReadonly];
9367
9373
  const editAction = !this.parent.eventSettings.allowEditing || readonly;
9368
9374
  const deleteAction = !this.parent.eventSettings.allowDeleting || readonly;
@@ -14273,7 +14279,8 @@ class Crud {
14273
14279
  }
14274
14280
  const updateEvents = (eventData instanceof Array) ? eventData : [eventData];
14275
14281
  const args = {
14276
- requestType: action === 'EditOccurrence' ? 'eventChange' : 'eventRemove', cancel: false,
14282
+ requestType: action === 'EditOccurrence' ? 'eventChange' : 'eventRemove',
14283
+ cancel: false,
14277
14284
  addedRecords: [], changedRecords: updateEvents, deletedRecords: []
14278
14285
  };
14279
14286
  args.data = occurrenceData;
@@ -14556,6 +14563,10 @@ class Crud {
14556
14563
  return parentEvent;
14557
14564
  }
14558
14565
  excludeDateCheck(eventStartTime, exceptionDateList) {
14566
+ const timezone = this.parent.timezone || this.parent.tzModule.getLocalTimezoneName();
14567
+ if (timezone) {
14568
+ eventStartTime = this.parent.tzModule.remove(new Date(+eventStartTime.getTime()), timezone);
14569
+ }
14559
14570
  const exDate = getRecurrenceStringFromDate(eventStartTime);
14560
14571
  if (!isNullOrUndefined(exceptionDateList)) {
14561
14572
  if (exceptionDateList.indexOf(exDate) === -1) {
@@ -25582,8 +25593,11 @@ class TimelineViews extends VerticalView {
25582
25593
  let diffInMinutes = ((date.getHours() - startHour.getHours()) * 60) + (date.getMinutes() - startHour.getMinutes());
25583
25594
  if (!isNullOrUndefined(currentDateIndex)) {
25584
25595
  if (currentDateIndex[0] !== 0) {
25585
- if (this.parent.activeView.colLevels[0] && this.parent.activeView.colLevels[0][0].colSpan) {
25586
- diffInDates = currentDateIndex[0] * this.parent.activeView.colLevels[0][0].colSpan * this.getWorkCellWidth();
25596
+ const index = this.parent.activeView.colLevels.findIndex((level) => level[0].type === 'dateHeader');
25597
+ if (this.parent.activeView.colLevels[parseInt(index.toString(), 10)] &&
25598
+ this.parent.activeView.colLevels[parseInt(index.toString(), 10)][0].colSpan) {
25599
+ diffInDates = currentDateIndex[0] * this.parent.activeView.colLevels[parseInt(index.toString(), 10)][0].colSpan *
25600
+ this.getWorkCellWidth();
25587
25601
  }
25588
25602
  else {
25589
25603
  const endHour = this.getEndHour();
@@ -26484,99 +26498,144 @@ class ICalendarImport {
26484
26498
  }
26485
26499
  }
26486
26500
  iCalendarParser(iCalString) {
26487
- const fields = this.parent.eventFields;
26488
- const events = [];
26489
- const uId = 'UID';
26490
- const calArray = iCalString.replace(new RegExp('\\r', 'g'), '').split('\n');
26491
- let isEvent = false;
26492
- let curEvent;
26493
- // eslint-disable-next-line prefer-const
26494
- let id = this.parent.eventBase.getEventMaxID();
26495
- let count = 0;
26496
- calArray.forEach((element) => {
26497
- let index;
26498
- let type;
26499
- let value;
26500
- if (!isEvent && element === 'BEGIN:VEVENT') {
26501
- isEvent = true;
26502
- curEvent = {};
26503
- }
26504
- if (isEvent && element === 'END:VEVENT') {
26505
- isEvent = false;
26506
- events.push(curEvent);
26507
- curEvent = null;
26508
- }
26509
- if (isEvent) {
26510
- index = element.indexOf(':');
26511
- type = element.substr(0, index).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
26512
- value = element.substr(index + 1, element.length - (index + 1)).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
26513
- if (element.indexOf('SUMMARY') !== -1) {
26514
- type = 'SUMMARY';
26515
- }
26516
- if (element.indexOf('DTSTART') !== -1) {
26517
- curEvent[fields.startTime] = this.dateParsing(element);
26518
- curEvent[fields.isAllDay] = this.allDay;
26519
- this.allDay = false;
26520
- }
26521
- else if (element.indexOf('DTEND') !== -1) {
26522
- curEvent[fields.endTime] = this.dateParsing(element);
26523
- }
26524
- else if (element.indexOf('EXDATE') !== -1) {
26525
- value = getRecurrenceStringFromDate(this.dateParsing(element));
26526
- curEvent[fields.recurrenceException] = (isNullOrUndefined(curEvent[fields.recurrenceException])) ?
26527
- value : curEvent[fields.recurrenceException] + ',' + value;
26528
- }
26529
- else if (element.indexOf('RECURRENCE-ID') !== -1) {
26530
- value = getRecurrenceStringFromDate(this.dateParsing(element));
26531
- curEvent[fields.recurrenceException] = value;
26532
- curEvent[fields.recurrenceID] = value;
26501
+ let iCalData = {
26502
+ isEvent: false,
26503
+ curEvent: null,
26504
+ id: this.parent.eventBase.getEventMaxID(),
26505
+ count: 0,
26506
+ events: [],
26507
+ key: null
26508
+ };
26509
+ const iStringLength = iCalString.length;
26510
+ let lastPosition = iCalString.search(/[^ \t]/);
26511
+ let position = lastPosition;
26512
+ let iString;
26513
+ let newlineOffset;
26514
+ do {
26515
+ position = iCalString.indexOf('\n', lastPosition) + 1;
26516
+ if (position === 0) {
26517
+ position = iStringLength;
26518
+ newlineOffset = 0;
26519
+ }
26520
+ else if (position > 1 && iCalString[position - 2] === '\r') {
26521
+ newlineOffset = 2;
26522
+ }
26523
+ else {
26524
+ newlineOffset = 1;
26525
+ }
26526
+ // eslint-disable-next-line security/detect-object-injection
26527
+ const firstChar = iCalString[lastPosition];
26528
+ if (firstChar === ' ' || firstChar === '\n' || firstChar === '\t') {
26529
+ iString += iCalString.slice(lastPosition + 1, position - newlineOffset);
26530
+ }
26531
+ else {
26532
+ if (iString) {
26533
+ iCalData = this.updateEventData(iString, iCalData);
26533
26534
  }
26534
- else {
26535
- switch (type) {
26536
- case 'BEGIN':
26537
- break;
26538
- case 'UID':
26539
- curEvent[`${uId}`] = value;
26540
- if (typeof (id) == 'number') {
26541
- curEvent[fields.id] = parseInt(value, 10);
26542
- if (isNaN(curEvent[fields.id])) {
26543
- curEvent[fields.id] = id + count;
26544
- count++;
26545
- }
26546
- }
26547
- else {
26548
- curEvent[fields.id] = value;
26549
- }
26550
- break;
26551
- case 'SUMMARY':
26552
- curEvent[fields.subject] = value;
26553
- break;
26554
- case 'LOCATION':
26555
- curEvent[fields.location] = value;
26556
- break;
26557
- case 'DESCRIPTION':
26558
- curEvent[fields.description] = value;
26559
- break;
26560
- case 'ISREADONLY':
26561
- curEvent[fields.isReadonly] = (value.indexOf('true') > -1);
26562
- break;
26563
- case 'RRULE':
26564
- curEvent[fields.recurrenceRule] = value;
26565
- break;
26566
- default:
26567
- if (this.parent.resourceCollection.length > 0) {
26568
- const resData = this.parent.resourceCollection.filter((data) => data.field === type);
26569
- curEvent[`${type}`] = (resData.length > 0 && (typeof (resData[0].dataSource[0][resData[0].idField]) == 'number')) ? parseInt(value, 10) : value;
26570
- }
26571
- else {
26572
- curEvent[`${type}`] = value;
26535
+ iString = iCalString.slice(lastPosition, position - newlineOffset);
26536
+ }
26537
+ lastPosition = position;
26538
+ } while (position !== iStringLength);
26539
+ iString = iString.trim();
26540
+ if (iString.length) {
26541
+ iCalData = this.updateEventData(iString, iCalData);
26542
+ }
26543
+ const app = extend([], iCalData.events, null, true);
26544
+ this.parent.addEvent(this.processOccurrence(app, iCalData.id));
26545
+ }
26546
+ updateEventData(iString, iCalData) {
26547
+ const fields = this.parent.eventFields;
26548
+ const SEPARATOR = '\r\n';
26549
+ const id = iCalData.id;
26550
+ const events = iCalData.events;
26551
+ let isEvent = iCalData.isEvent;
26552
+ let count = iCalData.count;
26553
+ let curEvent = iCalData.curEvent;
26554
+ let key = iCalData.key;
26555
+ if (!isEvent && iString === 'BEGIN:VEVENT') {
26556
+ isEvent = true;
26557
+ curEvent = {};
26558
+ }
26559
+ if (isEvent && iString === 'END:VEVENT') {
26560
+ isEvent = false;
26561
+ events.push(curEvent);
26562
+ curEvent = null;
26563
+ }
26564
+ if (isEvent) {
26565
+ const index = iString.indexOf(':');
26566
+ let type = iString.substring(0, index).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
26567
+ let value = iString.substring(index + 1, iString.length).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
26568
+ if (iString.indexOf('SUMMARY') !== -1) {
26569
+ type = 'SUMMARY';
26570
+ }
26571
+ if (iString.indexOf('DTSTART') !== -1) {
26572
+ curEvent[fields.startTime] = this.dateParsing(iString);
26573
+ curEvent[fields.isAllDay] = this.allDay;
26574
+ this.allDay = false;
26575
+ }
26576
+ else if (iString.indexOf('DTEND') !== -1) {
26577
+ curEvent[fields.endTime] = this.dateParsing(iString);
26578
+ }
26579
+ else if (iString.indexOf('EXDATE') !== -1) {
26580
+ value = getRecurrenceStringFromDate(this.dateParsing(iString));
26581
+ curEvent[fields.recurrenceException] = isNullOrUndefined(curEvent[fields.recurrenceException]) ?
26582
+ value : curEvent[fields.recurrenceException] + ',' + value;
26583
+ }
26584
+ else if (iString.indexOf('RECURRENCE-ID') !== -1) {
26585
+ value = getRecurrenceStringFromDate(this.dateParsing(iString));
26586
+ curEvent[fields.recurrenceException] = value;
26587
+ curEvent[fields.recurrenceID] = value;
26588
+ }
26589
+ else {
26590
+ key = type || key;
26591
+ switch (key) {
26592
+ case 'BEGIN':
26593
+ break;
26594
+ case 'UID':
26595
+ curEvent[`${type}`] = value;
26596
+ if (typeof (id) == 'number') {
26597
+ curEvent[fields.id] = parseInt(value, 10);
26598
+ if (isNaN(curEvent[fields.id])) {
26599
+ curEvent[fields.id] = id + count;
26600
+ count++;
26573
26601
  }
26574
- }
26602
+ }
26603
+ else {
26604
+ curEvent[fields.id] = value;
26605
+ }
26606
+ break;
26607
+ case 'SUMMARY':
26608
+ curEvent[fields.subject] = this.getFormattedString(value);
26609
+ break;
26610
+ case 'LOCATION':
26611
+ curEvent[fields.location] = this.getFormattedString(value);
26612
+ break;
26613
+ case 'DESCRIPTION':
26614
+ if (curEvent[fields.description]) {
26615
+ curEvent[fields.description] = this.getFormattedString(curEvent[fields.description] + SEPARATOR + value);
26616
+ }
26617
+ else {
26618
+ curEvent[fields.description] = this.getFormattedString(value);
26619
+ }
26620
+ break;
26621
+ case 'ISREADONLY':
26622
+ curEvent[fields.isReadonly] = (value.indexOf('true') > -1);
26623
+ break;
26624
+ case 'RRULE':
26625
+ curEvent[fields.recurrenceRule] = value;
26626
+ break;
26627
+ default:
26628
+ if (this.parent.resourceCollection.length > 0) {
26629
+ const resData = this.parent.resourceCollection.filter((data) => data.field === type);
26630
+ curEvent[`${type}`] = (resData.length > 0 && (typeof (resData[0].dataSource[0][resData[0].idField]) == 'number')) ? parseInt(value, 10) : value;
26631
+ }
26632
+ else {
26633
+ curEvent[`${type}`] = value;
26634
+ }
26575
26635
  }
26576
26636
  }
26577
- });
26578
- const app = extend([], events, null, true);
26579
- this.parent.addEvent(this.processOccurrence(app, id));
26637
+ }
26638
+ return { isEvent, curEvent, id, count, events, key };
26580
26639
  }
26581
26640
  processOccurrence(app, maxId) {
26582
26641
  const appoint = [];
@@ -26640,7 +26699,7 @@ class ICalendarImport {
26640
26699
  }
26641
26700
  return parentException + ',' + occurrenceException;
26642
26701
  }
26643
- getDateString(value) {
26702
+ getFormattedString(value) {
26644
26703
  value = value || '';
26645
26704
  // eslint-disable-next-line no-useless-escape
26646
26705
  return (value.replace(/\\\,/g, ',').replace(/\\\;/g, ';').replace(/\\[nN]/g, '\n').replace(/\\\\/g, '\\'));
@@ -26648,7 +26707,7 @@ class ICalendarImport {
26648
26707
  dateParsing(element) {
26649
26708
  const split = element.split(':');
26650
26709
  const value = split[split.length - 1];
26651
- let newDate = new Date(this.getDateString(value));
26710
+ let newDate = new Date(this.getFormattedString(value));
26652
26711
  if (element && (element.indexOf('VALUE=DATE') > -1 || element.indexOf('RECURRENCE-ID;TZID') > -1)) {
26653
26712
  const data = /^(\d{4})(\d{2})(\d{2})$/.exec(value);
26654
26713
  if (data !== null) {