@syncfusion/ej2-schedule 22.2.11 → 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]) };
@@ -14275,7 +14279,8 @@ class Crud {
14275
14279
  }
14276
14280
  const updateEvents = (eventData instanceof Array) ? eventData : [eventData];
14277
14281
  const args = {
14278
- requestType: action === 'EditOccurrence' ? 'eventChange' : 'eventRemove', cancel: false,
14282
+ requestType: action === 'EditOccurrence' ? 'eventChange' : 'eventRemove',
14283
+ cancel: false,
14279
14284
  addedRecords: [], changedRecords: updateEvents, deletedRecords: []
14280
14285
  };
14281
14286
  args.data = occurrenceData;
@@ -14558,6 +14563,10 @@ class Crud {
14558
14563
  return parentEvent;
14559
14564
  }
14560
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
+ }
14561
14570
  const exDate = getRecurrenceStringFromDate(eventStartTime);
14562
14571
  if (!isNullOrUndefined(exceptionDateList)) {
14563
14572
  if (exceptionDateList.indexOf(exDate) === -1) {
@@ -25584,8 +25593,11 @@ class TimelineViews extends VerticalView {
25584
25593
  let diffInMinutes = ((date.getHours() - startHour.getHours()) * 60) + (date.getMinutes() - startHour.getMinutes());
25585
25594
  if (!isNullOrUndefined(currentDateIndex)) {
25586
25595
  if (currentDateIndex[0] !== 0) {
25587
- if (this.parent.activeView.colLevels[0] && this.parent.activeView.colLevels[0][0].colSpan) {
25588
- 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();
25589
25601
  }
25590
25602
  else {
25591
25603
  const endHour = this.getEndHour();
@@ -26486,115 +26498,144 @@ class ICalendarImport {
26486
26498
  }
26487
26499
  }
26488
26500
  iCalendarParser(iCalString) {
26489
- const fields = this.parent.eventFields;
26490
- const events = [];
26491
- const uId = 'UID';
26492
- const calArray = iCalString.replace(new RegExp('\\r', 'g'), '').split('\n');
26493
- const descriptionIndex = calArray.findIndex((line) => line.startsWith('DESCRIPTION:'));
26494
- if (descriptionIndex !== -1) {
26495
- let description = calArray[descriptionIndex].substring('DESCRIPTION:'.length);
26496
- for (let i = descriptionIndex + 1; i < calArray.length; i++) {
26497
- if (calArray[i].startsWith(' ') || !(/[A-Z]{3}:/.test(calArray[i]))) {
26498
- description += calArray[i];
26499
- }
26500
- else {
26501
- calArray[descriptionIndex] = 'DESCRIPTION:' + description;
26502
- break;
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);
26503
26534
  }
26535
+ iString = iCalString.slice(lastPosition, position - newlineOffset);
26504
26536
  }
26537
+ lastPosition = position;
26538
+ } while (position !== iStringLength);
26539
+ iString = iString.trim();
26540
+ if (iString.length) {
26541
+ iCalData = this.updateEventData(iString, iCalData);
26505
26542
  }
26506
- let isEvent = false;
26507
- let curEvent;
26508
- // eslint-disable-next-line prefer-const
26509
- let id = this.parent.eventBase.getEventMaxID();
26510
- let count = 0;
26511
- calArray.forEach((element) => {
26512
- let index;
26513
- let type;
26514
- let value;
26515
- if (!isEvent && element === 'BEGIN:VEVENT') {
26516
- isEvent = true;
26517
- curEvent = {};
26518
- }
26519
- if (isEvent && element === 'END:VEVENT') {
26520
- isEvent = false;
26521
- events.push(curEvent);
26522
- curEvent = null;
26523
- }
26524
- if (isEvent) {
26525
- index = element.indexOf(':');
26526
- type = element.substr(0, index).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
26527
- value = element.substr(index + 1, element.length - (index + 1)).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
26528
- if (element.indexOf('SUMMARY') !== -1) {
26529
- type = 'SUMMARY';
26530
- }
26531
- if (element.indexOf('DTSTART') !== -1) {
26532
- curEvent[fields.startTime] = this.dateParsing(element);
26533
- curEvent[fields.isAllDay] = this.allDay;
26534
- this.allDay = false;
26535
- }
26536
- else if (element.indexOf('DTEND') !== -1) {
26537
- curEvent[fields.endTime] = this.dateParsing(element);
26538
- }
26539
- else if (element.indexOf('EXDATE') !== -1) {
26540
- value = getRecurrenceStringFromDate(this.dateParsing(element));
26541
- curEvent[fields.recurrenceException] = (isNullOrUndefined(curEvent[fields.recurrenceException])) ?
26542
- value : curEvent[fields.recurrenceException] + ',' + value;
26543
- }
26544
- else if (element.indexOf('RECURRENCE-ID') !== -1) {
26545
- value = getRecurrenceStringFromDate(this.dateParsing(element));
26546
- curEvent[fields.recurrenceException] = value;
26547
- curEvent[fields.recurrenceID] = value;
26548
- }
26549
- else {
26550
- switch (type) {
26551
- case 'BEGIN':
26552
- break;
26553
- case 'UID':
26554
- curEvent[`${uId}`] = value;
26555
- if (typeof (id) == 'number') {
26556
- curEvent[fields.id] = parseInt(value, 10);
26557
- if (isNaN(curEvent[fields.id])) {
26558
- curEvent[fields.id] = id + count;
26559
- count++;
26560
- }
26561
- }
26562
- else {
26563
- curEvent[fields.id] = value;
26564
- }
26565
- break;
26566
- case 'SUMMARY':
26567
- curEvent[fields.subject] = value;
26568
- break;
26569
- case 'LOCATION':
26570
- curEvent[fields.location] = value;
26571
- break;
26572
- case 'DESCRIPTION':
26573
- if (!(curEvent[fields.description])) {
26574
- curEvent[fields.description] = value.replace(/\\,/g, ',')
26575
- .replace(/\\n/g, '\n');
26576
- }
26577
- break;
26578
- case 'ISREADONLY':
26579
- curEvent[fields.isReadonly] = (value.indexOf('true') > -1);
26580
- break;
26581
- case 'RRULE':
26582
- curEvent[fields.recurrenceRule] = value;
26583
- break;
26584
- default:
26585
- if (this.parent.resourceCollection.length > 0) {
26586
- const resData = this.parent.resourceCollection.filter((data) => data.field === type);
26587
- curEvent[`${type}`] = (resData.length > 0 && (typeof (resData[0].dataSource[0][resData[0].idField]) == 'number')) ? parseInt(value, 10) : value;
26588
- }
26589
- else {
26590
- curEvent[`${type}`] = value;
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++;
26591
26601
  }
26592
- }
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
+ }
26593
26635
  }
26594
26636
  }
26595
- });
26596
- const app = extend([], events, null, true);
26597
- this.parent.addEvent(this.processOccurrence(app, id));
26637
+ }
26638
+ return { isEvent, curEvent, id, count, events, key };
26598
26639
  }
26599
26640
  processOccurrence(app, maxId) {
26600
26641
  const appoint = [];
@@ -26658,7 +26699,7 @@ class ICalendarImport {
26658
26699
  }
26659
26700
  return parentException + ',' + occurrenceException;
26660
26701
  }
26661
- getDateString(value) {
26702
+ getFormattedString(value) {
26662
26703
  value = value || '';
26663
26704
  // eslint-disable-next-line no-useless-escape
26664
26705
  return (value.replace(/\\\,/g, ',').replace(/\\\;/g, ';').replace(/\\[nN]/g, '\n').replace(/\\\\/g, '\\'));
@@ -26666,7 +26707,7 @@ class ICalendarImport {
26666
26707
  dateParsing(element) {
26667
26708
  const split = element.split(':');
26668
26709
  const value = split[split.length - 1];
26669
- let newDate = new Date(this.getDateString(value));
26710
+ let newDate = new Date(this.getFormattedString(value));
26670
26711
  if (element && (element.indexOf('VALUE=DATE') > -1 || element.indexOf('RECURRENCE-ID;TZID') > -1)) {
26671
26712
  const data = /^(\d{4})(\d{2})(\d{2})$/.exec(value);
26672
26713
  if (data !== null) {