diff --git a/packages/devextreme/js/__internal/ui/calendar/m_calendar.base_view.ts b/packages/devextreme/js/__internal/ui/calendar/m_calendar.base_view.ts index 71e50a036f7..0bf21de761a 100644 --- a/packages/devextreme/js/__internal/ui/calendar/m_calendar.base_view.ts +++ b/packages/devextreme/js/__internal/ui/calendar/m_calendar.base_view.ts @@ -147,24 +147,27 @@ const BaseView = (Widget as any).inherit({ }, _getMultipleRangesText() { - const { ranges } = this.option(); + const { value } = this.option(); + const ranges = coreDateUtils.getRangesByDates(value); if (ranges.length > 2) { // @ts-expect-error const dateRangeCountText = messageLocalization.format('dxCalendar-selectedDateRangeCount', ranges.length); - return `${dateRangeCountText}`; + return dateRangeCountText; } const selectedDatesText = messageLocalization.format('dxCalendar-selectedDates'); - const rangesText = ranges.map((range) => this._getMultipleRangeText(range)).join(', '); + const rangesText = ranges + .map((range) => this._getRangeText(range)) + .join(', '); const result = `${selectedDatesText}: ${rangesText}`; return result; }, - _getMultipleRangeText(range) { + _getRangeText(range) { const [startDate, endDate] = range; const formattedStartDate = dateLocalization.format(startDate, ARIA_LABEL_DATE_FORMAT); diff --git a/packages/devextreme/js/__internal/ui/calendar/m_calendar.multiple.selection.strategy.ts b/packages/devextreme/js/__internal/ui/calendar/m_calendar.multiple.selection.strategy.ts index a4b4c32c8e5..b3d8080569a 100644 --- a/packages/devextreme/js/__internal/ui/calendar/m_calendar.multiple.selection.strategy.ts +++ b/packages/devextreme/js/__internal/ui/calendar/m_calendar.multiple.selection.strategy.ts @@ -1,4 +1,3 @@ -import { DAY_INTERVAL } from './m_calendar.base_view'; import CalendarSelectionStrategy from './m_calendar.selection.strategy'; class CalendarMultiSelectionStrategy extends CalendarSelectionStrategy { @@ -8,12 +7,9 @@ class CalendarMultiSelectionStrategy extends CalendarSelectionStrategy { } getViewOptions() { - const value = this.dateOption('value'); - return { - value, + value: this.dateOption('value'), range: [], - ranges: this._generateRanges(value), selectionMode: 'multiple', onWeekNumberClick: this._shouldHandleWeekNumberClick() ? this._weekNumberClickHandler.bind(this) : null, }; @@ -56,60 +52,6 @@ class CalendarMultiSelectionStrategy extends CalendarSelectionStrategy { this.dateValue(selectedDates, event); } - - _generateRanges(values) { - const datesInMilliseconds = values.map((value) => { - const date = new Date(new Date(value).setHours(0, 0, 0, 0)).getTime(); - - return date; - }); - const sortedDates = datesInMilliseconds.sort((a, b) => a - b); - - const getRange = (date, dates, index) => { - const range = date === dates[index - 1] - ? [date] - : [date, dates[index - 1]]; - - return range.map((value) => new Date(value)); - }; - - const ranges = []; - - let startDate = sortedDates[0]; - - sortedDates.forEach((date, index) => { - if (index === 0) { - return; - } - - const previousDate = sortedDates[index - 1]; - const isNewRange = date - previousDate > DAY_INTERVAL; - - if (isNewRange) { - const range = getRange(startDate, sortedDates, index); - - // @ts-expect-error - ranges.push(range); - - startDate = date; - } - }); - - const range = getRange(startDate, sortedDates, sortedDates.length); - - // @ts-expect-error - ranges.push(range); - - return ranges; - } - - processValueChanged(value, previousValue): void { - const ranges = this._generateRanges(value); - - this._updateViewsOption('ranges', ranges); - - super.processValueChanged(value, previousValue); - } } export default CalendarMultiSelectionStrategy; diff --git a/packages/devextreme/js/core/utils/date.js b/packages/devextreme/js/core/utils/date.js index 7aa54270e76..207665f3713 100644 --- a/packages/devextreme/js/core/utils/date.js +++ b/packages/devextreme/js/core/utils/date.js @@ -689,6 +689,45 @@ const getMachineTimezoneName = () => { : null; }; +const getRangesByDates = (dates) => { + const datesInMilliseconds = dates.map((value) => { + const date = new Date(new Date(value).setHours(0, 0, 0, 0)).getTime(); + + return date; + }); + + const sortedDates = datesInMilliseconds.sort((a, b) => a - b); + + const getRange = (date, dates, index) => { + const range = date === dates[index - 1] + ? [date] + : [date, dates[index - 1]]; + + return range.map((value) => new Date(value)); + }; + + const msInDay = toMilliseconds('day'); + const ranges = []; + + let startDate = sortedDates[0]; + + for(let i = 1; i <= sortedDates.length; ++i) { + const currentDate = sortedDates[i]; + const previousDate = sortedDates[i - 1]; + const isNewRange = currentDate - previousDate > msInDay; + + if(isNewRange || i === sortedDates.length) { + const range = getRange(startDate, sortedDates, i); + + ranges.push(range); + + startDate = currentDate; + } + } + + return ranges; +}; + const dateUtils = { dateUnitIntervals: dateUnitIntervals, @@ -752,6 +791,8 @@ const dateUtils = { createDateWithFullYear: createDateWithFullYear, getMachineTimezoneName: getMachineTimezoneName, + + getRangesByDates: getRangesByDates, }; dateUtils.sameView = function(view, date1, date2) {