From d1247fb196a58d08ba44cd88894cccf5997d6f9e Mon Sep 17 00:00:00 2001
From: Aryamnov Eugeniy <51905811+AryamnovEugeniy@users.noreply.github.com>
Date: Thu, 10 Dec 2020 16:26:47 +0300
Subject: [PATCH] fix(react-scheduler): display time in Time Scale correctly
when a DST change is present (#3198)
---
.../src/plugins/day-view.test.tsx | 26 ++++-
.../src/plugins/day-view.tsx | 31 +++++-
.../src/plugins/integrated-grouping.test.tsx | 47 +++++++-
.../src/plugins/integrated-grouping.tsx | 15 ++-
.../src/plugins/week-view.test.tsx | 26 ++++-
.../src/plugins/week-view.tsx | 31 +++++-
.../src/plugins/common/computeds.test.ts | 63 +++++++++++
.../src/plugins/common/computeds.ts | 36 ++++--
.../src/plugins/common/helpers.test.ts | 18 ++-
.../src/plugins/common/helpers.ts | 11 ++
.../integrated-grouping/computeds.test.ts | 104 +++++++++++++++++-
.../plugins/integrated-grouping/computeds.ts | 16 +++
12 files changed, 392 insertions(+), 32 deletions(-)
diff --git a/packages/dx-react-scheduler/src/plugins/day-view.test.tsx b/packages/dx-react-scheduler/src/plugins/day-view.test.tsx
index 4fa9b66170..98b939c69a 100644
--- a/packages/dx-react-scheduler/src/plugins/day-view.test.tsx
+++ b/packages/dx-react-scheduler/src/plugins/day-view.test.tsx
@@ -3,8 +3,11 @@ import { mount } from 'enzyme';
import { pluginDepsToComponents, getComputedState } from '@devexpress/dx-testing';
import { PluginHost } from '@devexpress/dx-react-core';
import {
- computed, viewCellsData,
- calculateWeekDateIntervals, getTimeTableHeight,
+ computed,
+ viewCellsData,
+ timeCellsData,
+ calculateWeekDateIntervals,
+ getTimeTableHeight,
} from '@devexpress/dx-scheduler-core';
import { DayView } from './day-view';
import { BasicView } from './basic-view';
@@ -18,6 +21,7 @@ jest.mock('@devexpress/dx-scheduler-core', () => ({
availableViews: jest.fn(),
calculateWeekDateIntervals: jest.fn(),
getTimeTableHeight: jest.fn(),
+ timeCellsData: jest.fn(),
}));
const defaultDeps = {
@@ -58,6 +62,7 @@ describe('Day View', () => {
(getters, viewName, baseComputed) => baseComputed(getters, viewName),
);
global.Date.now = () => 123;
+ timeCellsData.mockImplementation(() => 'timeCellsData');
});
afterEach(() => {
jest.resetAllMocks();
@@ -108,6 +113,21 @@ describe('Day View', () => {
expect(calculateWeekDateIntervals)
.toHaveBeenCalledWith(2, 3, 4, 5, 1);
});
+
+ it('should export timeCellsData getter', () => {
+ const tree = mount((
+
+ {pluginDepsToComponents(defaultDeps)}
+
+
+ ));
+
+ expect(timeCellsData)
+ .toBeCalledWith(undefined, 0, 24, 30, expect.any(Number));
+
+ expect(getComputedState(tree).timeCellsData)
+ .toBe('timeCellsData');
+ });
});
describe('Templates', () => {
@@ -128,7 +148,7 @@ describe('Day View', () => {
rowComponent: expect.any(Function),
tickCellComponent: expect.any(Function),
labelComponent: expect.any(Function),
- cellsData: getComputedState(tree).viewCellsData,
+ cellsData: getComputedState(tree).timeCellsData,
formatDate: defaultDeps.getter.formatDate,
});
});
diff --git a/packages/dx-react-scheduler/src/plugins/day-view.tsx b/packages/dx-react-scheduler/src/plugins/day-view.tsx
index 9346f40a94..84781098d3 100644
--- a/packages/dx-react-scheduler/src/plugins/day-view.tsx
+++ b/packages/dx-react-scheduler/src/plugins/day-view.tsx
@@ -5,11 +5,17 @@ import {
TemplateConnector,
TemplatePlaceholder,
PluginComponents,
+ Getter,
} from '@devexpress/dx-react-core';
import {
- viewCellsData as viewCellsDataCore, calculateWeekDateIntervals,
- VIEW_TYPES, getTimeTableHeight,
+ viewCellsData as viewCellsDataCore,
+ calculateWeekDateIntervals,
+ VIEW_TYPES,
+ getTimeTableHeight,
+ timeCellsData as timeCellsDataCore,
+ computed,
} from '@devexpress/dx-scheduler-core';
+import { memoize } from '@devexpress/dx-core';
import { BasicView } from './basic-view';
import { VerticalViewProps } from '../types';
@@ -28,6 +34,10 @@ const calculateAppointmentsIntervalsBaseComputed = cellDuration => ({
}) => calculateWeekDateIntervals(
appointments, startViewDate, endViewDate, excludedDays, cellDuration,
);
+const timeCellsDataComputed = (startDayHour, endDayHour) => ({
+ viewCellsData, cellDuration,
+}) => timeCellsDataCore(viewCellsData, startDayHour, endDayHour, cellDuration, Date.now());
+
const TimeScalePlaceholder = () => ;
class DayViewBase extends React.PureComponent {
@@ -57,6 +67,13 @@ class DayViewBase extends React.PureComponent {
timeTableRowComponent: 'TimeTableRow',
};
+ timeCellsDataComputed = memoize((viewName, startDayHour, endDayHour) => getters => computed(
+ getters,
+ viewName,
+ timeCellsDataComputed(startDayHour, endDayHour),
+ getters.timeCellsData,
+ ));
+
render() {
const {
layoutComponent,
@@ -108,22 +125,28 @@ class DayViewBase extends React.PureComponent {
}}
/>
+
+
{(params: any) => (
{({
- currentView, viewCellsData, groups, formatDate,
+ currentView, timeCellsData, groups, formatDate,
groupOrientation: getGroupOrientation,
timeTableElementsMeta,
}) => {
if (currentView.name !== viewName) return ;
const groupOrientation = getGroupOrientation?.(viewName);
+
return (
({
expandGroups: jest.fn(),
updateTimeTableCellElementsMeta: jest.fn(),
updateAllDayCellElementsMeta: jest.fn(),
+ updateTimeCellsData: jest.fn(),
}));
describe('IntegratedGrouping', () => {
@@ -38,6 +45,7 @@ describe('IntegratedGrouping', () => {
allDayElementsMeta: 'allDayElementsMeta',
timeTableElementsMeta: 'timeTableElementsMeta',
allDayPanelExists: 'allDayPanelExists',
+ timeCellsData: 'timeCellsData',
},
};
beforeEach(() => {
@@ -49,6 +57,7 @@ describe('IntegratedGrouping', () => {
expandGroups.mockImplementation(() => 'expandGroups');
updateTimeTableCellElementsMeta.mockImplementation(() => 'timeTableElementsMeta updated');
updateAllDayCellElementsMeta.mockImplementation(() => 'allDayElementsMeta updated');
+ updateTimeCellsData.mockImplementation(() => 'timeCellsData updated');
});
afterEach(jest.resetAllMocks);
@@ -124,6 +133,38 @@ describe('IntegratedGrouping', () => {
.toBe('groupedViewCellsData');
});
+ it('should provide timeCellsData getter', () => {
+ const tree = mount((
+
+ {pluginDepsToComponents(defaultDeps)}
+
+
+ ));
+
+ expect(updateTimeCellsData)
+ .toHaveBeenCalledWith('groupedViewCellsData', 'timeCellsData', 'groups', 'resourcesToGroupBy', 'groupOrientation');
+ expect(getComputedState(tree).timeCellsData)
+ .toBe('timeCellsData updated');
+ });
+
+ it('should not update timeCellsData getter if it is undefined', () => {
+ const tree = mount((
+
+ {pluginDepsToComponents(defaultDeps, {
+ getter: {
+ timeCellsData: undefined,
+ },
+ })}
+
+
+ ));
+
+ expect(updateTimeCellsData)
+ .toHaveBeenCalledTimes(0);
+ expect(getComputedState(tree).timeCellsData)
+ .toBe(undefined);
+ });
+
it('should provide timeTableAppointments getter', () => {
const tree = mount((
diff --git a/packages/dx-react-scheduler/src/plugins/integrated-grouping.tsx b/packages/dx-react-scheduler/src/plugins/integrated-grouping.tsx
index 0492df506c..5a612b9f88 100644
--- a/packages/dx-react-scheduler/src/plugins/integrated-grouping.tsx
+++ b/packages/dx-react-scheduler/src/plugins/integrated-grouping.tsx
@@ -4,7 +4,7 @@ import {
getGroupsFromResources, expandViewCellsDataWithGroups,
sortFilteredResources, filterResourcesByGrouping, updateGroupingWithMainResource,
expandGroups, VERTICAL_GROUP_ORIENTATION, VIEW_TYPES,
- updateTimeTableCellElementsMeta, updateAllDayCellElementsMeta,
+ updateTimeTableCellElementsMeta, updateAllDayCellElementsMeta, updateTimeCellsData,
} from '@devexpress/dx-scheduler-core';
import { IntegratedGroupingProps } from '../types';
@@ -78,6 +78,18 @@ const getAllDayElementsMetaComputed = ({
allDayPanelExists, viewCellsData, currentView,
);
+const getTimeCellsDataComputed = ({
+ viewCellsData, timeCellsData, currentView,
+ groups, resourcesToGroupBy, groupOrientation,
+}: Getters) => timeCellsData
+ && updateTimeCellsData(
+ viewCellsData,
+ timeCellsData,
+ groups,
+ resourcesToGroupBy,
+ groupOrientation(currentView.name),
+ );
+
const IntegratedGroupingBase: React.SFC = React.memo(() => (
= React.memo(()
+
diff --git a/packages/dx-react-scheduler/src/plugins/week-view.test.tsx b/packages/dx-react-scheduler/src/plugins/week-view.test.tsx
index a73d16ebf7..6384772c30 100644
--- a/packages/dx-react-scheduler/src/plugins/week-view.test.tsx
+++ b/packages/dx-react-scheduler/src/plugins/week-view.test.tsx
@@ -3,8 +3,11 @@ import { mount } from 'enzyme';
import { pluginDepsToComponents, getComputedState } from '@devexpress/dx-testing';
import { PluginHost } from '@devexpress/dx-react-core';
import {
- computed, viewCellsData,
- calculateWeekDateIntervals, getTimeTableHeight,
+ computed,
+ viewCellsData,
+ timeCellsData,
+ calculateWeekDateIntervals,
+ getTimeTableHeight,
} from '@devexpress/dx-scheduler-core';
import { WeekView } from './week-view';
import { BasicView } from './basic-view';
@@ -19,6 +22,7 @@ jest.mock('@devexpress/dx-scheduler-core', () => ({
availableViews: jest.fn(),
calculateWeekDateIntervals: jest.fn(),
getTimeTableHeight: jest.fn(),
+ timeCellsData: jest.fn(),
}));
const defaultDeps = {
@@ -57,6 +61,7 @@ describe('Week View', () => {
beforeEach(() => {
computed.mockImplementation((getters, viewName, baseComputed) => baseComputed(getters, viewName));
global.Date.now = () => 123;
+ timeCellsData.mockImplementation(() => 'timeCellsData');
});
afterEach(() => {
jest.resetAllMocks();
@@ -110,6 +115,21 @@ describe('Week View', () => {
expect(calculateWeekDateIntervals)
.toHaveBeenCalledWith(2, 3, 4, 5, 1);
});
+
+ it('should export timeCellsData getter', () => {
+ const tree = mount((
+
+ {pluginDepsToComponents(defaultDeps)}
+
+
+ ));
+
+ expect(timeCellsData)
+ .toBeCalledWith(undefined, 0, 24, 30, expect.any(Number));
+
+ expect(getComputedState(tree).timeCellsData)
+ .toBe('timeCellsData');
+ });
});
describe('Templates', () => {
@@ -130,7 +150,7 @@ describe('Week View', () => {
rowComponent: expect.any(Function),
tickCellComponent: expect.any(Function),
labelComponent: expect.any(Function),
- cellsData: getComputedState(tree).viewCellsData,
+ cellsData: getComputedState(tree).timeCellsData,
formatDate: defaultDeps.getter.formatDate,
});
});
diff --git a/packages/dx-react-scheduler/src/plugins/week-view.tsx b/packages/dx-react-scheduler/src/plugins/week-view.tsx
index 2c8dc30de5..290cca960e 100644
--- a/packages/dx-react-scheduler/src/plugins/week-view.tsx
+++ b/packages/dx-react-scheduler/src/plugins/week-view.tsx
@@ -5,13 +5,19 @@ import {
TemplateConnector,
TemplatePlaceholder,
PluginComponents,
+ Getter,
} from '@devexpress/dx-react-core';
import {
- viewCellsData as viewCellsDataCore, calculateWeekDateIntervals,
- VIEW_TYPES, getTimeTableHeight,
+ viewCellsData as viewCellsDataCore,
+ calculateWeekDateIntervals,
+ VIEW_TYPES,
+ getTimeTableHeight,
+ timeCellsData as timeCellsDataCore,
+ computed,
} from '@devexpress/dx-scheduler-core';
import { BasicView } from './basic-view';
import { WeekViewProps } from '../types';
+import { memoize } from '@devexpress/dx-core';
const DAYS_IN_WEEK = 7;
const viewCellsDataBaseComputed = (
@@ -29,6 +35,10 @@ const calculateAppointmentsIntervalsBaseComputed = cellDuration => ({
}) => calculateWeekDateIntervals(
appointments, startViewDate, endViewDate, excludedDays, cellDuration,
);
+const timeCellsDataComputed = (startDayHour, endDayHour) => ({
+ viewCellsData, cellDuration,
+}) => timeCellsDataCore(viewCellsData, startDayHour, endDayHour, cellDuration, Date.now());
+
const TimeScalePlaceholder = () => ;
class WeekViewBase extends React.PureComponent {
@@ -59,6 +69,13 @@ class WeekViewBase extends React.PureComponent {
timeTableRowComponent: 'TimeTableRow',
};
+ timeCellsDataComputed = memoize((viewName, startDayHour, endDayHour) => getters => computed(
+ getters,
+ viewName,
+ timeCellsDataComputed(startDayHour, endDayHour),
+ getters.timeCellsData,
+ ));
+
render() {
const {
layoutComponent,
@@ -112,22 +129,28 @@ class WeekViewBase extends React.PureComponent {
}}
/>
+
+
{(params: any) => (
{({
- currentView, viewCellsData, groups, formatDate,
+ currentView, timeCellsData, groups, formatDate,
groupOrientation: getGroupOrientation,
timeTableElementsMeta,
}) => {
if (currentView.name !== viewName) return ;
const groupOrientation = getGroupOrientation?.(viewName);
+
return (
{
});
});
});
+
+describe('#timeCellsData', () => {
+ const startDayHour = 2;
+ const endDayHour = 4;
+ const cellDuration = 30;
+
+ it('should return viewCellsData if there is no DST change', () => {
+ const currentDate = '2020-12-07T00:00:00';
+ const cellsData = [[{
+ startDate: new Date('2020-12-07T00:00:00'),
+ endDate: new Date('2020-12-07T00:00:00'),
+ }]];
+
+ expect(timeCellsData(
+ cellsData, startDayHour, endDayHour, cellDuration, currentDate,
+ )).toBe(cellsData);
+ });
+
+ it('should return correct time data when a DST change is present', () => {
+ const dateWithDSTChange = new Date('2020-03-08T02:00:00');
+ const cellsData = [[{
+ startDate: new Date('2020-03-08T02:00:00'),
+ endDate: new Date('2020-03-08T02:30:00'),
+ }], [{
+ startDate: new Date('2020-03-08T02:30:00'),
+ endDate: new Date('2020-03-08T03:00:00'),
+ }], [{
+ startDate: new Date('2020-03-08T03:00:00'),
+ endDate: new Date('2020-03-08T03:30:00'),
+ }], [{
+ startDate: new Date('2020-03-08T03:30:00'),
+ endDate: new Date('2020-03-08T04:00:00'),
+ }]];
+
+ const timeCells = timeCellsData(
+ cellsData, startDayHour, endDayHour, cellDuration, dateWithDSTChange,
+ );
+
+ expect(timeCells)
+ .toHaveLength(4);
+
+ expect(timeCells[0][0].startDate.getHours()).toBe(2);
+ expect(timeCells[0][0].startDate.getMinutes()).toBe(0);
+ expect(timeCells[0][0].endDate.getHours()).toBe(2);
+ expect(timeCells[0][0].endDate.getMinutes()).toBe(30);
+
+ expect(timeCells[1][0].startDate.getHours()).toBe(2);
+ expect(timeCells[1][0].startDate.getMinutes()).toBe(30);
+ expect(timeCells[1][0].endDate.getHours()).toBe(3);
+ expect(timeCells[1][0].endDate.getMinutes()).toBe(0);
+
+ expect(timeCells[2][0].startDate.getHours()).toBe(3);
+ expect(timeCells[2][0].startDate.getMinutes()).toBe(0);
+ expect(timeCells[2][0].endDate.getHours()).toBe(3);
+ expect(timeCells[2][0].endDate.getMinutes()).toBe(30);
+
+ expect(timeCells[3][0].startDate.getHours()).toBe(3);
+ expect(timeCells[3][0].startDate.getMinutes()).toBe(30);
+ expect(timeCells[3][0].endDate.getHours()).toBe(4);
+ expect(timeCells[3][0].endDate.getMinutes()).toBe(0);
+ });
+});
diff --git a/packages/dx-scheduler-core/src/plugins/common/computeds.ts b/packages/dx-scheduler-core/src/plugins/common/computeds.ts
index 74b704a232..715825f0f2 100644
--- a/packages/dx-scheduler-core/src/plugins/common/computeds.ts
+++ b/packages/dx-scheduler-core/src/plugins/common/computeds.ts
@@ -6,7 +6,10 @@ import {
SchedulerView,
} from '../../types';
import { calculateFirstDateOfWeek } from '../../utils';
-import { isMidnight } from './helpers';
+import {
+ isMidnight,
+ containsDSTChange,
+} from './helpers';
const subtractSecond: PureComputed<
[Date]
@@ -31,17 +34,6 @@ export const dayScale: DayScaleFn = (
return result;
};
-const containsDSTChange = (date: SchedulerDateTime) => {
- const momentDate = moment(date);
- momentDate.startOf('day');
- const isStartDST = momentDate.isDST();
-
- momentDate.endOf('day');
- const isEndDst = momentDate.isDST();
-
- return (isStartDST && !isEndDst) || (!isStartDST && isEndDst);
-};
-
export const timeScale: TimeScaleFn = (
currentDate,
firstDayOfWeek,
@@ -119,6 +111,26 @@ export const viewCellsData: ViewCellsDataFn = (
}, [] as ViewCell[][]);
};
+export const timeCellsData: PureComputed<
+ [ViewCell[][], number, number, number, number], ViewCell[][]
+> = (
+ cellsData, startDayHour, endDayHour, cellDuration, currentTime,
+) => {
+ const { startDate: firstViewDate } = cellsData[0][0];
+ if (!containsDSTChange(firstViewDate)) {
+ return cellsData;
+ }
+
+ const nextDay = moment(firstViewDate)
+ .add(1, 'day')
+ .toDate();
+ const validCellsData = viewCellsData(
+ nextDay, undefined, 1, [], startDayHour, endDayHour, cellDuration, currentTime,
+ );
+
+ return validCellsData;
+};
+
export const allDayCells: PureComputed<
[ViewCell[][]], AllDayCell[][]
> = viewCells => [viewCells[0].map(cell => ({
diff --git a/packages/dx-scheduler-core/src/plugins/common/helpers.test.ts b/packages/dx-scheduler-core/src/plugins/common/helpers.test.ts
index b71e851037..238e950d43 100644
--- a/packages/dx-scheduler-core/src/plugins/common/helpers.test.ts
+++ b/packages/dx-scheduler-core/src/plugins/common/helpers.test.ts
@@ -1,6 +1,6 @@
import {
getViewType, isMidnight, viewBoundText, checkCellGroupingInfo,
- isDateValid, areDatesSame, getTimeTableHeight,
+ isDateValid, areDatesSame, getTimeTableHeight, containsDSTChange,
} from './helpers';
import { VERTICAL_TYPE, HORIZONTAL_TYPE } from '../../constants';
import { formatDateTimeGetter } from '../scheduler-core/computeds';
@@ -174,3 +174,19 @@ describe('#getTimeTableHeight', () => {
.toBe('height');
});
});
+
+describe('#containsDSTchange', () => {
+ const pacificTimezoneOffset = 480;
+ const winterDate = new Date(2020, 2, 7);
+ const hasDST = winterDate.getTimezoneOffset() === pacificTimezoneOffset;
+
+ it('should return false when there is no dst change', () => {
+ expect(containsDSTChange(winterDate))
+ .toBe(false);
+ });
+
+ it('should return true when a DST change is present', () => {
+ expect(containsDSTChange(new Date(2020, 2, 8)))
+ .toBe(hasDST);
+ });
+});
diff --git a/packages/dx-scheduler-core/src/plugins/common/helpers.ts b/packages/dx-scheduler-core/src/plugins/common/helpers.ts
index 11dc58bf6d..78732772da 100644
--- a/packages/dx-scheduler-core/src/plugins/common/helpers.ts
+++ b/packages/dx-scheduler-core/src/plugins/common/helpers.ts
@@ -118,3 +118,14 @@ export const areDatesSame: PureComputed<
export const getTimeTableHeight: PureComputed<
[CellElementsMeta], number | undefined
> = timeTableElementsMeta => timeTableElementsMeta.parentRect?.().height;
+
+export const containsDSTChange = (date: SchedulerDateTime) => {
+ const momentDate = moment(date);
+ momentDate.startOf('day');
+ const isStartDST = momentDate.isDST();
+
+ momentDate.endOf('day');
+ const isEndDst = momentDate.isDST();
+
+ return (isStartDST && !isEndDst) || (!isStartDST && isEndDst);
+};
diff --git a/packages/dx-scheduler-core/src/plugins/integrated-grouping/computeds.test.ts b/packages/dx-scheduler-core/src/plugins/integrated-grouping/computeds.test.ts
index f9874dd055..888217d0f6 100644
--- a/packages/dx-scheduler-core/src/plugins/integrated-grouping/computeds.test.ts
+++ b/packages/dx-scheduler-core/src/plugins/integrated-grouping/computeds.test.ts
@@ -2,7 +2,7 @@ import {
filterResourcesByGrouping, sortFilteredResources,
getGroupsFromResources, expandViewCellsDataWithGroups,
updateGroupingWithMainResource, expandGroups, updateTimeTableCellElementsMeta,
- updateAllDayCellElementsMeta,
+ updateAllDayCellElementsMeta, updateTimeCellsData,
} from './computeds';
import { expandGroupedAppointment, groupAppointments } from './helpers';
import { sliceAppointmentsByDays } from '../all-day-panel/helpers';
@@ -496,4 +496,106 @@ describe('IntegratedGrouping computeds', () => {
});
});
});
+
+ describe('#updateTimeCellsData', () => {
+ const groups = [[
+ { fieldName: 'resource1', id: 1 },
+ { fieldName: 'resource1', id: 2 },
+ ]];
+ const resources = [
+ { fieldName: 'resource1' },
+ ];
+ const pacificTimezoneOffset = 480;
+ const winterDate = new Date(2020, 2, 7);
+ const isPacificTimeZone = winterDate.getTimezoneOffset() === pacificTimezoneOffset;
+
+ it('should return viewCellsData if DST change is not present', () => {
+ const viewCellsData = [[{
+ startDate: new Date(2020, 11, 7),
+ endDate: new Date(2020, 11, 7, 1),
+ }]];
+
+ const timeCells = updateTimeCellsData(
+ viewCellsData,
+ undefined,
+ groups,
+ resources,
+ HORIZONTAL_GROUP_ORIENTATION,
+ );
+ expect(timeCells)
+ .toBe(viewCellsData);
+ });
+
+ if (isPacificTimeZone) {
+ it('should return timeCells if DST change is present and horizontal grouping is used', () => {
+ const viewCellsData = [[{
+ startDate: new Date(2020, 2, 8),
+ endDate: new Date(2020, 2, 8, 1),
+ }]];
+ const previousTimeCells = [[{
+ startDate: new Date(2020, 2, 9),
+ endDate: new Date(2020, 2, 9, 1),
+ }]];
+
+ const timeCells = updateTimeCellsData(
+ viewCellsData,
+ previousTimeCells,
+ groups,
+ resources,
+ HORIZONTAL_GROUP_ORIENTATION,
+ );
+
+ expect(timeCells)
+ .not.toBe(viewCellsData);
+ expect(timeCells)
+ .toBe(previousTimeCells);
+ });
+
+ // tslint:disable-next-line: max-line-length
+ it('should return correct timeCells if DST change is present and vertical grouping is used', () => {
+ const viewCellsData = [[{
+ startDate: new Date(2020, 2, 8),
+ endDate: new Date(2020, 2, 8, 1),
+ }]];
+ const previousTimeCells = [[{
+ startDate: new Date(2020, 2, 9),
+ endDate: new Date(2020, 2, 9, 1),
+ }]];
+
+ const timeCells = updateTimeCellsData(
+ viewCellsData,
+ previousTimeCells,
+ groups,
+ resources,
+ VERTICAL_GROUP_ORIENTATION,
+ );
+
+ expect(timeCells)
+ .not.toBe(viewCellsData);
+ expect(timeCells)
+ .not.toBe(previousTimeCells);
+
+ expect(timeCells)
+ .toEqual([[{
+ startDate: new Date(2020, 2, 9),
+ endDate: new Date(2020, 2, 9, 1),
+ groupingInfo: [{
+ id: 1,
+ fieldName: 'resource1',
+ }],
+ endOfGroup: true,
+ groupOrientation: VERTICAL_GROUP_ORIENTATION,
+ }], [{
+ startDate: new Date(2020, 2, 9),
+ endDate: new Date(2020, 2, 9, 1),
+ groupingInfo: [{
+ id: 2,
+ fieldName: 'resource1',
+ }],
+ endOfGroup: true,
+ groupOrientation: VERTICAL_GROUP_ORIENTATION,
+ }]]);
+ });
+ }
+ });
});
diff --git a/packages/dx-scheduler-core/src/plugins/integrated-grouping/computeds.ts b/packages/dx-scheduler-core/src/plugins/integrated-grouping/computeds.ts
index 5f76d8f974..f41ac2bf4f 100644
--- a/packages/dx-scheduler-core/src/plugins/integrated-grouping/computeds.ts
+++ b/packages/dx-scheduler-core/src/plugins/integrated-grouping/computeds.ts
@@ -10,6 +10,7 @@ import {
} from './helpers';
import { sliceAppointmentsByDays } from '../all-day-panel/helpers';
import { HORIZONTAL_GROUP_ORIENTATION, VERTICAL_GROUP_ORIENTATION } from '../../constants';
+import { containsDSTChange } from '../common/helpers';
export const filterResourcesByGrouping: PureComputed<
[Array, Array], Array
@@ -222,3 +223,18 @@ const initializeCellElementsData: PureComputed<
validGetCellRects: cellElementsMeta.getCellRects.slice(),
};
};
+
+export const updateTimeCellsData: PureComputed<
+ [ViewCell[][], ViewCell[][], Group[][], ValidResource[], GroupOrientation], ViewCell[][]
+> = (viewCellsData, timeCellsData, groups, sortedResources, groupOrientation) => {
+ const { startDate: firstViewDate } = viewCellsData[0][0];
+ if (!containsDSTChange(firstViewDate)) {
+ return viewCellsData;
+ }
+
+ if (groupOrientation !== VERTICAL_GROUP_ORIENTATION) {
+ return timeCellsData;
+ }
+
+ return expandVerticallyGroupedCells(timeCellsData, groups, sortedResources);
+};